Skip to content

fix(app): prevent streaming content duplication during event coalescing#14820

Open
praxstack wants to merge 2 commits intoanomalyco:devfrom
praxstack:fix/streaming-content-duplication
Open

fix(app): prevent streaming content duplication during event coalescing#14820
praxstack wants to merge 2 commits intoanomalyco:devfrom
praxstack:fix/streaming-content-duplication

Conversation

@praxstack
Copy link

@praxstack praxstack commented Feb 23, 2026

Issue for this PR

Closes #14822

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

During streaming, SSE events are batched in 16ms windows. message.part.updated events coalesce (text-end replaces text-start at same queue index), but message.part.delta events never coalesce. When both land in the same batch, the full text gets applied via reconcile, then stale deltas append on top — doubling the content.

The fix adds a voided Set in global-sdk.tsx. When a message.part.updated coalesces, all stale message.part.delta events for that messageID+partID are voided. Voided indices are skipped during flush. Zero overhead when no coalescing occurs (the common case).

How did you verify your code works?

  • All 12 typecheck tasks pass
  • Tested locally with bun run --cwd packages/desktop tauri dev
  • Sent messages during streaming, confirmed no duplication
  • Quit and reopened app, confirmed content still correct
  • Linux E2E tests pass (2 failing checks are pre-existing: Windows @mention flaky test + Linux test infra issue)

Screenshots / recordings

Text-only change in event batching layer, no UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…cing

When message.part.updated events coalesce within a 16ms batch window
(text-end replaces text-start at the same queue index), stale
message.part.delta events remained in the queue. On flush, the reducer
applied the full text from the coalesced update, then appended the
stale deltas on top — doubling the content.

Fix: When a message.part.updated event coalesces over an earlier entry,
void all stale message.part.delta events for the same messageID:partID
already in the queue. Voided indices are skipped during flush.

Zero overhead in normal operation (voided set stays empty when no
coalescing occurs). Scoped by messageID+partID to avoid affecting
unrelated parts.

Fixes content repetition visible during LLM streaming in desktop UI.
Content displays correctly after app restart (loaded from DB).
@github-actions
Copy link
Contributor

Hey! Your PR title 🐛 fix(app): prevent streaming content duplication during event coalescing doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions github-actions bot added needs:title needs:compliance This means the issue will auto-close after 2 hours. labels Feb 23, 2026
@praxstack praxstack changed the title 🐛 fix(app): prevent streaming content duplication during event coalescing fix(app): prevent streaming content duplication during event coalescing Feb 23, 2026
@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions github-actions bot removed needs:issue needs:compliance This means the issue will auto-close after 2 hours. labels Feb 23, 2026
@github-actions
Copy link
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming content duplication during LLM streaming in desktop/web UI

1 participant