Repository navigation
fix(goose): end the turn when a final send succeeds - #2997
Merged
Merged
Conversation
Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Signed-off-by: Bradley Axen <baxen@squareup.com>
Co-authored-by: mbot <3754f8729004d95654c46dbab3129e4ab9ef05cc2534e2a3fbfc155983bd637b@buzz.block.builderlab.xyz> Signed-off-by: Bradley Axen <baxen@squareup.com>
tlongwell-block
marked this pull request as ready for review
November 7, 2026 20:57
…til the turn ends The cancel now waits for the tool_call_update of the final send itself, matched by the ACP tool-call id goose passes in the MCP call's `_meta["agent-tool-call-request-id"]`, instead of the first completed or failed update. An earlier call's late update can no longer cancel before goose has the send's result. Without an id, nothing is cancelled and the turn ends on its own, as before. `ending` stays set until the cancelled prompt returns, so a message sent while the cancel is in flight runs as the next turn instead of being steered into the turn being cancelled. Tests: a message sent during the cancel is queued; an unrelated late completion does not cancel; a final send without an id ends on its own. All three fail at f037cc7. Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> Signed-off-by: Tyler Longwell <tlongwell@squareup.com>
tlongwell-block
approved these changes
Nov 7, 2026
tlongwell-block
added a commit
that referenced
this pull request
Nov 8, 2026
* origin/main: (47 commits) fix(relay): report a community's membership refusal once, not as raw 403s (#3012) test(browser): fix red main and two cross-PR flakes (#3015) feat(agent-activity): keep remote agent outcomes readable (#2913) test(solo): cover agent tagging behind a background read-state snapshot (#2941) fix(desktop): quit on SIGTERM, SIGINT and SIGHUP so agents stop with Buzz (#2905) feat(unread): opening a channel quiets its sidebar row (#2998) fix(goose): end the turn when a final send succeeds (#2997) fix(relay): report a community's refusal once, not as raw 403s (#2978) Give fast Builderlab models their own section and a bolt in the model picker (#2592) feat(dev): `just desktop me` keeps Keychain approvals across rebuilds (#3002) fix(relay): show one quiet reconnect toast after 30 s, above the composer (#2968) feat(memory): render rich markdown and navigable buzz links (#2981) fix(identity): never strand first run on a key another account holds (#2996) Let agent_create propose instructions (#2332) fix(unread): raise a local read floor over dropped marks, and halve save validation (#2977) Add Codex huddle auto-join and thinking presence (#2927) feat(claude): set up Claude from a button beside Harness (#2975) docs(plugins): document the decisions API in the authoring guide (#2994) fix(agent-harness): stop telling agents to use GitHub-flavored Markdown (#2639) feat(identity): brand federated sign-in and return to the app (#2982) ... Signed-off-by: Tyler Longwell <tlongwell@squareup.com> Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz> # Conflicts: # src/bundled/codex/voice.ts
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.
What
With goose, a
send(orreply_in_subthread) markedfinal: truenow ends the goose turn, as it already does for Claude Code (continue: false) and Pi.Until now
AcpSession.finished()only settled the Buzz work. goose went on with one more model call, and Buzz never posted its text. In that call, agents that had putfinalon a message promising more work ("I'll start the PR…") noticed the mistake, decided the protocol made them stop, and dropped the work. Buzz also counted the work as done while goose was still running.How
goose v1.57.0 has no way for a tool result to end a turn.
PostToolUsehooks only notify, andStophooks can only block. ACPsession/canceldoes it cleanly:goose-agent/src/machine.rsfinalize).stopReason: "cancelled".AcpSessionalready handles that for a turn the owner did not stop.Two races are handled in
acp/session.ts:finished()reaches goose before goose records thesendresult, so goose would save the send as interrupted and the model might resend it next turn. goose reports a batch's results together, once every call has one (ops_toolcalling.rs). So afterfinished(), the session cancels on the firsttool_call_updatethat iscompletedorfailed.finished()and that update is queued as the next turn instead of steered into the turn being cancelled.finished()keeps its existing guard: when another message is waiting for its answer, the turn is not ended.Non-goals: no change to the
finalprompt or tool description, and nothing in goose.Validation
src/bundled/goose/goose.test.ts: three new tests. The turn is cancelled only after the completed result arrives, and the next turn's results don't cancel it. A message arriving mid-ending runs as the next turn. No cancel while another message waits. The first two fail onorigin/mainand pass here.vitest run src/bundled/goose src/features/agent-harness src/features/agents src/bundled/mesh-compute: 1984 passed.tsc --noEmitis clean.Live goose-acp 1.57.0 (
GOOSE_ACP_BIN=… vitest run src/bundled/goose/goose.live.test.ts). The new test "ends the turn after a final send, keeping the send's result" asserts:session/cancelafter the final send;Sent.), so goose did not save the send as interrupted.It fails on
origin/main(no cancel) and passes here.origin/mainand on this branch: they expect{ ok: true }wherefinished()returns{ ok: true, answered: true }. That predates this change, and I left it alone.Deferred