fix(native-chat): chat copy that promised a retry, an update, or a coming change (#25157)

* fix(native-chat): chat copy that promised a retry, an update, or a coming change

- Subagent and background-task rows Orca can no longer settle read "status
  unavailable" ("2 agents with status unavailable"), not "no recent update",
  which implied an update was still coming.
- /compact or /clear refused behind an unconfirmed earlier message says "Wait
  for the agent to finish, then try again." There is no Retry for that message.
- The skills menu in SSH chats says skills can't be listed there; a skill typed
  by name still goes to the agent.
- A write the host refuses because this agent or location can't run as a chat
  says "Orca can't run this agent in a chat here." plus what didn't happen.
- Spanish gains the chat notice, background-task and subagent rows it lacked.

* fix(native-chat): whole count sentences for background-task states, and translation fixes

- Background-task header counts use one translated sentence per state
  (stateWorkingCount ... stateIdleCount), so Spanish and French can agree
  the state with the count; English output is unchanged and pinned by a test.
- es: subagent failed/idle/stopped counts and the waiting/blocked reasons
  read correctly for any count.
- fr: "listées" agrees with the feminine "skills" in the SSH skills line.
- ja: subagent status-unavailable count uses the 件 counter.
- Correct the refusal-table comment: hostUnsupported is also returned and
  recorded, not only thrown.

* fix(native-chat): es/fr background-task counts agree with any task kind

* revert(native-chat): leave the /compact unconfirmed-message refusal to its own PR

Restores main's settleEarlierMessage copy in every locale and drops its comment.
The refusal's behaviour, not only its words, is being fixed separately.

* test(native-chat): expect this PR's Spanish blocked reason in the tool-run language test
This commit is contained in:
Brennan Benson
2026-10-06 11:52:35 -07:00
committed by GitHub
parent defd85a9eb
commit 07981bd12e
23 changed files with 186 additions and 73 deletions
@@ -127,7 +127,7 @@ describe('NativeChatPickerMenu', () => {
/>
)
expect(screen.getAllByText("Skills aren't available in SSH chats")).toHaveLength(2)
expect(screen.getAllByText("Skills can't be listed in SSH chats")).toHaveLength(2)
expect(screen.queryByText("Couldn't load skills")).toBeNull()
expect(screen.queryByRole('button', { name: 'Retry' })).toBeNull()
})
@@ -44,7 +44,7 @@ export const NativeChatPickerMenu = memo(function NativeChatPickerMenu({
autocomplete.skillErrorKind === 'unavailable'
? translate(
'components.native-chat.composer.skillsUnavailableHost',
"Skills aren't available in SSH chats"
"Skills can't be listed in SSH chats"
)
: translate('components.native-chat.composer.skillsLoadFailed', "Couldn't load skills")
@@ -62,10 +62,10 @@ describe('NativeChatBackgroundTaskRun', () => {
expect(screen.getAllByText('Background task')).toHaveLength(1)
})
it('reads a state this build has no word for as no recent update, never as live', () => {
it('reads a state this build has no word for as status unavailable, never as live', () => {
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: models a row a newer build wrote, which the wire admits as an open string.
render(<NativeChatBackgroundTaskRun block={task({ state: 'teleported' as 'done' })} />)
expect(screen.getByText(/no recent update/)).toBeInTheDocument()
expect(screen.getByText(/status unavailable/)).toBeInTheDocument()
})
})
@@ -291,7 +291,7 @@ describe('background-task row reasons', () => {
{ id: 'a4', kind: 'agent', description: 'busy child', state: 'working' }
])
expect(rows).toHaveLength(4)
expect(rows[0].textContent).toContain('ssh child · no recent update')
expect(rows[0].textContent).toContain('ssh child · status unavailable')
expect(rows[1].textContent).toContain('flaky child · failed')
expect(rows[2].textContent).toContain('approval child · needs approval')
// A running row has nothing to explain.
@@ -104,7 +104,7 @@ it("says a code's own words that the history didn't load, and nothing under them
})
// "This isn't available in this chat." would name nothing the reader asked for.
it('says only that the history did not load for a chat its host cannot run', () => {
it('says why the history did not load for a chat its host cannot run', () => {
mocks.status = 'error'
mocks.readRefusal = {
code: 'structured_agent_session_unsupported',
@@ -114,7 +114,11 @@ it('says only that the history did not load for a chat its host cannot run', ()
renderPane()
expect(screen.getAllByText("This chat's history couldn't be loaded.")).toHaveLength(1)
expect(
screen.getAllByText(
"Orca can't run this agent in a chat here. This chat's history couldn't be loaded."
)
).toHaveLength(1)
expect(screen.queryByText(/isn't available|newer Orca/)).toBeNull()
})
@@ -168,7 +168,7 @@ describe('NativeChatSubagentRun', () => {
)
const row = screen.getByRole('button')
expect(row).toHaveTextContent('no recent update')
expect(row).toHaveTextContent('status unavailable')
// `unverifiable` with no terminal timestamp has no known run length, so the
// clock would measure to `now` and report the time since we lost sight of
// the child as how long it ran — on a row that is not even counting.
@@ -189,7 +189,7 @@ describe('NativeChatSubagentRun', () => {
)
const row = screen.getByRole('button')
expect(row).toHaveTextContent('1 with no recent update')
expect(row).toHaveTextContent('1 with status unavailable')
expect(row.textContent).not.toContain('·')
})
@@ -48,7 +48,10 @@ function subagentStateLabel(
case 'stopped':
return translate('components.native-chat.subagents.state.stopped', 'stopped')
case 'unverifiable':
return translate('components.native-chat.subagents.state.unverifiable', 'no recent update')
return translate(
'components.native-chat.subagents.state.unverifiable',
'status unavailable'
)
}
}
switch (state) {
@@ -79,7 +82,7 @@ function subagentStateLabel(
case 'unverifiable':
return translate(
'components.native-chat.subagents.state.unverifiableCount',
'{{value0}} with no recent update',
'{{value0}} with status unavailable',
{ value0: count }
)
}
@@ -101,6 +101,6 @@ describe('tool run sentences', () => {
expect(screen.getByText('Subagente')).toBeInTheDocument()
expect(screen.getByText('Flujo de trabajo en segundo plano')).toBeInTheDocument()
expect(screen.getByText('Salida: /tmp/result.txt')).toBeInTheDocument()
expect(screen.getByText('bloqueado · falló')).toBeInTheDocument()
expect(screen.getByText('bloqueado · con error')).toBeInTheDocument()
})
})
@@ -65,6 +65,8 @@ const SENTENCES: Record<AgentSessionWriteNoticeSentence, () => string> = {
unsupported: () => translate('components.native-chat.writeNotice.unsupported', COPY.unsupported),
notAvailable: () =>
translate('components.native-chat.writeNotice.notAvailable', COPY.notAvailable),
cannotRunHere: () =>
translate('components.native-chat.writeNotice.cannotRunHere', COPY.cannotRunHere),
unreachable: () => translate('components.native-chat.writeNotice.unreachable', COPY.unreachable),
recordFailed: () =>
translate('components.native-chat.writeNotice.recordFailed', COPY.recordFailed),
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest'
import type { AgentSessionBackgroundTask } from '../../../../shared/agent-session-wire'
import { backgroundTasksHeaderContent } from './background-task-header-content'
import {
backgroundTaskCountedState,
buildBackgroundTaskGroups,
formatBackgroundTaskTokens,
resolveBackgroundTaskName
@@ -77,7 +78,7 @@ describe('backgroundTasksHeaderContent', () => {
expect(
header([agent('a', { state: 'unverifiable' }), agent('b', { state: 'unverifiable' })])
).toEqual({
segments: [{ text: '2 agents with no recent update', kind: 'agent' }],
segments: [{ text: '2 agents with status unavailable', kind: 'agent' }],
detail: null
})
})
@@ -184,6 +185,18 @@ describe('buildBackgroundTaskGroups', () => {
})
})
describe('backgroundTaskCountedState', () => {
it('words a count with each state as one sentence', () => {
expect(backgroundTaskCountedState('2 agents', 'working')).toBe('2 agents working')
expect(backgroundTaskCountedState('2 agents', 'monitoring')).toBe('2 agents monitoring')
expect(backgroundTaskCountedState('2 agents', 'waiting')).toBe('2 agents waiting')
expect(backgroundTaskCountedState('2 agents', 'blocked')).toBe('2 agents blocked')
expect(backgroundTaskCountedState('2 agents', 'done')).toBe('2 agents done')
expect(backgroundTaskCountedState(3, 'idle')).toBe('3 stopped')
expect(backgroundTaskCountedState(3, 'unverifiable')).toBe('3 with status unavailable')
})
})
describe('formatBackgroundTaskTokens', () => {
it('renders compact token counts like the mock', () => {
expect(formatBackgroundTaskTokens(950)).toBe('950')
@@ -122,9 +122,10 @@ export function backgroundTaskStateWord(state: RunState): string {
case 'idle':
return translate('components.native-chat.backgroundTasks.stateIdle', 'stopped')
case 'unverifiable':
// Settled unknown or out of contact: claims neither an exit nor a coming update.
return translate(
'components.native-chat.backgroundTasks.stateUnverifiable',
'no recent update'
'status unavailable'
)
}
}
@@ -146,15 +147,52 @@ export function backgroundTaskStateReason(state: RunState): string | null {
}
}
/** A count and its state ("2 agents waiting"); after a count, "no recent update" needs a "with". */
/** A count and its state ("2 agents waiting"), one whole sentence per state so a language can
* agree the state with the count. */
export function backgroundTaskCountedState(counted: string | number, state: RunState): string {
return state === 'unverifiable'
? translate(
'components.native-chat.backgroundTasks.stateUnverifiableCount',
'{{value0}} with no recent update',
switch (state) {
case 'working':
return translate(
'components.native-chat.backgroundTasks.stateWorkingCount',
'{{value0}} working',
{ value0: counted }
)
: `${counted} ${backgroundTaskStateWord(state)}`
case 'monitoring':
return translate(
'components.native-chat.backgroundTasks.stateMonitoringCount',
'{{value0}} monitoring',
{ value0: counted }
)
case 'waiting':
return translate(
'components.native-chat.backgroundTasks.stateWaitingCount',
'{{value0}} waiting',
{ value0: counted }
)
case 'blocked':
return translate(
'components.native-chat.backgroundTasks.stateBlockedCount',
'{{value0}} blocked',
{ value0: counted }
)
case 'done':
return translate('components.native-chat.backgroundTasks.stateDoneCount', '{{value0}} done', {
value0: counted
})
case 'idle':
return translate(
'components.native-chat.backgroundTasks.stateIdleCount',
'{{value0}} stopped',
{ value0: counted }
)
case 'unverifiable':
// After a count, "status unavailable" needs a "with".
return translate(
'components.native-chat.backgroundTasks.stateUnverifiableCount',
'{{value0}} with status unavailable',
{ value0: counted }
)
}
}
function tokenScaleText(value: number): string {
File diff suppressed because one or more lines are too long
@@ -221,7 +221,7 @@ describe('chat strip rows from a legacy background-task roster', () => {
container.innerHTML = markup
expect([...container.querySelectorAll('li')].map((row) => row.textContent)).toEqual([
'Failed child · failed',
'Background agent · no recent updateStop',
'Background agent · status unavailableStop',
'Cancelled child',
'Approve edits · needs approvalStop',
'Summarize logs900',
+1
View File
@@ -2892,6 +2892,7 @@
"messageNotSaved": "Couldn't save your message.",
"messagesUnsettled": "A message you sent earlier isn't confirmed yet.",
"notAvailable": "This isn't available in this chat.",
"cannotRunHere": "Orca can't run this agent in a chat here.",
"notDoneAnswer": "Your answer was not sent.",
"notDoneCommand": "The command didn't run.",
"notDoneGoal": "The goal wasn't changed.",
+12 -5
View File
@@ -17845,6 +17845,7 @@
"updateOrcaToOpenChat": "Update Orca to open it.",
"unsupported": "This needs a newer Orca on the computer running this chat. Update Orca there, then try again.",
"notAvailable": "This isn't available in this chat.",
"cannotRunHere": "Orca can't run this agent in a chat here.",
"unreachable": "Orca couldn't reach the agent.",
"recordFailed": "Orca couldn't save this to the chat's history.",
"conversationCleared": "This conversation has been cleared.",
@@ -17929,7 +17930,7 @@
"skills": "Skills",
"loadingSkills": "Loading skills...",
"skillsLoaded": "Skills loaded",
"skillsUnavailableHost": "Skills aren't available in SSH chats",
"skillsUnavailableHost": "Skills can't be listed in SSH chats",
"skillsLoadFailed": "Couldn't load skills",
"retrySkills": "Retry",
"skillCommandCollision": "Also a skill name - agent decides",
@@ -18116,13 +18117,19 @@
"countTasksMany": "{{value0}} tasks",
"headerTotal": "{{value0}} background tasks",
"stateWorking": "working",
"stateWorkingCount": "{{value0}} working",
"stateMonitoring": "monitoring",
"stateMonitoringCount": "{{value0}} monitoring",
"stateWaiting": "waiting",
"stateWaitingCount": "{{value0}} waiting",
"stateBlocked": "blocked",
"stateBlockedCount": "{{value0}} blocked",
"stateDone": "done",
"stateDoneCount": "{{value0}} done",
"stateIdle": "stopped",
"stateUnverifiable": "no recent update",
"stateUnverifiableCount": "{{value0}} with no recent update",
"stateIdleCount": "{{value0}} stopped",
"stateUnverifiable": "status unavailable",
"stateUnverifiableCount": "{{value0}} with status unavailable",
"reasonWaiting": "needs approval",
"reasonBlocked": "failed",
"groupAgents": "Agents",
@@ -18210,12 +18217,12 @@
"idle": "idle",
"failed": "failed",
"stopped": "stopped",
"unverifiable": "no recent update",
"unverifiable": "status unavailable",
"workingCount": "{{value0}} working",
"idleCount": "{{value0}} idle",
"failedCount": "{{value0}} failed",
"stoppedCount": "{{value0}} stopped",
"unverifiableCount": "{{value0}} with no recent update"
"unverifiableCount": "{{value0}} with status unavailable"
},
"startedOne": "Kicked off 1 subagent",
"startedN": "Kicked off {{value0}} subagents",
+19 -12
View File
@@ -17621,6 +17621,7 @@
"updateOrcaToOpenChat": "Actualice Orca para abrirlo.",
"unsupported": "Esto requiere una versión más reciente de Orca en el equipo que ejecuta este chat. Actualice Orca allí y vuelva a intentarlo.",
"notAvailable": "Esto no está disponible en este chat.",
"cannotRunHere": "Orca no puede ejecutar este agente en un chat aquí.",
"unreachable": "Orca no pudo comunicarse con el agente.",
"recordFailed": "Orca no pudo guardar esto en el historial del chat.",
"conversationCleared": "Esta conversación se borró.",
@@ -17704,7 +17705,7 @@
"commands": "Comandos",
"skills": "Habilidades",
"loadingSkills": "Cargando habilidades…",
"skillsUnavailableHost": "Las habilidades no están disponibles en los chats SSH",
"skillsUnavailableHost": "Las habilidades no se pueden listar en los chats SSH",
"skillsLoadFailed": "No se pudieron cargar las habilidades",
"retrySkills": "Reintentar",
"skillCommandCollision": "También es un nombre de habilidad - el agente decide",
@@ -17908,17 +17909,17 @@
"subagents": {
"unnamed": "Subagente",
"state": {
"failedCount": "{{value0}} fallidas",
"failedCount": "{{value0}} con error",
"working": "trabajando",
"failed": "falló",
"stopped": "detenido",
"unverifiable": "sin actualización reciente",
"unverifiableCount": "{{value0}} sin actualización reciente",
"unverifiable": "estado no disponible",
"unverifiableCount": "{{value0}} con estado no disponible",
"completed": "completado",
"idle": "idle",
"idle": "inactivo",
"workingCount": "{{value0}} trabajando",
"idleCount": "{{value0}} inactivo",
"stoppedCount": "{{value0}} detenido"
"idleCount": "{{value0}} inactivo(s)",
"stoppedCount": "{{value0}} detenido(s)"
},
"startedOne": "Inició 1 subagente",
"startedN": "Inició {{value0}} subagentes",
@@ -17986,15 +17987,21 @@
"countTasksMany": "{{value0}} tareas",
"headerTotal": "{{value0}} tareas en segundo plano",
"stateWorking": "trabajando",
"stateWorkingCount": "{{value0}} trabajando",
"stateMonitoring": "supervisando",
"stateMonitoringCount": "{{value0}} supervisando",
"stateWaiting": "esperando",
"stateWaitingCount": "{{value0}} esperando",
"stateBlocked": "bloqueado",
"stateDone": "listo",
"stateBlockedCount": "{{value0}} en estado bloqueado",
"stateDone": "terminado",
"stateDoneCount": "{{value0}} en estado terminado",
"stateIdle": "detenido",
"stateUnverifiable": "sin actualización reciente",
"stateUnverifiableCount": "{{value0}} sin actualización reciente",
"reasonWaiting": "necesita aprobación",
"reasonBlocked": "falló",
"stateIdleCount": "{{value0}} en estado detenido",
"stateUnverifiable": "estado no disponible",
"stateUnverifiableCount": "{{value0}} con estado no disponible",
"reasonWaiting": "aprobación pendiente",
"reasonBlocked": "con error",
"groupShell": "Shell",
"groupMonitors": "Monitores",
"groupWorkflows": "Flujos de trabajo"
+12 -5
View File
@@ -17720,6 +17720,7 @@
"updateOrcaToOpenChat": "Mettez à jour Orca pour l'ouvrir.",
"unsupported": "Cela nécessite une version plus récente d'Orca sur l'ordinateur qui exécute ce chat. Mettez Orca à jour sur cet ordinateur, puis réessayez.",
"notAvailable": "Ceci n'est pas disponible dans ce chat.",
"cannotRunHere": "Orca ne peut pas exécuter cet agent dans un chat ici.",
"unreachable": "Orca n'a pas pu joindre l'agent.",
"recordFailed": "Orca n'a pas pu enregistrer ceci dans l'historique du chat.",
"conversationCleared": "Cette conversation a été effacée.",
@@ -17768,7 +17769,7 @@
"skills": "Skills",
"loadingSkills": "Chargement des skills...",
"skillsLoaded": "Skills chargées",
"skillsUnavailableHost": "Les skills ne sont pas disponibles dans les chats SSH",
"skillsUnavailableHost": "Les skills ne peuvent pas être listées dans les chats SSH",
"skillsLoadFailed": "Impossible de charger les skills",
"retrySkills": "Réessayer",
"skillCommandCollision": "Aussi un nom de skill - l'agent décide",
@@ -18054,13 +18055,19 @@
"countTasksMany": "{{value0}} tâches",
"headerTotal": "{{value0}} tâches en arrière-plan",
"stateWorking": "fonctionnement",
"stateWorkingCount": "{{value0}} en cours",
"stateMonitoring": "surveillance",
"stateMonitoringCount": "{{value0}} en surveillance",
"stateWaiting": "en attendant",
"stateWaitingCount": "{{value0}} en attente",
"stateBlocked": "bloqué",
"stateBlockedCount": "{{value0}} à l'état bloqué",
"stateDone": "fait",
"stateDoneCount": "{{value0}} à l'état terminé",
"stateIdle": "arrêté",
"stateUnverifiable": "aucune mise à jour récente",
"stateUnverifiableCount": "{{value0}} sans mise à jour récente",
"stateIdleCount": "{{value0}} à l'état arrêté",
"stateUnverifiable": "statut indisponible",
"stateUnverifiableCount": "{{value0}} au statut indisponible",
"reasonWaiting": "a besoin d'approbation",
"reasonBlocked": "échoué",
"groupAgents": "Agents",
@@ -18085,12 +18092,12 @@
"idle": "idle",
"failed": "échoué",
"stopped": "arrêté",
"unverifiable": "aucune mise à jour récente",
"unverifiable": "statut indisponible",
"workingCount": "{{value0}} fonctionne",
"idleCount": "{{value0}} inactif",
"failedCount": "{{value0}} a échoué",
"stoppedCount": "{{value0}} arrêté",
"unverifiableCount": "{{value0}} sans mise à jour récente"
"unverifiableCount": "{{value0}} au statut indisponible"
},
"startedOne": "A lancé 1 sous-agent",
"startedN": "Lancement des sous-agents {{value0}}",
+12 -5
View File
@@ -17656,6 +17656,7 @@
"updateOrcaToOpenChat": "開くには Orca を更新してください。",
"unsupported": "このチャットを実行しているコンピューターに新しいバージョンの Orca が必要です。そのコンピューターで Orca を更新してから、もう一度お試しください。",
"notAvailable": "このチャットでは利用できません。",
"cannotRunHere": "Orca はここでこの Agent をチャットで実行できません。",
"unreachable": "Orca は Agent に接続できませんでした。",
"recordFailed": "Orca はこれをチャットの履歴に保存できませんでした。",
"conversationCleared": "この会話はクリアされました。",
@@ -17739,7 +17740,7 @@
"commands": "コマンド",
"skills": "スキル",
"loadingSkills": "スキルを読み込み中…",
"skillsUnavailableHost": "SSH チャットではスキルを利用できません",
"skillsUnavailableHost": "SSH チャットではスキルを一覧表示できません",
"skillsLoadFailed": "スキルを読み込めませんでした",
"retrySkills": "再試行",
"skillCommandCollision": "スキル名でもあります - Agent が判断します",
@@ -17990,13 +17991,19 @@
"countTasksMany": "{{value0}} タスク",
"headerTotal": "{{value0}} バックグラウンドタスク",
"stateWorking": "実行中",
"stateWorkingCount": "{{value0}} 実行中",
"stateMonitoring": "監視",
"stateMonitoringCount": "{{value0}} 監視",
"stateWaiting": "待機中",
"stateWaitingCount": "{{value0}} 待機中",
"stateBlocked": "ブロックされました",
"stateBlockedCount": "{{value0}} ブロックされました",
"stateDone": "終わり",
"stateDoneCount": "{{value0}} 終わり",
"stateIdle": "止まった",
"stateUnverifiable": "最近の更新なし",
"stateUnverifiableCount": "{{value0}} は最近の更新なし",
"stateIdleCount": "{{value0}} 止まった",
"stateUnverifiable": "状態を取得できません",
"stateUnverifiableCount": "{{value0}} は状態を取得できません",
"reasonWaiting": "承認が必要です",
"reasonBlocked": "失敗した",
"groupAgents": "Agent",
@@ -18021,12 +18028,12 @@
"idle": "idle",
"failed": "失敗した",
"stopped": "止まった",
"unverifiable": "最近の更新なし",
"unverifiable": "状態を取得できません",
"workingCount": "{{value0}} は動作しています",
"idleCount": "{{value0}} アイドル状態",
"failedCount": "{{value0}} 件失敗",
"stoppedCount": "{{value0}} が停止しました",
"unverifiableCount": "{{value0}} は最近の更新なし"
"unverifiableCount": "{{value0}} 件は状態を取得できません"
},
"startedOne": "1 人のサブ Agent を解雇しました",
"startedN": "{{value0}} サブ Agent をキックオフしました",
+12 -5
View File
@@ -17656,6 +17656,7 @@
"updateOrcaToOpenChat": "열려면 Orca를 업데이트하세요.",
"unsupported": "이 채팅을 실행 중인 컴퓨터에 최신 버전의 Orca가 필요합니다. 해당 컴퓨터에서 Orca를 업데이트한 후 다시 시도하세요.",
"notAvailable": "이 채팅에서는 사용할 수 없습니다.",
"cannotRunHere": "Orca는 여기에서 이 에이전트를 채팅으로 실행할 수 없습니다.",
"unreachable": "Orca가 에이전트에 연결하지 못했습니다.",
"recordFailed": "Orca가 이 내용을 채팅 기록에 저장하지 못했습니다.",
"conversationCleared": "이 대화는 지워졌습니다.",
@@ -17739,7 +17740,7 @@
"commands": "명령어",
"skills": "스킬",
"loadingSkills": "스킬 로딩 중…",
"skillsUnavailableHost": "SSH 채팅에서는 스킬을 사용할 수 없습니다",
"skillsUnavailableHost": "SSH 채팅에서는 스킬 목록을 표시할 수 없습니다",
"skillsLoadFailed": "스킬을 불러올 수 없습니다",
"retrySkills": "재시도",
"skillCommandCollision": "스킬 이름이기도 합니다 - 에이전트가 결정합니다",
@@ -17990,13 +17991,19 @@
"countTasksMany": "{{value0}} 작업",
"headerTotal": "{{value0}} 백그라운드 작업",
"stateWorking": "작업 중",
"stateWorkingCount": "{{value0}} 작업 중",
"stateMonitoring": "모니터링",
"stateMonitoringCount": "{{value0}} 모니터링",
"stateWaiting": "대기 중",
"stateWaitingCount": "{{value0}} 대기 중",
"stateBlocked": "막힌",
"stateBlockedCount": "{{value0}} 막힌",
"stateDone": "완료",
"stateDoneCount": "{{value0}} 완료",
"stateIdle": "중지됨",
"stateUnverifiable": "최근 업데이트 없음",
"stateUnverifiableCount": "{{value0}} 최근 업데이트 없음",
"stateIdleCount": "{{value0}} 중지됨",
"stateUnverifiable": "상태를 확인할 수 없음",
"stateUnverifiableCount": "{{value0}} 상태를 확인할 수 없음",
"reasonWaiting": "승인이 필요합니다",
"reasonBlocked": "실패한",
"groupAgents": "에이전트",
@@ -18021,12 +18028,12 @@
"idle": "idle",
"failed": "실패한",
"stopped": "중지됨",
"unverifiable": "최근 업데이트 없음",
"unverifiable": "상태를 확인할 수 없음",
"workingCount": "{{value0}} 작업 중",
"idleCount": "{{value0}} 유휴",
"failedCount": "{{value0}} 실패",
"stoppedCount": "{{value0}} 중지됨",
"unverifiableCount": "{{value0}} 최근 업데이트 없음"
"unverifiableCount": "{{value0}} 상태를 확인할 수 없음"
},
"startedOne": "서브에이전트 1명 추방",
"startedN": "{{value0}} 하위 에이전트가 시작되었습니다.",
+12 -5
View File
@@ -17621,6 +17621,7 @@
"updateOrcaToOpenChat": "请更新 Orca 以打开它。",
"unsupported": "运行此聊天的计算机需要更新版本的 Orca。请在该计算机上更新 Orca 后重试。",
"notAvailable": "此聊天中无法使用此功能。",
"cannotRunHere": "Orca 无法在此处以聊天方式运行此智能体。",
"unreachable": "Orca 无法连接到智能体。",
"recordFailed": "Orca 无法将此内容保存到聊天历史记录中。",
"conversationCleared": "此对话已被清除。",
@@ -17704,7 +17705,7 @@
"commands": "命令",
"skills": "技能",
"loadingSkills": "正在加载技能…",
"skillsUnavailableHost": "SSH 聊天中无法使用技能",
"skillsUnavailableHost": "SSH 聊天中无法列出技能",
"skillsLoadFailed": "无法加载技能",
"retrySkills": "重试",
"skillCommandCollision": "也是技能名称 — 由智能体决定",
@@ -17955,13 +17956,19 @@
"countTasksMany": "{{value0}} 任务",
"headerTotal": "{{value0}} 后台任务",
"stateWorking": "处理中",
"stateWorkingCount": "{{value0}} 处理中",
"stateMonitoring": "监控",
"stateMonitoringCount": "{{value0}} 监控",
"stateWaiting": "等待",
"stateWaitingCount": "{{value0}} 等待",
"stateBlocked": "被阻止",
"stateBlockedCount": "{{value0}} 被阻止",
"stateDone": "完毕",
"stateDoneCount": "{{value0}} 完毕",
"stateIdle": "停止了",
"stateUnverifiable": "暂无近期更新",
"stateUnverifiableCount": "{{value0}} 暂无近期更新",
"stateIdleCount": "{{value0}} 停止了",
"stateUnverifiable": "状态不可用",
"stateUnverifiableCount": "{{value0}} 状态不可用",
"reasonWaiting": "需要批准",
"reasonBlocked": "失败的",
"groupAgents": "智能体",
@@ -17986,12 +17993,12 @@
"idle": "idle",
"failed": "失败的",
"stopped": "停止了",
"unverifiable": "暂无近期更新",
"unverifiable": "状态不可用",
"workingCount": "{{value0}} 工作",
"idleCount": "{{value0}} 空闲",
"failedCount": "{{value0}} 失败",
"stoppedCount": "{{value0}} 已停止",
"unverifiableCount": "{{value0}} 暂无近期更新"
"unverifiableCount": "{{value0}} 状态不可用"
},
"startedOne": "踢掉 1 个子智能体",
"startedN": "启动 {{value0}} 子智能体",
@@ -341,15 +341,21 @@ describe('the notice for every reason a host names', () => {
}))
)
// An unsupported location or agent, or no chat host, is not fixed by updating Orca. A read asked
// for nothing "this" could name, so it says only that the history didn't load.
it('says an unsupported write only is not available when the host names why', () => {
// An unsupported location or agent, or no chat host, is not fixed by updating Orca. Only an
// agent or location the host can't run names its cause; a read otherwise asked for nothing
// "this" could name, so it says only that the history didn't load.
it('says an unsupported write never asks for an update when the host names why', () => {
for (const { failure, write, parts, cell } of cells) {
if (failure.code === 'structured_agent_session_unsupported') {
expect(parts, cell).toEqual(
write === 'read-history' ? ['notDoneReadHistory'] : ['notAvailable']
)
if (failure.code !== 'structured_agent_session_unsupported') {
continue
}
if (failure.details?.reason === 'hostUnsupported') {
expect(parts, cell).toEqual(['cannotRunHere', NOT_DONE[write]])
continue
}
expect(parts, cell).toEqual(
write === 'read-history' ? ['notDoneReadHistory'] : ['notAvailable']
)
}
})
@@ -441,7 +447,9 @@ describe('the notice for every reason a host names', () => {
const notDone = parts.filter((part) => typeof part === 'string' && part.startsWith('notDone'))
const answeredAway = write === 'answer' && parts.includes('questionChanged')
const unsupported =
failure.code === 'structured_agent_session_unsupported' && write !== 'read-history'
failure.code === 'structured_agent_session_unsupported' &&
failure.details?.reason !== 'hostUnsupported' &&
write !== 'read-history'
const saysNotDone =
write === 'read-history' && failure.code === 'agent_session_journal_unreadable'
expect(notDone, cell).toEqual(
@@ -165,14 +165,15 @@ const REASON_WORDS = {
history: { cause: 'chatSavedByNewerOrca', step: 'updateOrcaToOpenChat' }
}
},
// Thrown, so a client meets these only as an RPC error. The code's own words ask for an update,
// which only a method the host doesn't know proves; no reason here means an older Orca. An
// unsupported location or agent, or no chat host, is not fixed by updating, and a client missing
// the capability words this with its own older copy.
// Mostly thrown as an RPC error; `hostUnsupported` is also returned and recorded. The code's own
// words ask for an update, which only a method the host doesn't know proves; no reason here means
// an older Orca. An unsupported location or agent, or no chat host, is not fixed by updating, and
// a client missing the capability words this with its own older copy. Only `hostUnsupported`
// names its cause: this agent or location can't run as a chat.
structured_agent_session_unsupported: {
clientCapabilityMissing: causeWords('notAvailable', 'hostFinding'),
hostDisabled: causeWords('notAvailable', 'hostFinding'),
hostUnsupported: causeWords('notAvailable', 'hostFinding')
hostUnsupported: causeWords('cannotRunHere', 'hostFinding')
},
agent_session_owner_restart_failed: {}
} satisfies {
@@ -41,6 +41,7 @@ export const AGENT_SESSION_WRITE_NOTICE_COPY = {
unsupported:
'This needs a newer Orca on the computer running this chat. Update Orca there, then try again.',
notAvailable: "This isn't available in this chat.",
cannotRunHere: "Orca can't run this agent in a chat here.",
unreachable: "Orca couldn't reach the agent.",
recordFailed: "Orca couldn't save this to the chat's history.",
conversationCleared: 'This conversation has been cleared.',