fix(gateway): prevent session hygiene compression from overwriting original transcript - #39731
Conversation
…iginal transcript When the hygiene agent has _session_db=None, _compress_context skips session rotation but the gateway unconditionally calls rewrite_transcript(), permanently overwriting the original messages with compressed ones. Fix: move rewrite_transcript inside the session-rotation branch in gateway/run.py so it only executes when a new session was created. Additionally, rotate the session_id in conversation_compression.py even when _session_db is None, so the gateway can always distinguish old vs new transcripts. Fixes NousResearch#39704
|
Thanks @annguyenNous — this is a correct diagnosis of the gateway session-hygiene transcript-overwrite data-loss bug (same site you pointed at, The same bug was fixed on main via #52658 (salvaging #50098), which reads the compaction result flag Your fix and the merged one solve the identical data-loss class. Closing as superseded — credit to you for the independent diagnosis. The transcript-overwrite path is now guarded on main. |
Fixes #39704
Problem
When Gateway Session Hygiene triggers compression and the temporary
AIAgenthas_session_db=None, the original session's messages are permanently overwritten with compressed ones. This is a data loss bug — the uncompressed transcript is gone forever.Root cause: Two code paths interact incorrectly:
agent/conversation_compression.py:501—_compress_contextgates the entire session-rotation block onif agent._session_db:. When it'sNone, no new session is created andsession_idremains unchanged.gateway/run.py:9277—rewrite_transcript()executes unconditionally, outside theif _hyg_new_sid != session_entry.session_idblock. When no rotation occurred, it overwrites the original session's messages.Fix
gateway/run.py: Moverewrite_transcript()inside the session-rotationifblock so it only runs when a new session was actually created. Add a log message in theelsebranch for the no-rotation case.agent/conversation_compression.py: Add anelsebranch after theif agent._session_db:block that still rotatessession_ideven without a session DB. This ensures the gateway's existingif _hyg_new_sid != session_entry.session_idcheck works correctly, and the context engine notification fires with the correctold_session_id.Verification
_session_dbavailable: behavior unchanged — old session preserved, new session gets compressed messages_session_db=None: session_id rotates,rewrite_transcriptis NOT called, original transcript preserved, compressed messages used in-memory only