diff --git a/agent/transcript_repair.py b/agent/transcript_repair.py index c379b7d8f7..ea98d5a467 100644 --- a/agent/transcript_repair.py +++ b/agent/transcript_repair.py @@ -155,8 +155,9 @@ def resolve_and_repair_transcript_batch( adopt = transcript_row_snapshot(target_row) != expected if not adopt: serialized = serialize_message_fn(msg, float(target_row["timestamp"])) - if "token_count" not in msg: - # Replay dicts never carry token_count; a missing key means "unknown", not NULL. + if serialized["token_count"] is None: + # Replays never decode token_count (the agent flush row sets it to None): None means + # "unknown", not NULL. serialized = {**serialized, "token_count": target_row["token_count"]} if any(target_row[column] != serialized[column] for column in _OWNED_COLUMNS): _rewrite_row(conn, session_id, target_row, serialized) diff --git a/tests/hermes_state/test_unaddressed_rewrite_identity.py b/tests/hermes_state/test_unaddressed_rewrite_identity.py index 1bf7c0035b..e7e0e320bb 100644 --- a/tests/hermes_state/test_unaddressed_rewrite_identity.py +++ b/tests/hermes_state/test_unaddressed_rewrite_identity.py @@ -55,8 +55,10 @@ def test_mutated_replay_rewrites_its_original_row(db, include_row_ids, content, assert restored[0][MESSAGE_UID] == before[0]["message_uid"] assert (DB_ROW_SNAPSHOT in restored[0]) is not include_row_ids - # Real rewrite sites change the payload BEFORE clearing the persisted marker. + # Real rewrite sites change the payload BEFORE clearing the persisted marker. The agent flush row + # (session_persistence._db_flush_row) always carries the token_count key, None for a replay. restored[0]["content"] = "after repair" + restored[0]["token_count"] = None restored[0].pop(_DB_PERSISTED_MARKER, None) assert db.append_messages_batch(sid, restored) == 0