fix(memory): keep max_msg_id valid when an overwrite rollback empties the cache - #994
Open
Linxiushen wants to merge 1 commit into
Open
Linxiushen wants to merge 1 commit into
Linxiushen wants to merge 1 commit into
Conversation
… the cache DefaultMemory._delete_single() recomputes max_msg_id with max(self.cache_messages.keys()) after popping the entry that held it. In history_mode='overwrite', add() rolls back every cached block from the first mismatching one; when the very first block mismatches (a new conversation reusing the same store, or an edited history) the last entry is deleted too, the dict is empty and max() raises ValueError, which propagates out of add() and ends the agent run as unrecoverable. Use the same -1 empty-store sentinel load_cache() sets, so the next block is numbered from 0 exactly as on a fresh store.
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.
Change Summary
DefaultMemory._delete_single()(ms_agent/memory/default_memory.py) recomputesmax_msg_idwithmax(self.cache_messages.keys())after popping the entry that held the maximum. Withhistory_mode='overwrite',add()rolls back every cached block starting from the first one whose hash no longer matches the incoming history. When the very first block mismatches — a second conversation reusing the same memory directory, or an edited/cleared history — the last cached entry is deleted as well, the dict is empty, andmax()raises:The exception leaves
add()uncaught, reachesrun_loop's handler asErrorRaised(recoverable=False)and terminates the whole agent run. It is not hit with the defaulthistory_mode='add'; it needshistory_mode: overwritein the memory config (the mode has its own test,test_overwrite_with_tool, which only covers a partial rollback where block 0 still matches).Fix:
max(self.cache_messages.keys(), default=-1).-1is the sentinelload_cache()already uses for an empty store, soadd_single()'sself.max_msg_id += 1numbers the next block from 0 exactly as on a fresh store; verified that "full rollback, then add a block" ends in the same state as "add the same block to a new store" (cache keys,max_msg_id, block hash,memory_snapshot).Tests:
tests/memory/test_default_memory_rollback.py— two cases (second session with a different first turn; rollback that empties the cache and re-adds), withmem0stubbed since only the cache bookkeeping is under test. Both fail onmainwith theValueErrorabove and pass with the change. A differential over the well-formed overwrite/add scenarios (build 3 blocks, resubmit same history, partial rollback, tail rollback, reload from disk, delete a non-max id) produces identical state dumps before and after;pytest tests/memorygoes from 176 to 178 passed with the same pre-existing environment failures.flake8 / isort / yapf (repo
setup.cfg) clean on the changed lines (E126/W604reported elsewhere in the file pre-exist onmain).Related issue number
None found (searched
max_msg_id,_delete_single,history_mode,overwrite,max() iterable).Checklist
pre-commitchecks (flake8 / isort / yapf fromsetup.cfg) pass on the changed filesWritten with Claude Code (AI-assisted) and submitted under the account owner's authorization.