fix(tui_gateway): stop replaying live-turn user text after redirect - #84589
StanleyStetson wants to merge 1 commit into
Conversation
a578f24 to
3219756
Compare
A mid-turn correction (Desktop session.redirect / busy-input interrupt redirect) must not leave a server-queue self-copy of the live inflight user prompt. Otherwise post-turn _drain_queued_prompt restarts that original text as a fresh agent turn after Q completes (NousResearch#84417). Scrub text-only self-duplicates of inflight_turn.user on successful redirect/steer, refuse admitting them in _enqueue_prompt, rewrite merged "{P}\n\n{Q}" slots to Q-only, bump _queued_prompt_generation on compression session rotation, and restore the claimed queue envelope when generation cancels mid-drain. Stabilize profile-scoped agent-build unit tests under CI load. Fixes NousResearch#84417
3219756 to
7c39f7d
Compare
|
This was generated by AI during triage. Summary: Problems:
Solution: Evidenceno deterministic fact backs this claim — model belief, not executed or read evidence Checked against |
|
Thank you for this fix! It was salvaged into #86593 (cherry-picked onto current main with your authorship preserved in the commit history) and is now merged. Closing this PR since the work has landed. |
What does this PR do?
Stops the tui_gateway server queue from re-firing the live turn's original user prompt P after a mid-turn correction Q (Desktop
session.redirect/ busy-input interrupt redirect). That re-fire produced a second agent turn and a second activerole=userrow with the same content (#84417).Root cause (contract layer): while turn P was live, a text-only self-copy of P could sit in
session["queued_prompt"]/queued_prompts(e.g. mid-busy re-submit while redirect was not available; consecutive-text merge could also glueP\n\nQ). Successful redirect/steer of Q did not scrub that self-duplicate, so post-settle_drain_queued_promptrestarted P.Approach:
inflight_turn.useron successful redirect/steer; rewrite merged{P}\n\n{Q}→Qonly._enqueue_prompt(scrub first so merge cannot re-glue P+Q)._queued_prompt_generationso an in-flight drain claim cannot dispatch with a stale generation. If generation cancels a claim mid-drain, the claimed envelope is restored to the queue (legitimate follow-ups are not dropped).Scope / residual (honest limits of this PR):
$queuedPromptsBySession) is unchanged; a user-queued follow-up can still drain by design.Related Issue
Fixes #84417
Type of Change
Changes Made
tui_gateway/server.py—_sanitize_queued_entry_vs_inflight_user,_drop_queued_duplicates_of_inflight_user; scrub on successful busy redirect/steer; refuse self-dup in_enqueue_prompt; bump_queued_prompt_generationin_sync_session_key_after_compresson rotation; restore claimed queue envelope when generation cancels mid-drain.tui_gateway/methods_session.py— scrub on successfulsession.redirectandsession.steer(Desktop production path).tests/test_tui_gateway_queue_on_busy.py— redirect scrub, hard-interrupt path, merge rewrite, drain E2E (no second P), enqueue refuse, compress generation bump / no-op, generation-cancel restores claimed head.tests/test_tui_gateway_server.py—session.redirectRPC scrub + build-window queue of Q scrubs stale P.How to Test
tests/test_tui_gateway_queue_on_busy.py— 25 passed; relatedsession.redirect/ compress re-anchor tests passed viascripts/run_tests.sh.session.redirectRPC)session.redirectenqueue of Q scrubs P_drain_queued_promptdoes not start a turn with PP\n\nQrewrites to Q-onlyqueued_prompt=P+ redirect(Q) → pre-fix drain re-fired P; post-fix queue scrubbed, drain no-op.Checklist
Code
fix(scope):,feat(scope):, etc.)scripts/run_tests.shon the affected tests and they pass (project canonical runner)scripts/run_tests.shDocumentation & Housekeeping
docs/, docstrings) — N/Acli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/A