fix(mcp): reuse one resident session for remember - #4582
Closed
ZaynJarvis wants to merge 1 commit into
Closed
Conversation
Every remember call minted a fresh mcp-store-<uuid> session. A session directory survives its own commit -- the live messages.jsonl is rewritten empty and the content moves to history/archive_NNN -- so each remembered fact left a permanently near-empty directory behind, holding an empty messages.jsonl plus .meta.json, .abstract.md, .overview.md and archive_001/. Use one resident session id per user. Sessions are already scoped to viking://user/<user_id>/sessions/, so a fixed id is per-user without any additional keying, and the archives now accumulate inside one directory instead of one directory per fact. This is the source of the largest class of session-directory clutter that issue #4029 proposes to sweep with a background GC. It does not replace that GC: archives still accumulate and still need a retention policy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Collaborator
Author
|
Closing. The directory-per-fact effect is real, but session directories do not enter the vector store and their .abstract.md / .overview.md are written deterministically by Session._generate_abstract / _generate_overview rather than by the semantic pipeline, so collapsing them saves neither billing nor LLM work — only clutter. The cost that does exist is one archive per commit, each with an LLM-generated Working Memory document (prompts/templates/compression/ov_wm_v2.yaml). This PR does not touch that, because remember still commits on every call. Anything worth doing here has to address commit cadence, which trades against how soon a memory becomes searchable — a separate discussion, not this two-line change. |
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.
Draft — the behaviour question in "Open question" below should be settled before this merges.
Problem
Every
remembercall minted a freshmcp-store-<uuid>session (mcp_endpoint.py:715-733).A session directory survives its own commit.
remembercommits withoutkeep_recent_count, so it takes the default0: every message moves intohistory/archive_001/, andsession.py:5279-5287then rewrites the livemessages.jsonlas an empty string. The directory stays, along with.meta.json,.abstract.mdand.overview.md.Net effect: one permanently near-empty directory per remembered fact. That is the reported "lots of empty directories, hard to read, and we bill per file" experience.
Change
Use one resident session id per user. Sessions are already scoped to
viking://user/<user_id>/sessions/, so a fixed id is per-user without any extra keying — no account, peer, or agent component needed.The diff is one constant and one assignment.
Relationship to #4029
#4029 proposes an opt-in retention/GC sweep for session directories and commit archives. This PR does not replace it — archives still accumulate inside the resident session and still need a retention policy.
What it does is remove the largest class of garbage at the source, so the GC is no longer the only thing standing between a busy deployment and unbounded directory count. Cleaning up files that never needed to exist is the wrong place to spend a background scanner.
Open question
rememberstill commits on every call, so a busy user accumulateshistory/archive_NNNinside the one resident session. Committing less eagerly would cut that too, but it changes when extraction runs and therefore when a memory becomes searchable. I have deliberately not touched that — it is a latency contract, not a cleanup detail. Worth deciding whether it belongs here or in #4029's retention work.Also worth a look: concurrent
remembercalls now share a session, so one call's commit can sweep in another's just-added messages. That is harmless for extraction (all of it is material to extract, and it produces fewer archives), but it is a real behaviour change from the isolated-session-per-call model and should be a conscious choice rather than a side effect.Tests
tests/server/test_mcp_remember_session_reuse.py, 4 cases: two calls reuse one session, the id is stable rather than random, the commit targets the session that was written to, and content still reaches the session with empty messages skipped.They stub the service and the identity contextvar directly, so unlike the rest of
tests/server/test_mcp_endpoint.pythey run without a server configuration file.Verified they fail without the fix (3 of 4 fail when the uuid id is restored).
tests/server,tests/sessionandtests/serviceshow an identical failure set with and without the change — 177 failed / 790 errors before and after, 1124 → 1128 passed. Those pre-existing failures are this machine lacking a compiledovbinary and a server config.