Skip to content

fix(ui): preserve queued chat messages across session switches#73679

Merged
BunsDev merged 1 commit intoopenclaw:mainfrom
tmimmanuel:fix/73621-preserve-chat-queue-session-switch
Apr 29, 2026
Merged

fix(ui): preserve queued chat messages across session switches#73679
BunsDev merged 1 commit intoopenclaw:mainfrom
tmimmanuel:fix/73621-preserve-chat-queue-session-switch

Conversation

@tmimmanuel
Copy link
Copy Markdown
Contributor

Summary

  • Problem: Control UI queued chat messages were stored only in the active chatQueue and were cleared when switching sessions.
  • Why it matters: A queued follow-up could silently disappear if the user navigated away before the active run finished.
  • What changed: Queue state is now preserved per session and restored when switching back; overview session switching uses the same session-switch helper.
  • What did NOT change (scope boundary): This does not persist queued messages to the gateway or disk; it preserves the existing client-side queue across in-UI session navigation.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: resetChatStateForSessionSwitch() unconditionally cleared state.chatQueue, even when the queue belonged to the session being left.
  • Missing detection / guardrail: Existing session-switch tests checked reset behavior but did not assert queued message preservation.
  • Contributing context (if known): Queued messages are client-side until flushed, so clearing local queue state drops them silently.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: ui/src/ui/app-render.helpers.node.test.ts
  • Scenario the test should lock in: Queue a message in one session, switch away, then switch back and confirm the queued item is restored.
  • Why this is the smallest reliable guardrail: The bug is in session-switch state reset logic, so a focused helper test covers the failure directly.
  • Existing test that already covers this (if any): N/A
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Queued Control UI messages remain associated with their original session when navigating to another session and are visible again when returning.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 28, 2026

Greptile Summary

This PR fixes a bug where queued chat messages were silently dropped when switching sessions by introducing chatQueueBySession — a per-session map that saves the active queue before a session switch and restores it on return. The overview's onSessionKeyChange handler is also unified with the existing switchChatSession helper to prevent a parallel code path with the same bug. The implementation is correct, and a focused unit test covers the round-trip save/restore behavior.

Confidence Score: 5/5

Safe to merge — the fix is well-scoped, correctly handles all switching scenarios, and is backed by new tests.

No P0 or P1 issues found. The save/restore logic is correct across all switching permutations (switch away, switch back, multiple round-trips, empty queue cleanup). Lit reactivity is properly handled via new object references. The unification of the overview switch path with switchChatSession is a deliberate, documented improvement.

No files require special attention.

Reviews (1): Last reviewed commit: "fix(ui): preserve queued chat messages a..." | Re-trigger Greptile

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 28, 2026

Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve.

Keep this PR open. Current main still clears the Control UI chat queue on session switches, has no per-session queue store, and the supplied PR remains a focused implementation candidate for open bug #73621 rather than obsolete cleanup.

Best possible solution:

Review and either land or request changes on this PR as the focused client-side fix for #73621. The narrow boundary should be Control UI state: save the active queue before switching sessions, restore it when switching back, route all session-switch surfaces through one helper, and add the proposed regression test without changing gateway or disk persistence.

What I checked:

  • Current main clears the shared queue in the common switch helper: resetChatStateForSessionSwitch() still assigns state.chatQueue = [] during every session switch, matching the PR's stated root cause rather than the proposed fixed behavior. (ui/src/ui/app-render.helpers.ts:87, b85edb3f0cf6)
  • Overview session switching has a separate queue-clearing path: The overview onSessionKeyChange handler directly resets session chat state and clears state.chatQueue, so current main still has the parallel path the PR routes through switchChatSession(). (ui/src/ui/app-render.ts:1567, b85edb3f0cf6)
  • No per-session queue state exists on main: AppViewState and OpenClawApp expose a single chatQueue; rg found no chatQueueBySession implementation in current UI source. (ui/src/ui/app-view-state.ts:110, b85edb3f0cf6)
  • Queued follow-ups are active UI memory state until flushed: Queued messages are appended to host.chatQueue and later drained from that same in-memory array when connected and not busy; clearing it during navigation can drop an unsent follow-up. (ui/src/ui/app-chat.ts:165, b85edb3f0cf6)
  • Docs describe the affected queued-follow-up UX: The Control UI docs state that normal follow-ups queue while a run is active, which is the user-visible behavior affected by this PR. Public docs: docs/web/control-ui.md. (docs/web/control-ui.md:172, b85edb3f0cf6)
  • Existing test coverage does not assert restoration: The current switchChatSession test seeds chatQueue, but it does not assert save/restore behavior across switching back to the original session; the PR's proposed regression test remains useful. (ui/src/ui/app-render.helpers.node.test.ts:496, b85edb3f0cf6)

Likely related people:

  • Ayaan Zaidi: Current-main blame and git log -S/-G for resetChatStateForSessionSwitch, chatQueue, and the overview switch path point to the commit that introduced the checked-out Control UI files and queue behavior. (role: introduced current-main behavior / adjacent UI owner; confidence: medium; commits: d8c4d7c3c10f; files: ui/src/ui/app-render.helpers.ts, ui/src/ui/app-render.ts, ui/src/ui/app-chat.ts)
  • BunsDev: The PR timeline shows BunsDev was mentioned by the contributor and assigned for follow-up, though I did not find current-main code provenance for this exact UI path under that handle. (role: assigned maintainer / likely reviewer; confidence: low; files: ui/src/ui/app-render.helpers.ts, ui/src/ui/app-render.ts)

Remaining risk / open question:

  • The proposed per-session queue store should get maintainer review for lifecycle details: restored queue ordering, inactive-session removal, and attachment payload retention while queued items sit outside the active chatQueue.
  • Open PR fix(webchat): persist chat queue to localStorage with drain-on-reconnect #73154 overlaps in the broader browser-refresh/localStorage queue-persistence area, so landing should keep this PR's in-memory session-switch fix compatible with any later durable queue design.

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

@tmimmanuel
Copy link
Copy Markdown
Contributor Author

@BunsDev
I passed ai checks. CI failures are not related with my changes.
Please review my PR.

Copy link
Copy Markdown
Member

@BunsDev BunsDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against #73621, the maintainer note in #issuecomment-4337307063, and the related queue persistence context in #51549 / #73154.

This is the focused fix for the session-switch loss path: the active queue is saved under the previous session before session reset, restored when switching back, the overview session selector now goes through the same switchChatSession helper, and the regression test covers switch-away / switch-back with a queued follow-up.

I do not consider this superseded by #73154: that PR is the broader refresh/reconnect/localStorage queue persistence candidate for #51549, while this PR intentionally keeps #73621 to in-UI session navigation without adding disk/gateway persistence.

Local proof on commit 86f0557:

  • OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test ui/src/ui/app-render.helpers.node.test.ts
  • pnpm tsgo:test:ui
  • pnpm exec oxfmt --check --threads=1 ui/src/ui/app-render.helpers.node.test.ts ui/src/ui/app-render.helpers.ts ui/src/ui/app-render.ts ui/src/ui/app-view-state.ts ui/src/ui/app.ts

CI is still red, but the failed jobs I sampled are unrelated plugin/bundled/boundary/build-artifact failures; the PR touches only Control UI queue/session state files and the core UI CI job is green. Do not merge until branch protection/check policy is satisfied or maintainers explicitly accept the unrelated red CI.

@BunsDev BunsDev merged commit 0bbbc99 into openclaw:main Apr 29, 2026
56 of 70 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…law#73679)

Fixes openclaw#73621.

Preserve queued Control UI chat messages across in-UI session switches by saving the active queue per session before reset and restoring it when switching back. Route the overview session selector through the shared switchChatSession helper so it follows the same queue lifecycle.

Validation:
- OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test ui/src/ui/app-render.helpers.node.test.ts
- pnpm tsgo:test:ui
- pnpm exec oxfmt --check --threads=1 ui/src/ui/app-render.helpers.node.test.ts ui/src/ui/app-render.helpers.ts ui/src/ui/app-render.ts ui/src/ui/app-view-state.ts ui/src/ui/app.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI — queued message silently lost when switching to another session

2 participants