Skip to content

fix(gateway): prevent session hygiene compression from overwriting original transcript - #39731

Closed
annguyenNous wants to merge 1 commit into
NousResearch:mainfrom
annguyenNous:fix/hygiene-compression-data-loss
Closed

fix(gateway): prevent session hygiene compression from overwriting original transcript#39731
annguyenNous wants to merge 1 commit into
NousResearch:mainfrom
annguyenNous:fix/hygiene-compression-data-loss

Conversation

@annguyenNous

Copy link
Copy Markdown
Contributor

Fixes #39704

Problem

When Gateway Session Hygiene triggers compression and the temporary AIAgent has _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:

  1. agent/conversation_compression.py:501_compress_context gates the entire session-rotation block on if agent._session_db:. When it's None, no new session is created and session_id remains unchanged.

  2. gateway/run.py:9277rewrite_transcript() executes unconditionally, outside the if _hyg_new_sid != session_entry.session_id block. When no rotation occurred, it overwrites the original session's messages.

Fix

gateway/run.py: Move rewrite_transcript() inside the session-rotation if block so it only runs when a new session was actually created. Add a log message in the else branch for the no-rotation case.

agent/conversation_compression.py: Add an else branch after the if agent._session_db: block that still rotates session_id even without a session DB. This ensures the gateway's existing if _hyg_new_sid != session_entry.session_id check works correctly, and the context engine notification fires with the correct old_session_id.

Verification

  • With _session_db available: behavior unchanged — old session preserved, new session gets compressed messages
  • With _session_db=None: session_id rotates, rewrite_transcript is NOT called, original transcript preserved, compressed messages used in-memory only

…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
@teknium1

Copy link
Copy Markdown
Contributor

Thanks @annguyenNous — this is a correct diagnosis of the gateway session-hygiene transcript-overwrite data-loss bug (same site you pointed at, gateway/run.py _hyg_* guard).

The same bug was fixed on main via #52658 (salvaging #50098), which reads the compaction result flag _last_compaction_in_place in the guard instead of gating on the id change. That approach also covers the /compress site and the in-place-success case (where the id is unchanged for a success reason, not a failure), which is why it was the version that landed alongside the compression.in_place default flip (#38763).

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Session Hygiene compression overwrites original messages when _session_db is None

3 participants