fix(agents): use currentAttemptAssistant for incomplete-turn classification#94305
fix(agents): use currentAttemptAssistant for incomplete-turn classification#94305LiuwqGit wants to merge 1 commit into
Conversation
|
Replaces #94188 (closed due to branch reset). This PR is a 1-line helper-level classification fix verified by L2 vitest proofs. I don't have a live OpenClaw environment for Changes:
|
d75fda7 to
af5b277
Compare
|
Rebased to latest main (commit af5b277). The earlier comment about needing |
|
Codex review: needs maintainer review before merge. Reviewed June 18, 2026, 8:17 AM ET / 12:17 UTC. Summary PR surface: Source 0, Tests +71. Total +71 across 2 files. Reproducibility: yes. at source level: current main still passes stale Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this narrow classifier fix if exact-head CI stays green, and keep broader delivery observability or recovery tooling as separate follow-up work. Do we have a high-confidence way to reproduce the issue? Yes at source level: current main still passes stale Is this the best way to solve the issue? Yes, this is the best narrow fix: it changes only the final classification input while preserving the early AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c88d5f261192. Label changesLabel justifications:
Evidence reviewedPR surface: Source 0, Tests +71. Total +71 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Summary
update_plan(stopReason=toolUse) and the model then produces a final plain-text turn with stopReason=stop,resolveIncompleteTurnPayloadTextincorrectly classifies the turn as incomplete because it checkslastAssistant.stopReason(stale snapshot) instead of the freshercurrentAttemptAssistant.update_planclosure) triggers this on every run.isDeliverablePayload,assistantTextsincomplete branch,replayMetadata, orlivenessState.Linked context
Closes #80918
Related #76477 (original incomplete-turn safety contract — preserved)
Real behavior proof
lastAssistantfalse-positive afterupdate_plan→ finalstopturnresolveIncompleteTurnPayloadTextlogic, run on Linux (Node 24)lastAssistant.stopReason="toolUse"and freshcurrentAttemptAssistant.stopReason="stop",resolveIncompleteTurnPayloadTextreturnsnull(not incomplete). The real final text passes through to payload delivery. Node repro confirms the exact bug scenario, regression scenario, and normal path all behave correctly.isIncompleteTerminalAssistantTurn,resolveIncompleteTurnPayloadText). Vitest coverage exists as supplemental proof for the actual module imports. L3 proof via node repro with terminal output capture.params.attempt.lastAssistantdirectly), the same scenario produces"⚠️ Agent couldn't generate a response."instead ofnull. Confirmable by reverting the one-line change and running the node repro or vitest tests.Tests and validation
pnpm test src/agents/embedded-agent-runner/run.incomplete-turn.test.ts— 119/119 passeduses currentAttemptAssistant over stale lastAssistant for incomplete-turn classification (#80918)— unit test forisIncompleteTerminalAssistantTurndoes not flag stale lastAssistant=toolUse when currentAttemptAssistant=stop exists (#80918)— integration test forresolveIncompleteTurnPayloadTextstill flags incomplete-turn when currentAttemptAssistant is absent and lastAssistant=toolUse (#76477 regression)— confirms real incomplete-turn still fires#76477regression tests still pass (unchanged behavior for legitimate incomplete-turn scenarios)Risk checklist
isIncompleteTerminalAssistantTurncall inresolveIncompleteTurnPayloadTextnow usescurrentAttemptAssistant ?? lastAssistantinstead of rawlastAssistant. IfcurrentAttemptAssistantexists but has an unexpected stopReason, classification could change. Mitigated by: (a) the regression test forcurrentAttemptAssistant=undefinedstill flags incomplete-turn, (b) the existingtoolUseTerminalearly guard on line 282 still uses the stalelastAssistantto prevent pre-tool text from suppressing the check, (c) all 117 existing tests pass.Current review state
assistantTextsafter the incomplete-turn branch fired, which violated the#76477safety contract by promoting pre-tool narration into successful output. This PR fixes the classification itself so the incomplete-turn branch is never entered in theupdate_plan → stopscenario — leaving the payload delivery path and safety contract untouched.