Skip to content

feat(openclaw): per-agent memory isolation via sessionKey#4112

Closed
dominiquedutra wants to merge 1 commit intomem0ai:mainfrom
dominiquedutra:feature/openclaw-per-agent-isolation
Closed

feat(openclaw): per-agent memory isolation via sessionKey#4112
dominiquedutra wants to merge 1 commit intomem0ai:mainfrom
dominiquedutra:feature/openclaw-per-agent-isolation

Conversation

@dominiquedutra
Copy link
Copy Markdown

Problem

In multi-agent OpenClaw setups, all agents share the same userId namespace. Memories stored by one agent are recalled by another, making per-role isolation impossible without manual workarounds.

Closes #3998

Solution

Two small helper functions inside register() that route memory reads/writes to the correct userId namespace automatically — with zero breaking changes for single-agent setups.

How it works

OpenClaw session keys follow the pattern agent:<agentId>:<uuid> for sub-agents, and start with main for the primary session. The helpers extract the agentId from the session key and use it as the userId, falling back to cfg.userId for the primary session.

function extractAgentId(sessionKey: string | undefined): string | undefined {
  if (!sessionKey) return undefined;
  const match = sessionKey.match(/^agent:([^:]+):/);
  const agentId = match?.[1];
  // "main" is the primary session — fall back to configured userId
  if (!agentId || agentId === "main") return undefined;
  return agentId;
}

function effectiveUserId(sessionKey?: string): string {
  return extractAgentId(sessionKey) ?? cfg.userId;
}

sessionKey is threaded through buildAddOptions and buildSearchOptions, so every memory read/write in the before_agent_start and agent_end hooks is automatically scoped to the correct agent.

Backward compatibility

  • Single-agent setups: sessionKey is undefined or starts with main, so effectiveUserId() returns cfg.userId — behavior is unchanged.
  • Multi-agent setups: each agent automatically gets its own isolated namespace.

Changes

  • Added extractAgentId(sessionKey) helper inside register()
  • Added effectiveUserId(sessionKey) helper inside register()
  • buildAddOptions accepts optional sessionKey parameter
  • buildSearchOptions accepts optional sessionKey parameter
  • Both before_agent_start (auto-recall) and agent_end (auto-capture) hooks thread sessionId as sessionKey
  • Header updated to document the per-agent isolation feature

How to Test

  1. Configure two agents in openclaw.config.yaml, e.g. ana and clawd, both using the same mem0 plugin with the same userId.
  2. In an ana session, call the memory_store tool to store a fact: "Ana prefers concise answers".
  3. In a clawd session, call memory_search for "preferences" — the result should be empty (no cross-contamination).
  4. Back in ana, call memory_search for "preferences" — the stored fact should be returned.
  5. Verify that the primary (main) session still reads/writes under cfg.userId as before.

Production status

This patch has been running in production on a 3-agent setup for several days with a self-hosted Qdrant vector store. No regressions observed.

Adds two helper functions inside register():
- extractAgentId(sessionKey): parses agentId from the session key
  pattern agent:<agentId>:<uuid>; returns undefined for 'main' sessions
- effectiveUserId(sessionKey): returns agentId or falls back to cfg.userId

Both buildAddOptions and buildSearchOptions now accept an optional
sessionKey parameter. The before_agent_start (auto-recall) and
agent_end (auto-capture) hooks pass sessionId as sessionKey, so every
memory read/write is automatically scoped to the correct agent namespace.

Single-agent setups are unaffected: when sessionKey is absent or starts
with 'main', effectiveUserId() returns cfg.userId as before.

Fixes mem0ai#3998
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 22, 2026

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Per-agent memory isolation for openclaw-mem0 plugin

4 participants