fix(gateway): emit agent:start on interrupt/drain follow-up turns - #37269
Closed
Couiz wants to merge 1 commit into
Closed
fix(gateway): emit agent:start on interrupt/drain follow-up turns#37269Couiz wants to merge 1 commit into
Couiz wants to merge 1 commit into
Conversation
The main message dispatch emits the `agent:start` hook before running the agent, but the interrupt/drain follow-up path in `_run_agent` promoted a queued message straight into a recursive `_run_agent` call without emitting `agent:start`. Every hook listening on `agent:start` (SessionStart-style integrations, activity loggers, visualizers) silently missed interrupt/queue follow-up turns — an event-emission gap, not a hook bug. Emit `agent:start` on the drain path right before the recursive `_run_agent`, mirroring the main-dispatch payload (platform, user_id, chat_id, session_id, message[:500]) but built from the follow-up turn's source (`next_source`) and the final, already-transcribed text (`next_message`) — so voice follow-ups carry the transcript, not the raw audio placeholder. The emit sits after every discard guard (draining, interrupt depth-cap, stale /goal continuation, transcription→None) so it fires exactly once per turn, only when the follow-up actually proceeds to the agent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 4, 2026
Author
|
Consolidated into #39126 — the three changes (agent:start on drain, trigger/depth tagging, agent:end on drain) are one coherent concern, and the agent:end fix's payload carries the trigger/interrupt_depth tagging, so they aren't cleanly separable. A single PR off fresh main reviews better than three stacked PRs across diverging bases. Closing in favor of #39126. |
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
The main message dispatch emits the
agent:starthook before running the agent, but the interrupt/drain follow-up path in_run_agentpromotes a queued message straight into the recursive_run_agentcall without emittingagent:start.With
busy_input_mode: interrupt, a message typed while the agent is busy interrupts the run, is queued in_pending_messages, and later drains as a follow-up turn — so every hook listening onagent:start(SessionStart-style integrations, activity loggers, visualizers) silently misses these turns. The hook system is fine; the gateway just never fires the event on this path.agent:startcurrently fires only in the main dispatch.Fix
Emit
agent:startonce on the drain path, immediately before the follow-up_run_agentcall, mirroring the main-dispatch payload but built from the drain-site variables (next_source, and the final, already-transcribednext_message). It sits after every discard guard (stale/goalcontinuation,_prepare_inbound_message_textreturningNone), inside the sametryblock as the main-path emit, so it:_run_agent;messageto 500 chars like the main path;15 lines, surgical — the main dispatch is untouched and
_run_agent's signature is unchanged.Tests
New
tests/gateway/test_drain_emits_agent_start.pydrives the real drain path via_pending_messages(mocking only transcription), asserting:agent:startemit with a main-path-shaped payload for text follow-ups;messagetruncated to 500 chars;_prepare→None, stale/goalcontinuation).RED before the fix (3 positive tests fail, 2 discard-guards pass), GREEN after. The full gateway interrupt/drain/pending/restart suite stays green (102 passed).
ruff checkpasses. No lockfile or unrelated changes.