fix(acp): don't lose queued prompts when the drain echo hits a dead connection - #71012
Open
israellot wants to merge 1 commit into
Open
fix(acp): don't lose queued prompts when the drain echo hits a dead connection#71012israellot wants to merge 1 commit into
israellot wants to merge 1 commit into
Conversation
Contributor
|
Thanks for the focused ACP regression fix. Current main still pops This is an automated hermes-sweeper review. |
israellot
force-pushed
the
fix/acp-queued-prompt-loss
branch
from
August 19, 2026 12:50
ac6d6d5 to
298289c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The post-turn queued-prompt drain in
acp_adapter/server.pycan permanently lose a user's queued message when the client disconnects mid-drain:The drain pops the queued text and then awaits the user-message echo unguarded. If the client goes away at that instant,
session_updateraises (e.g.ConnectionResetError) and the exception escapesprompt()after the pop: the queued text is neither run nor re-queued — permanently lost. User-visible symptom: you type a message while a turn is running, see it acknowledged as "Queued for the next turn (1 queued)", and it silently evaporates.The fix wraps the drain echo in
try/except Exceptionwith a debug log. The echo is cosmetic — the popped prompt is the payload — so a dying connection must never preventawait self.prompt(...)from running the popped text. The transcript persists server-side and replays on reattach, so a missed echo is harmless while a missed turn is data loss. No othersession_updatecall sites are touched: this is the only echo site in the drain flow with the pop-then-lose shape.Reproduction sketch
state.queued_prompts.prompt()after the pop — the queued prompt never runs and is gone from the queue.The regression test reproduces this deterministically by exercising the real
prompt()path withrun_conversationmocked (first turn enqueues a prompt) and a mock conn whosesession_updateraisesConnectionResetErroron exactly the drain'sUserMessageChunkecho. On upstream/main before the fix it fails with theConnectionResetErrorescaping and only onerun_conversationcall; with the fix it asserts the queued text runs as the second turn and the queue is drained.How to test
Platforms tested
Linux fully verified; Windows/macOS not manually tested (change is pure Python exception handling, no platform-specific I/O; footguns check clean).
Related