Skip to content

fix(tui): stabilize optimistic user messages across history reloads, runId reassignment, and abort#86205

Merged
RomneyDa merged 5 commits into
mainfrom
tui-disappearing-messages
Jun 5, 2026
Merged

fix(tui): stabilize optimistic user messages across history reloads, runId reassignment, and abort#86205
RomneyDa merged 5 commits into
mainfrom
tui-disappearing-messages

Conversation

@RomneyDa

@RomneyDa RomneyDa commented May 24, 2026

Copy link
Copy Markdown
Member

What this fixes

The TUI renders an outbound user message optimistically, before the gateway persists it. Three situations could make that optimistic row disappear, jump position, or linger as a ghost. This PR makes it stable across all three by tracking it as a keyed pending entry that is reconciled against real history.

  1. A stale history reload wipes the message. A chat.history rebuild (or run-error refresh) landing before the message is persisted used to clear the optimistic render. Pending rows now survive clearAll, are restored across rebuilds, and are reconciled (by text + timestamp) once persisted history catches up. (Original regressions: [Bug]: [tui] Outbound messages not visible until agent response completes (loadHistory wipes optimistic render) #54722, [Bug]: TUI input vanishes silently — messages typed/pasted disappear from history with no response #59014.)

  2. The gateway reassigns the runId. When chat.send returns a different runId than the locally generated one, the pending row is re-keyed in place via ChatLog.rekeyPendingUser (a map-key swap, no re-mount), so it keeps its transcript position even if a reply already rendered below it.

  3. Abort before the run registers. A new pendingSubmitDraft tracks a submit until it is durably registered (proven by isRunObserved or completion). abortActive drops the optimistic row only while the submit is still unregistered; once registered, the row is left to history. This removes both the ghost row that used to linger after aborting a pending submit and the risk of dropping a row whose reply already showed.

It also removes two unused ChatLog helpers (commitPendingUser, hasPendingUser) that had no caller.

Why it exists

Outbound TUI messages silently vanishing or mis-rendering is a recurring, high-annoyance class of bug (#54722, #59014). The optimistic-render path had no durable link between the rendered row and the eventual persisted/streamed run, so any reload, runId reassignment, or abort in the wrong window lost or misplaced it.

Commits

  • fix(tui): preserve optimistic user messages — pending-row preservation + reconcile across history reloads (case 1).
  • refactor(tui): drop unused pending-user chat-log helpers — remove dead commitPendingUser / hasPendingUser.
  • fix(tui): reconcile optimistic user row across runId reassignment and abort — in-place re-key (case 2) + gated abort cleanup with the isRunObserved registration guard (case 3).

Related issues

Verification

Maintainer local proof (no live Gateway run):

node scripts/run-vitest.mjs run --config test/vitest/vitest.tui.config.ts \
  src/tui/components/chat-log.test.ts src/tui/tui-command-handlers.test.ts \
  src/tui/tui-session-actions.test.ts src/tui/tui-event-handlers.test.ts
node scripts/run-vitest.mjs run --config test/vitest/vitest.tui-pty.config.ts
node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json   # CI check-test-types lane (covers src/tui)
.agents/skills/autoreview/scripts/autoreview --mode local
  • TUI unit lanes: 179 passed (4 files)
  • Fake-backend PTY lane: 13 passed
  • Test + prod types: clean · oxfmt --check: clean · git diff --check: clean
  • autoreview: patch is correct, no accepted/actionable findings

New regression coverage: in-place re-key preserves transcript order; abort drops a not-yet-registered pending row; abort keeps a registered row; the draft is not re-armed when the accepted run already emitted events.

Not tested: no live Gateway/provider/streaming run; the fake-backend PTY harness does not prove transport, embedded runtime, providers, or session persistence.

@openclaw-barnacle openclaw-barnacle Bot added size: S maintainer Maintainer-authored PR labels May 24, 2026
@clawsweeper

clawsweeper Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 5, 2026, 3:05 PM ET / 19:05 UTC.

Summary
The PR changes TUI optimistic user messages into keyed pending rows that survive history rebuilds, re-key to gateway-accepted run IDs, and are dropped only for unregistered aborted or failed sends, with focused TUI regression coverage.

PR surface: Source +75, Tests +207. Total +282 across 10 files.

Reproducibility: yes. from source inspection and linked reports: current main renders an unkeyed optimistic user row, while loadHistory() rebuilds with clearAll(), so a stale refresh can wipe the row before persisted history catches up. I did not run a live TUI/Gateway reproduction in this read-only review.

Review metrics: 1 noteworthy metric.

  • TUI pending state fields: 1 added. pendingSubmitDraft becomes the in-memory owner for whether abort may drop an optimistic row, so its lifecycle needs maintainer review before merge.

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:

  • Maintainer should review the current merge ref against the recent TUI queue/abort/history cluster before landing.
  • [P2] Add live Gateway or embedded-local TUI proof only if maintainers require transport or session-persistence coverage beyond the focused lanes.

Risk before merge

  • [P1] A missed interleaving across send resolution, run registration, history reload, final/error events, and abort cleanup could still hide, duplicate, or mis-associate transcript rows.
  • [P1] The supplied proof is focused TUI unit and fake-backend PTY proof; the scoped TUI guide says that lane does not prove Gateway transport, embedded runtime, providers, session persistence, or live streaming.
  • [P1] The PR overlaps a recent TUI queue/abort/history cluster, so maintainers should review the current merge ref rather than only the branch-era diff.

Maintainer options:

  1. Review and Land the Merge Ref (recommended)
    Proceed after a maintainer reviews this merge ref against the recent TUI queue, abort, and history cluster and accepts the remaining async race risk.
  2. Require Live TUI Proof
    Ask for a live Gateway or embedded-local TUI run showing stale-history preservation and abort cleanup before merge if transport/session-persistence confidence is required.
  3. Pause for Sequencing
    Pause this PR if maintainers decide the recently landed TUI queue or abort fixes should be the canonical path before this broader pending-row reconciliation lands.

Next step before merge

  • [P2] Protected maintainer PR plus TUI message/session-state race risk needs human sequencing; I found no narrow automated repair to queue.

Security
Cleared: The diff stays inside TUI state handling and tests, with no dependency, workflow, secret, install, package, or code-execution surface changes.

Review details

Best possible solution:

Land the current merge ref only after maintainer review accepts the remaining TUI race risk or asks for a live/embedded TUI proof extension; the desired end state is one keyed optimistic row that remains visible until history or explicit failure owns it.

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

Yes from source inspection and linked reports: current main renders an unkeyed optimistic user row, while loadHistory() rebuilds with clearAll(), so a stale refresh can wipe the row before persisted history catches up. I did not run a live TUI/Gateway reproduction in this read-only review.

Is this the best way to solve the issue?

Yes, this appears to be the best TUI-layer fix: it keeps one keyed pending row and reconciles against canonical history rather than adding a broader Gateway protocol change. A protocol-level run-ID contract would be larger and is not needed for this bounded repair.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 36d9241cf7d6.

Label changes

Label changes:

  • add proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-patch focused TUI unit, fake-backend PTY, type, format, and autoreview output; it does not claim live Gateway/provider/session-persistence proof.

Label justifications:

  • P2: This is a normal-priority TUI message-rendering/session-state repair with limited blast radius but real user-visible annoyance.
  • merge-risk: 🚨 session-state: The patch changes how TUI run registration, pending submit state, history refresh, and abort cleanup share state.
  • merge-risk: 🚨 message-delivery: A bad merge could hide, duplicate, or wrongly keep outbound user transcript rows even when the backend run is handled correctly.
  • 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 (terminal): The PR body includes after-patch focused TUI unit, fake-backend PTY, type, format, and autoreview output; it does not claim live Gateway/provider/session-persistence proof.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-patch focused TUI unit, fake-backend PTY, type, format, and autoreview output; it does not claim live Gateway/provider/session-persistence proof.
Evidence reviewed

PR surface:

Source +75, Tests +207. Total +282 across 10 files.

View PR surface stats
Area Files Added Removed Net
Source 6 83 8 +75
Tests 4 239 32 +207
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 10 322 40 +282

What I checked:

  • Repository policy applied: Root and scoped TUI review policy were read; the scoped TUI guide specifically limits fake-backend PTY proof from proving Gateway transport, embedded runtime, providers, session persistence, or live streaming. (src/tui/AGENTS.md:1, 36d9241cf7d6)
  • Current main behavior: Current main renders outbound text as an unkeyed user row before send resolution, so a later history rebuild has no row identity to preserve or reconcile. (src/tui/tui-command-handlers.ts:751, 36d9241cf7d6)
  • History rebuild path: Current main rebuilds TUI history with chatLog.clearAll(), which clears the optimistic row before server history necessarily contains the sent user message. (src/tui/tui-session-actions.ts:452, 36d9241cf7d6)
  • PR implementation: The merge ref adds keyed pending submit state, re-keys pending user rows to the accepted run ID, and drops pending rows on send failure. (src/tui/tui-command-handlers.ts:753, 6e37c58d607d)
  • PR history reconciliation: The merge ref preserves pending rows across loadHistory(), collects history user timestamps, reconciles matching rows, and restores only unmatched pending rows. (src/tui/tui-session-actions.ts:458, 6e37c58d607d)
  • PR registration guard: The event handler marks submitted runs registered when chat or lifecycle events arrive and exposes isRunObserved so abort cleanup does not drop rows whose reply already rendered. (src/tui/tui-event-handlers.ts:274, 6e37c58d607d)

Likely related people:

  • vincentkoc: Authored prior pending-send and clock-skew reconciliation fixes in the same TUI optimistic/history area. (role: feature-history owner; confidence: high; commits: 51d6d7013f07, f0a44232716d, 397b0d85f571; files: src/tui/tui-command-handlers.ts, src/tui/tui-session-actions.ts, src/tui/components/chat-log.ts)
  • vignesh07: Authored the earlier TUI optimistic user-message preservation change referenced by the current behavior path. (role: introduced adjacent optimistic-message behavior; confidence: high; commits: 61a0b0293104, 726ef48c2ac8, 6084c26d0046; files: src/tui/tui-command-handlers.ts, src/tui/tui-event-handlers.ts)
  • neeravmakwana: Authored the recently merged busy-submit queue PR touching the same TUI pending-state and abort surfaces. (role: recent adjacent owner; confidence: medium; commits: 6842d72a9c7b; files: src/tui/tui-command-handlers.ts, src/tui/tui-session-actions.ts, src/tui/tui.ts)
  • steipete: Recent TUI history-sync and refactor commits touch surrounding session/history behavior and tests. (role: recent adjacent contributor; confidence: medium; commits: ff2e9a52ff10, 2d6d6797d81a, 675764e866e8; files: src/tui/tui-session-actions.ts, src/tui/tui-command-handlers.ts, src/tui/tui-event-handlers.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: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels May 24, 2026
@clawsweeper

clawsweeper Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

🔥 Warming up: real-behavior proof passed; findings, security review, or rank-up moves are still in progress.

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.
What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@RomneyDa RomneyDa marked this pull request as draft May 27, 2026 20:02
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 27, 2026
@BingqingLyu

This comment was marked as spam.

@RomneyDa RomneyDa force-pushed the tui-disappearing-messages branch from 028e159 to 5259464 Compare June 1, 2026 17:38
@RomneyDa

RomneyDa commented Jun 1, 2026

Copy link
Copy Markdown
Member Author

Addressed the ClawSweeper feedback and rebased onto current origin/main (ba88b7a178).

Summary:

  • Removed the CHANGELOG.md edit from this contributor PR.
  • Kept optimistic user messages pending after the first gateway run binding; they are now removed only when chat.history reconciliation sees the persisted user message or when chat.send fails explicitly.
  • Added regressions for stale history rebuilds, run-binding retention, and send-failure cleanup.

Verification:

  • git diff --check
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-tui-disappearing-$RANDOM OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=30000 node scripts/run-vitest.mjs run --config test/vitest/vitest.tui.config.ts src/tui/components/chat-log.test.ts src/tui/tui-command-handlers.test.ts src/tui/tui-session-actions.test.ts src/tui/tui-event-handlers.test.ts --reporter=verbose (4 files, 174 tests)
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/tmp/openclaw-vitest-tui-pty-$RANDOM OPENCLAW_VITEST_MAX_WORKERS=1 OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=30000 node scripts/run-vitest.mjs run --config test/vitest/vitest.tui-pty.config.ts (1 file, 13 tests)
  • .agents/skills/autoreview/scripts/autoreview --mode local (clean)

Real behavior proof:
Behavior addressed: TUI optimistic user messages no longer disappear after gateway run binding when a stale chat.history reload races before persistence catches up.
Real environment tested: local macOS checkout after pnpm install restored the declared rastermill dependency.
Exact steps or command run after this patch: focused TUI unit lane and TUI PTY lane listed above.
Evidence after fix: tests cover stale history rebuild preservation, run-binding retention until history reconciliation, and explicit send-failure cleanup.
Observed result after fix: focused TUI lanes pass.
What was not tested: live gateway/TUI manual reproduction.

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 1, 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:

@clawsweeper clawsweeper Bot added the merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. label Jun 1, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 5, 2026
@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: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 5, 2026
@RomneyDa RomneyDa changed the title Preserve TUI optimistic user messages across history reloads fix(tui): stabilize optimistic user messages across history reloads, runId reassignment, and abort Jun 5, 2026
@RomneyDa RomneyDa marked this pull request as ready for review June 5, 2026 18:25
@RomneyDa

RomneyDa commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@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:

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 5, 2026
@RomneyDa RomneyDa merged commit ac9a219 into main Jun 5, 2026
178 checks passed
@RomneyDa RomneyDa deleted the tui-disappearing-messages branch June 5, 2026 19:09
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 6, 2026
…runId reassignment, and abort (openclaw#86205)

* fix(tui): preserve optimistic user messages

* refactor(tui): drop unused pending-user chat-log helpers

* fix(tui): reconcile optimistic user row across runId reassignment and abort

* refactor(tui): reuse asDateTimestampMs for history timestamp coercion

* test(tui): fix event-handler chatLog render mock arity
849261680 pushed a commit to 849261680/openclaw that referenced this pull request Jun 7, 2026
…runId reassignment, and abort (openclaw#86205)

* fix(tui): preserve optimistic user messages

* refactor(tui): drop unused pending-user chat-log helpers

* fix(tui): reconcile optimistic user row across runId reassignment and abort

* refactor(tui): reuse asDateTimestampMs for history timestamp coercion

* test(tui): fix event-handler chatLog render mock arity
wangmiao0668000666 pushed a commit to wangmiao0668000666/openclaw that referenced this pull request Jun 9, 2026
…runId reassignment, and abort (openclaw#86205)

* fix(tui): preserve optimistic user messages

* refactor(tui): drop unused pending-user chat-log helpers

* fix(tui): reconcile optimistic user row across runId reassignment and abort

* refactor(tui): reuse asDateTimestampMs for history timestamp coercion

* test(tui): fix event-handler chatLog render mock arity
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

maintainer Maintainer-authored PR merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. 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. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: M 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.

2 participants