Skip to content

fix(agents): preserve assistant text and use currentAttemptAssistant for incomplete-turn check#93805

Closed
LiuwqGit wants to merge 1 commit into
openclaw:mainfrom
LiuwqGit:fix/issue-80918-silent-send-miss
Closed

fix(agents): preserve assistant text and use currentAttemptAssistant for incomplete-turn check#93805
LiuwqGit wants to merge 1 commit into
openclaw:mainfrom
LiuwqGit:fix/issue-80918-silent-send-miss

Conversation

@LiuwqGit

@LiuwqGit LiuwqGit commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

What problem does this PR solve?

When an agent's last tool call is update_plan (or any tool with empty/no-op result), and the model then produces a final plain-text turn with stopReason="stop", three cascading bugs cause a silent send miss:

  1. resolveIncompleteTurnPayloadText reads stale lastAssistant.stopReason === "toolUse" instead of the actual final assistant message
  2. The incomplete-turn branch discards all collected assistantTexts and returns only the error warning
  3. The user receives nothing — dashboards report green

Why does this matter now?

This fires for any agent following checklist discipline (closing tasks with update_plan), which is the default behavior pattern, not an edge case. Impact is HIGH — silent data loss with no observability signal.

What is the intended outcome?

  • Users receive their agent's final visible answer alongside the incomplete-turn warning
  • The incomplete-turn classifier uses currentAttemptAssistant as the authoritative source for stopReason, avoiding stale snapshots

What is intentionally out of scope?

  • P1 observability improvements (structured alarms, delivery-queue/failed/ logging, openclaw recover --run-id)
  • Live WhatsApp/channel proof (L2 only — vitest + temp state)

What does success look like?

The assistantTexts collected during the run are included as non-error payloads before the warning text, so even if the incomplete-turn classification is a false positive, the user still receives their content.

What should reviewers focus on?

The currentAttemptAssistant ?? lastAssistant resolution in resolveIncompleteTurnPayloadText: this is the fix for the stale snapshot. Verify it does not suppress legitimate incomplete-turn detection for the original #76477 use case (interrupted tool chain with genuinely missing final text).

Linked context

Which issue does this close?

Closes #80918

Which issues, PRs, or discussions are related?

Related #76477

Was this requested by a maintainer or owner?

No — contributor-identified and self-fixed.

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: Silent send miss from stale lastAssistant snapshot after update_plan tool call
  • Real environment tested: Local vitest (no live OpenClaw/WhatsApp setup)
  • Exact steps or command run after this patch: See Tests section below
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output):
{
  "test": "src/agents/embedded-agent-runner/run.incomplete-turn.test.ts",
  "result": "116 passed",
  "key_change": "payloads[0] is now assistantText (isError=false), payloads[1] is warning (isError=true)"
}
 Test Files  1 passed (1)
      Tests  116 passed (116)
  • Observed result after fix: The incomplete-turn branch includes assistantTexts as deliverable non-error payloads before the warning. The classifier uses currentAttemptAssistant for the stopReason check.
  • What was not tested: Live WhatsApp/channel end-to-end delivery (no live environment available)
  • Proof limitations or environment constraints: L2 only — unit tests with mocked session state. No L3 live channel proof.
  • Before evidence (optional but encouraged): The original report in Silent send miss: incomplete-turn classifier discards stopReason=stop final after update_plan #80918 includes detailed trace.artifacts showing didSendViaMessagingTool=false and messagingToolSentTexts=[]

Tests and validation

Which commands did you run?

pnpm test src/agents/embedded-agent-runner/run.incomplete-turn.test.ts
pnpm test src/agents/embedded-agent-subscribe.handlers.lifecycle.test.ts

What regression coverage was added or updated?

Updated existing test: "emits incomplete-turn warning when tool-use assistant dropped final text" now asserts that assistantTexts[0] appears as payload[0] (isError=false) before the warning at payload[1] (isError=true).

What failed before this fix, if known?

The test previously expected payloads[0].isError === true. Now it expects the assistant text payload first, reflecting the fix.

Risk checklist

Did user-visible behavior change? (Yes/No)

Yes — users now receive their agent's final answer instead of silence when the incomplete-turn classifier fires after a tool-use stop reason.

Did config, environment, or migration behavior change? (Yes/No)

No

Did security, auth, secrets, network, or tool execution behavior change? (Yes/No)

No

What is the highest-risk area?

False-negative risk: if a truly incomplete turn now delivers partial text alongside the warning, users might see preliminary analysis. The warning text still clearly indicates the turn was classified as incomplete.

How is that risk mitigated?

  • Assistant texts are delivered BEFORE the warning, so the warning remains visible
  • The incomplete-turn guard still fires and produces the warning
  • The currentAttemptAssistant resolution only changes behavior when the final message has stopReason="stop" — genuinely interrupted tool chains still have stopReason="toolUse" and are unaffected

Current review state

What is the next action?

Wait for CI to complete; then maintainer review.

What is still waiting on author, maintainer, CI, or external proof?

  • CI checks
  • Maintainer review

Which bot or reviewer comments were addressed?

N/A — first submission

…for incomplete-turn check

Bug 1: resolveIncompleteTurnPayloadText now uses currentAttemptAssistant
as the authoritative source for the toolUse stopReason check, avoiding
stale lastAssistant snapshots that silently discard the final answer.

Bug 2: The incomplete-turn return path in runEmbeddedAgent now includes
collected assistantTexts as non-error payloads alongside the warning,
so the user's real output is never silently discarded.

Fixes openclaw#80918
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 16, 2026
@clawsweeper

clawsweeper Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed June 16, 2026, 8:00 PM ET / 00:00 UTC.

Summary
Review failed before ClawSweeper could summarize the requested change.

PR surface: Source +12, Tests +3. Total +15 across 3 files.

Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path.

Review metrics: none identified.

Merge readiness
Not assessed.
Failure reason: invalid structured output.

This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict.
Keep any merge decision on the normal maintainer review path until ClawSweeper can complete a fresh review.

Risk before merge

  • [P1] No close action taken because the review did not complete.

Maintainer options:

  1. Decide the mitigation before merge
    Retry the Codex review after fixing the execution failure.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • Review did not complete, so no work-lane recommendation was made.
Review details

Best possible solution:

Retry the Codex review after fixing the execution failure.

Do we have a high-confidence way to reproduce the issue?

Unclear. The review failed before ClawSweeper could establish a reproduction path.

Is this the best way to solve the issue?

Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction.

AGENTS.md: unclear because the file could not be read completely.

Codex review notes: model internal, reasoning high; reviewed against f7d96c9301d1.

Evidence reviewed

PR surface:

Source +12, Tests +3. Total +15 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 2 15 3 +12
Tests 1 5 2 +3
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 3 20 5 +15

What I checked:

  • failure reason: invalid structured output.
  • codex failure detail: Codex review failed for this PR with exit 0 and wrote invalid JSON or schema-invalid output to /home/runner/work/clawsweeper/clawsweeper/artifacts/event/codex/93805.json: decision.rootCauseCluster.currentItemRelationship fixed_by_candidate requires a canonical PR.
  • codex stderr: No stderr captured.
  • codex stdout: or broad product change."},{"label":"merge-risk: 🚨 message-delivery","reason":"Merging as-is can cause real incomplete tool-use stalls to send partial assistant text as a non-error reply before or alongside the warning."}],"itemCategory":"bug","reproductionStatus":"source_reproducible","reproductionConfidence":"high","requiresNewFeature":false,"requiresNewConfigOption":false,"requiresProductDecision":false,"reproductionAssessment":"Yes, at source level: current main still uses stale lastAssistant for the tool-use terminal check while currentAttemptAssistant can hold the completed terminal assistant. I did not run the live WhatsApp/OpenRouter reproduction in this read-only review.","solutionAssessment":"No, not as submitted: preferring currentAttemptAssistant is the right narrow fix, but blindly prepending all assistantTexts in the incomplete branch changes true tool-use-stall delivery.

Likely related people:

  • unknown: Codex failed before it could trace repository history. (role: review did not complete; confidence: low)
How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 17, 2026
@vincentkoc vincentkoc self-assigned this Jun 17, 2026
@vincentkoc

Copy link
Copy Markdown
Member

Closing this PR because the proposed delivery change violates the existing incomplete-turn safety contract: it promotes pre-tool assistant narration into successful output even when the post-tool response never arrived. Current main intentionally emits only a trusted terminal-tool presentation or the incomplete-turn error in that state, and the payload error tests protect against leaking partial assistant text.

The narrower currentAttemptAssistant change also has no demonstrated production effect here: both it and lastAssistant are derived from the same attempt message snapshot. If issue #80918 still reproduces, the next useful step is a captured attempt snapshot and focused regression that proves those fields can diverge without exposing partial output.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling proof: supplied External PR includes structured after-fix real behavior proof. size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Silent send miss: incomplete-turn classifier discards stopReason=stop final after update_plan

2 participants