Repository navigation
Agent chat: a steer is one continuous turn; only Stop or Esc reads as stopped - #22691
Conversation
A prompt sent now to an agent that cannot steer cancels the running turn and runs next. The transcript must draw it inline in one turn timed from the first prompt, without 'You stopped after' or 'stopped the turn'; a real Stop keeps its line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
… stopped A prompt sent now to an agent that cannot steer makes acpmux cancel the running turn and run the prompt next. The pane drew that as a Stop: 'You stopped after 55s', 'Sent now · stopped the turn', then a fresh 'Working for'. Now the cancel a prompt sent now caused (queue_order next while the turn ran, then turn_result cancelled) marks its summary continued, the prompt reads Steered and draws inline in the turn, and the turn's Working and Worked clocks run from the first prompt. A real Stop keeps its line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Pending: CI is running on Last result: Unclear: Written by web and size checks: green
Agents: Tour of |
|
Bead |
|
Found 22 test failures on Blacksmith runners: Failures
...and 12 more test failures. View all on Blacksmith
|
|
|
The edited-files checkpoint, Find and shell reveal, the hover footer, running subagent groups and the minimap still split a turn at a steer; the cancel a sent-now prompt caused flashes 'You stopped after' before the steer's record, and comes back when an older page ends at the steer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
Review of #22691: code beyond the transcript still split a turn at each prompt row. A leaf turnStart.ts holds continuesTurn and opensTurn, and: - diff.ts turnRows and App's last edit turn run past steers; a turn's checkpoint pair spans its first part's start to the end of the part that ended it, and a turn has ended only on a summary that is not continued (endsTurn). - Find and a shell's Bash row open the fold the turn draws (turns.ts turnFoldFor); the hover footer is the chain's (turnFooterFrom). - runningGroups and the minimap's turns skip steers. - A continued summary that is the last turn's last one draws nothing, so 'You stopped after' does not flash before the steer's record. - An older page that holds the cancel marks the held sent-now prompt a steer after foldOlder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
|
Verification note:
CI's Fleet webviews suite:
|
…point nor leaks across a history fold Review of #22691 at 4a22c0b: the cancel a Send now caused counted as a turn end for the edits card's checkpoint, and foldOlder neither kept nor reset the pending Send now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…; foldOlder keeps a pending Send now - rowMarks.ts marks a summary only when it ends its turn (endsTurn), so a Send now's cancel after an edit no longer asks for a pair that does not exist yet (readTurnFromRows threw, leaving the card without counts). - foldOlder saves, resets and restores interrupting with the rest of the live state: an older page neither leaks its Send now into the live turn (a later Stop read as continued) nor clears the live one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
… end_turn Send now continues too Coordinator ruling on #22691: nothing new reads "Steered" (#22773 removes the steer marks). acpmux #22808 ends Claude's Send now with end_turn rather than a cancel, which must also draw as one turn; a failed turn still shows its failure. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…ed mark, whatever ended it - The prompt row is marked `continues` (accepted, drawn inline) instead of steer "landed", so it shows no "Steered" line (coordinator ruling; #22773 removes the steer marks). continuesTurn reads either. - acpmux #22808 ends Claude's Send now with end_turn: any turn_result while a Send now waits marks the summary continued, except a failure, which shows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
|
owner: 01a15ba3 |
Review of #22691 at 46f55be: a Send now removed, withdrawn or refused left the turn's summary continued for good (no footer, no checkpoint), and Stop followed by Send now before the cancel read as continued. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…ns over a Send now Review of #22691 at 46f55be: - queue_removed or prompt_refused for the pending Send now clears it; after the turn ended, its summary is no longer continued, so the turn shows its footer, 'You stopped after' and its checkpoint. - Another prompt opening a turn first does the same. - Refused at dispatch (acpmux does not stream prompt_refused to the pane): once the chat is idle and the prompt is neither queued nor running, the summary reads ended; the prompt running after all puts it back. - Stop clears a pending Send now, and a Send now within Stop's grace does not arm one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
Bugbot needs on-demand usage enabledBugbot uses usage-based billing for this team and requires on-demand usage to be enabled. A team admin can enable on-demand usage in the Cursor dashboard. |
The never-run Send now cases expected 55s; the fold times a turn to its answer (40s in), as the real Stop case does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
|
From the subsession-visibility lane: no overlap. My open PRs (#22827, #22879, #22895) don't touch direct.ts, turns.ts, turnStart.ts or rowMarks.ts. Two things to keep:
|
… keeps one turn Review of #22691 at d5ace1c: acpmux ends the turn, reads ready and dequeues the Send now before recording it; a snapshot in that gap ended the turn ("You stopped after", and the checkpoint asked for the first part only). A turn error for the Send now must still end the turn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…ll not run Review of #22691 at d5ace1c: the snapshot-time guess (idle, not queued) fired in acpmux's normal gap between dequeued and the Send now's record, ending the turn and asking for a one-part checkpoint. It is gone. The turn stays continued until the prompt's own record, or a record that it will not run: queue_removed, prompt_refused (now asked for by name on a local acpmux), a turn_error, another prompt's record, or the refusal answering this pane's own send. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…inues The transport error a closed socket gives the Send now's request (native.timed_out) is not acpmux refusing the prompt: acpmux still runs it after the reattach. Also drops the turn_error test, whose branch never runs (a turn_error comes only after the prompt's user_message). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
A closed socket fails the Send now's request with native.timed_out, but acpmux still runs the prompt, so the turn it ended stays continued. Drops the turn_error branch too: a turn_error comes only after the prompt's user_message, so awaiting is already clear by then. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…r-continuous-turn # Conflicts: # webviews/src/agent-session/acpmux/composer.gallery.ts # webviews/src/agent-session/acpmux/conversation/transcript.gallery.ts # webviews/src/agent-session/acpmux/conversation/turns.ts # webviews/src/agent-session/acpmux/direct.ts # webviews/src/agent-session/acpmux/model.ts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15ba3-d09a-7940-9fd6-158e10477c0e&host=cosmic-gray
…r-continuous-turn # Conflicts: # webviews/src/agent-session/acpmux/composer.gallery.ts # webviews/src/agent-session/acpmux/conversation/SteerMark.tsx # webviews/test/agent-pane-queue-steer.test.ts
…age-hover-rows-rebased Base's #22691 (a steer is one continuous turn) and #22910 (estimates) met this PR's SteerMark removal: SteerMark stays deleted, the hover footer uses base's turnFooterFrom except on a prompt (one action row at a time), and a steer reserves a line only while it waits (PendingSteer); the queue-steer test keeps the read-receipt assertions. Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c08-3514-7430-9c71-6b7ba4fdac72&host=cosmic-gray
|
Shipped in:
|
Problem
When Leo sends a message while a turn is running, and the agent can't take it mid-turn, acpmux ends the running turn and runs the message next. It ends the turn with a cancel, or, after acpmux #22808, Claude ends it with
end_turn. The transcript drew this as a Stop: "You stopped after 55s" over the work, "Sent now · stopped the turn" under his message, and a fresh "Working for 18s". He never pressed Stop.The turn really does end and restart under the hood. This PR keeps that data model and only merges how it is drawn. The "Worked for" and "You stopped after" lines below are the turn's fold label.
Change
direct.ts: telling a Send now from a real Stop.queue_orderwithnext: truewhile a turn is open and the prompt is still queued. That armsinterrupting.turn_resultthat is notfailed(cancelled orend_turn) marks its summarycontinued. A failure still shows.user_messagerow is markedcontinues. That means accepted and drawn inline, with no mark of its own: nothing reads "Steered".queue_order next, so it is unchanged.foldOldersaves, resets and restoresinterrupting, and patches a held sent-now row after an older page brings its cancel.queue_removed(removed or withdrawn),prompt_refused(a local acpmux streams it now that the pane asks for it by name), another prompt'suser_message, or the refusal answering this pane's own send. A transport error on that send (a closed socket fails it withnative.timed_out) is not a refusal: acpmux still runs the prompt, so the turn stays continued. The summary then dropscontinuedand shows its footer, "You stopped after" and its checkpoint. Betweendequeuedand the prompt's record, the chat reads idle while the prompt is about to run; the turn stays continued through that gap.turnStart.ts. It holdscontinuesTurn(a steer, or a prompt thatcontinues) andopensTurn. Everything that finds a turn by its prompt now walks past such a prompt:turns.tsturns, with one Working and Worked clock from the first prompt. It also draws no "You stopped after" for acontinuedsummary, including the moment before the prompt's record arrives.diff.tsturnRows, and App's last edit turn.endsTurn).rowMarks.ts, which marks only turn-ending summaries.turnFoldFor), and the hover footer (turnFooterFrom).runningGroupsand the minimap's turns.stoppedsteer state and itssteer.stoppedstring. Native steers keep their existing marks; Agent chat: Claude's hover rows under every message (read receipts, Pin, Read aloud) #22773 removes those.Screenshots
These show the first version, where the sent-now message read "Steered". It now carries no mark.
Verification
Each fix lands as a tests-only commit followed by the fix commit. The tests are in
webviews/test/transcript-steer-continuous.test.tsx. Each test commit fails on the fleet and its fix passes, runningscripts/ci/run-webviews-tests.shwithcmux-ci run. They cover:foldOlderleaks;end_turn;dequeuedand the Send now's record (still continued, no checkpoint request);native.timed_out): the turn stays continued;The suite's other failures are the same on each test commit and its fix:
agent-pane-column-edges,apps-flow,composer-html-paste-edit,hover-row-sweep,stats-page,thread-minimap-feel,tooltip-surface,whats-new-text-selection.Observed / Not run
The red-to-green proof is
transcript-steer-continuous.test.tsx(bun + JSDOM, runs on the fleet).agent-pane-queue-steer.test.tsis a browser-lane file:requireBrowserLaneskips it unlessCI=trueorCMUX_BROWSER_TESTS=1, so it never ran on the fleet and its update is checked only by GitHub CI.The later commits were made in a sparse
/tmpclone, because the shared repo's git was frozen on cosmic-gray.scripts/web-lint.shthere reported no errors in changed files, also after the base merge. Its other errors were in untouched pages (missing generatedstrings.jsonand out-of-clone fixtures), plus checks that needschemas/,Packages/or the acpmux spec, which the clone lacks. CI's web lint lane is the check.No macOS build or dogfood.
Known gaps:
prompt_refused: a remote acpmux, a pane reloaded after the refusal, or a pane other than the sender's.prompt_refusedis a log record, not a transcript record, so only the sending pane's own refusal answer or a local live stream ends the turn.prompt_refused, the refusal is read before the turn it ends, so loading the older page draws that turn as continued.cancel()clears the pending Send now, but acpmux records no Stop, so replaying Stop followed by Send now draws a continued turn where the live pane drew it stopped. The durable fix is for acpmux to record acancel_requestedevent; that is not built here.Localization: one key removed, no new strings.
Agent session: cosmic-gray
🤖 Generated with Claude Code