openclaw - ✅(Solved) Fix [Bug]: Thinking/reasoning content leaks into cron announce delivery for Matrix/Feishu [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#73186Fetched 2026-04-29 06:22:25
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Participants
Timeline (top)
referenced ×6cross-referenced ×2

Thinking/reasoning content leaks into cron announce delivery for Matrix and Feishu channels in OpenClaw v2026.4.24. Duplicate delivery also occurs in some cases.

Root Cause

Root Cause Analysis

Fix Action

Fixed

PR fix notes

PR #40534: fix(cron): filter reasoning/thinking payloads from announce delivery

Description (problem / solution / changelog)

Summary

  • Filters reasoning/thinking payloads from cron announce delivery pipeline end-to-end
  • Propagates isReasoning flag through buildEmbeddedRunPayloads .map() return and EmbeddedPiRunResult type
  • Filters reasoning in all 3 payload-selection helpers + firstText fallback + error-recovery detection
  • Reasoning payloads are never deliverable and never mask error status

Root cause

The isReasoning flag was correctly set internally by buildEmbeddedRunPayloads() but:

  1. Not propagated in the .map() return value (payloads.ts)
  2. Not declared on the EmbeddedPiRunResult payload type (types.ts)
  3. Not filtered in cron delivery helpers (helpers.ts)
  4. Not filtered in firstText fallback (run.ts:754)
  5. Not excluded from error-recovery detection (run.ts:844)

Commits

  1. 39d426d — Filter reasoning in helpers + add isReasoning to EmbeddedPiRunResult type
  2. 3877d9a — Fix firstText fallback bypass (Codex review)
  3. b003338 — Propagate isReasoning in buildEmbeddedRunPayloads .map() (Greptile review)
  4. 402ba05 — Exclude reasoning from hasSuccessfulPayloadAfterLastError (Codex P2 review)

Reasoning-only scenario trace (run.ts:754-764)

VariableValueWhy
firstText"".find((p) => !p.isReasoning) finds nothing
pickSummaryFromPayloads()undefinedBoth passes skip isReasoning
pickLastNonEmptyTextFromPayloads()undefinedBoth passes skip isReasoning
synthesizedTextundefinedBoth sources undefined
pickLastDeliverablePayload()undefinedBoth passes skip isReasoning
hasSuccessfulPayloadAfterLastErrorfalseReasoning excluded from recovery check
deliveryPayloads[]Nothing delivered

Closes #40480

Test plan

  • All 26 helpers tests pass (20 existing + 6 new)
  • pnpm check succeeds
  • Manual test: cron with thinking-enabled model → verify announce delivery contains only the final answer

🤖 Generated with Claude Code

Changed files

  • src/agents/pi-embedded-runner/run/payloads.ts (modified, +1/-0)
  • src/agents/pi-embedded-runner/types.ts (modified, +1/-0)
  • src/cron/isolated-agent/helpers.test.ts (modified, +37/-0)
  • src/cron/isolated-agent/helpers.ts (modified, +15/-6)
  • src/cron/isolated-agent/run.ts (modified, +7/-2)

PR #73363: fix(memory-core): keep isReasoning on payloads, skip reasoning blocks in cron-announce summary (#73186)

Description (problem / solution / changelog)

Summary

Fixes #73186. Cron jobs running with thinking enabled (e.g. deepseek/deepseek-v4-pro via volcengine, configured thinkingDefault: high) currently leak the model's reasoning content into Matrix and Feishu announce deliveries. The reporter traced the root cause: buildEmbeddedRunPayloads() in src/agents/pi-embedded-runner/run/payloads.ts sets isReasoning: true on the reasoning payload internally, but the final .map() only forwards isError, dropping the isReasoning marker. Downstream pickSummaryFromPayloads() / pickLastNonEmptyTextFromPayloads() in the cron isolated-agent helpers then have no way to skip reasoning blocks and pick them up as the announce summary text.

This PR carries isReasoning through to the returned payload, then teaches both cron-side pickers to skip reasoning blocks in the primary pass (same shape as the existing isError skip), falling back to reasoning text only when nothing else exists. The picker behavior on non-reasoning payloads is byte-identical to before.

Changes

FileWhat
src/agents/pi-embedded-runner/run/payloads.tsAdd isReasoning: item.isReasoning to the payload returned by .map() so the marker the function set internally actually reaches downstream consumers.
src/cron/isolated-agent/helpers.tsExtract a small SummaryPayload type that includes isReasoning?: boolean. Update pickSummaryFromPayloads / pickLastNonEmptyTextFromPayloads to skip reasoning and error payloads in their first pass, with the existing fallback loop preserved as a last resort.
src/agents/pi-embedded-runner/run/payloads.test.tsNew test that asserts isReasoning: true is propagated on the reasoning payload while a sibling final-answer payload stays isReasoning-falsy.
src/cron/isolated-agent/helpers.test.tsThree new cases on each picker — primary pass skips reasoning, last-position reasoning is skipped, and the fallback path still surfaces reasoning text when no real text exists.
CHANGELOG.mdAppend ### Fixes entry under ## Unreleased, attribution Thanks @KeWang0622.
 5 files changed, 81 insertions(+), 10 deletions(-)

Tests

  • pnpm test src/cron/isolated-agent/ — 258 pass (cron isolated-agent suite, 8 new)
  • pnpm test src/agents/pi-embedded-runner/run/payloads.test.ts — 20 pass (1 new)
  • pnpm exec oxfmt --check — clean
  • pnpm exec oxlint — 0 warnings, 0 errors

Context

Closes #73186 (only the first sub-bug — the thinking-leak path). The reporter also flagged a duplicate-delivery sub-bug in the same issue; that one threads through extractAssistantVisibleText / resolveFinalAssistantVisibleText / preferFinalAssistantVisibleText, which the issue says already exist on main. I'd rather keep this PR focused on the verifiable leak path; happy to follow up on the duplicate-delivery sub-bug separately if maintainers want it bundled.

The fallback behavior is intentionally conservative: if the only payload is a reasoning block, the picker returns it rather than nothing. That mirrors the existing isError-fallback shape and avoids regressing in the rare case where reasoning is the only signal available.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-runner/run/payloads.test.ts (modified, +23/-0)
  • src/agents/pi-embedded-runner/run/payloads.ts (modified, +4/-0)
  • src/cron/isolated-agent/helpers.test.ts (modified, +35/-0)
  • src/cron/isolated-agent/helpers.ts (modified, +18/-10)
RAW_BUFFERClick to expand / collapse

Summary

Thinking/reasoning content leaks into cron announce delivery for Matrix and Feishu channels in OpenClaw v2026.4.24. Duplicate delivery also occurs in some cases.

Environment

  • OpenClaw: [email protected] (npm global install)
  • Runtime deps: openclaw-2026.4.24-9805e7ca3f7e
  • Channels affected: Matrix (primary, via @openclaw-bot:matrix.local), Feishu
  • Model: deepseek/deepseek-v4-pro with thinking=high, proxied through volcengine (api: "openai-completions")
  • Config: "thinkingDefault": "high", "blockStreamingDefault": "off"

Symptoms

  1. Thinking content visible in cron announce: When a cron job runs with isolated session + announce delivery, the model internal reasoning (prefixed with "Let me think about…", "First I should…", etc.) appears in the delivered message alongside the actual answer.

  2. Duplicate content: The same message content is sometimes delivered twice to the chat.

Root Cause Analysis

Bug 1: Thinking leaked into cron announce

The flow through the codebase:

  1. @mariozechner/pi-ai/dist/providers/openai-completions.js:149-169 — the API reasoning_content delta is correctly captured into type: "thinking" content blocks (separate from type: "text" blocks).
  2. @mariozechner/pi-agent-core/dist/agent-loop.js:181-199 — thinking stream events are emitted as message_update alongside text events.
  3. The cron announce delivery path goes through pickSummaryFromPayloads() / pickLastNonEmptyTextFromPayloads() which do NOT check the isReasoning flag on payloads.

Critical finding: The isReasoning flag is set internally by buildEmbeddedRunPayloads() in src/agents/pi-embedded-runner/run/payloads.ts but is dropped in the .map() return — only isError is propagated, not isReasoning. Even if downstream filters existed, the flag never reaches them.

The fix described in issue #40480 (extractAssistantVisibleText() / resolveFinalAssistantVisibleText() / preferFinalAssistantVisibleText: true) exists in GitHub main branch but is not present in the v2026.4.24 dist. These symbols are absent from plugin-runtime-deps/openclaw-2026.4.24-*/dist/.

Bug 2: Duplicate content

In block-reply-pipeline-Ci53E9jN.js:81, when thinking and text payloads have different isReasoning states, visibilityConflict triggers and they are flushed as separate payloads. If isReasoning propagation is broken, both thinking and text payloads may reach the channel as distinct messages.

Additionally, extensions/matrix/monitor-DJy6SVy2.js:1492 does filter reply.isReasoning === true in deliverMatrixReplies(), but cron announce delivery does NOT go through deliverMatrixReplies() — it takes an entirely different path through the isolated agent runner.

Per-channel comparison

ChannelisReasoning filter (live reply)isReasoning filter (cron announce)
Telegram✅ (post-fix main branch only)✅ (post-fix main branch only)
MatrixdeliverMatrixReplies():1492 + tag stripping❌ different code path
Feishu❌ no code-level filter at all❌ prompt-level only

Related Issues/PRs

  • #40480 (closed, fix unreleased to npm)
  • #40534 (open/stale — the actual payload-level fix with isReasoning propagation)
  • #41208 (closed by bot — too-many-PRs policy)
  • #6470 (closed — general thinking leak, not cron-specific)

Suggested Fixes

  1. Release #40480 fix: The extractAssistantVisibleText() / preferFinalAssistantVisibleText infrastructure on main should be released to npm.

  2. Propagate isReasoning flag: buildEmbeddedRunPayloads() in payloads.ts needs isReasoning: item.isReasoning in its .map() return (as identified in PR #40534 reviews).

  3. Filter reasoning in cron helpers: pickSummaryFromPayloads(), pickLastNonEmptyTextFromPayloads(), pickLastDeliverablePayload() should skip isReasoning payloads in both primary and fallback passes.

  4. Channel parity: Matrix and Feishu need equivalent cron announce protection — either via preferFinalAssistantVisibleText opt-in or by routing through the channel existing reply filtering.

extent analysis

TL;DR

The most likely fix for the issue is to propagate the isReasoning flag in buildEmbeddedRunPayloads() and filter out reasoning payloads in cron helpers.

Guidance

  • Verify that the isReasoning flag is being set correctly in buildEmbeddedRunPayloads() and that it is being propagated to downstream functions.
  • Update pickSummaryFromPayloads(), pickLastNonEmptyTextFromPayloads(), and pickLastDeliverablePayload() to skip payloads with isReasoning set to true.
  • Consider releasing the fix from #40480 to npm to include the extractAssistantVisibleText() and preferFinalAssistantVisibleText infrastructure.
  • Review the channel-specific code for Matrix and Feishu to ensure that they have equivalent cron announce protection.

Example

// In buildEmbeddedRunPayloads()
return items.map((item) => ({
  ...item,
  isReasoning: item.isReasoning, // propagate the isReasoning flag
}));

// In pickSummaryFromPayloads(), pickLastNonEmptyTextFromPayloads(), and pickLastDeliverablePayload()
if (payload.isReasoning) {
  return null; // skip payloads with isReasoning set to true
}

Notes

The provided fix is based on the analysis of the issue and may require additional testing and verification to ensure that it fully resolves the problem. The isReasoning flag propagation and filtering in cron helpers should be thoroughly tested to prevent any unintended consequences.

Recommendation

Apply the workaround by propagating the isReasoning flag and filtering out reasoning payloads in cron helpers, as this is a more immediate solution that can be implemented without waiting for the release of the fix from #40480.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix [Bug]: Thinking/reasoning content leaks into cron announce delivery for Matrix/Feishu [2 pull requests, 1 participants]