Context
PR #491 added validate_agent_id and gated the three MCP + CLI session-start surfaces (mem_session_start, mm session start, mm session wrap). Hostile-shaped agent_id values now produce a clear error rather than round-tripping into storage as malformed agent-runtime:foo:bar namespace strings.
The LangGraph adapter (packages/memtomem/src/memtomem/integrations/langgraph.py) builds the same namespace shape but bypasses the gate:
MemtomemStore.start_agent_session (around line 294) only checks agent_id is non-empty, then concatenates at line 299: ns = namespace or f"{_AGENT_NAMESPACE_PREFIX}{agent_id}".
- The same prefix is also concatenated at lines 171/173/190 (
MemtomemStore) and inside MemtomemCheckpointer.namespace_for.
Today the in-process Python caller can still produce agent-runtime:foo:bar records via the LangGraph adapter even though the MCP / CLI surfaces refuse them.
A separate, smaller drift point worth resolving in the same PR: langgraph.py:43 redefines _AGENT_NAMESPACE_PREFIX = "agent-runtime:" instead of importing from memtomem.constants. The redefinition predates the multi-agent shipping work and was kept on the assumption that the integration shouldn't import from MCP-side modules — but constants.py is intentionally above the MCP / CLI / integration split exactly so all three can derive from it.
What we want
- Apply
validate_agent_id at every site in langgraph.py that interpolates an agent_id into the agent-runtime namespace.
- Replace the local
_AGENT_NAMESPACE_PREFIX literal with from memtomem.constants import AGENT_NAMESPACE_PREFIX (and validate_agent_id).
- Update the validator docstring (
constants.py) to reflect that the LangGraph adapter is now wired in.
Acceptance
- All three concat sites in
langgraph.py raise InvalidNameError (or its public alias) before the malformed namespace ever reaches storage.
- Regression test (alongside the existing
test_validate_agent_id parity tests) pinning that MemtomemStore.start_agent_session(agent_id="foo:bar") cannot land an agent-runtime:foo:bar row.
- No new circular import —
langgraph.py → constants.py → context._names is one-way today.
Out of scope
- Migrating any agent ids that may already be stored from prior LangGraph use — this is a forward gate.
- The separate
mem_agent_register / mem_agent_search parity question — tracked in its own follow-up issue.
Provenance
Context
PR #491 added
validate_agent_idand gated the three MCP + CLI session-start surfaces (mem_session_start,mm session start,mm session wrap). Hostile-shapedagent_idvalues now produce a clear error rather than round-tripping into storage as malformedagent-runtime:foo:barnamespace strings.The LangGraph adapter (
packages/memtomem/src/memtomem/integrations/langgraph.py) builds the same namespace shape but bypasses the gate:MemtomemStore.start_agent_session(around line 294) only checksagent_idis non-empty, then concatenates at line 299:ns = namespace or f"{_AGENT_NAMESPACE_PREFIX}{agent_id}".MemtomemStore) and insideMemtomemCheckpointer.namespace_for.Today the in-process Python caller can still produce
agent-runtime:foo:barrecords via the LangGraph adapter even though the MCP / CLI surfaces refuse them.A separate, smaller drift point worth resolving in the same PR:
langgraph.py:43redefines_AGENT_NAMESPACE_PREFIX = "agent-runtime:"instead of importing frommemtomem.constants. The redefinition predates the multi-agent shipping work and was kept on the assumption that the integration shouldn't import from MCP-side modules — butconstants.pyis intentionally above the MCP / CLI / integration split exactly so all three can derive from it.What we want
validate_agent_idat every site inlanggraph.pythat interpolates anagent_idinto the agent-runtime namespace._AGENT_NAMESPACE_PREFIXliteral withfrom memtomem.constants import AGENT_NAMESPACE_PREFIX(andvalidate_agent_id).constants.py) to reflect that the LangGraph adapter is now wired in.Acceptance
langgraph.pyraiseInvalidNameError(or its public alias) before the malformed namespace ever reaches storage.test_validate_agent_idparity tests) pinning thatMemtomemStore.start_agent_session(agent_id="foo:bar")cannot land anagent-runtime:foo:barrow.langgraph.py → constants.py → context._namesis one-way today.Out of scope
mem_agent_register/mem_agent_searchparity question — tracked in its own follow-up issue.Provenance