You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Short-term memory is process-local: recent episodes are never reloaded, replicas diverge, and the persisted summary is last-writer-wins #1748
ShortTermMemory keeps its recent episodes in a deque in process memory (episodic_memory/short_term_memory/short_term_memory.py:123-129). create() reloads only the summary and carries the comment # ToDo: Retrieve the episodes from raw data storage (:157-173). The consolidator's summary, pending episodes and worker task are per instance (:502-524). The summary is persisted by save_short_term_memory, which is SELECT then UPDATE-or-INSERT with no upsert and no lock (common/session_manager/session_data_manager_sql_impl.py:378-424).
With the default session_manager.instance_cache_size: 0 (common/configuration/__init__.py:75-79) the instance closes when its last reference drops (episodic_memory/instance_lru_cache.py:208-218), so even on one process every request starts with an empty recent window. Only the summary survives, and only if summarization ran.
With a cache, each replica holds its own deque for the same session and answers short-term queries from the episodes it received itself. Each replica's consolidator builds a summary on top of its own copy and overwrites the others'. Two replicas' first saves can both INSERT; the loser's IntegrityError is not in the caught set (:647) and reaches the summary loop's catch-all, so that replica's summary is never set.
Either short-term memory is declared a single-process component and a multi-replica deployment refuses or disables it, or its state lives in the database: episodes reloaded on open, summary saved by an upsert keyed on session and sequence. #1719 covers its cancellation and reset defects; this issue is the cross-replica one.
Notes
Code read at d6068cdbf (main), paths under packages/server/src/memmachine_server/. Short-term memory is not needed for horizontal scaling, so removal is acceptable; the issue records the decision so it is explicit rather than silent.
What happened
ShortTermMemorykeeps its recent episodes in adequein process memory (episodic_memory/short_term_memory/short_term_memory.py:123-129).create()reloads only the summary and carries the comment# ToDo: Retrieve the episodes from raw data storage(:157-173). The consolidator's summary, pending episodes and worker task are per instance (:502-524). The summary is persisted bysave_short_term_memory, which is SELECT then UPDATE-or-INSERT with no upsert and no lock (common/session_manager/session_data_manager_sql_impl.py:378-424).session_manager.instance_cache_size: 0(common/configuration/__init__.py:75-79) the instance closes when its last reference drops (episodic_memory/instance_lru_cache.py:208-218), so even on one process every request starts with an empty recent window. Only the summary survives, and only if summarization ran.IntegrityErroris not in the caught set (:647) and reaches the summary loop's catch-all, so that replica's summary is never set.ShortTermMemory.createcallsdata_manager.create_tables()on every instance build (:159-162), which with cache size 0 is every add or search. Schema provisioning runs from every process's boot path: create_all races on cold boot and never evolves a table, Alembic runs destructive migrations on first use #1570 covers the DDL side.Expected
Either short-term memory is declared a single-process component and a multi-replica deployment refuses or disables it, or its state lives in the database: episodes reloaded on open, summary saved by an upsert keyed on session and sequence. #1719 covers its cancellation and reset defects; this issue is the cross-replica one.
Notes
Code read at
d6068cdbf(main), paths underpackages/server/src/memmachine_server/. Short-term memory is not needed for horizontal scaling, so removal is acceptable; the issue records the decision so it is explicit rather than silent.🤖 Written by Claude Code (Claude Fable 5.1) on behalf of @edwinyyyu.