fix(memory): avoid re-shipping retained turns on session switch - #88358
Closed
rafpigna wants to merge 1 commit into
Closed
fix(memory): avoid re-shipping retained turns on session switch#88358rafpigna wants to merge 1 commit into
rafpigna wants to merge 1 commit into
Conversation
Hindsight's on_session_switch() flush re-shipped the entire _session_turns buffer regardless of the append watermark. On append-capable APIs, once a boundary retain persisted turns 1..N, a later session switch (/new, /reset, /undo, context compression) appended the whole buffer again — duplicating already-retained turns into the same document. The flush now only ships the delta since the last retain boundary on append-capable APIs, re-sends the full session on overwrite APIs (where each retain replaces the document), and skips entirely when nothing new is buffered — so no already-retained turn is ever re-shipped at switch time. Adds a test asserting a switch after a boundary retain ships only the partial block, and seeds the retain watermark in the session-switch test helper.
Collaborator
Duplicate of #41911: both fix the same Hindsight session-switch append-watermark flush, sending only the unretained delta. |
Author
|
Thank you for the triage note. You are right — I missed #41911 when I searched I'll close this PR. Please go ahead with #41911. If it is useful, I'm happy to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes a silent data-duplication bug in the Hindsight memory provider's
on_session_switch()flush path.With
retain_every_n_turns > 1and an append-capable Hindsight API(≥ 0.5.0),
sync_turn()persists a delta at every Nth-turn boundary andadvances the append watermark. The
on_session_switch()flush, however,re-shipped the entire
_session_turnsbuffer regardless of thatwatermark. So once turns 1..N had already been retained at a boundary, a
later session switch (
/new,/reset,/undo, context compression)would append the whole buffer again into the same document — silently
duplicating already-retained turns.
The fix makes the switch flush respect the watermark: on append-capable
APIs it ships only the delta since the last boundary, on overwrite APIs it
re-sends the full session (each retain replaces the document there), and it
skips entirely when nothing new is buffered — so no already-retained turn
is ever re-shipped at switch time.
Related Issue
N/A — reported in this PR. (Note: several sibling PRs on the general
Hindsight turn-flush topic are open upstream — e.g.
#77454,#55936,#55046,#80503. Those target the shutdown/session-exit data-loss class;this PR targets a distinct defect: the session-switch flush re-shipping
already-retained turns. None of the open PRs address this duplication, and
one (
#55936) explicitly preserves the "switch sends all turns" behaviorthat this PR corrects.)
Type of Change
Changes Made
plugins/memory/hindsight/__init__.py: inon_session_switch(), thebuffered-turn flush now computes
turns_since_retainfrom the appendwatermark, ships only the delta on append-capable APIs (full session on
overwrite APIs), and no-ops when nothing new is buffered — instead of
always re-shipping every buffered turn.
tests/plugins/memory/test_hindsight_provider.py: newTestSessionSwitchBufferFlushNoReshiptest — after a boundary retainpersisted turns 1..N, a switch must flush only the partial block (N+1..),
never re-shipping already-retained turns.
tests/agent/test_memory_session_switch.py: seeds the retain watermark(
_last_retained_turn_count) in the bare-provider test helper, whichon_session_switch()now reads.How to Test
pytest):retain_every_n_turns > 1on an append-capable server, run past oneretain boundary (so the watermark advances), buffer a few more turns,
then call
on_session_switch(). Before the fix the flush carries thewhole buffer (duplicating turns 1..N in the document); after the fix it
carries only the partial block.
Checklist
Code
fix(scope):)scripts/run_tests.sh(wholetests/plugins/memory/+tests/agent/test_memory_session_switch.py): 343 passed, 0 failedDocumentation & Housekeeping
on_session_switch())cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
Test run (canonical runner, reduced scope — the three prior shutdown tests
were intentionally dropped from this PR since that work is covered by
sibling open PRs):
AI Tools were used to speed-up the development. Tools used are 100%
compatible with the project license.