feat(openclaw): add per-agent memory isolation for multi-agent setups#4245
Merged
feat(openclaw): add per-agent memory isolation for multi-agent setups#4245
Conversation
Enable automatic memory namespace isolation when OpenClaw runs multiple
agents. Each agent's memories are scoped via `${userId}:agent:${agentId}`
derived from the session key, ensuring no cross-contamination.
Key changes:
- Add extractAgentId/effectiveUserId/resolveUserId helpers for session
key parsing and collision-safe namespace derivation
- Update all 4 tools (search, store, list, forget) with `agentId` param
- Update auto-recall and auto-capture hooks to pass sessionKey through
- Add --agent flag to CLI search and stats commands
- Zero breaking changes: single-agent setups always resolve to cfg.userId
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
xkonjin
reviewed
Mar 8, 2026
xkonjin
left a comment
There was a problem hiding this comment.
Quick review pass:
- Main risk area here is auth/session state and stale credential handling.
- I didn’t see targeted regression coverage in the diff; please add or point CI at a focused test for the changed path in index.ts.
- Before merge, I’d smoke-test the behavior touched by index.ts with malformed input / retry / rollback cases, since that’s where this class of change usually breaks.
Address reviewer feedback (xkonjin): extract per-agent isolation helpers (extractAgentId, effectiveUserId, agentUserId, resolveUserId) as exported pure functions for testability, add 24 focused Vitest regression tests covering malformed input, edge cases, and the resolve priority chain. Update README with per-agent isolation docs, agentId tool params, and --agent CLI examples. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gotexis
approved these changes
Mar 8, 2026
deshraj
approved these changes
Mar 9, 2026
| All memory tools (`memory_search`, `memory_store`, `memory_list`, `memory_forget`) accept an optional `agentId` parameter to query another agent's namespace: | ||
|
|
||
| ``` | ||
| memory_search({ query: "user's tech stack", agentId: "researcher" }) |
Collaborator
There was a problem hiding this comment.
This type of query pattern will restrict what kinds of filters one can do. We ideally want to support all the params that v2 search endpoint of Mem0 supports.
Collaborator
There was a problem hiding this comment.
Not sure if we want to add it as part of this PR or a separate PR.
jamebobob
pushed a commit
to jamebobob/mem0-vigil-recall
that referenced
this pull request
Mar 29, 2026
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.
Summary
Adds automatic per-agent memory namespace isolation for OpenClaw multi-agent setups. Each agent gets its own memory namespace derived from the session key, ensuring no cross-contamination between agents while maintaining full backward compatibility for single-agent users.
Problem
The current plugin treats all agents as a single user — every agent reads and writes to the same
userIdnamespace. In multi-agent setups (e.g. researcher + coder + planner), this means:memory_search,memory_store, etc.) have no awareness of which agent is calling themSolution
Per-agent namespace isolation
Session keys follow the pattern
agent:<agentId>:<uuid>. Four helper functions parse and route to collision-safe namespaces:Session key: "agent:researcher:abc-123"
→ extractAgentId() → "researcher"
→ effectiveUserId() → "utkarsh:agent:researcher"
Session key: undefined | "plain-uuid" | "agent:main:abc-123"
→ extractAgentId() → undefined
→ effectiveUserId() → "utkarsh" (unchanged — backward compatible)
The
${userId}:agent:${agentId}format prevents collisions (e.g. a user named "researcher" won't clash with an agent named "researcher").Tool-level agent support
All 4 tools gain an
agentIdparameter for explicit cross-agent operations:memory_search— search a specific agent's memoriesmemory_store— store under a specific agent's namespacememory_list— list a specific agent's memoriesmemory_forget— delete from a specific agent's namespacePriority:
agentId>userId> session-derived > configured default.CLI enhancements
openclaw mem0 search "query" --agent researcher— search a specific agent's namespaceopenclaw mem0 stats --agent researcher— view stats for a specific agentHook updates
sessionKeythroughbuildSearchOptionsso recalled memories are agent-scopedsessionKeythroughbuildAddOptionsso captured memories go to the correct namespaceBackward Compatibility
Zero breaking changes. Single-agent users are unaffected because their session keys are either:
undefined→ falls back tocfg.userIdagent:prefix → falls back tocfg.userIdagent:main:<uuid>→"main"is explicitly treated as the primary session → falls back tocfg.userIdAll paths resolve to the same
cfg.userIdthey always did.Testing
--agentflag on search/stats)Key tests verified:
Checklist:
Related
effectiveUserId()returns the rawagentId(e.g."researcher") instead of a namespaced${userId}:agent:${agentId}. This means an agent named"researcher"collides with a real user named"researcher", and agents with the same name across different users share memories.memory_search,memory_store,memory_list,memory_forget) still route to the globalcfg.userId, bypassing isolation entirely for explicit tool calls.--agentflag onopenclaw mem0 searchoropenclaw mem0 stats, so operators cannot inspect per-agent memories.register()with no way to unit test. This PR exports them as standalone functions with 21 unit tests.Maintainer Checklist