Skip to content

fix(agent): recover blank streamed replies from final answer#71467

Merged
steipete merged 2 commits into
openclaw:mainfrom
Sanjays2402:fix/71454-blank-streamed-reply-fallback
Apr 25, 2026
Merged

fix(agent): recover blank streamed replies from final answer#71467
steipete merged 2 commits into
openclaw:mainfrom
Sanjays2402:fix/71454-blank-streamed-reply-fallback

Conversation

@Sanjays2402

Copy link
Copy Markdown
Contributor

Summary

Describe the problem and fix in 2–5 bullets:

If this PR fixes a plugin beta-release blocker, title it fix(<plugin-id>): beta blocker - <summary> and link the matching Beta blocker: <plugin-name> - <summary> issue labeled beta-blocker. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation.

  • Problem: interactive chat runs can finish with stopReason=stop but payloads=0 when the streamed assistant text array contains only whitespace, causing the gateway to surface the generic incomplete-turn error instead of the final answer.
  • Why it matters: users see “Agent couldn't generate a response” even though the agent completed and persisted a usable final answer.
  • What changed: payload construction now ignores whitespace-only streamed assistant texts before deciding whether fallback to the final assistant message is needed.
  • What did NOT change (scope boundary): incomplete-turn retry/liveness behavior, tool-use handling, and provider-specific model behavior are unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write N/A. If the cause is unclear, write Unknown.

  • Root cause: buildEmbeddedRunPayloads treated assistantTexts.length > 0 as proof that a streamed user-visible reply existed, even when every streamed entry was blank/whitespace.
  • Missing detection / guardrail: there was coverage for completely missing streamed text falling back to final-answer content, but not for whitespace-only streamed text.
  • Contributing context (if known): phased final-answer extraction already had the correct final reply, but the blank streamed array blocked fallback.

Regression Test Plan (if applicable)

For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write N/A.

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/pi-embedded-runner/run/payloads.test.ts
  • Scenario the test should lock in: whitespace-only streamed assistant text falls back to the persisted final-answer assistant content.
  • Why this is the smallest reliable guardrail: the bug is isolated to payload assembly fallback selection.
  • Existing test that already covers this (if any): existing fallback test covered absent streamed text, but not whitespace-only entries.
  • If no new test is added, why not: N/A — new regression test added.

User-visible / Behavior Changes

Interactive chat replies that previously produced the generic incomplete-turn error can now deliver the final assistant answer when it is present in the stored assistant message.

Diagram (if applicable)

Before:
[assistantTexts: ["   "]] -> [fallback skipped] -> [payloads=0] -> [generic incomplete-turn error]

After:
[assistantTexts: ["   "]] -> [blank text ignored] -> [final_answer fallback] -> [reply delivered]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS / Darwin 25.5.0
  • Runtime/container: Node.js 25.9.0, pnpm 10.33.0
  • Model/provider: N/A
  • Integration/channel (if any): Telegram-style interactive chat symptom from issue report
  • Relevant config (redacted): default payload assembly path

Steps

  1. Build embedded run payloads with assistantTexts: [" "].
  2. Provide a lastAssistant with phased final_answer text.
  3. Inspect generated outbound payloads.

Expected

  • The final-answer text is emitted as the outbound payload.

Actual

  • Before this change, no payload was emitted because the blank streamed text array blocked fallback.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

pnpm test -- --run src/agents/pi-embedded-runner/run/payloads.test.ts

✓ unit-fast src/agents/pi-embedded-runner/run/payloads.test.ts (18 tests)
Test Files  1 passed (1)
Tests       18 passed (18)

Typecheck note:

NODE_OPTIONS=--max-old-space-size=8192 pnpm exec tsc --noEmit --pretty false
src/agents/pi-embedded-runner.sanitize-session-history.test.ts(985,13): error TS2352: Conversion of type 'AgentMessage' to type 'Record<string, unknown>' may be a mistake...

This appears unrelated to this PR; this change only touches run/payloads.ts and its payload unit test.

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: regression unit test passes; existing payload tests still pass.
  • Edge cases checked: media-directive fallback behavior still uses non-empty assistant text normalization for comparison; whitespace-only streamed text no longer suppresses final-answer fallback.
  • What you did not verify: full repository typecheck due to unrelated existing TS2352 error noted above; live Telegram reproduction.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: Filtering blank streamed entries could alter behavior if whitespace-only assistant replies were intentionally user-facing.
    • Mitigation: whitespace-only payloads are not deliverable user-visible content; silent replies are handled separately by existing NO_REPLY logic.

@greptile-apps

greptile-apps Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug in buildEmbeddedRunPayloads where whitespace-only streamed assistant texts (e.g., [" "]) prevented fallback to the stored final_answer content, causing the gateway to surface a generic incomplete-turn error instead of the real reply. The fix filters out blank entries via nonEmptyAssistantTexts before deciding whether a streamed payload is present, and adds a targeted regression test to lock in the corrected behaviour.

Confidence Score: 5/5

Safe to merge — targeted one-file logic fix with a clear regression test and no impact on tool-use, retry, or provider-specific paths.

The change is minimal and well-tested: three variable renames/additions in a single function, all backed by a new unit test that directly reproduces the reported scenario. Existing tests continue to pass, and the assistantTextsHaveMedia check that still uses params.assistantTexts is inconsequential because whitespace-only strings cannot carry media directives.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(agent): recover blank streamed repli..." | Re-trigger Greptile

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: XS labels Apr 25, 2026
@steipete steipete force-pushed the fix/71454-blank-streamed-reply-fallback branch 2 times, most recently from bc29469 to fa12bbc Compare April 25, 2026 08:01
@steipete steipete force-pushed the fix/71454-blank-streamed-reply-fallback branch from fa12bbc to 24d96a3 Compare April 25, 2026 08:02
@steipete steipete merged commit 24e9924 into openclaw:main Apr 25, 2026
5 checks passed
@steipete

Copy link
Copy Markdown
Contributor

Landed via rebase onto main.

  • Gate: pnpm test src/agents/pi-embedded-runner/run/payloads.test.ts; pnpm check:changed
  • PR head after rebase: 24d96a3
  • Main commit: 24e9924

Thanks @Sanjays2402!

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

Labels

agents Agent runtime and tooling size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: payloads=0 incomplete-turn error in regular interactive chat sessions (not cron) — persists after #40868 closed

2 participants