fix(chat): dedupe duplicate assistant bubbles and align continuation bubbles#501
Merged
shanselman merged 2 commits intoMay 22, 2026
Conversation
…bubbles Two related fixes for the screenshot bug where the same assistant text rendered twice in a row and continuation bubbles were indented left of the first bubble. Rendering (OpenClawChatTimeline.RenderAssistantEntry): - Reserve a 36x36 spacer for continuation assistant entries so the bubble's left edge stays aligned with the first entry in the burst (matches the user-burst path above and the tool-burst path below). - bubbleRow margin and footer leftInset now depend only on showAssistAvatar, so the slot is consistently inset regardless of whether the avatar is actually drawn. Reducer (ChatTimelineReducer.UpsertAssistant): - Added an identical-text dedupe safety net: if the most recent Assistant entry within the same turn (i.e. before any User boundary) has byte-equal text to the incoming message, collapse them. This catches duplicate ChatMessageEvent emissions from the gateway regardless of the ReconcilePrevious flag. - On merge, restore ActiveAssistantId to the merged entry so subsequent deltas/messages do not split into a new bubble. Tests: - DuplicateFinalAssistant_IdenticalText_DedupesWithoutReconcileFlag - SubsequentAssistant_DifferentText_AfterTurnEnd_CreatesNewEntry Validation: build.ps1, Shared.Tests (1869 passed / 28 skipped), Tray.Tests (1193 passed). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
758a0e9 to
4231fea
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
shanselman
added a commit
that referenced
this pull request
May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Screenshot bug: in the chat surface, the same assistant text could render twice in a row, and continuation assistant bubbles in a same-sender burst were indented ~36 px further left than the first bubble in the burst.
Fixes
A. Rendering —
OpenClawChatTimeline.RenderAssistantEntrybubbleRowmargin and footerleftInsetnow depend only onshowAssistAvatar(notshowAssistAvatar && showAvatar), so the slot inset is consistent whether the avatar is drawn or hidden as a spacer.B. Reducer —
ChatTimelineReducer.UpsertAssistantAssistantentry within the same turn (i.e. before anyUserboundary) has byte-equal text to the incoming message, collapse them. Catches duplicateChatMessageEventemissions from the gateway regardless of theReconcilePreviousflag.ActiveAssistantIdto the merged entry so subsequent deltas/messages do not split into a new bubble.Tests
New reducer tests:
DuplicateFinalAssistant_IdenticalText_DedupesWithoutReconcileFlag— reproduces the screenshot bug.SubsequentAssistant_DifferentText_AfterTurnEnd_CreatesNewEntry— guards against over-aggressive dedupe in a new turn.Validation
./build.ps1— all projects succeeded.OpenClaw.Shared.Tests— 1869 passed, 28 skipped.OpenClaw.Tray.Tests— 1193 passed.d5/d6continuation-bubble case).