Skip to content

Agent chat: a stopped subagent's line says why (stopped by you, interrupted by Send now) and offers Restart - #24051

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
tp/subagent-stopped-reason
Oct 22, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
tp/subagent-stopped-reason

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Leo: "UI ALSO NEEDS TO BE BETTER". A subagent's end line in the agent chat read Subagent stopped: <name> · 17m 6s: fine as info, but it never said why the subagent stopped, and there was no way to run it again.

What changes

  • The reason. A stopped (cancelled) subagent's line now adds why it stopped, when the pane knows: Subagent stopped: Check the docs · stopped by you · 1m 36s, or · interrupted by Send now ·. The reason comes from data the pane already has:
    • a foreground subagent that stops while a Send now is cancelling the turn (the queue_order record that sets interrupting in direct.ts). acpmux records this, so the reason survives a reload;
    • a foreground subagent that stops after this pane's Stop on the turn (stopAfterSeq), or any subagent this pane stopped from its own Stop button (_acpmux/subagent_stop). Both read stopped by you. These are known only to the live pane: the reasons survive the fold's rebuilds, but a page reload loses them, because acpmux records no cause for a cancel;
    • anything else (Claude's own TaskStop, another client's or agent's cancel, a Codex interrupt, a background subagent whose turn stopped) shows no reason. An unknown reason is left blank, never guessed.
    • "finished" and "failed" need no extra segment: those lines already read Subagent finished: and Subagent failed:. Claude's task_notification status maps through acpmux's adapter (failed → failed, stopped → cancelled, else completed) and arrives as the line's state.
  • Restart. On hover or keyboard focus, a stopped, failed or lost subagent's line offers Restart. It uses the same compact icon button as the message hover row (cmux NEXT agent chat: message hover rows like Claude's (check, age, Copy, Retry, Fork; just now; exact time above) #23769): Retry icon, "Restart" as the tooltip title, and "Ask the agent to run this subagent again with the same prompt" under it. Neither acpmux nor Claude Code has an op that resumes a stopped subagent, so Restart sends the chat the prompt the person would type: Run the Explore subagent "Check the docs" again with the same prompt: followed by the original prompt. The original prompt is the prompt acpmux already records on subagent_spawned, and the send goes through the composer's chat.send, as Retry does. It shows only for the chat's own subagents with a recorded prompt and a connected chat. No new backend op.
  • All 6 new strings are translated into all 21 languages.

Tests

  • subagents/subagentFold.test.ts: reason mapping (Send now, Stop, pane Stop request, background subagent, stopRunning, rebuild survival, running again forgets, unknown → none, finished/failed carry none).
  • subagents/restart.test.ts: when Restart is offered; the prompt text (with and without kind; braces in the prompt kept as is).
  • test/subagent-tray.test.tsx: the rendered line with each reason and with none; Restart wiring (click → restartSubagent(agent); none for finished or no-prompt lines; none without the action).

Before / after (gallery, synthetic fixtures)

agent-pane.subagent-tray: failed-line now shows a failure, both reasons and an unknown one; the new restart-on-hover variant shows the focused Restart button. Live side by side: scripts/gallery-compare.sh tp/subagent-stopped-reason --entry agent-pane.subagent-tray (tailnet).

Before After
before after
before (the variant is new: the old line, no Restart) after

Tests run on cmux16 at the head: 33 pass, 0 fail; vp check finds no type errors in 2284 files.

What the base already fixed (vs Leo's nightly 03960f5)

Nothing for this item: #23104, #24031, #24087 and #23962 changed when subagents end and how the tray counts them, but the stopped line still had no reason and no Restart.

Web only (no Swift). risk:normal.

Agent session: cosmic-gray

🤖 Generated with Claude Code

…rupted by Send now) and offers Restart

Leo: "UI ALSO NEEDS TO BE BETTER". Lines read "Subagent stopped: <name> · 17m 6s"
with no reason and no way to run the subagent again.

- The reason comes from what the pane knows: a foreground subagent stopped
  while a Send now's cancel (its queue_order) or this pane's Stop was ending
  the turn, or a subagent this pane asked to stop (_acpmux/subagent_stop).
  Anything else (Claude's own TaskStop, another client's cancel, a Codex
  interrupt) shows no reason rather than a guess. Reasons survive the fold's
  rebuilds; a Send now's survives a reload (acpmux records it).
- Restart, on hover or focus, on a stopped, failed or lost subagent of the
  chat's own whose prompt acpmux recorded: it sends the chat a prompt asking
  its agent to run that subagent again with its kind and prompt, through the
  composer's chat.send (as Retry does). No new backend op.
- New strings in all 21 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray
@cursor

cursor Bot commented Oct 22, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot 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.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 15e53fe: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr24051 -f ref=tp/subagent-stopped-reason -f platform=macos -f backend_mode=local

Gallery before/after for 15e53fe: 16 states rendered, 2 images differ, 1556 more touched states not rendered. Images are in the run's artifact, not on this public PR.

gh run download 39750805392 -R manaflow-ai/cmux -n gallery-advisory-24051-15e53fe0a2e89d7eed588cde8bcd98b7d11ba390 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/standard Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/typing-in-dock Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/typing-in-dock Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/long-title Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/long-title Apple System Colors unchanged 0% own App.tsx
agent-pane.orchestration-lab/local-queue Apple System Colors Light unchanged 0% own App.tsx
agent-pane.orchestration-lab/local-queue Apple System Colors unchanged 0% own App.tsx
agent-pane.orchestration-lab/build-box Apple System Colors Light unchanged 0% own App.tsx
agent-pane.orchestration-lab/build-box Apple System Colors unchanged 0% own App.tsx
agent-pane.orchestration-lab/cloud-fair-share Apple System Colors Light unchanged 0% own App.tsx
agent-pane.orchestration-lab/cloud-fair-share Apple System Colors unchanged 0% own App.tsx
agent-pane.streaming-follow-motion/stream Apple System Colors Light unchanged 0% own App.tsx
agent-pane.streaming-follow-motion/stream Apple System Colors unchanged 0% own App.tsx
agent-pane.streaming-text/claude Apple System Colors Light unchanged 0% own App.tsx
agent-pane.streaming-text/claude Apple System Colors unchanged 0% own App.tsx
agent-pane.streaming-text/codex Apple System Colors Light changed 0% own App.tsx
agent-pane.streaming-text/codex Apple System Colors changed 0% own App.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Checks job structure (+1 more) is not red on the base 2d13b66; do not merge until green; see lane-rules

Tour of 15e53fe0a2 (run): no media. The tour did not run: only webview code changed (13 path(s)), which the gallery advisory run checks in Linux Chromium on the pull request (its artifact holds any captures); add the media-tour-mac label, then re-add media-tour, to tour it on a Mac.

@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 10 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmpo6gbbtdk/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmprjmhdsfz/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs
convention violations found (ERROR lines above)./
convention violations found (ERROR lines above).
View Logs
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)/
test_every_part_of_bun_run_check_runs_in_the_warn_branch (main.WebviewsWarnSplitCov
ersCheck.test_every_part_of_bun_run_check_runs_in_the_warn_branch)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules)
View Logs
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')/
test_every_submodule_free_checkout_on_an_owned_runner_resets_submodules (main.Reuse
dWorkspaceSubmodules.test_every_submodule_free_checkout_on_an_owned_runner_resets_submo
dules) (job='web-bundles')
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by transcript-parity on cosmic-gray · session

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-dcigw created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / nightly-guards / workflow-guard-tests / release-notary is red on 16 of 20 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex xhigh, correctness first): BLOCK at 404ee07

  • BLOCK — stale turn cause can label the wrong subagent. subagentFold.ts:330-338 applies the fold-wide cause to every cancelled foreground agent. direct.ts:2915 sets that cause before every update, while the fold explicitly allows native/foreground children to outlive a turn (subagentFold.ts:89-91). A late cancellation from an older agent can therefore display “stopped by you” or “interrupted by Send now” for an unrelated later turn; unknown must remain unlabelled.
  • BLOCK — a reason leaks across a resumed agent lifecycle. subagentFold.ts:268-274 clears agent.stopReason when an agent reports running again but leaves stops.reasons[id]. A later cancellation of the same id with no known cause falls back to that old reason at subagentFold.ts:338.
  • BLOCK — Restart bypasses read-only and session guards. App.tsx:4634-4637 exposes restartSubagent whenever connected and directly calls chat.send; it does not check summary.watching, remote sendability, read-only pane state, or that the clicked row still belongs to the selected session. The normal composer has an explicit watched-chat guard at App.tsx:7503-7529. During a held session switch, an old Restart row can also route its prompt to the newly selected chat.

Localization is complete: the six added catalog keys each have all 21 supported locales, and {name}, {kind}, and {prompt} placeholders match English. git diff --check passed. Focused Bun tests were skipped because webviews/node_modules is absent; no builds were run, per the review instructions.

…erun forgets its old reason; Restart guarded like the composer

Codex xhigh review of #24051 (BLOCK at 404ee07):
- A stale turn cause could label a subagent an earlier turn started: the
  cause now applies only to subagents the current turn started.
- A reason survived a subagent running again: it is forgotten then.
- Restart now shows only for the chat the pane shows, not View Only, not in
  a subagent's read-only pane, and a row left over from a chat switch sends
  nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a16030-bf28-7072-b1f6-b83bbd0beacc&host=cosmic-gray
@teamleaderleo teamleaderleo added risk:medium and removed risk:normal Risk tier (docs/ci/risk-tiers.md) labels Oct 22, 2026
@github-actions github-actions Bot added risk:normal Risk tier (docs/ci/risk-tiers.md) and removed risk:medium labels Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex xhigh, correctness first): BLOCK at e04ab85

  • BLOCK — the session-switch guard still races the held snapshot. App.tsx:4637-4645 compares the clicked row’s owner with sessionIdRef.current, but that ref is assigned from the rendered snapshot at App.tsx:4378-4379. direct.ts:4262-4264 changes the client’s selected session immediately while holding the old snapshot during the attach. During that hold, an old Restart row still sees the old owner and passes the check; App.tsx:5954-5962 routes chat.send through the current client, so the recorded prompt can be sent to the newly selected chat.
  • BLOCK — Restart omits the composer’s remote-send guard. remoteEditing.ts:22-27 makes remote Codex/opencode chats non-sendable, and Composer.tsx:752-755 enforces that. App.tsx:4637-4640 gates Restart only on connected, sessionId, watching, and readOnlySubagent; it never checks remoteComposer(snapshot).canSend. A remote Codex/opencode stopped subagent can therefore show Restart and attempt a send that the composer correctly suppresses.

The three prior findings are otherwise addressed: turn causes are limited to agents in the current turn (subagentFold.ts:269-271), resumed agents clear persisted reasons (subagentFold.ts:275-280), and watched/read-only/disconnected snapshots no longer expose Restart (App.tsx:4637-4645). Localization is complete: all six added keys have all 21 locales with matching {name}, {kind}, and {prompt} placeholders. git diff --check passed. Focused Bun tests were skipped because webviews/node_modules is absent; no builds were run.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex xhigh, correctness first): SHIP at 6f1eec4

The two prior blockers are fixed:

  • restart.ts:32-47 now exposes Restart only when the chat is connected, not View Only, not a read-only subagent pane, and remoteComposer(...).canSend is true. This matches the Composer’s remote guard.
  • restart.ts:49-53 plus App.tsx:4644-4648 require both the rendered snapshot session and directClient.current.selectedSession to match the row owner, so a stale row during direct.ts:4262-4264’s snapshot hold cannot send into the next chat.
  • The earlier stop-reason fixes remain correct: current-turn membership scopes cause (subagentFold.ts:269-271), resumed agents delete persisted reasons (subagentFold.ts:275-280), and session reset replaces the shared stop store.

Localization is complete: all six added keys have all 21 locales with matching {name}, {kind}, and {prompt} placeholders. git diff --check passed. Fleet verification supplied for this head: 43 tests pass and typecheck is clean. Local focused Bun tests were skipped because webviews/node_modules is absent; no builds were run.

Non-blocking nit: the new Restart routing helpers are unit-tested, while the full App/direct-client switch-hold interaction is covered by static identity checks rather than UI automation.

@teamleaderleo teamleaderleo added the ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds label Oct 22, 2026
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex xhigh, correctness first): SHIP at 15e53fe

The requested base-update and catalog checks pass:

  • git diff 2d13b66db776 15e53fe0a2e --stat contains exactly the PR’s 13 files.
  • The parsed catalog is exactly base’s 1,650 entries plus the six new keys; no existing key/value changed. Localizable.xcstrings is 792 added lines and no deletions.
  • Each new key has all 21 locales, with matching {name}, {kind}, and {prompt} placeholders.
  • The non-catalog implementation remains the previously reviewed behavior: current-turn stop-cause scoping, resumed-reason clearing, sendability/read-only guards, and selected-session switch-hold fencing.

git diff --check passed. Fleet verification supplied for this head: 43 tests pass, typecheck clean, and xcstrings lint passed. Local focused Bun tests were skipped because webviews/node_modules is absent; no builds were run.

Non-blocking nit: the full App/direct-client switch interaction remains covered by static identity checks and helper tests rather than UI automation.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/39766181620 at 81640d1 failed: cmux-next web bundles (source-keyed cache).
Those jobs last passed at ecc390d. This pull request is one of 4 merged since: #24069, #24261, #24351, #24051.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

base-red-watch: cmux-next / cmux-next web bundles (source-keyed cache) went red on feat-cmux-next in https://github.com/manaflow-ai/cmux/actions/runs/39767130461 (first red at 6c1cab2, last green at ecc390d). Suspect: #24051 (commit 81640d1). If it is yours, fix forward on feat-cmux-next.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/39767073305 at aa8d973 failed: cmux-next web bundles (source-keyed cache).
Those jobs last passed at ecc390d. This pull request is one of 5 merged since: #24069, #24261, #24351, #24051, #24325.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

base-red-watch: cmux-next / cmux-next web bundles (source-keyed cache) went red on feat-cmux-next in https://github.com/manaflow-ai/cmux/actions/runs/39768589871 (first red at 81640d1, last green at ecc390d). Suspect: #24051 (commit 81640d1). If it is yours, fix forward on feat-cmux-next.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant