Skip to content

Fix duplicate assistant transcript merge - #2055

Merged
1 commit merged into
nesquena:masterfrom
franksong2702:franksong2702/issue-2051-assistant-dedup
May 11, 2026
Merged

1 commit merged into
nesquena:masterfrom
franksong2702:franksong2702/issue-2051-assistant-dedup

Conversation

@franksong2702

Copy link
Copy Markdown
Contributor

Thinking Path

  • Issue Bug: Chat responses appear twice in browser (duplicate messages) #2051 reports duplicate assistant responses in the browser.
  • The frontend done handler replaces local state with the server session payload, so if the browser renders two assistant bubbles, the first layer to check is the server-side transcript merge.
  • _merge_display_messages_after_agent_result() already avoids duplicating an eager-checkpointed current user turn, but it did not guard against the same assistant message being replayed twice in the current result delta.
  • The safe fix is narrow: skip only adjacent assistant messages with the same merge identity. This treats provider/result replay as duplicate, while preserving identical assistant text in separate user turns.

What Changed

  • Added a merge guard in api/streaming.py for adjacent duplicate assistant messages.
  • Added a regression test that reproduces the Bug: Chat responses appear twice in browser (duplicate messages) #2051 failure: a result delta containing the same assistant bubble twice now persists only one copy.
  • Added a negative-path test proving identical assistant text across different user turns is still preserved.
  • Added a changelog entry.

Why It Matters

This prevents duplicate assistant bubbles from being persisted into s.messages and then sent back to the browser in the done SSE payload. Keeping the guard adjacent-only avoids silently rewriting legitimate history where two separate turns happen to produce the same visible assistant text.

Closes #2051.

Verification

  • RED: pytest -q tests/test_session_save_mode.py::test_duplicate_assistant_delta_is_not_persisted_twice tests/test_session_save_mode.py::test_same_assistant_text_across_different_turns_is_preserved
    • failed before the fix with the duplicate assistant message still present
  • pytest -q tests/test_session_save_mode.py::test_duplicate_assistant_delta_is_not_persisted_twice tests/test_session_save_mode.py::test_same_assistant_text_across_different_turns_is_preserved
    • 2 passed
  • pytest -q tests/test_session_save_mode.py tests/test_issue1217_transcript_compaction.py tests/test_session_lineage_full_transcript.py tests/test_issue1361_cancel_data_loss.py
    • 40 passed
  • python -m py_compile api/streaming.py
  • git diff --check

Risks / Follow-ups

  • This intentionally does not global-deduplicate all assistant content. Global content dedup could drop legitimate repeated answers across different user turns.
  • If a future report involves duplicate tool-result rows, that should be handled with its own regression case rather than broadened here without evidence.

Model Used

AI-assisted with OpenAI Codex in Codex desktop. Model: GPT-5.3 Codex.

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Shipped via stage-337 → master in v0.51.44 (commit f00cb74f). Thanks @franksong2702 — third PR from you this release alone.

The adjacent-only dedup choice is the right framing: it targets the provider-replay case (#2051) without silently collapsing legitimate history where two separate turns happen to produce the same assistant text. The negative-path test test_same_assistant_text_across_different_turns_is_preserved locks that invariant.

A follow-up worth filing: the negative test only exercises content-identity collisions; a more adversarial test would include identical tool_calls shapes too (the merge identity is role + content + tool_call_id + json.dumps(tool_calls, sort_keys=True)). Not a release blocker — your test surface already covers the targeted bug class — but worth a follow-up issue if the bug recurs in any form.

Release: https://github.com/nesquena/hermes-webui/releases/tag/v0.51.44

franksong2702 pushed a commit to franksong2702/hermes-webui-fork that referenced this pull request May 11, 2026
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
Release T (v0.51.44): 5-PR batch (nesquena#2048 + nesquena#2052 + nesquena#2053 + nesquena#2055 + nesquena#1970) + test-suite network isolation
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
Release T (v0.51.44): 5-PR batch (nesquena#2048 + nesquena#2052 + nesquena#2053 + nesquena#2055 + nesquena#1970) + test-suite network isolation
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.

Bug: Chat responses appear twice in browser (duplicate messages)

2 participants