fix(session): preserve sidecar order in display merges

This commit is contained in:
ai-ag2026
2026-05-28 19:58:17 +02:00
parent b103f4ad68
commit 1cd58f6f5a
3 changed files with 43 additions and 0 deletions
+4
View File
@@ -3,6 +3,10 @@
## [Unreleased]
### Fixed
- Messaging/session display merges now preserve sidecar transcript order when the sidecar already contains at least as many rows as the mirrored state store, avoiding role/content fallback sorting when timestamp precision collapses.
## [v0.51.153] — 2026-05-28 — Release DY (stage-batch35 — 11-PR low-risk cleanup: title-language + clarify SSE + upload filename + discoverability + SSE reconnect + gateway image + docker docs)
### Changed
+6
View File
@@ -2223,6 +2223,12 @@ def _merged_session_messages_for_display(session, cli_messages=None) -> list:
sidecar_messages = list(getattr(session, "messages", []) or [])
if cli_messages:
if sidecar_messages and sidecar_messages != cli_messages:
if len(sidecar_messages) >= len(cli_messages):
return merge_session_messages_append_only(
sidecar_messages,
cli_messages,
truncation_watermark=getattr(session, "truncation_watermark", None),
)
merged_messages = []
seen_message_keys = set()
for msg in sorted(list(cli_messages) + list(sidecar_messages), key=lambda m: (
@@ -66,6 +66,39 @@ def test_messaging_merge_helper_dedupes_equivalent_timestamp_formats():
assert [m["content"] for m in merged] == ["hi", "same answer"]
def test_messaging_merge_preserves_longer_sidecar_order_when_timestamps_collapse():
"""A repaired messaging sidecar can preserve order but lose subsecond timestamps.
Re-sorting those messages by ``(timestamp, role, content)`` groups assistant
and tool rows before user rows, making the WebUI look like replies vanished.
"""
session = SimpleNamespace(
messages=[
{"role": "assistant", "content": "prior answer", "timestamp": 100.0},
{"role": "user", "content": "first prompt", "timestamp": 101.0},
{"role": "assistant", "content": "first answer", "timestamp": 101.0},
{"role": "user", "content": "second prompt", "timestamp": 101.0},
{"role": "assistant", "content": "second answer", "timestamp": 101.0},
]
)
cli_messages = [
{"role": "user", "content": "first prompt", "timestamp": 101.1},
{"role": "assistant", "content": "first answer", "timestamp": 101.2},
{"role": "user", "content": "second prompt", "timestamp": 101.3},
{"role": "assistant", "content": "second answer", "timestamp": 101.4},
]
merged = routes._merged_session_messages_for_display(session, cli_messages)
assert [m["content"] for m in merged] == [
"prior answer",
"first prompt",
"first answer",
"second prompt",
"second answer",
]
def test_branch_handler_uses_merged_messaging_messages_for_keep_count():
branch_idx = ROUTES_PY.index('parsed.path == "/api/session/branch":')
block = ROUTES_PY[branch_idx : branch_idx + 2600]