fix(clarify): unblock wait_for_response on thread-scoped interrupt (salvages #25506) - #84560
Open
ayushnangia wants to merge 2 commits into
Open
fix(clarify): unblock wait_for_response on thread-scoped interrupt (salvages #25506)#84560ayushnangia wants to merge 2 commits into
ayushnangia wants to merge 2 commits into
Conversation
Salvages NousResearch#25506 (liuhao1024): the wait loop now checks tools.interrupt.is_interrupted() once per slice, so /stop and interrupt-mode messages unblock a pending clarify instead of wedging the agent thread for the full timeout (600s default) or forever in unlimited mode. The end-of-run clear_session cleanup cannot fire while this wait blocks, so the interrupt flag was set but never observed (NousResearch#83889 RC1). Also folds yflmq001's callsite gap from the NousResearch#84119 review: an interrupted wait now reports '[interrupted by user]' instead of the misleading '[user did not respond within Nm]'. Sweeper verdict on NousResearch#25506: keep_open, salvageability=high.
Contributor
fix(clarify): unblock wait_for_response on thread-scoped interrupt (salvages #25506) Good salvage — checking
|
ayushnangia
force-pushed
the
fix/clarify-interrupt-wait
branch
from
August 17, 2026 19:35
aa6e89f to
2fc928f
Compare
wait_for_response's interrupt exit left the thread-scoped flag set; gateway executor threads are reused across turns, so the NEXT clarify wait on that thread would abort instantly (Enough1122 review on NousResearch#84560). The early-exit path now clears the flag for its own thread; the agent loop's clear remains the owner of turn-scoped semantics.
ayushnangia
force-pushed
the
fix/clarify-interrupt-wait
branch
from
August 23, 2026 13:42
2fc928f to
597bfcb
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
Salvage of #25506 (@liuhao1024, May 14 — conflicting, author inactive, sweeper verdict keep_open/salvageability=high): the clarify
wait_for_responseloop never observes the thread-scoped interrupt flag, so/stopor an interrupt-mode message cannot unblock an agent waiting on a clarify prompt. The agent thread wedges for the full clarify timeout (600s default) — or forever whentimeout <= 0(unlimited mode). RC1 of #83889; anchor of family E in the stall triage #84047.Root cause
The deadlock is a cycle.
AIAgent.interrupt()propagates the thread-scoped signal to tool workers (run_agent.py:2696-2703, per the sweeper's review of #25506), butwait_for_response(tools/clarify_gateway.py) polls only its resolution event and the inactivity heartbeat. Theclear_sessioncleanup that cancels pending clarify entries runs at end-of-run (gateway/run.py) — which is unreachable while the thread is blocked in this wait. Flag set, never observed; cleanup ready, never reached.Changes
tools/clarify_gateway.py:wait_for_responsecheckstools.interrupt.is_interrupted()once per slice, before the slice, so an already-interrupted thread never waits at all. Mechanism is @liuhao1024's from fix(clarify): check interrupt flag in gateway wait_for_response loop #25506; defensive import/try so a broken probe can never re-wedge the wait. A response that races the interrupt and resolves first still wins.gateway/run.py(_clarify_callback_sync): an interrupted wait now returns[interrupted by user]instead of the misleading[user did not respond within Nm]— @yflmq001's gap from the fix(gateway): unblock clarify wait on /stop or interrupt-mode messages #84119 review, folded as suggested.Validation
scripts/run_tests.sh tests/tools/test_clarify_interrupt_wait.py tests/tools/test_clarify_tool.py tests/tools/test_clarify_gateway.py→ 48 passed, 0 failed.pytest --timeout=25guard — on unfixed code the unlimited-wait case blocks forever, which is the bug).test_clarify_active_session_bypass/ photon poll / thread-followup reproduce identically on clean main — unrelated.Scope notes
clear_sessioninside_interrupt_and_clear_session), but it only covers gateway-driven interrupts; the in-loop check covers all interrupt sources, so it ships first.