Repository navigation
fix(native-chat): put Continue in the card that says the reply stopped - #27097
Conversation
… reply Continue sat in its own row above the message box, away from the reply it continues and often outside the chat column. It now sits inside the transcript's notice card that says why the reply stopped, as a filled primary button beside that sentence.
- A paired server with no name is called "the remote server", so the card words the stop from its cause instead of the host's stored "You can continue in this conversation." beside the Continue button. - Continue is an xs primary button that fits the text row without a margin workaround. - continueNow is a plain useCallback: its inputs (target, session id, the composer error reporter) are already stable. - Test the real chain: a cut journal through the structured session shows exactly one Continue, inside the stop card.
Review status: ready for a decision (still a draft, not merged)The problem. When Orca quits, crashes, or restarts for an update while an agent is replying, the chat keeps the cut-off reply and shows a card under it saying Orca stopped. The way to pick the reply back up is a Continue button. On main that button is a faint, borderless "Continue" in its own row above the message box, apart from the card and often outside the chat column, so it is easy to miss and looks unrelated to the card. What changes for the user. Continue is now a filled button inside that card, on the same line as the sentence ("Orca on Local Mac stopped unexpectedly while this response was in progress. [▶ Continue]"). The separate row above the message box is gone. Clicking it works as before. A paired server that has no name now reads "Orca on the remote server stopped unexpectedly…" instead of the host's stored sentence, so the card never says "You can continue in this conversation" right next to the button. Fixed during review (commit e3bba00, then one merge of current main at 067d41b):
Deferred (small, not blocking):
Verified
Not verified: a real agent (QA used OpenCode with a local stand-in model), SSH or paired-server chats live (unit tests cover the unnamed-server wording), Windows and Linux rendering, and screen-reader output. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to The Continue action is placed in the matching stop notice, with no actionable merge-blocking risk established by the supplied evidence. Pre-merge checks |
|
ELI5
When Orca quits, crashes, or restarts for an update while an agent is replying, the native chat keeps the cut-off reply and shows a small card under it that says what happened ("Orca on Local Mac stopped unexpectedly while this response was in progress."). The way to pick the reply back up is a Continue button. That button lived somewhere else: a separate, faint row above the message box, often sitting outside the chat column. It was easy to miss and looked unrelated to the card that explains the stop.
Continue now sits inside that card, on the same line as the sentence, as a filled button with a play icon.
What Changed
Before: the card said the reply stopped, and a small ghost-style (no background) "Continue" button sat in its own row just above the message box, right-aligned to a fixed 56rem width that didn't match the chat column. Nothing tied it to the card.
After: the card reads like
ⓘ Orca on Local Mac stopped unexpectedly while this response was in progress. [▶ Continue]. The separate row above the message box is gone. Clicking Continue works as before: the button disappears and the agent picks the reply back up. If the host can't continue, there is no button and the card says "You can continue in this conversation", the same as before.Paired server with no name: the card used to fall back to the host's own stored sentence, which ends in "You can continue in this conversation." With the button now in the same card, that would say the same thing twice. Such a server is now called "the remote server" ("Orca on the remote server stopped unexpectedly while this response was in progress."), so the card is worded from the stop's cause exactly like a named machine. One new translated string, in all six locales.
Mechanism:
NativeChatOrcaStopView: machine name, whether the host can continue). It now also carries which cut-off turn Continue is offered on (offeredTurnItemId) and acontinueNowhandler.NativeChatNoticeRow, which draws the card, already knows the turn its stop row belongs to (block.orcaStop.turnItemId). When that matches the offered turn, it rendersNativeChatInterruptedContinueButtonbeside the sentence. Only the card for the latest cut can match, so there is at most one button.useNativeChatInterruptedContinuationis unchanged in what it decides (when Continue is offered, what a click sends, the failure line in the composer).continueNowis a plainuseCallbackover values that are already stable, so the context only changes when what the rows show changes, and transcript rows don't re-render on every chat render.NativeChatInterruptedContinue(the old standalone row) is removed fromNativeChatStructuredSession.Why
This replaces #27042, which kept the separate row and only lined it up with the chat column. Lined up or not, the button still sat away from the sentence that explains why you'd press it.
Where this differs from the common pattern, labelled:
The button is the
default(primary) variant atxssize: primary because it is the one affirmative action in that state (a ghost button in muted card text is why it went unnoticed),xsto match the card's text row height per the style guide.Linked Issue
None. Supersedes #27042 (follow-up to #25675, which added Continue).
Visual Proof
Captured live on a hidden test copy of Orca (macOS), with OpenCode talking to a local stand-in model. Orca was force-quit mid-reply, then reopened.
Before (main): Continue sits in its own faint row above the message box, apart from the card.
After, dark: Continue is inside the card, on the same line as the sentence. Nothing above the message box.
After, light:
After, narrow window (1000 px wide): the sentence wraps to three lines and the button stays inside the card.
After clicking Continue: the button goes away, the agent picks the reply back up, and no error appears in the message box.
Testing
NativeChatNoticeRow.test.tsx: the card for the offered cut shows Continue next to its sentence and clicking it calls the handler; a card for a different turn shows no button; an unnamed paired server is worded from the cause.NativeChatStructuredSession.orca-stop-continue.test.tsx(new): renders the real session, hook, context and rows with a journal holding an Orca-stop cut, and asserts exactly one Continue, beside the stop sentence, and no "You can continue" text. Fails if the unnamed-server wording is reverted.NativeChatInterruptedContinue.test.tsx: existing behaviour tests (when Continue is offered, what it sends, refusals, the composer failure line) now drive the button from the view the rows receive.22 related test files (290 tests) pass on the tree merged with current main;
orca-ci-checks(lint, code quality, localization, ratchets, typecheck) pass.I manually tested these changes locally
Automated tests added/updated, or explained why not below
AI Disclosure
Review
Agent skill upstream boundary
Notes
Renderer-only change. Same on macOS, Linux and Windows, and for local, SSH and paired-server chats: which chats get Continue is still decided by the host's capability and the journal, exactly as before. No data or wire changes. The only other visible change is the wording for a paired server with no name (see What Changed).
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)