fix(agent): guard merged assistant compaction handoffs - #85394
fix(agent): guard merged assistant compaction handoffs#85394abundantbeing wants to merge 2 commits into
Conversation
|
CI's only failure is unrelated to this two-file compaction patch: |
|
Latest-head CI has one unrelated failure in |
PR: fix(agent): guard merged assistant compaction handoffs
|
bf55f4a to
db16c76
Compare
|
CI note for the maintainers: the failing slice on this head is unrelated to this PR's diff and reproduces on clean
A CI re-run (maintainer-only; the fork token gets 403 on |
b3cfbcf to
746a7d2
Compare
Treat a merged assistant-role summary carrier as the driving reference handoff when it immediately follows a completed assistant stop. Its preserved prose and stale tool_calls are assistant continuity, not a fresh live user request. Keep legitimate in-flight behavior unchanged when there is no completed stop, a real user turn follows, or a distinct later assistant tool-call row continues the loop. Extends the NousResearch#80622 active-turn guard for the merged-carrier shape reported under NousResearch#42768.
Identify a completed merged assistant handoff from the carrier's own stop state instead of an unrelated adjacent history row. Keep carriers with pending tool calls actionable so compaction cannot abort a live tool chain.
746a7d2 to
57f567a
Compare
andrexibiza
left a comment
There was a problem hiding this comment.
Reviewed exact head 57f567adf3bc9acfd1ad9547592f710c98331cde.
Code verdict: no blocking findings.
The production trace supports the narrow predicate:
- merge-into-tail preserves the assistant carrier's own normalized
finish_reasonandtool_calls; role="assistant"+ merged-summary classification +finish_reason="stop"+ notool_callstherefore identifies completed historical assistant output rather than a live request;- pending carrier tool calls, a later real user turn, and a distinct later assistant tool-call row remain actionable.
The regression matrix covers both sides of that boundary. Provider-native stop reasons are normalized before this row is persisted, so the "stop" check is not Anthropic-specific. Exact-head CI is green across CI, Docker Build/Test/Publish, and Nix flake check.
Merge disposition: #91516 is a content-identical cherry-pick of both commits onto current main (c481a5f4f345eef3ee9435e632a440fa4ed987a8) with @abundantbeing's authorship preserved; both changed-file blob SHAs are identical. This head is now 263 commits behind current main. Merge exactly one vehicle. Given live state, #91516 is the current-base integration copy; close #85394 as superseded after #91516 lands, or update this original onto current main and close #91516. Do not merge both.
|
Topology closure: #91516 is the sole current-base landing vehicle for this implementation.
Closing #85394 unmerged as superseded would leave one landing authority without erasing the original contribution/review chronology. Do not merge both. |
|
Merged via #91516 — both of your commits cherry-picked onto current main with your authorship preserved (rebase merge, no squash). The guard verified exactly as described: side-by-side E2E against main confirmed the completed merged carrier was re-driving the model, and your fix flips precisely that case while live tool-call carriers stay in flight. 20/20 tests green, mutation-checked. Thanks for the sharp fix, @abundantbeing! |
What does this PR do?
Extends the #80622 active-turn guard to the merged assistant carrier shape that still escaped it.
When compaction merges its summary into an assistant tail row, the completed carrier identifies itself with
role="assistant",classify_summary_content(...) == "merged", and its ownfinish_reason="stop". That carrier's preserved prose is historical assistant output, not a fresh user request.The guard is deliberately narrow:
finish_reason="stop"is reference-onlytool_callsremains live and must continue the tool chainThis avoids the rejected adjacent-row heuristic: the message before a merged carrier may be unrelated, while the carrier's own finish state is the direct production invariant.
Issue linkage
Tests
RED first:
GREEN:
20 passedin the focused active-turn suite195 passedacross the adjacent compaction surfaceruffcleancompileallcleangit diff --checkcleanChecklist
mainpytest tests/ -qpasses locallyI ran the complete adjacent compaction surface rather than claiming an unrelated full-suite run.