Skip to content

fix(ui): deduplicate streaming chat segments to prevent growing duplicate bubbles#47399

Closed
LittleBreak wants to merge 1 commit into
openclaw:mainfrom
LittleBreak:fix/webchat-streaming-duplicate-bubbles
Closed

fix(ui): deduplicate streaming chat segments to prevent growing duplicate bubbles#47399
LittleBreak wants to merge 1 commit into
openclaw:mainfrom
LittleBreak:fix/webchat-streaming-duplicate-bubbles

Conversation

@LittleBreak

Copy link
Copy Markdown

Summary

Fixes #47188 — webchat streaming responses create multiple duplicate message bubbles with growing text instead of updating a single bubble in-place.

Root Cause

The gateway sends the full accumulated assistant text in each streaming delta event. When a tool call interrupts the stream, app-tool-stream.ts saves the current chatStream (full accumulated text) as a segment. After the tool completes, new delta events arrive containing the full text again (including text already in segments), causing each segment to show incrementally more duplicated text.

This was previously masked by a loadChatHistory() call after every tool result (removed in 0e8672a to fix a reload storm). Removing that call exposed this pre-existing segment duplication bug.

Fix

Introduce chatStreamSegmentOffset to track the length of text already committed to segments:

  • app-tool-stream.ts: When saving a segment on tool start, use chatStream.slice(offset) to store only the delta text (not the full accumulated text). Update offset = chatStream.length after each save.
  • views/chat.ts: When rendering the live stream bubble, use stream.slice(offset) to display only new text after the last segment.
  • Reset offset in resetToolStream().

Files Changed (8)

File Change
ui/src/ui/app-tool-stream.ts Segment save logic + offset tracking
ui/src/ui/views/chat.ts Render delta text, add streamSegmentOffset prop
ui/src/ui/app.ts Add @state() chatStreamSegmentOffset
ui/src/ui/app-view-state.ts Add type field
ui/src/ui/app-render.ts Pass offset prop
ui/src/ui/views/chat.test.ts Add dedup test
ui/src/ui/app-tool-stream.node.test.ts Update host fixture
ui/src/ui/app-gateway.node.test.ts Update host fixture

Testing

  • All 52 existing tests pass (27 chat controller + 25 chat view)
  • New test verifies segment offset stripping prevents duplicate text in stream bubbles
  • Format check passes

🤖 This PR was prepared with AI assistance.

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

Labels