mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 18:17:36 +00:00
* fix(native-chat): say each chat outcome once and drop internal-only surfaces After a restart, resuming a chat reported the same outcome in up to four places: a toast, the chat's own note, the status bar entry and the resume dialog. Success also toasted, and a lost answer or unconfirmed dismissal raised toasts of their own. The chat's note and the status bar entry (which opens the dialog listing every affected chat) now carry it alone, and the resume guidance no longer talks about which process "owns this session". Provider events Orca does not recognise and that carry no words of their own are logged instead of journaled as raw "codex · notification:foo" rows. Rows with the provider's own sentence, failures, and records of replies Orca already sent stay. The approval card no longer shows the matched ask rule, its settings source or a "Blocked path" line; it keeps the request, its detail and the reason. * fix(native-chat): store wordless provider events, hide them only when drawn Dropping text-less provider events on the host also dropped Codex's turn/plan/updated row, which the task list (checklist and composer progress panel) is built from. The host now journals these rows exactly as before, and desktop and mobile chats leave out a row whose only text is the host's "provider · kind" label. Failures, notices, rows with the provider's own sentence and records of requests Orca answered still show. A hidden legacy Codex collab-call row still counts as the agent acting for which subagent section stays open. Claude's local slash command output is read from `content` for that one event kind only, so it shows as the row's text instead of disappearing. * fix(native-chat): rows no client draws never fill the Codex cap or split a turn's work - Codex per-turn cap: a wordless provider row (decided by the same shared rule the clients use) has its own silent storage bound, so it no longer crowds out rows that draw and never produces a "N more provider notifications not shown" line about rows nobody sees. Plan updates are exempt from the cap, so the task list keeps updating after a noisy turn. - A Claude local command's row an older host stored with only its label (/usage output in the payload) stays drawn instead of disappearing. - A settled turn whose only extra row draws nothing offers no expand arrow, and a wordless row no longer splits one tool run into two. * fix(native-chat): a resume request that never reached the chats says so once, with Retry When the resume request fails before the host reserved anything (the host is not ready, or its recovery record cannot be written), the host has nothing to record, and the chats used to fall silently back to "N chats to resume". The status bar and dialog now show them as failed, with the existing guidance and Retry, until Retry, Dismiss, a host answer that no longer offers them, or a relaunch. Comments that still cited the removed toast are corrected. * fix(native-chat): keep mobile tool runs whole and a failed Dismiss's chat marked - Mobile draws no task list, so it now drops wordless provider rows, plan updates included, before folding tool runs; a mid-run plan update no longer leaves two run headers back to back. - A Dismiss the host never took keeps a lost resume request's chat shown as failed instead of turning it back into a plain offer. The lost request's real error now goes to the renderer log, since the row carries this side's own reason code. - Comments corrected: the Codex cap no longer claims dropped wordless rows stay countable, and the resume comments cover a chat a lost request never reached. * fix(native-chat): tell the user what their Resume click did, in one toast Clicking Resume in the dialog (or Retry on a row) closes the dialog and acts on chats that are mostly off-screen, and nothing said what happened. One toast now summarises that click: "Resumed N chats and asked them to continue", "N chats couldn't be resumed" with Show (opens the dialog), "Couldn't confirm N chats were resumed", or the mixed case in the same toast. A request lost before it reached the chats counts its chats as not resumed. An opted-in automatic resume at launch raises no toast; dismissal and other bookkeeping stay silent. * fix(native-chat): Show on the Resume toast re-reads before opening; fix toast translations Show could open nothing when the host retired the failure while the toast was up, because the dialog draws nothing without rows and the request stayed latched. Show now goes through the status bar entry's re-read-then-open path, moved into the store so both use it. The French, Japanese, Korean and Chinese "Resumed N chats and asked them to continue" strings are rewritten to match their sibling strings. Tests pin Show on the toast of a lost resume request whose chats the re-read still lists. * test(native-chat): click the Resume toast's Show through a typed helper The tests reached sonner's action handler with Reflect.apply, which the anti-slop lint rejects. One test-support helper now returns the last toast's Show as a typed click. * fix(native-chat): name the path an approval needs when the request doesn't show it The approval card dropped Claude's blocked path along with the ask rule, so a request like `git push` that needs access to `.git/config` no longer said what it touches. Bring the path back as "Needs access to: <path>", only when the description, reason or request detail doesn't already show it (verbatim or JSON-escaped). One shared rule serves desktop and mobile; the ask rule stays out. * fix(native-chat): count a blocked path as shown only when the text names the whole path '/srv/data' inside '/srv/data-old/x' hid the "Needs access to" line although the path itself was never shown. A match now needs the next character to end the path: end of text, whitespace, a quote or a separator. Also pin that the desktop approval mapping passes the blocked path through and drops the ask rule. * fix(native-chat): the automatic resume at launch gets the same one outcome toast as a click An opted-in launch resume now calls the same announce as a clicked Resume, with the same copy: how many resumed, how many couldn't (with Show), unconfirmed, or mixed, said once. Dismiss and bookkeeping stay silent; a launch whose chats all moved on raises nothing. * fix(native-chat): the resume success toast says "Resumed N chats" Each chat's own note already says Orca asked it to continue, so the toast drops "and asked it/them to continue" in every locale; the couldn't-resume and couldn't-confirm counts and Show are unchanged.
62 lines
4.0 KiB
TypeScript
62 lines
4.0 KiB
TypeScript
// The message Orca sends when a user asks an interrupted agent to carry on.
|
|
//
|
|
// Identical for both providers, and deliberately not promptless. Codex's `turn/start`
|
|
// would accept an empty `input`, but Claude's SDK has no promptless form, so a bare continuation
|
|
// would make the two lanes behave differently — and the wording is the part that tells an agent to
|
|
// VERIFY its last action before repeating it. Both reasons point the same way.
|
|
//
|
|
// Sending this needs the user's OPT-IN, not their presence: the restart prompt's resume sends it,
|
|
// and so does a launch the user ticked "resume automatically" for. That is acceptable because the
|
|
// work being continued is the user's own, the wording above tells the agent to VERIFY its last
|
|
// action before repeating it, and each chat it reaches carries a note saying so. Reattaching
|
|
// without a send remains a separate operation that never comes here.
|
|
|
|
import type { AgentSessionResumeMarker } from './agent-session-resume-marker'
|
|
|
|
export const AGENT_SESSION_RESTART_CONTINUATION_MESSAGE =
|
|
"Orca restarted, so your previous reply was cut off partway through. Before continuing, check whether your most recent action completed — don't repeat it if it did. Then carry on."
|
|
|
|
/** For a marker that may stand for more than a reply: subagents, background commands, monitors or
|
|
* a prompt the restart stopped. Names none of them — the provider restates what it lost on
|
|
* resume, and a body that varied with the journal would change between retries of one offer. */
|
|
export const AGENT_SESSION_RESTART_WORK_CONTINUATION_MESSAGE =
|
|
"Orca restarted, which stopped what you were doing: a reply in progress, any subagents or background commands you had running, and any request waiting on the user. Before continuing, check what finished before the restart and don't repeat it. Restart anything still needed, ask again for anything still waiting on the user, then carry on."
|
|
|
|
/**
|
|
* The continuation a marker gets. A function of the marker alone, because the payload fingerprint
|
|
* covers the body and a retried offer must reach the ledger with the same one. A marker from a
|
|
* build that recorded only a working lead keeps the original wording.
|
|
*/
|
|
export function restartContinuationMessage(
|
|
marker: Pick<AgentSessionResumeMarker, 'activity'>
|
|
): string {
|
|
return marker.activity
|
|
? AGENT_SESSION_RESTART_WORK_CONTINUATION_MESSAGE
|
|
: AGENT_SESSION_RESTART_CONTINUATION_MESSAGE
|
|
}
|
|
|
|
/**
|
|
* Host-authored journal note marking the send as Orca's rather than the user's.
|
|
*
|
|
* Attribution lives in the journal, not on the provider wire. Codex's `turn/start` has no parameter
|
|
* we already send that could carry it, and adding one would be a new client-controlled field on a
|
|
* path that deliberately allowlists its params — untestable against older app-servers and
|
|
* Codex-only, which would break the both-providers symmetry above. The journal is ours, carries no
|
|
* compatibility risk, behaves identically for both providers, and is queryable with the rest of the
|
|
* session history.
|
|
*/
|
|
export const AGENT_SESSION_RESTART_CONTINUATION_NOTE =
|
|
'Orca asked this agent to continue after a restart. Your own prompt was not re-sent.'
|
|
|
|
/** Host-authored notes left in a chat the continuation did not carry on, so the chat itself says
|
|
* what happened and what to do. The next message the user sends is the manual continuation. */
|
|
export const AGENT_SESSION_RESTART_CONTINUATION_REFUSED_NOTE =
|
|
"Orca couldn't continue this chat after the restart. Send a message to continue it."
|
|
export const AGENT_SESSION_RESTART_CONTINUATION_UNCONFIRMED_NOTE =
|
|
"Orca asked this agent to continue after the restart but couldn't confirm it did. Check its latest reply before sending another message."
|
|
|
|
/** For a chat Orca could not get hold of. Why decides the fix, which the restart list gives; advice
|
|
* to send a message would meet the same refusal. */
|
|
export const AGENT_SESSION_RESTART_NOT_CONNECTED_NOTE =
|
|
"Orca couldn't reconnect this chat after the restart, so it didn't ask the agent to continue."
|