Skip to content

fix(memory): keep turns a rewind took back out of long-term memory - #7571

Open
dev-S-t wants to merge 1 commit into
google:mainfrom
dev-S-t:fix/memory-skip-rewound-events
Open

dev-S-t wants to merge 1 commit into
google:mainfrom
dev-S-t:fix/memory-skip-rewound-events

Conversation

@dev-S-t

@dev-S-t dev-S-t commented Oct 16, 2026

Copy link
Copy Markdown

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

Problem:
Runner.rewind_async keeps every event and appends a rewind event, and _apply_rewinds decides which events are still live; prompt building and compaction both use it. add_session_to_memory in all five memory services read session.events directly, so the turns a rewind took back were ingested into long-term memory, and load_memory / preload_memory handed them back to the model in later sessions. The rewind documentation says the rewound requests are ignored when the next model requests are prepared.

Solution:
add_session_to_memory in InMemoryMemoryService, SqliteMemoryService, VertexAiMemoryBankService, VertexAiRagMemoryService and FirestoreMemoryService passes _apply_rewinds(session.events) instead of session.events, the same filter the prompt and compaction paths use.

  • InMemoryMemoryService replaces a session's events on each call, so adding the session again after a rewind also drops turns stored before the rewind.
  • Not changed, to keep this to one concern: add_events_to_memory, where the caller chooses the events, and memories a remote service (Memory Bank, RAG, Firestore) already ingested before the rewind; the rewind documentation leaves external systems to the caller.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

New tests, one per service, each with a kept turn, a rewound turn and the rewind event:

  • test_in_memory_memory_service.py::test_add_session_to_memory_skips_rewound_events: search no longer finds the rewound turn, also when the session was added once before the rewind.
  • test_sqlite_memory_service.py::test_add_session_to_memory_skips_rewound_events (FTS on and off).
  • test_vertex_ai_memory_bank_service.py::test_add_session_to_memory_skips_rewound_events: only the kept event is sent to ingest_events.
  • test_vertex_ai_rag_memory_service.py::test_add_session_to_memory_skips_rewound_events: the uploaded file has the kept turn and not the rewound one.
  • test_firestore_memory_service.py::test_add_session_to_memory_skips_rewound_events: only the kept turn's keywords are written.

All 6 cases fail with the src/ change reverted and pass with it:

$ pytest tests/unittests/memory tests/unittests/integrations/firestore/test_firestore_memory_service.py
195 passed

The full tests/unittests run has no new failures: 6 more tests pass than on main, and the tests that fail locally (Windows shell, symlink and path tests) fail on main too.

Manual End-to-End (E2E) Tests:

The script in #7570 (no model or credentials needed) rewinds a two-turn session and adds it to InMemoryMemoryService and SqliteMemoryService.

Before:

events the model sees after the rewind: ['I am planning a trip to Paris.', 'Paris sounds great.']
InMemoryMemoryService recalls the undone turn: ['Actually my new address is 42 Baker Street.', 'Noted, 42 Baker Street.']
SqliteMemoryService recalls the undone turn: ['Noted, 42 Baker Street.', 'Actually my new address is 42 Baker Street.']

After:

events the model sees after the rewind: ['I am planning a trip to Paris.', 'Paris sounds great.']
InMemoryMemoryService recalls the undone turn: []
SqliteMemoryService recalls the undone turn: []

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

add_session_to_memory in the five memory services read session.events
directly, so the turns Runner.rewind_async took back were ingested, and
load_memory / preload_memory returned them in later sessions. Filter the
events with _apply_rewinds, as prompt building and compaction already do.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates various memory services (Firestore, SQLite, In-Memory, Vertex AI Memory Bank, and Vertex AI RAG) to filter out rewound events when adding a session to memory by applying the _apply_rewinds utility function. It also adds corresponding unit tests for each service to ensure that rewound events are correctly skipped and not stored. I have no additional feedback to provide as there are no review comments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

After Runner.rewind_async, add_session_to_memory still stores the rewound turns in long-term memory

2 participants