Repository navigation
cmux NEXT agent pane: a prompt a dropped connection lost goes again, no "Not sent" (lost-prompt replay on) - #32389
Conversation
…no "Not sent" The host's prompt journal sends a prompt the daemon dropped with its connection (an acpmux restart or update mid-send) again on the next connection, under its promptId, now on by default. The page waits for it to show there instead of saying "Not sent: The agent connection was interrupted" at once and handing it back; only one that never shows says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-140531107322b17b78f0
…deps; format Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-140531107322b17b78f0
|
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)
Gallery before/after for
States
Pick other states with a Default changesThis pull request changes 2 defaults at
Signed off on this commit by Merge receipt: merged as Regenerate the snapshot with Shipped in:
|
|
Owned by an agent session · session |
|
Review (codex, router-review): SHIP at 71a596d Reviewer: codex gpt-6-astra high, fast tier. Follow-ups: 2. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward. SHIP at 71a596d Visual verdict: no images; Leo tries the build
Follow-ups:
|
The base removed the journal's size and entry caps (#33145) and the byDaemon close (#32389, #36333): record drops its too-large branch and trim, and the two write-race tests use a forget on another thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-a57dc6a4e0ad73610b3a
Leo, about a chat that said "Not sent: The agent connection was interrupted. Read its saved state before retrying." while the agent was alive:
Leo-ask: ask-7877c9aa95
What was wrong
When acpmux's connection drops while a prompt is still on its way (an acpmux restart or a daemon update mid-send, a reset socket), the pane's pending
session/promptis rejected with "The agent connection was interrupted". The agent itself was fine. Then:#23027 built the fix's parts: the host's prompt journal sends such a prompt again on the next connection, under its promptId and marked
resendso acpmux runs it at most once, and the page has hooks to wait for it. But the replay stayed behind a Debug toggle that was off, and the page never waited. The other line in Leo's screenshot, "Permission groups are disconnected. Refresh before answering.", is already gone on base. #23027 made the permission panel wait quietly for the reconnect attach, and that string has no callers left.What changes
AgentPaneTunables.lostPromptReplayis on by default (schemas/defaults/cmux-next.jsonfollows). The host journal sends a prompt the daemon dropped with its connection again on the next one. The Debug toggle stays, so it can be turned off.direct.ts: a prompt lost with its connection before acpmux took it, on a connection to this Mac's acpmux and small enough for the journal (8 MiB), carrieslostPrompt {sessionId, promptId}. A held sender's immediate "Not sent" notice is skipped for it.lostPrompt.ts:resentAfterLosswaits on the pane's next connected client for the prompt to show there. It reuses the existingwaitForResendandawaitResent, waiting 30 s for a connection and 10 s for the prompt to show.App.tsx: the established-chat send and the held send both wait for that before giving the prompt back. If it shows, the send counts as delivered (promptLanded), and the held composer lets go of it. Only a prompt that never shows comes back to the composer, with the "Not sent" line, the same way as before.No new Swift logic: the Swift change is a default flip and two comments.
Risk
This changes how an agent-pane send recovers from a lost connection. When the wait gives up (no reconnect within 30 s) and the journal later sends the prompt after all, a person who edits the returned prompt and sends it gets a new promptId. That is the same edge #23027's reviews found. It is an edge of the new behaviour, filed as a follow-up. A remote-origin connection, which has no journal, and a prompt over 8 MiB keep today's behaviour.
Tests
lostPrompt.test.tsaddsa prompt the connection lost before acpmux took it waits for the host's resend, never 'Not sent' at once. It uses a mock acpmux whose socket drops as the prompt reaches it. With basedirect.tsswapped in, it fails (lostPromptundefined; the notice is drawn). With this change, it passes.resentAfterLossis covered for each outcome: the prompt shows, a connection comes back but the prompt never shows, no connection comes back, and a refusal that is not a lost prompt.71a596db: webview lint 0/0, typecheck clean, fmt clean.lostPrompt.test.ts,agent-pane-connect-disconnect.test.tsandsrc/agent-session/acpmux/conversationgive 761 pass and 1 fail. The failure isBackgroundMark.test.tsx"only Open in terminal…", which this PR does not touch.cmux-ci compile-check --appat1d5a4d1cpassed. The Swift diff is the same at the head. The existingAgentPaneUnsentPromptTestsreplay test runs both arms of the toggle.Agent session: agent session
🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Fixes a lost agent-pane prompt showing "Not sent: The agent connection was interrupted" while the agent was fine. When acpmux's connection drops mid-send (a restart, an update, a reset socket), the host's prompt journal now sends the prompt again on the next connection and the pane waits for it to show there instead of saying "Not sent" at once. The
lostPromptReplaydebug toggle is now on by default.Written for commit 71a596d. Summary will update on new commits.