fix(gateway): prioritize user interrupts over internal events - #61858
Open
rungmc357 wants to merge 2 commits into
Open
fix(gateway): prioritize user interrupts over internal events#61858rungmc357 wants to merge 2 commits into
rungmc357 wants to merge 2 commits into
Conversation
rungmc357
force-pushed
the
fix/prioritize-user-over-internal-events
branch
from
July 15, 2026 15:52
f60bfe6 to
a1f3fb1
Compare
Contributor
Author
|
Rebased onto current The new tests exercise the real queue helpers and verify:
The media-burst test fails against the prior production commit and passes with the included head-merge fix, so the production delta is required rather than test-only churn. Verification on current
|
Queue-level regression coverage for the user-over-internal priority fix: - Interleaved user + internal arrivals: all user events keep arrival order and precede all internal events, pinning the overflow partition invariant ([user..., internal...]) the first-internal insertion relies on. - Drain execution order (dequeue + promote, mirroring the real drain site), not just the in-memory slot/overflow arrangement. - Full _BUSY_QUEUE_MAX_PENDING queue: user steering replaces an internal event (head-slot and overflow variants) instead of being dropped, and a queue full of user events never sheds one to admit an internal event. - Handler-level: a user interrupt outranks multiple queued internal completions, which cascade after it in arrival order. The photo-burst test exposed a real regression in the priority fix: with an internal event in the overflow, a media follow-up was inserted into the overflow ahead of it instead of album-merging into the user-owned head slot, splitting one burst into N turns. Fixed by letting the existing head-slot merge win over the overflow priority insertion — the head is already ahead of every internal event, so user priority is preserved either way. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rungmc357
force-pushed
the
fix/prioritize-user-over-internal-events
branch
from
July 30, 2026 10:11
a1f3fb1 to
dca5bae
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.
Summary
When a gateway session is busy, synthetic
internal=Truecompletion events intentionally queue without interrupting the active turn. If one reaches the pending head before a real user follow-up, the user message can still abort the model call but remain behind that internal event in the FIFO. The recursive next turn then handles the synthetic notification first, delaying the user's steering despite the interrupt acknowledgement.This change gives real user events priority over queued internal events while preserving arrival order within each class. When the bounded queue is full, it prefers dropping a synthetic notification rather than live operator input.
Related follow-ups to #49738 (internal completions do not interrupt busy sessions) and #49776 (busy-session FIFO queueing). I searched existing issues and PRs and did not find an equivalent fix.
Reproduction
busy_input_mode: interrupt.internal=True).Changes
Test plan
scripts/run_tests.sh tests/gateway/test_internal_event_never_interrupts_busy_session.py tests/gateway/test_queue_consumption.py tests/gateway/test_queue_command.py tests/gateway/test_busy_session_ack.py tests/gateway/test_session_race_guard.pyuv run --extra dev ruff check .python3 scripts/check-windows-footguns.py --allgit diff --check origin/main...HEADRisk and rollback
Risk is limited to ordering in a busy session when real and internal events coexist in the same pending queue. Media-only merging, all-user FIFO ordering, and all-internal FIFO ordering are unchanged. The focused queue tests cover the surrounding interrupt and dequeue paths.
Rollback is a single-commit revert; no configuration, migration, or persistent data changes are involved.