fix(claude): resolve queue-operation prompt completion deadlock#259
Open
nixecn wants to merge 1 commit into
Open
fix(claude): resolve queue-operation prompt completion deadlock#259nixecn wants to merge 1 commit into
nixecn wants to merge 1 commit into
Conversation
When a prompt is delivered via tmux paste-buffer while the Claude REPL is busy (cooking/tool_use), Claude CLI records it as a 'type=queue-operation, operation=enqueue, content=<prompt>' entry (optionally followed later by an attachment/queued_command), and does NOT synthesize a 'type=user' message. The completion pipeline was blind to queue-operation records: structured_event() dropped them entirely, so handle_user_event() never saw the CCB_REQ_ID anchor, anchor_seen stayed False, assistant events (including the final end_turn and the last_assistant_uuid needed for turn_duration matching) were gated out, and the attempt hung in 'running' forever, backing up the mailbox queue. This manifested in the field as repeated pm (central dispatcher) stalls because pm is the agent that most often receives async replies while busy. A 183-job sample of the pm session log found 14 queue-op prompt deliveries; 9 of them failed to complete automatically (7 incomplete, 2 cancelled by human recovery). Fix: 1. structured_event() now synthesizes a role=user event from queue-operation/enqueue records carrying the full prompt text, so the anchor (CCB_REQ_ID) is observed and anchor_seen flips. 2. structured_event() also emits zero-text assistant events for assistant entries whose content is pure tool_use/thinking blocks (previously dropped because extract_message yields no visible text). These carry the assistant uuid so that pre-anchor bookkeeping can track last_assistant_uuid and the later turn_duration system event's parent_uuid matches. 3. _process_event() runs a pre-anchor bookkeeping pass on every assistant event (uuid tracking only) before the anchor_seen gate; full chunk/reply/turn-boundary handling still requires anchor_seen. A detailed diagnosis is in docs/claude-queue-operation-completion-deadlock-diagnosis.md. Verified: - All 14 historical queue-op stuck jobs (sampled from the pm session) now reach TURN_BOUNDARY under the patched detector. - idle-REPL (user/text_string) path is unchanged; regression on normal prompts passes. - Existing claude parsing/event_reading/exec_polling/assistant_events tests still pass (19/19).
Contributor
Author
|
这个PR修改的内容,已经经过一段时间使用的验证了。 所以可以放心合并。 |
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.
Problem
When CCB delivers a prompt to Claude via
tmux paste-bufferwhile the ClaudeREPL is busy (cooking / tool_use), Claude CLI records it as
and does not synthesize a
type=usermessage. The completion pipeline wasblind to
queue-operationrecords:structured_event()dropped them entirely, sohandle_user_event()never saw theCCB_REQ_IDanchor;anchor_seenstayedFalse;end_turn, and thelast_assistant_uuidneeded forturn_durationmatching) was gated out;runningforever, backing up the mailbox queue.Field impact: repeated
pm(central dispatcher) stalls, becausepmis theagent that most often receives async replies while busy. A 183-job sample
of the pm session log found 14 queue-op prompt deliveries; 9 of them
failed to complete automatically (7 incomplete, 2 cancelled by human recovery).
Full diagnosis:
docs/claude-queue-operation-completion-deadlock-diagnosis.md(added by this PR, 183 lines).
Fix
Three coordinated changes:
Synthesize a user event from queue-operation records
(
lib/provider_backends/claude/comm_runtime/parsing_runtime/structured.py)structured_event()now emits arole=userevent forqueue-operation/enqueueentries carrying the full prompt text, so theCCB_REQ_IDanchor is observed andanchor_seenflips.Emit zero-text assistant events for tool_use / thinking-only entries
(same file)
Previously dropped because
extract_messageyielded no visible text.These carry the assistant
uuidso pre-anchor bookkeeping can tracklast_assistant_uuidand the laterturn_durationsystem event'sparent_uuidmatches.Pre-anchor uuid bookkeeping
(
lib/provider_backends/claude/execution_runtime/polling.py)_process_event()now runs a bookkeeping pass on every assistant event(uuid tracking only) before the
anchor_seengate. Fullchunk/reply/turn-boundary handling still requires
anchor_seen.Total: +335 / -2 across 3 files (docs + 2 code files).
Verification
now reach
TURN_BOUNDARYunder the patched detector.user/text_string) path is unchanged — regression onnormal prompts passes.