Skip to content

fix(agents): coerce non-text/image MCP tool-result blocks to text (fixes #90710)#90728

Merged
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
849261680:fix/90710-anthropic-mcp-content-blocks
Jun 6, 2026
Merged

fix(agents): coerce non-text/image MCP tool-result blocks to text (fixes #90710)#90728
clawsweeper[bot] merged 1 commit into
openclaw:mainfrom
849261680:fix/90710-anthropic-mcp-content-blocks

Conversation

@849261680

@849261680 849261680 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

MCP CallToolResult.content[] can include resource_link, resource, and audio blocks (MCP SDK ContentBlock union), but toAgentToolResult in agent-bundle-mcp-materialize.ts cast that array straight into AgentToolResult.content, whose contract is only (TextContent | ImageContent)[]. That cast lied to the type system, so the bad blocks flowed downstream where the Anthropic provider/transport "non-text ⇒ image" branch built an image block with undefined data/media_type. Anthropic rejects that with HTTP 400, and because the malformed block stays in conversation history, every subsequent turn replays it and 400s too — the session is permanently poisoned until history is reset.

  • Fix at the materialize boundary so the text/image contract stays honest, instead of patching each downstream provider converter. This fixes all providers, not just Anthropic.
  • Pass through valid images unchanged; coerce resource_link[title|name] uri, resourceresource.text ?? uri, audio[audio <mime>], and malformed/unknown blocks → stringified text.
  • Discriminated-union handling means a future MCP SDK block type surfaces here rather than silently mis-coercing.
  • Out of scope: the provider-side convertContentBlocks keep their honest text|image signatures; they no longer receive wider MCP blocks, so they are intentionally untouched.

Linked context

Closes #90710

Reporter: @RanSHammer (clear repro + root-cause diagnosis).

Real behavior proof (required for external PRs)

  • Behavior addressed: a real MCP server returning non-text/image blocks (resource_link for a .docx, plus resource/audio) no longer leaks those blocks into the agent tool result. They are coerced to text at the materialize boundary, so the Anthropic image branch never builds an empty image block (no 400, no poisoned history).
  • Real environment tested: ran the actual OpenClaw bundle-MCP runtime (createBundleMcpToolRuntimecreateSessionMcpRuntime) against a real spawned stdio MCP server subprocess (MCP SDK 1.29.0 McpServer) over real JSON-RPC. No vitest, no mocks — production code paths, executed on both origin/main (before) and this branch (after). Node 22.22.2, macOS.
  • Exact steps or command run after this patch: spawned a real stdio MCP server whose get_attachment tool returns [text, resource_link(.docx), resource(memo), audio], then drove the real runtime and printed the materialized AgentToolResult.content:
    node --import tsx drive.mts <repoRoot> (driver dynamically imports src/agents/agent-bundle-mcp-materialize.ts from the given checkout and calls the materialized tool).
  • Evidence after fix: copied live console output from the real runtime run on this branch (f70dccf33e):
=== materialized AgentToolResult.content ===
[
  { "type": "text", "text": "Here is the attachment:" },
  { "type": "text", "text": "[Quarterly report] https://mail.example.com/att/quarterly.docx" },
  { "type": "text", "text": "inline memo body" },
  { "type": "text", "text": "[audio audio/mpeg]" }
]

Before (same driver + same real MCP server against unfixed origin/main materialize), the array carried raw non-text/image blocks — exactly what the Anthropic image branch then turns into an empty image source and 400s on:

=== materialized AgentToolResult.content ===
[
  { "type": "text", "text": "Here is the attachment:" },
  { "name": "quarterly.docx", "title": "Quarterly report",
    "uri": "https://mail.example.com/att/quarterly.docx",
    "mimeType": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "type": "resource_link" },
  { "type": "resource", "resource": { "uri": "memo://note", "text": "inline memo body" } },
  { "type": "audio", "data": "QUFBQQ==", "mimeType": "audio/mpeg" }
]
  • Observed result after fix: every non-text/image block is now a text block; the valid image case (not shown above) still passes through as an image. The resource_link/resource/audio blocks that previously sat illegally inside the (text|image)[] array are gone, so the provider can no longer build a data:undefined / media_type:undefined image block.
  • What was not tested: a live round-trip against the hosted Anthropic API to observe the literal HTTP 400 (no Anthropic credentials wired in this checkout). The 400 trigger is shown structurally — the before output contains the exact malformed blocks the provider's image branch consumes (src/llm/providers/anthropic.ts:140, src/agents/anthropic-transport-stream.ts:287).
  • Proof limitations or environment constraints: ran on a local source checkout via tsx; the spawned MCP server is a minimal real SDK server rather than the reporter's Superhuman Mail remote MCP, but it emits the same ContentBlock shapes.

Tests and validation

Which commands did you run?

  • Real-runtime repro above (before/after) — production paths, real MCP subprocess.
  • node scripts/run-vitest.mjs src/agents/agent-bundle-mcp-tools.materialize.test.ts → 13 passed (supplemental)
  • tsgo core + test:src lanes → exit 0; oxfmt --check + oxlint on changed files → clean (supplemental)

What regression coverage was added or updated?

Two new cases in agent-bundle-mcp-tools.materialize.test.ts:

  • resource_link / resource (text + blob) / audio blocks coerce to text while a valid image passes through.
  • A malformed image block (missing base64 source) coerces to text instead of an empty image block.

 openclaw#90710)

MCP CallToolResult.content can include resource_link, resource, and audio
blocks, but toAgentToolResult cast them straight into AgentToolResult, which
only carries text/image. Downstream the Anthropic provider/transport image
branch then built an image block with undefined data/media_type, Anthropic
returned 400, and because the bad block stayed in history every later turn
400d too -> permanently poisoned session.

Normalize MCP content at the materialize boundary so the text/image contract
stays honest: pass through valid images, coerce resource_link/resource/audio
and malformed images to text. Fixes all providers, not just Anthropic.
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. size: S labels Jun 5, 2026
@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: passed. Reviewed June 5, 2026, 10:15 PM ET / 02:15 UTC.

Summary
The PR converts wider MCP CallToolResult content blocks into text/image AgentToolResult blocks at the bundle-MCP materialization boundary and adds regression tests.

PR surface: Source +36, Tests +66. Total +102 across 2 files.

Reproducibility: yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/image-only result contract, and the PR body includes before/after real-runtime output from a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Review metrics: none identified.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Next step before merge

  • No ClawSweeper repair job is needed; the clean automerge path can rely on exact-head review, required checks, and GitHub mergeability gates.

Security
Cleared: The diff changes local TypeScript content normalization and tests only; it does not add dependencies, scripts, permissions, secret handling, or supply-chain surface.

Review details

Best possible solution:

Land the materialization-boundary normalization after exact-head checks pass, keep provider converters typed to text/image, and let the linked issue close on merge.

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

Yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/image-only result contract, and the PR body includes before/after real-runtime output from a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Is this the best way to solve the issue?

Yes. Normalizing at the bundle-MCP materialization boundary is the narrowest maintainable fix because it restores the core tool-result contract for all downstream providers, while patching only Anthropic would leave invalid content in agent history.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3a2f54e6a866.

Label changes

Label changes:

  • add status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (live_output): The PR body includes after-fix copied live output from a real spawned stdio MCP server through the real bundle-MCP runtime, plus before output from current main showing the leaked block shapes.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: 🚀 automerge armed.

Label justifications:

  • P1: The linked bug can break Anthropic agent turns after MCP tool output and poison subsequent session history for affected users.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 🚀 automerge armed: This PR is in ClawSweeper's automerge lane. Sufficient (live_output): The PR body includes after-fix copied live output from a real spawned stdio MCP server through the real bundle-MCP runtime, plus before output from current main showing the leaked block shapes.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix copied live output from a real spawned stdio MCP server through the real bundle-MCP runtime, plus before output from current main showing the leaked block shapes.
Evidence reviewed

PR surface:

Source +36, Tests +66. Total +102 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 39 3 +36
Tests 1 66 0 +66
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 105 3 +102

What I checked:

  • Current main contract leak: Current main casts MCP result.content directly into AgentToolResult.content, so wider MCP blocks can pass a text/image-only contract boundary unchanged. (src/agents/agent-bundle-mcp-materialize.ts:28, 3a2f54e6a866)
  • AgentToolResult contract: AgentToolResult.content is typed and documented as only TextContent or ImageContent, which supports fixing the leak before provider conversion. (packages/agent-core/src/types.ts:419, 3a2f54e6a866)
  • MCP dependency contract: MCP SDK 1.29.0 defines ContentBlock as text, image, audio, resource_link, or resource, and CallToolResult.content as an array of ContentBlock.
  • Downstream Anthropic failure path: The Anthropic provider converter accepts text/image content but maps any non-text block in the image path into an image source using mimeType and data. (src/llm/providers/anthropic.ts:121, 3a2f54e6a866)
  • Transport sibling has same invariant: The Anthropic transport converter also treats non-text content as image content, so boundary normalization protects both provider paths. (src/agents/anthropic-transport-stream.ts:261, 3a2f54e6a866)
  • PR implementation: The PR maps MCP text, valid image, audio, resource_link, resource, malformed image, and unknown blocks into valid AgentToolResult text/image blocks before returning tool output. (src/agents/agent-bundle-mcp-materialize.ts:30, f70dccf33ed1)

Likely related people:

  • steipete: GitHub path history for bundle-MCP materialization/runtime points to recent MCP operator/runtime and documentation commits by steipete, including the central materialization path this PR changes. (role: feature owner and recent area contributor; confidence: high; commits: 38d3d11cbc0c, ec8cb8bcbfae, f2d8facb4876; files: src/agents/agent-bundle-mcp-materialize.ts, src/agents/agent-bundle-mcp-runtime.ts, src/agents/agent-bundle-mcp-tools.materialize.test.ts)
  • obviyus: Recent Anthropic provider history includes multiple agent/provider cache-boundary fixes by obviyus on the downstream provider path implicated by the bug. (role: recent adjacent contributor; confidence: medium; commits: 9ed9af4f3939, 01cc68ee0d22, 2454952544b1; files: src/llm/providers/anthropic.ts)
  • Jerry-Xin: Recent Anthropic transport and MCP runtime cleanup history includes fixes by Jerry-Xin on paths adjacent to replay poisoning and runtime lifecycle behavior. (role: recent adjacent contributor; confidence: medium; commits: 8dc9cfe7349e, dc344a33fbfc; files: src/agents/anthropic-transport-stream.ts, src/agents/agent-bundle-mcp-runtime.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

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
  • 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.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. labels Jun 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: mock-only-proof Candidate: PR proof only shows tests, mocks, snapshots, lint, typecheck, or CI. labels Jun 5, 2026
@849261680

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review — real behavior proof added to the PR body (real spawned stdio MCP server → real bundle-MCP runtime, before/after on origin/main vs this branch). The Real behavior proof check is now green.

@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@849261680

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review — the PR head was briefly overwritten by an unintended commit and has now been restored to the boundary-normalization fix (f70dccf). The previous verdict reviewed the wrong (now-reverted) code against a stale base. Current head: materialize-boundary normalization only, CI fully green (131 pass / 0 fail), real-behavior proof in the body. Please re-review f70dccf.

@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Re-review progress:

@849261680

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

Re-review progress:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 5, 2026
@Takhoffman

Copy link
Copy Markdown
Contributor

@clawsweeper automerge

@clawsweeper

clawsweeper Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper merged this PR after the passing review.

Source: clawsweeper[bot]
Feedback: structured ClawSweeper verdict: pass (sha=f70dccf33ed1cd3e4daacdfb3c352b39e23283b1)
Merge status: merged by ClawSweeper automerge
Merged at: 2026-06-06T02:16:11Z
Merge commit: b1e4b6b65e2c

What merged:

  • The PR converts wider MCP CallToolResult content blocks into text/image AgentToolResult blocks at the bundle-MCP materialization boundary and adds regression tests.
  • PR surface: Source +36, Tests +66. Total +102 across 2 files.
  • Reproducibility: yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/ ... a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Automerge notes:

  • No ClawSweeper repair was needed after automerge opt-in.

The automerge loop is complete.

Automerge progress:

  • 2026-06-06 02:08:55 UTC review queued f70dccf33ed1 (queued)
  • 2026-06-06 02:15:53 UTC review passed f70dccf33ed1 (structured ClawSweeper verdict: pass (sha=f70dccf33ed1cd3e4daacdfb3c352b39e2328...)
  • 2026-06-06 02:16:15 UTC merged f70dccf33ed1 (merged by ClawSweeper automerge)

@clawsweeper clawsweeper Bot added clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 6, 2026
@clawsweeper clawsweeper Bot added the status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane. label Jun 6, 2026
@clawsweeper clawsweeper Bot merged commit b1e4b6b into openclaw:main Jun 6, 2026
421 of 439 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 6, 2026
 openclaw#90710) (openclaw#90728)

Summary:
- The PR converts wider MCP CallToolResult content blocks into text/image AgentToolResult blocks at the bundle-MCP materialization boundary and adds regression tests.
- PR surface: Source +36, Tests +66. Total +102 across 2 files.
- Reproducibility: yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/ ...  a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head f70dccf.
- Required merge gates passed before the squash merge.

Prepared head SHA: f70dccf
Review: openclaw#90728 (comment)

Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
849261680 added a commit to 849261680/openclaw that referenced this pull request Jun 7, 2026
 openclaw#90710) (openclaw#90728)

Summary:
- The PR converts wider MCP CallToolResult content blocks into text/image AgentToolResult blocks at the bundle-MCP materialization boundary and adds regression tests.
- PR surface: Source +36, Tests +66. Total +102 across 2 files.
- Reproducibility: yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/ ...  a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head f70dccf.
- Required merge gates passed before the squash merge.

Prepared head SHA: f70dccf
Review: openclaw#90728 (comment)

Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
wangmiao0668000666 pushed a commit to wangmiao0668000666/openclaw that referenced this pull request Jun 9, 2026
 openclaw#90710) (openclaw#90728)

Summary:
- The PR converts wider MCP CallToolResult content blocks into text/image AgentToolResult blocks at the bundle-MCP materialization boundary and adds regression tests.
- PR surface: Source +36, Tests +66. Total +102 across 2 files.
- Reproducibility: yes. Source inspection shows current main lets MCP resource/audio blocks cross into a text/ ...  a spawned stdio MCP server; I did not run a live hosted Anthropic API round trip in this read-only review.

Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.

Validation:
- ClawSweeper review passed for head f70dccf.
- Required merge gates passed before the squash merge.

Prepared head SHA: f70dccf
Review: openclaw#90728 (comment)

Co-authored-by: 宇宙熊Yzx <53250620+849261680@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jun 9, 2026
…26.6.5) (#963)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.6.1` → `2026.6.5` |

---

### Release Notes

<details>
<summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary>

### [`v2026.6.5`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#202665)

[Compare Source](openclaw/openclaw@v2026.6.1...v2026.6.5)

##### Highlights

- QQBot now strips model reasoning/thinking scaffolding before native delivery, preventing raw `<thinking>` content from leaking into channel replies. ([#&#8203;89913](openclaw/openclaw#89913), [#&#8203;90132](openclaw/openclaw#90132)) Thanks [@&#8203;openperf](https://github.com/openperf).
- MCP tool results now coerce `resource_link`, `resource`, `audio`, malformed image, and future non-text/image blocks at the materialize boundary, preventing Anthropic 400s and poisoned session history after a tool returns richer MCP content. ([#&#8203;90710](openclaw/openclaw#90710), [#&#8203;90728](openclaw/openclaw#90728)) Thanks [@&#8203;RanSHammer](https://github.com/RanSHammer) and [@&#8203;849261680](https://github.com/849261680).
- Anthropic extended-thinking sessions recover after prompt-cache expiry or Gateway restart because stream start events wait for `message_start`, letting pre-generation signature errors trigger the existing recovery retry. ([#&#8203;90667](openclaw/openclaw#90667), [#&#8203;90697](openclaw/openclaw#90697)) Thanks [@&#8203;openperf](https://github.com/openperf).
- Parallel is now a bundled `web_search` provider with `PARALLEL_API_KEY` discovery, guarded endpoint handling, cache-safe session ids, onboarding picker support, and docs. ([#&#8203;85158](openclaw/openclaw#85158)) Thanks [@&#8203;NormallyGaussian](https://github.com/NormallyGaussian).
- Google Vertex ADC users get static catalog rows and runtime model resolution again, while single-provider cooldown recovery and memory adapter status checks are more reliable. ([#&#8203;90506](openclaw/openclaw#90506), [#&#8203;90609](openclaw/openclaw#90609), [#&#8203;90717](openclaw/openclaw#90717), [#&#8203;90816](openclaw/openclaw#90816)) Thanks [@&#8203;849261680](https://github.com/849261680).
- Matrix can preflight voice notes before mention gating, preserve thread reads/replies through Matrix relations pagination, and carry QA coverage for voice and thread flows. ([#&#8203;78016](openclaw/openclaw#78016), [#&#8203;90415](openclaw/openclaw#90415))
- Auth and plugin install state is more durable: auth profiles now live in SQLite, official npm plugin install records keep their trusted pins, and prerelease fallback integrity checks avoid carrying stale integrity forward. ([#&#8203;89102](openclaw/openclaw#89102), [#&#8203;88585](openclaw/openclaw#88585))
- macOS node mode no longer silently self-reconnects away from a healthy direct Gateway session, reducing unexpected companion app session churn. ([#&#8203;90668](openclaw/openclaw#90668), [#&#8203;90815](openclaw/openclaw#90815)) Thanks [@&#8203;vrurg](https://github.com/vrurg).
- Upgrade and service paths are safer: cron legacy JSON stores migrate during doctor preflight, service env placeholders no longer mask state-dir secrets, WhatsApp startup waits are bounded, and disabled WhatsApp accounts tear down on config reload. ([#&#8203;90072](openclaw/openclaw#90072), [#&#8203;90208](openclaw/openclaw#90208), [#&#8203;90277](openclaw/openclaw#90277), [#&#8203;90488](openclaw/openclaw#90488), [#&#8203;90486](openclaw/openclaw#90486), [#&#8203;87951](openclaw/openclaw#87951), [#&#8203;87965](openclaw/openclaw#87965)) Thanks [@&#8203;MonkeyLeeT](https://github.com/MonkeyLeeT), [@&#8203;sallyom](https://github.com/sallyom), [@&#8203;mcaxtr](https://github.com/mcaxtr), and [@&#8203;MukundaKatta](https://github.com/MukundaKatta).

##### Changes

- Search/providers: add the Parallel bundled web-search plugin, live provider tests, registration contracts, onboarding/docs wiring, and guarded `api.parallel.ai/v1/search` support. ([#&#8203;85158](openclaw/openclaw#85158)) Thanks [@&#8203;NormallyGaussian](https://github.com/NormallyGaussian).
- Matrix/channels: add voice-message preflight and thread-aware read/reply behavior, including Matrix QA scenario wiring and docs for voice-message behavior. ([#&#8203;78016](openclaw/openclaw#78016), [#&#8203;90415](openclaw/openclaw#90415))
- Skills/ClawHub: install ClawHub skills backed by GitHub repositories through the resolved install API, download the pinned GitHub commit, keep install-policy checks, and report install telemetry after success. ([#&#8203;90478](openclaw/openclaw#90478)) Thanks [@&#8203;Patrick-Erichsen](https://github.com/Patrick-Erichsen).
- Google Chat/channels: add native approval card actions and click handling so Google Chat approvals use platform-native cards instead of generic message flow.
- Mobile: Android provider/model screens now surface expiring, unavailable, unresolved, and attention states more clearly, while iOS settings and Talk tabs keep diagnostics, gateway rows, attachment labels, and unavailable Talk controls reachable.
- Memory: QMD search can use the new rerank toggle, and memory adapter status uses the resolved default model identity when checking plain status. ([#&#8203;61834](openclaw/openclaw#61834))
- Docs/tooling: add Parallel search docs, refresh weather-skill guidance toward `web_fetch`, clarify legacy `openai-codex` auth, document release/test helper scripts, and tighten changed-test routing docs for CI/debugging work. ([#&#8203;90028](openclaw/openclaw#90028), [#&#8203;90250](openclaw/openclaw#90250)) Thanks [@&#8203;fuller-stack-dev](https://github.com/fuller-stack-dev).
- Release/process: switch release trains to `YYYY.M.PATCH` monthly patch numbering, keep pre-transition tags compatible, and pin the June 2026 floor at `2026.6.5` after the published beta.
- Platform maintenance: refresh Android, Swift/macOS, Docker, CodeQL, Buildx, Docker build/push, and Codex Action dependencies for this release train. ([#&#8203;74980](openclaw/openclaw#74980), [#&#8203;81757](openclaw/openclaw#81757), [#&#8203;86481](openclaw/openclaw#86481), [#&#8203;86483](openclaw/openclaw#86483), [#&#8203;90601](openclaw/openclaw#90601))
- QQBot: add `/bot-group-allways on|off` slash command (with named-account and default-account support) to toggle whether group messages require an `@mention` before the bot replies, and clear the runtime config snapshot after the write so the new account-level `defaultRequireMention` takes effect immediately without restart. ([#&#8203;91423](openclaw/openclaw#91423)) Thanks [@&#8203;cxyhhhhh](https://github.com/cxyhhhhh).

##### Fixes

- Channel content boundaries: QQBot now strips reasoning/thinking tags before sending, preserving final answers while hiding internal model narration from users. ([#&#8203;89913](openclaw/openclaw#89913), [#&#8203;90132](openclaw/openclaw#90132)) Thanks [@&#8203;openperf](https://github.com/openperf).
- Agents/MCP/providers: coerce non-text/image MCP tool-result blocks before they reach provider converters, preserving valid images and turning richer MCP content into text instead of malformed image blocks. ([#&#8203;90710](openclaw/openclaw#90710), [#&#8203;90728](openclaw/openclaw#90728)) Thanks [@&#8203;RanSHammer](https://github.com/RanSHammer) and [@&#8203;849261680](https://github.com/849261680).
- Anthropic/Codex/ACP/agent recovery: defer Anthropic stream start events until `message_start`, strip stale compaction thinking signatures before Anthropic replay, detect unsigned thinking-only stalls, refresh prompt fences after compaction writes, reject empty completion handoffs, preserve parent streaming-off overrides/shared progress commentary, forward heartbeat metadata to context-engine hooks, and cover Codex session/thread migration edge cases. ([#&#8203;90667](openclaw/openclaw#90667), [#&#8203;90697](openclaw/openclaw#90697), [#&#8203;90163](openclaw/openclaw#90163), [#&#8203;90108](openclaw/openclaw#90108), [#&#8203;89874](openclaw/openclaw#89874), [#&#8203;89505](openclaw/openclaw#89505), [#&#8203;90632](openclaw/openclaw#90632), [#&#8203;89302](openclaw/openclaw#89302), [#&#8203;90729](openclaw/openclaw#90729), [#&#8203;90317](openclaw/openclaw#90317), [#&#8203;90319](openclaw/openclaw#90319)) Thanks [@&#8203;openperf](https://github.com/openperf), [@&#8203;100yenadmin](https://github.com/100yenadmin), and [@&#8203;ooiuuii](https://github.com/ooiuuii).
- Provider/model resolution: preserve Google Vertex ADC auth markers in generated catalogs, re-probe a single-provider primary after cooldown, share Codex model visibility, fail closed for unknown model auth, preserve Codex alias availability, keep unresolved profile refs unknown, and avoid resolving auth while listing models. ([#&#8203;90506](openclaw/openclaw#90506), [#&#8203;90609](openclaw/openclaw#90609), [#&#8203;90717](openclaw/openclaw#90717), [#&#8203;90702](openclaw/openclaw#90702)) Thanks [@&#8203;849261680](https://github.com/849261680).
- Gateway/macOS/mobile: avoid duplicate Gateway probe warnings by identity, rate-limit node pairing requests while preserving paired-node reconnects, keep macOS node mode on a healthy direct Gateway session, keep iOS diagnostics and gateway rows reachable, and avoid Linux ARM Gradle resource tasks during Android builds. ([#&#8203;85791](openclaw/openclaw#85791), [#&#8203;90147](openclaw/openclaw#90147), [#&#8203;90668](openclaw/openclaw#90668), [#&#8203;90815](openclaw/openclaw#90815)) Thanks [@&#8203;giodl73-repo](https://github.com/giodl73-repo) and [@&#8203;vrurg](https://github.com/vrurg).
- TUI/chat/Workboard/auto-reply: optimistic user messages stay stable across stale history reloads, runId reassignment, and abort windows instead of disappearing, jumping, or lingering as ghost rows; Workboard stale lifecycle bulk updates no longer overwrite newer status/provenance; message-tool sends now count as delivery. ([#&#8203;86205](openclaw/openclaw#86205), [#&#8203;89600](openclaw/openclaw#89600), [#&#8203;88592](openclaw/openclaw#88592), [#&#8203;90123](openclaw/openclaw#90123)) Thanks [@&#8203;RomneyDa](https://github.com/RomneyDa).
- Cron/update/service env: doctor config preflight now migrates legacy cron JSON stores into SQLite before runtime reads, service env planning skips unresolved placeholders that would mask state-dir `.env` values, and session transcript rewrites keep registry markers/discriminants consistent. ([#&#8203;90072](openclaw/openclaw#90072), [#&#8203;90208](openclaw/openclaw#90208), [#&#8203;90277](openclaw/openclaw#90277), [#&#8203;90488](openclaw/openclaw#90488)) Thanks [@&#8203;MonkeyLeeT](https://github.com/MonkeyLeeT) and [@&#8203;sallyom](https://github.com/sallyom).
- Security/config/tooling: guard MCP HTTP redirects, protect global agent config defaults, and keep release/test/tooling proof failures bounded and explicit. ([#&#8203;89732](openclaw/openclaw#89732), [#&#8203;90145](openclaw/openclaw#90145))
- Channels: WhatsApp restarts when per-account config changes, bounds background startup waits, closes failed sockets, and preserves reconnect behavior; Mattermost slash commands keep their state on `globalThis`; Feishu streaming cards preserve full merged content; voice-call tracks Twilio streams after connect; ClickClack reply tools respect `toolsAllow`. ([#&#8203;87951](openclaw/openclaw#87951), [#&#8203;87965](openclaw/openclaw#87965), [#&#8203;90486](openclaw/openclaw#90486), [#&#8203;68113](openclaw/openclaw#68113), [#&#8203;90534](openclaw/openclaw#90534), [#&#8203;90181](openclaw/openclaw#90181), [#&#8203;90607](openclaw/openclaw#90607), [#&#8203;89500](openclaw/openclaw#89500)) Thanks [@&#8203;MukundaKatta](https://github.com/MukundaKatta), [@&#8203;mcaxtr](https://github.com/mcaxtr), [@&#8203;infoanton](https://github.com/infoanton), [@&#8203;mushuiyu886](https://github.com/mushuiyu886), and [@&#8203;sahibzada-allahyar](https://github.com/sahibzada-allahyar).
- Feishu: retry transient send rate-limit errors (HTTP 429, per-chat code 230020, tenant-level code 11232) with linear backoff, including SDK responses that fulfill with rate-limit bodies instead of throwing, and route streaming-card sends through the retry wrapper. ([#&#8203;89659](openclaw/openclaw#89659)) Thanks [@&#8203;ladygege](https://github.com/ladygege).
- Release/CI/E2E: main CI guard drift, PR merge diff scoping, live Docker credential staging, base-image qualification, installer Docker classification, Playwright dependency install recovery, API-key auth for Codex live Docker lanes, Parallels option terminators, and JSON-mode progress handling are tighter so release proof fails cleaner. ([#&#8203;90532](openclaw/openclaw#90532), [#&#8203;90287](openclaw/openclaw#90287), [#&#8203;90058](openclaw/openclaw#90058)) Thanks [@&#8203;RomneyDa](https://github.com/RomneyDa), [@&#8203;hxy91819](https://github.com/hxy91819), and [@&#8203;mrunalp](https://github.com/mrunalp).
- Release/CI/E2E: Docker E2E and live Docker harness runs now apply default memory, CPU, and process ceilings while preserving explicit per-lane overrides.
- Release/CI/E2E: plugin lifecycle matrix resource sampling now fails phases that exceed RSS, wall-clock, or CPU ceilings instead of only logging the measurements.
- Release/CI/E2E: Codex npm plugin live assertions now cap transcript discovery and diagnostic log reads so failure proof stays bounded.
- Tests/state isolation: QA Lab valid-tool-call metrics now require runtime tool-call evidence when runtime parity data is available instead of counting tool-backed scenario pass status alone.
- Tests/state isolation: QA Lab runtime parity now fails planned-only tool-call rows without matching tool results instead of treating matching mock plans as real tool evidence.
- Tests/state isolation: provider, media, auth, cron, task, session, sandbox, Gateway, and Codex timeout fixtures now scope more home/state/env data per test, reducing cross-test leakage and making release validation failures less noisy. ([#&#8203;90027](openclaw/openclaw#90027), [#&#8203;89974](openclaw/openclaw#89974))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/963
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling clawsweeper:automerge Maintainer opted this PR into bounded ClawSweeper-reviewed automerge P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 🚀 automerge armed This PR is in ClawSweeper's automerge lane.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

convertContentBlocks coerces MCP resource_link/resource/audio blocks into malformed image blocks -> Anthropic 400 -> poisoned session history

2 participants