fix(agent): don't acknowledge a steer that the ending turn drops - #4992
Open
shani-singh1 wants to merge 1 commit into
Open
fix(agent): don't acknowledge a steer that the ending turn drops#4992shani-singh1 wants to merge 1 commit into
shani-singh1 wants to merge 1 commit into
Conversation
`RunCtx::run` drains the steer queue only at each round boundary (top of the
loop). When the provider returns `end_turn`, the run returns without a final
drain, and the outer prompt task clears `active_run_id`/`steer_tx` afterwards.
A steer that arrives in that window — after the last drain, before the turn
tears down — is accepted by the handler (`steer_tx.send` succeeds, it returns
`{runId, messageId}`) and then silently dropped: the run never drains it again.
The `steer_folds_into_active_turn_without_cancelling` test exposes this
intermittently as "steered text never reached the provider" (issue block#4942).
When `end_turn` is accepted, close the steer channel before ending. Closing
makes the handler reject any steer that races the decision (its `send` now
fails) instead of acknowledging one it can't deliver, so the client falls back
to a new turn. Then do a final drain of anything accepted *before* the close;
if a steer was folded in, run one more round to act on it rather than losing
it. A successful steer response therefore guarantees the run consumes the
steer.
The test gains a third canned response, consumed only in the rare timing where
the steer lands after the final round's request was dispatched and the fix runs
one extra round to deliver it; the common timing folds the steer into the
existing round and leaves it unused.
Fixes block#4942
Signed-off-by: Shani Singh <teamdeveloperworld@gmail.com>
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.
Fixes #4942.
Problem
RunCtx::run(crates/buzz-agent/src/agent.rs) drains the steer queue only at each round boundary — the top of the loop. When the provider returnsend_turn, the run returns without a final drain, and the outer prompt task clearsactive_run_id/steer_txonly afterwards.A steer that arrives in that window — after the last
drain_steers(), before the turn tears down — is accepted by the handler (steer_tx.sendsucceeds → it returns{runId, messageId}) and then silently dropped: the run has already left its loop and never drains it again.steer_folds_into_active_turn_without_cancellingexposes this intermittently as "steered text never reached the provider." The window is small, so it only fails under full-suite timing (it passes in isolation), which is exactly the flakiness reported.Fix
When
end_turnis accepted, before ending:self.steer.close()— closing the receiver makes the handler'ssteer_tx.sendfail for any steer that races this decision, so it is rejected (the client falls back to a new turn) instead of acknowledged-and-dropped.self.drain_steers()folds in anything accepted before the close.drain_steersnow returns whether it folded a non-empty steer; if it did,continueruns one more round to actually deliver it rather than losing it.So a successful steer response now guarantees the run consumes the steer — the invariant #4942 asks for. This only affects the end-of-turn path; mid-turn steering across rounds is unchanged (the channel stays open until
end_turn).The test gains a third canned response, consumed only in the rare timing where the steer lands after the final round's request was already dispatched and the fix runs one extra round to deliver it. In the common timing the steer folds into the existing round and the third response is unused.
Validation — please read
I could not run the
fake_llmintegration harness locally: on this Windows box everyfake_llmtest (including a trivialtext_only_end_turn) panics ininit_sessionat the agent-binary spawn/handshake, and it fails identically on cleanmainwith my branch stashed — so it's a pre-existing local-environment issue, not this change. What I did verify:cargo test -p buzz-agent --no-run— the code fix and the test change compile clean (0 errors/warnings).cargo test -p buzz-agent --lib— 389 pass. The only 2 failures areauth::tests::cache_path_includes_namespace_and_hashandhints::tests::discover_skills_dedup_by_name— OS-path-sensitive tests in modules this change doesn't touch, failing on cleanmaintoo.cargo fmt -p buzz-agent -- --check— clean.So the change is compile-verified and unit-test-clean; the end-to-end steer behavior is validated by CI, which runs the
fake_llmsuite on Linux. Flagging the gap plainly rather than implying a green integration run. The logic is deliberately minimal (aboolreturn + four lines on the accept path; the give-up early-return is untouched) to keep it low-risk.