Skip to content

fix(gateway): emit agent:start on interrupt/drain follow-up turns - #37269

Closed
Couiz wants to merge 1 commit into
NousResearch:mainfrom
Couiz:fix/gateway-drain-agent-start
Closed

fix(gateway): emit agent:start on interrupt/drain follow-up turns#37269
Couiz wants to merge 1 commit into
NousResearch:mainfrom
Couiz:fix/gateway-drain-agent-start

Conversation

@Couiz

@Couiz Couiz commented Jun 2, 2026

Copy link
Copy Markdown

Problem

The main message dispatch emits the agent:start hook before running the agent, but the interrupt/drain follow-up path in _run_agent promotes a queued message straight into the recursive _run_agent call without emitting agent: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 on agent: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:start currently fires only in the main dispatch.

Fix

Emit agent:start once on the drain path, immediately before the follow-up _run_agent call, mirroring the main-dispatch payload but built from the drain-site variables (next_source, and the final, already-transcribed next_message). It sits after every discard guard (stale /goal continuation, _prepare_inbound_message_text returning None), inside the same try block as the main-path emit, so it:

  • fires exactly once per turn, and only when the follow-up actually proceeds to _run_agent;
  • carries the transcript for voice follow-ups, not the raw-audio placeholder;
  • truncates message to 500 chars like the main path;
  • shares the main path's exception parity.

15 lines, surgical — the main dispatch is untouched and _run_agent's signature is unchanged.

Tests

New tests/gateway/test_drain_emits_agent_start.py drives the real drain path via _pending_messages (mocking only transcription), asserting:

  • one agent:start emit with a main-path-shaped payload for text follow-ups;
  • the voice follow-up payload carries the transcript, never the audio path;
  • message truncated to 500 chars;
  • no emit on the two discard branches (_prepareNone, stale /goal continuation).

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 check passes. No lockfile or unrelated changes.

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>
@Couiz

Couiz commented Jun 4, 2026

Copy link
Copy Markdown
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.

@Couiz Couiz closed this Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants