diff --git a/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.test.tsx b/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.test.tsx
index d07ae3ae745..1d985c70118 100644
--- a/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.test.tsx
@@ -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()
})
diff --git a/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.tsx b/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.tsx
index a88157523a6..0ae77cafa9a 100644
--- a/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatAutocompleteMenus.tsx
@@ -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")
diff --git a/src/renderer/src/components/native-chat/NativeChatBackgroundTaskRun.test.tsx b/src/renderer/src/components/native-chat/NativeChatBackgroundTaskRun.test.tsx
index cf1da100b4e..dc9e79c39bb 100644
--- a/src/renderer/src/components/native-chat/NativeChatBackgroundTaskRun.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatBackgroundTaskRun.test.tsx
@@ -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()
- expect(screen.getByText(/no recent update/)).toBeInTheDocument()
+ expect(screen.getByText(/status unavailable/)).toBeInTheDocument()
})
})
diff --git a/src/renderer/src/components/native-chat/NativeChatBackgroundTasksStatus.test.tsx b/src/renderer/src/components/native-chat/NativeChatBackgroundTasksStatus.test.tsx
index 8e829556fc0..b7c2947dc76 100644
--- a/src/renderer/src/components/native-chat/NativeChatBackgroundTasksStatus.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatBackgroundTasksStatus.test.tsx
@@ -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.
diff --git a/src/renderer/src/components/native-chat/NativeChatStructuredSession.read-error.test.tsx b/src/renderer/src/components/native-chat/NativeChatStructuredSession.read-error.test.tsx
index dd1f1846ec4..3715910cbc3 100644
--- a/src/renderer/src/components/native-chat/NativeChatStructuredSession.read-error.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatStructuredSession.read-error.test.tsx
@@ -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()
})
diff --git a/src/renderer/src/components/native-chat/NativeChatSubagentRun.test.tsx b/src/renderer/src/components/native-chat/NativeChatSubagentRun.test.tsx
index e66130b9c93..ddbb96347e3 100644
--- a/src/renderer/src/components/native-chat/NativeChatSubagentRun.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatSubagentRun.test.tsx
@@ -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('·')
})
diff --git a/src/renderer/src/components/native-chat/NativeChatSubagentRun.tsx b/src/renderer/src/components/native-chat/NativeChatSubagentRun.tsx
index d6fdf3b5e76..a5d9b2a2837 100644
--- a/src/renderer/src/components/native-chat/NativeChatSubagentRun.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatSubagentRun.tsx
@@ -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 }
)
}
diff --git a/src/renderer/src/components/native-chat/NativeChatToolRun.sentences.test.tsx b/src/renderer/src/components/native-chat/NativeChatToolRun.sentences.test.tsx
index 7f6a25d965d..086aca9b749 100644
--- a/src/renderer/src/components/native-chat/NativeChatToolRun.sentences.test.tsx
+++ b/src/renderer/src/components/native-chat/NativeChatToolRun.sentences.test.tsx
@@ -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()
})
})
diff --git a/src/renderer/src/components/native-chat/agent-session-write-notice-text.ts b/src/renderer/src/components/native-chat/agent-session-write-notice-text.ts
index 706777fe645..44f5e737f2a 100644
--- a/src/renderer/src/components/native-chat/agent-session-write-notice-text.ts
+++ b/src/renderer/src/components/native-chat/agent-session-write-notice-text.ts
@@ -65,6 +65,8 @@ const SENTENCES: Record 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),
diff --git a/src/renderer/src/components/native-chat/background-task-roster.test.ts b/src/renderer/src/components/native-chat/background-task-roster.test.ts
index d4d6167533f..804bd68bcb5 100644
--- a/src/renderer/src/components/native-chat/background-task-roster.test.ts
+++ b/src/renderer/src/components/native-chat/background-task-roster.test.ts
@@ -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')
diff --git a/src/renderer/src/components/native-chat/background-task-roster.ts b/src/renderer/src/components/native-chat/background-task-roster.ts
index a54e729c845..71ec84106e5 100644
--- a/src/renderer/src/components/native-chat/background-task-roster.ts
+++ b/src/renderer/src/components/native-chat/background-task-roster.ts
@@ -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 {
diff --git a/src/renderer/src/components/sidebar/__snapshots__/subagent-child-row-fallback-pixels.test.tsx.snap b/src/renderer/src/components/sidebar/__snapshots__/subagent-child-row-fallback-pixels.test.tsx.snap
index bb64a6a3f59..342897ca5a4 100644
--- a/src/renderer/src/components/sidebar/__snapshots__/subagent-child-row-fallback-pixels.test.tsx.snap
+++ b/src/renderer/src/components/sidebar/__snapshots__/subagent-child-row-fallback-pixels.test.tsx.snap
@@ -1,8 +1,8 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`chat strip rows from a legacy background-task roster > render exactly as before 1`] = `" "`;
+exports[`chat strip rows from a legacy background-task roster > render exactly as before 1`] = `" "`;
-exports[`chat strip rows from a legacy background-task roster > render exactly as before 2`] = `" "`;
+exports[`chat strip rows from a legacy background-task roster > render exactly as before 2`] = `" "`;
exports[`sidebar child rows from a legacy subagents snapshot > render a stale parent and a lost transport exactly as before 1`] = `
[
diff --git a/src/renderer/src/components/sidebar/subagent-child-row-fallback-pixels.test.tsx b/src/renderer/src/components/sidebar/subagent-child-row-fallback-pixels.test.tsx
index 3307d2f9dce..68463bc5ec8 100644
--- a/src/renderer/src/components/sidebar/subagent-child-row-fallback-pixels.test.tsx
+++ b/src/renderer/src/components/sidebar/subagent-child-row-fallback-pixels.test.tsx
@@ -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',
diff --git a/src/renderer/src/i18n/en-runtime-required.json b/src/renderer/src/i18n/en-runtime-required.json
index d262c825b45..9abb0410a1d 100644
--- a/src/renderer/src/i18n/en-runtime-required.json
+++ b/src/renderer/src/i18n/en-runtime-required.json
@@ -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.",
diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json
index d0a08821b98..e8d79b4e4fa 100644
--- a/src/renderer/src/i18n/locales/en.json
+++ b/src/renderer/src/i18n/locales/en.json
@@ -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",
diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json
index c670fbc079d..d769e6f3dcd 100644
--- a/src/renderer/src/i18n/locales/es.json
+++ b/src/renderer/src/i18n/locales/es.json
@@ -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"
diff --git a/src/renderer/src/i18n/locales/fr.json b/src/renderer/src/i18n/locales/fr.json
index 7dde6febdcc..fec8d16043d 100644
--- a/src/renderer/src/i18n/locales/fr.json
+++ b/src/renderer/src/i18n/locales/fr.json
@@ -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}}",
diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json
index becf91c95e5..88379cfe2ab 100644
--- a/src/renderer/src/i18n/locales/ja.json
+++ b/src/renderer/src/i18n/locales/ja.json
@@ -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 をキックオフしました",
diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json
index f81a9442788..5adf75f1fff 100644
--- a/src/renderer/src/i18n/locales/ko.json
+++ b/src/renderer/src/i18n/locales/ko.json
@@ -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}} 하위 에이전트가 시작되었습니다.",
diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json
index 9707c04c143..5a0fbe1c6d6 100644
--- a/src/renderer/src/i18n/locales/zh.json
+++ b/src/renderer/src/i18n/locales/zh.json
@@ -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}} 子智能体",
diff --git a/src/shared/agent-session-refusal-notice.test.ts b/src/shared/agent-session-refusal-notice.test.ts
index 41a9606deca..2d53a1330e2 100644
--- a/src/shared/agent-session-refusal-notice.test.ts
+++ b/src/shared/agent-session-refusal-notice.test.ts
@@ -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(
diff --git a/src/shared/agent-session-refusal-reason-words.ts b/src/shared/agent-session-refusal-reason-words.ts
index 43893f67b47..d8756a3c9ec 100644
--- a/src/shared/agent-session-refusal-reason-words.ts
+++ b/src/shared/agent-session-refusal-reason-words.ts
@@ -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 {
diff --git a/src/shared/agent-session-write-notice-copy.ts b/src/shared/agent-session-write-notice-copy.ts
index 0904ecf8551..3796de6eaf0 100644
--- a/src/shared/agent-session-write-notice-copy.ts
+++ b/src/shared/agent-session-write-notice-copy.ts
@@ -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.',