Skip to content

fix(ui): stabilize WebChat message ordering#74733

Closed
VladyslavLevchuk wants to merge 1 commit into
openclaw:mainfrom
VladyslavLevchuk:fix/webchat-message-order
Closed

fix(ui): stabilize WebChat message ordering#74733
VladyslavLevchuk wants to merge 1 commit into
openclaw:mainfrom
VladyslavLevchuk:fix/webchat-message-order

Conversation

@VladyslavLevchuk

@VladyslavLevchuk VladyslavLevchuk commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Rebased PR fix(ui): stabilize WebChat message ordering #74733 onto current origin/main and replaced the old XL patch with a focused WebChat reliability fix.
  • Keep optimistic user messages visible when a stale in-flight chat.history response resolves after a local send.
  • Avoid clearing active assistant stream/tool state while a run is still in progress.
  • Clear tool-stream artifacts during /clear/sessions.reset so old stream/tool cards cannot survive a reset.
  • Add a small temp-path guard cleanup for the current-main context treemap output path so pnpm check passes.

Problem

WebChat can start a chat.history request, then the user sends a message before that request resolves. The old response was reconciled against the request-start message list, so it could overwrite the newer optimistic user message and clear the active stream. Visually, the sent message could disappear and then come back only after a later response/history refresh.

Approach

  • Track local chat mutations separately from history request versions.
  • When a history response resolves after local state changed, merge against the latest visible chat state and preserve unanchored optimistic messages that are not present in the stale history payload.
  • Only clear streaming/tool state from history reloads when there is no active stream/run.
  • Reset tool-stream collections in the synchronous /clear reset path before reloading history.

Real behavior proof

  • Behavior or issue addressed: WebChat sent messages could disappear while an older chat.history request resolved after the local send; this patch keeps the optimistic send and active stream state visible.
  • Real environment tested: Vladyslav's Mac mini running the real OpenClaw launchd gateway (ai.openclaw.gateway) on port 18789, installed from this fork via the global /opt/homebrew/bin/openclaw npm symlink.
  • Exact steps or command run after this patch: Built and installed the final fork head, then restarted the real gateway: pnpm build, pnpm ui:build, npm install -g /Users/vladyslavlevchuk/Projects/openclaw-pr-74733, launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway, openclaw --version, curl -I http://127.0.0.1:18789/, and log inspection of ~/.openclaw/logs/gateway.log.
  • Evidence after fix: Copied live output from the real setup:
$ openclaw --version
OpenClaw 2026.5.10-beta.1 (48efa0e)

$ launchctl print gui/501/ai.openclaw.gateway
state = running
pid = 82744
last exit code = 0
arguments = /opt/homebrew/bin/openclaw gateway --port 18789

$ tail ~/.openclaw/logs/gateway.log
2026-05-10T14:18:23.620-04:00 [gateway] http server listening (10 plugins: acpx, active-memory, bonjour, browser, canvas, device-pair, file-transfer, memory-core, phone-control, talk-voice; 2.5s)
2026-05-10T14:18:24.289-04:00 [gateway] ready

$ curl -I http://127.0.0.1:18789/
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
  • Observed result after fix: The fork is running in a real OpenClaw gateway setup and serving the rebuilt Control UI from the final PR head. The WebChat race is covered by a regression test that reproduces the stale-history response landing after a local send and asserts the optimistic user message remains visible while the active stream remains intact.
  • What was not tested: I did not manually send a production WebChat message through the operator's live session after installing; the live setup is installed for operator verification, and stale 2026.5.7 native clients may need an app restart or browser hard refresh to reconnect to the beta gateway.

Verification

  • pnpm build passed.
  • pnpm ui:build passed.
  • pnpm check passed.
  • pnpm --dir ui exec vitest run src/ui/controllers/chat.test.ts src/ui/chat/history-merge.test.ts src/ui/app-chat.test.ts --config vitest.config.ts passed: 101 tests.
  • pnpm format:check CHANGELOG.md src/auto-reply/reply/context-treemap.ts ui/src/ui/controllers/chat.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/chat/history-merge.test.ts ui/src/ui/app-chat.ts ui/src/ui/app-chat.test.ts passed.
  • pnpm exec oxlint src/auto-reply/reply/context-treemap.ts ui/src/ui/controllers/chat.ts ui/src/ui/controllers/chat.test.ts ui/src/ui/chat/history-merge.test.ts ui/src/ui/app-chat.ts ui/src/ui/app-chat.test.ts passed.
  • pnpm tsgo:test:ui passed.
  • Final head 48efa0e303: pnpm check:changed passed.
  • Final head 48efa0e303: env -u OPENCLAW_ALLOW_INSECURE_PRIVATE_WS -u OPENCLAW_GATEWAY_HOST -u OPENCLAW_GATEWAY_TOKEN -u OPENCLAW_VAPID_SUBJECT pnpm test:changed:max passed: 21 shards.

Full Test Note

I also ran pnpm test after pnpm build. The branch-relevant shards passed, but the full local run failed in unrelated areas because this machine exports live OpenClaw gateway/VAPID env vars and because some broad current-main tests are sensitive to built dist/ or unrelated mock drift. I did not fold those unrelated repairs into this WebChat PR.

AI Assistance

AI-assisted. I reviewed the resulting diff and understand the behavior it changes.

@VladyslavLevchuk
VladyslavLevchuk marked this pull request as draft April 30, 2026 01:43
@clawsweeper

clawsweeper Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I did a careful shell check against current main, and this is already implemented.

Close: current main already ships same-or-better WebChat reconciliation for the stale chat.history race, active stream preservation, and reset cleanup; the remaining branch is conflicting and no longer the useful landing path. The May user comment about daily WebChat continuity is valid context, but the central fix landed afterward and is now in releases.

So I’m closing this as already implemented rather than keeping a duplicate issue open.

Review details

Best possible solution:

Keep the shipped current-main WebChat reconciliation implementation; any remaining durable user-send acceptance concern should stay on #86946.

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

Yes. Current-main source and regression tests cover a stale history request resolving after a local WebChat send while preserving the optimistic message and stream state; I did not run a live browser repro in this read-only pass.

Is this the best way to solve the issue?

Yes for the current-main solution, not for landing this PR. The shipped fix lives in the WebChat controller/stream reconciliation owner boundary with broader coverage, while this branch is now conflicting and redundant.

Security review:

Security review cleared: The diff touches UI controller/tests, changelog text, and a temp filename string; I found no dependency, credential, permission, CI, or supply-chain concern.

AGENTS.md: found and applied where relevant.

What I checked:

  • Current source preserves late optimistic sends: Current main collects optimistic messages appended after a history request starts and appends them after applying stale returned history, covering the PR's send-while-history-in-flight race. (ui/src/ui/controllers/chat.ts:725, 462c076a24e2)
  • Current source preserves active stream/tool state: Current main uses stream reconciliation before clearing stream/tool state, so stale history does not blindly clear active visible assistant text or tool cards. (ui/src/ui/controllers/chat.ts:741, 462c076a24e2)
  • Current tests cover the race: Current main has a regression test where a startup/history request is in flight, an optimistic user message is appended, and the stale history response resolves without removing the message or active stream state. (ui/src/ui/controllers/chat.test.ts:3167, 462c076a24e2)
  • Merged PR provenance: The complete stream/history/tool reconciliation work landed through merged PR fix(ui): preserve visible chat stream text #89530 as squash commit 17a285f. (17a285f29825)
  • Fix commit provenance: Commit 17a285f completed the visible stream preservation work and contains the earlier optimistic-send fix commit 43ced7b as an ancestor. (ui/src/ui/controllers/chat.ts:741, 17a285f29825)
  • Release provenance: Release v2026.6.2-beta.1 is the first release checked that contains the complete 17a285f fix; later stable releases v2026.6.5 and v2026.6.6 contain it too. (17a285f29825)

Likely related people:

  • vincentkoc: Authored the current-main optimistic-send preservation commit that added collectLateOptimisticTailMessages and regression coverage for sends appended while history is in flight. (role: recent feature contributor; confidence: high; commits: 43ced7bc4949; files: ui/src/ui/controllers/chat.ts, ui/src/ui/controllers/chat.test.ts, ui/src/ui/e2e/chat-flow.e2e.test.ts)
  • osolmaz: Authored and merged the current-main stream/history/tool reconciliation PR that completed the active stream preservation part of this PR's intent. (role: recent stream reconciliation contributor and merger; confidence: high; commits: 17a285f29825; files: ui/src/ui/controllers/chat.ts, ui/src/ui/chat/stream-reconciliation.ts, ui/src/ui/controllers/chat.test.ts)
  • zhang-guiping: Authored nearby WebChat terminal-send reconciliation commits in the same controller/test surface shortly before the stream reconciliation work landed. (role: adjacent recent contributor; confidence: medium; commits: c2d7b4a486b1, 0b98aea71a52; files: ui/src/ui/controllers/chat.ts, ui/src/ui/controllers/chat.test.ts)

Codex review notes: model internal, reasoning high; reviewed against 462c076a24e2; fix evidence: release v2026.6.2-beta.1, commit 17a285f29825.

@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from b1c77be to ee167f9 Compare April 30, 2026 01:53
@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime size: M and removed size: S labels Apr 30, 2026
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from ee167f9 to b13558d Compare April 30, 2026 02:01
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from b13558d to f8ca635 Compare April 30, 2026 02:15
@VladyslavLevchuk VladyslavLevchuk changed the title fix(ui): stabilize chat item timestamps fix(ui): stabilize webchat history refreshes Apr 30, 2026
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from f8ca635 to 4069f02 Compare April 30, 2026 02:26
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from 4069f02 to cd7e5c3 Compare April 30, 2026 02:44
@VladyslavLevchuk VladyslavLevchuk changed the title fix(ui): stabilize webchat history refreshes fix(ui): stabilize WebChat message ordering Apr 30, 2026
@VladyslavLevchuk
VladyslavLevchuk marked this pull request as ready for review April 30, 2026 03:00
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch 2 times, most recently from 1f5d1ca to 62a2076 Compare April 30, 2026 03:30
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch 7 times, most recently from 63df144 to 0afb27a Compare April 30, 2026 17:55
@openclaw-barnacle openclaw-barnacle Bot added the cli CLI command changes label Apr 30, 2026
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from 3c6572b to ff32a73 Compare May 10, 2026 17:48
@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. and removed gateway Gateway runtime cli CLI command changes size: XL labels May 10, 2026
@VladyslavLevchuk
VladyslavLevchuk marked this pull request as ready for review May 10, 2026 17:49
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch 2 times, most recently from 606340a to e0b4405 Compare May 10, 2026 18:05
@VladyslavLevchuk
VladyslavLevchuk force-pushed the fix/webchat-message-order branch from e0b4405 to 48efa0e Compare May 10, 2026 18:18
@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 May 10, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label May 30, 2026
@clawsweeper clawsweeper Bot added the rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. label May 30, 2026
@barnacle-openclaw barnacle-openclaw Bot removed the stale Marked as stale due to inactivity label May 30, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Jun 14, 2026
@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. P2 Normal backlog priority with limited blast radius. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 14, 2026
@clawsweeper

clawsweeper Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper applied the proposed close for this PR.

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

Labels

app: web-ui App: web-ui P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. size: S stale Marked as stale due to inactivity status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants