fix: preserve repeated state rows in replay delta

This commit is contained in:
Lumen Yang 2026-05-22 21:58:59 +00:00 committed by nesquena-hermes
parent 32658978a9
commit d0992730a9
2 changed files with 34 additions and 16 deletions

View file

@ -3270,21 +3270,19 @@ def state_db_delta_after_context(sidecar_context: list, state_messages: list) ->
if best_len < 2:
return state_messages
sidecar_key_set = set(sidecar_keys)
last_represented_state_index = best_len - 1
for idx, key in enumerate(state_keys[best_len:], start=best_len):
if key in sidecar_key_set:
last_represented_state_index = idx
delta = []
for msg, key in zip(
state_messages[last_represented_state_index + 1:],
state_keys[last_represented_state_index + 1:],
):
if key in sidecar_key_set:
continue
delta.append(msg)
return delta
# Drop only rows that can be aligned with the remaining sidecar context in
# order. This still tolerates stale state-only rows between mirrored context
# rows, but once the sidecar context is exhausted every later state row is a
# real delta, even if it repeats a short earlier message.
sidecar_index = best_len
state_index = best_len
while sidecar_index < len(sidecar_keys) and state_index < len(state_keys):
if state_keys[state_index] == sidecar_keys[sidecar_index]:
sidecar_index += 1
state_index += 1
if sidecar_index == len(sidecar_keys):
return state_messages[state_index:]
return state_messages[best_len:]
def merge_session_messages_append_only(sidecar_messages: list, state_messages: list) -> list:

View file

@ -4,7 +4,7 @@ import json
import sys
from types import SimpleNamespace
from api.models import Session, reconciled_state_db_messages_for_session
from api.models import Session, reconciled_state_db_messages_for_session, state_db_delta_after_context
from api.streaming import (
_assistant_reply_added_after_current_turn,
@ -513,6 +513,26 @@ def test_prefer_context_reconcile_starts_after_last_state_row_seen_in_context():
{"role": "user", "content": "new after represented boundary", "timestamp": 200.0},
]
def test_state_db_delta_preserves_fresh_rows_before_repeated_context_message():
sidecar_context = [
{"role": "user", "content": "ok"},
{"role": "assistant", "content": "ready"},
]
state_messages = [
{"role": "user", "content": "ok", "timestamp": 1.0},
{"role": "assistant", "content": "ready", "timestamp": 2.0},
{"role": "user", "content": "fresh question", "timestamp": 3.0},
{"role": "user", "content": "ok", "timestamp": 4.0},
{"role": "assistant", "content": "after repeat", "timestamp": 5.0},
]
delta = state_db_delta_after_context(sidecar_context, state_messages)
assert [m["content"] for m in delta] == ["fresh question", "ok", "after repeat"]
def test_non_streaming_chat_writeback_dedupes_full_context_replay():
previous_context = [
{"role": "assistant", "content": "cron banner"},