fix: preserve repeated state rows in replay delta
This commit is contained in:
parent
32658978a9
commit
d0992730a9
2 changed files with 34 additions and 16 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
|
|
|
|||
Loading…
Reference in a new issue