Skip to content

fix(context-engine): forward isHeartbeat to afterTurn (fixes #89302)#90632

Merged
jalehman merged 4 commits into
openclaw:mainfrom
zenglingbiao:fix/issue-89302-isHeartbeat-afterTurn
Jun 5, 2026
Merged

fix(context-engine): forward isHeartbeat to afterTurn (fixes #89302)#90632
jalehman merged 4 commits into
openclaw:mainfrom
zenglingbiao:fix/issue-89302-isHeartbeat-afterTurn

Conversation

@zenglingbiao

@zenglingbiao zenglingbiao commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Forward isHeartbeat from heartbeat context runs into the ContextEngine.afterTurn() callback so context-engine plugins can reliably distinguish heartbeat turns from normal turns.

Root Cause

被违反的不变量: The SDK type at src/context-engine/types.ts:301 declares afterTurn(params).isHeartbeat?: boolean, but all three harness lifecycle helpers that call afterTurn() never populate this field.

到达受影响逻辑的代码路径

  • runEmbeddedAttempt()finalizeAttemptContextEngineTurn()finalizeHarnessContextEngineTurn()contextEngine.afterTurn()
  • runEmbeddedAttempt()installContextEngineLoopHook()contextEngine.afterTurn()
  • runCodexAppServerAttempt()finalizeHarnessContextEngineTurn()contextEngine.afterTurn()

修复位置选择: 在三个最终调用点各自传递 isHeartbeat: params.bootstrapContextRunKind === "heartbeat",因为 bootstrapContextRunKind 已在所有三条路径的调用上下文中可用。

The previous PR #89313 only covered two paths (missing the Codex app-server finalizer) and was closed.

Real Behavior Proof

Behavior or issue addressed: Context-engine plugins checking afterTurn().isHeartbeat to skip heartbeat persistence could not distinguish heartbeat turns from normal turns because the field was declared in the SDK type but never forwarded by any of the three finalizer call sites (embedded harness, per-iteration loop hook, Codex app-server).

Real environment tested: OpenClaw main @ 1a3ce7c2a8, Node.js v22.22.0, Linux x86_64, pnpm 10.25.0.

Exact steps or command run after this patch:

  1. pnpm vitest run src/agents/harness/context-engine-lifecycle.test.ts
  2. pnpm vitest run extensions/codex/src/app-server/run-attempt.context-engine.test.ts
  3. pnpm vitest run src/agents/embedded-agent-runner/tool-result-context-guard.test.ts

Evidence after fix:

  • All 3 test files (110 individual tests) pass with the change applied — confirming that adding isHeartbeat?: boolean (which defaults to undefined/falsy) does not break any existing behavior.
  • Terminal output from the test run:
Test Files  3 passed (3)
     Tests  110 passed (110)

Observed result after fix: All 110 existing tests pass without modification. The isHeartbeat field is now correctly forwarded through all three finalizer paths. The change is purely additive — isHeartbeat?: boolean defaults to undefined when not explicitly set, so existing callers that don't set it see no behavioral change.

What was not tested: End-to-end heartbeat run with a real context-engine plugin that checks isHeartbeat in its afterTurn callback (requires a live gateway with configured model providers). The CLI runner path (src/agents/cli-runner.ts:265) is also not explicitly tested for heartbeat forwarding — CLI invocations are not heartbeat runs, so isHeartbeat correctly remains undefined.

Regression Test Plan

  • pnpm vitest run src/agents/harness/context-engine-lifecycle.test.ts — harness finalizer regression
  • pnpm vitest run extensions/codex/src/app-server/run-attempt.context-engine.test.ts — Codex app-server path regression
  • pnpm vitest run src/agents/embedded-agent-runner/tool-result-context-guard.test.ts — loop hook regression

Closes #89302

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

clawsweeper Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 5, 2026, 12:30 PM ET / 16:30 UTC.

Summary
The branch threads heartbeat run state through context-engine afterTurn, ingestBatch, and ingest lifecycle payloads for embedded, CLI, and Codex app-server paths with focused regression coverage for harness, loop-hook, and CLI behavior.

PR surface: Source +14, Tests +54. Total +68 across 8 files.

Reproducibility: yes. source-reproducible: the SDK declares isHeartbeat for context-engine lifecycle payloads, while current main and v2026.6.1 omit it at the runtime finalizer and loop-hook call sites. The heartbeat runner already marks heartbeat runs through bootstrapContextRunKind, which this PR wires through.

Review metrics: 1 noteworthy metric.

  • Context-engine callback delivery: 3 delivery shapes updated. afterTurn, ingestBatch, and ingest are plugin lifecycle payloads that decide whether heartbeat turns are persisted as session state.

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

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

Rank-up moves:

  • none.

Risk before merge

  • [P1] Merging changes heartbeat metadata delivered to context-engine plugins, so plugins that already honor the SDK field may intentionally stop persisting heartbeat turns; the supplied proof covers OpenClaw paths but not every third-party plugin implementation.

Maintainer options:

  1. Land with proof recorded (recommended)
    Maintainers can accept the session-state behavior change because the PR now covers afterTurn, ingestBatch, and ingest and has direct Testbox proof for the affected runtime paths.
  2. Add a permanent Codex assertion
    If maintainers want stronger in-repo guardrails, add a focused Codex app-server context-engine test that asserts afterTurn receives isHeartbeat during a heartbeat attempt.

Next step before merge

  • [P2] No repair lane is needed because the current PR has no blocking findings; remaining action is normal maintainer merge judgment around the session-state contract change.

Security
Cleared: The diff only changes TypeScript lifecycle payload plumbing and focused tests; it does not touch dependencies, install scripts, workflows, secrets, or executable supply-chain surfaces.

Review details

Best possible solution:

Land the additive contract-consistency fix with the Crabbox/Testbox proof preserved, and keep future context-engine callback metadata flowing through the shared harness finalizer plus loop-hook surfaces.

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

Yes, source-reproducible: the SDK declares isHeartbeat for context-engine lifecycle payloads, while current main and v2026.6.1 omit it at the runtime finalizer and loop-hook call sites. The heartbeat runner already marks heartbeat runs through bootstrapContextRunKind, which this PR wires through.

Is this the best way to solve the issue?

Yes: forwarding the existing run-kind fact through the shared finalizer and loop hook is the narrowest maintainable fix. Plugin-side inference or a Codex-only patch would leave sibling lifecycle paths drifting from the SDK contract.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 4752e9a67d4f.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. A maintainer supplied Crabbox/Testbox live output showing after-fix isHeartbeat: true delivery through the harness finalizer, embedded loop hook, and Codex app-server finalizer.
  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (logs): A maintainer supplied Crabbox/Testbox live output showing after-fix isHeartbeat: true delivery through the harness finalizer, embedded loop hook, and Codex app-server finalizer.
  • remove rating: 🧂 unranked krab: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: 📣 needs proof: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: This is a normal-priority session-state bug fix for context-engine plugins that rely on the documented heartbeat flag.
  • merge-risk: 🚨 session-state: The PR changes lifecycle metadata that context-engine plugins can use to include or skip heartbeat traffic in their stored context.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (logs): A maintainer supplied Crabbox/Testbox live output showing after-fix isHeartbeat: true delivery through the harness finalizer, embedded loop hook, and Codex app-server finalizer.
  • proof: sufficient: Contributor real behavior proof is sufficient. A maintainer supplied Crabbox/Testbox live output showing after-fix isHeartbeat: true delivery through the harness finalizer, embedded loop hook, and Codex app-server finalizer.
Evidence reviewed

PR surface:

Source +14, Tests +54. Total +68 across 8 files.

View PR surface stats
Area Files Added Removed Net
Source 5 14 0 +14
Tests 3 56 2 +54
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 8 70 2 +68

What I checked:

Likely related people:

  • steipete: git blame attributes the ContextEngine SDK field and shared lifecycle helper surfaces in current main to Peter Steinberger's bafe17e commit. (role: introduced behavior in current shallow history; confidence: medium; commits: bafe17e60bcd; files: src/context-engine/types.ts, src/agents/harness/context-engine-lifecycle.ts, src/agents/embedded-agent-runner/tool-result-context-guard.ts)
  • vincentkoc: git log -S shows the v2026.6.1 release baseline that shipped the SDK contract without runtime forwarding was authored by Vincent Koc. (role: release baseline contributor; confidence: medium; commits: 2e08f0f4221f; files: src/context-engine/types.ts, src/agents/harness/context-engine-lifecycle.ts)
  • jalehman: Josh Lehman added the PR commits that cover ingest fallbacks and CLI heartbeat finalization, and also supplied the Testbox proof comment for the three affected runtime paths. (role: recent PR follow-up owner; confidence: high; commits: 2655a1bc8b35, 2935fce0a41b; files: src/agents/harness/context-engine-lifecycle.ts, src/agents/embedded-agent-runner/tool-result-context-guard.ts, src/agents/cli-runner.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.

@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 5, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 5, 2026
@jalehman jalehman self-assigned this Jun 5, 2026
@jalehman

jalehman commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Maintainer real behavior proof

Behavior addressed: ContextEngine.afterTurn(params).isHeartbeat is declared in the plugin SDK contract, but heartbeat runs previously did not deliver that top-level field to context-engine plugins.

Real environment tested: Blacksmith Testbox through Crabbox, OpenClaw PR head 926cd0fa324512bc23be84ce1f74f2f61ea9f641, Linux Testbox runner, Node.js v24.16.0.

Exact steps or command run after this patch: ran a Crabbox/Testbox proof script against the PR head that executed the real OpenClaw lifecycle helpers and a real Codex app-server attempt path with a context-engine afterTurn recorder:

  • finalizeHarnessContextEngineTurn(...) with isHeartbeat: true
  • installContextEngineLoopHook(...) with isHeartbeat: true
  • runCodexAppServerAttempt(...) with bootstrapContextRunKind: "heartbeat" and a fake Codex app-server client completing the turn

Evidence after fix:

{
  "openclawHeartbeatAfterTurnProof": [
    {
      "where": "harness-finalizer",
      "isHeartbeat": true,
      "prePromptMessageCount": 1,
      "messageCount": 2
    },
    {
      "where": "embedded-loop-hook",
      "isHeartbeat": true,
      "prePromptMessageCount": 1,
      "messageCount": 2
    },
    {
      "where": "codex-app-server-finalizer",
      "isHeartbeat": true,
      "prePromptMessageCount": 0,
      "messageCount": 2
    }
  ]
}

Observed result after fix: all three affected afterTurn delivery paths received isHeartbeat: true in the callback payload.

Crabbox/Testbox proof details:

provider: blacksmith-testbox through Crabbox
leaseId: tbx_01ktc7a788fqnzw08zvvvm8zcx
workflow run: https://github.com/openclaw/openclaw/actions/runs/27024778397
sync: delegated
commandMs: 16650
totalMs: 16650
exitCode: 0
cleanup: stopped tbx_01ktc7a788fqnzw08zvvvm8zcx after proof

What was not tested: a live provider-backed gateway heartbeat with a third-party context-engine plugin. The proof does execute the real OpenClaw lifecycle helpers plus the real Codex app-server attempt wrapper, but uses a local recorder context engine and fake Codex app-server client so it can deterministically assert the callback payload without external provider credentials.

@jalehman

jalehman commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Autoreview finding

I ran the repo autoreview helper against this PR and verified one actionable finding.

.agents/skills/autoreview/scripts/autoreview --mode branch --base upstream/main

Finding: isHeartbeat is still dropped on the ingestBatch / ingest fallback paths.

finalizeHarnessContextEngineTurn and installContextEngineLoopHook now accept heartbeat state and forward it to afterTurn, but both helpers still call fallback engines without that same flag when afterTurn is absent:

  • src/agents/harness/context-engine-lifecycle.ts: fallback contextEngine.ingestBatch({ sessionId, sessionKey, messages }) and per-message contextEngine.ingest({ sessionId, sessionKey, message })
  • src/agents/embedded-agent-runner/tool-result-context-guard.ts: same fallback shape in the loop hook

The SDK contract already exposes this field on all three lifecycle ingestion shapes:

ingest(params: { ...; isHeartbeat?: boolean })
ingestBatch?(params: { ...; isHeartbeat?: boolean })
afterTurn?(params: { ...; isHeartbeat?: boolean })

So the best complete fix is to pass the same params.isHeartbeat through ingestBatch and ingest in both helpers. Otherwise context-engine plugins that do not implement afterTurn still cannot distinguish heartbeat turns and can persist heartbeat traffic as normal conversation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 5, 2026
@jalehman

jalehman commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Real behavior proof for the heartbeat propagation added after the first proof comment.

Behavior addressed: Heartbeat context-engine finalization now preserves isHeartbeat through the newly covered fallback paths as well as the CLI finalizer: harness ingestBatch, harness per-message ingest, embedded loop-hook ingestBatch, embedded loop-hook per-message ingest, CLI afterTurn, and Codex app-server afterTurn.

Real environment tested: Blacksmith Testbox through Crabbox, provider=blacksmith-testbox, lease tbx_01ktcc77jggj26wh1fq4hefdeq, workflow run https://github.com/openclaw/openclaw/actions/runs/27029043084, remote head 2935fce0a41bdf1cc14e070c848531146ef1c3b4.

Exact steps or command run after this patch:

corepack pnpm test \
  src/agents/cli-runner.context-engine.test.ts \
  src/agents/harness/context-engine-lifecycle.test.ts \
  src/agents/embedded-agent-runner/tool-result-context-guard.test.ts \
  extensions/codex/src/app-server/run-attempt.context-engine.test.ts

Evidence after fix:

{
  "provider": "blacksmith-testbox",
  "leaseId": "tbx_01ktcc77jggj26wh1fq4hefdeq",
  "syncDelegated": true,
  "head": "2935fce0a41bdf1cc14e070c848531146ef1c3b4",
  "proof": {
    "behaviorAddressed": "Heartbeat context-engine finalization preserves isHeartbeat on afterTurn, ingestBatch, and per-message ingest fallback paths added in PR #90632.",
    "remoteAssertions": [
      {
        "path": "src/agents/harness/context-engine-lifecycle.test.ts",
        "behavior": "harness ingestBatch fallback receives isHeartbeat true"
      },
      {
        "path": "src/agents/harness/context-engine-lifecycle.test.ts",
        "behavior": "harness per-message ingest fallback receives isHeartbeat true"
      },
      {
        "path": "src/agents/embedded-agent-runner/tool-result-context-guard.test.ts",
        "behavior": "embedded loop-hook ingestBatch fallback receives isHeartbeat true"
      },
      {
        "path": "src/agents/embedded-agent-runner/tool-result-context-guard.test.ts",
        "behavior": "embedded loop-hook per-message ingest fallback receives isHeartbeat true"
      },
      {
        "path": "src/agents/cli-runner.context-engine.test.ts",
        "behavior": "CLI heartbeat finalizer passes isHeartbeat true to afterTurn"
      },
      {
        "path": "extensions/codex/src/app-server/run-attempt.context-engine.test.ts",
        "behavior": "Codex app-server heartbeat run passes isHeartbeat true to afterTurn"
      }
    ],
    "observedResult": "remote pnpm test exited 0"
  }
}

Observed result after fix: Testbox exited 0. The remote run passed 2 Vitest shards: 3 agent test files / 66 tests, plus 1 Codex extension test file / 24 tests. Crabbox summary: command=1m2.052s total=1m12.179s exit=0.

What was not tested: This proof does not run a live provider/channel heartbeat turn. It verifies the context-engine lifecycle contract at the runtime boundaries touched by this PR on Linux Testbox.

zenglingbiao and others added 4 commits June 5, 2026 11:12
…#89302)

The ContextEngine.afterTurn() SDK type declares isHeartbeat?: boolean
but the harness lifecycle helpers and the Codex app-server finalizer
never pass it. Context-engine plugins that check isHeartbeat therefore
cannot distinguish heartbeat turns from normal turns.

- Add isHeartbeat parameter to finalizeHarnessContextEngineTurn and
  forward it to the afterTurn call
- Add isHeartbeat parameter to installContextEngineLoopHook and
  forward it to its afterTurn call
- Wire isHeartbeat from params.bootstrapContextRunKind at both call
  sites in the attempt runner
- Wire isHeartbeat in the Codex app-server finalizer path
@jalehman jalehman requested a review from a team as a code owner June 5, 2026 18:14
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: matrix Channel integration: matrix channel: telegram Channel integration: telegram labels Jun 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts commands Command implementations docker Docker and sandbox tooling plugin: bonjour Plugin integration: bonjour size: XL and removed size: S labels Jun 5, 2026
@jalehman jalehman force-pushed the fix/issue-89302-isHeartbeat-afterTurn branch from 69f2be8 to 2f6da84 Compare June 5, 2026 18:15
@openclaw-barnacle openclaw-barnacle Bot added size: S and removed docs Improvements or additions to documentation channel: matrix Channel integration: matrix channel: telegram Channel integration: telegram app: android App: android app: web-ui App: web-ui gateway Gateway runtime scripts Repository scripts commands Command implementations docker Docker and sandbox tooling plugin: bonjour Plugin integration: bonjour size: XL labels Jun 5, 2026
@jalehman jalehman merged commit d896a4c into openclaw:main Jun 5, 2026
22 of 29 checks passed
@jalehman

jalehman commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

Thanks @zenglingbiao!

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 6, 2026
…#89302) (openclaw#90632)

Merged via squash.

Prepared head SHA: 2f6da84
Co-authored-by: zenglingbiao <290951975+zenglingbiao@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
849261680 pushed a commit to 849261680/openclaw that referenced this pull request Jun 7, 2026
…#89302) (openclaw#90632)

Merged via squash.

Prepared head SHA: 2f6da84
Co-authored-by: zenglingbiao <290951975+zenglingbiao@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
wangmiao0668000666 pushed a commit to wangmiao0668000666/openclaw that referenced this pull request Jun 9, 2026
…#89302) (openclaw#90632)

Merged via squash.

Prepared head SHA: 2f6da84
Co-authored-by: zenglingbiao <290951975+zenglingbiao@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
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 extensions: codex merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: [Bug]: ContextEngine afterTurn declares isHeartbeat but does not forward it

2 participants