From eac9b473a91b2f63a4366a3fdb5837e4b5c7a54a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 01:39:50 +0000 Subject: [PATCH] feat: per-agent memory isolation for openclaw-mem0 plugin Co-authored-by: deshraj <2945708+deshraj@users.noreply.github.com> --- openclaw/index.ts | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/openclaw/index.ts b/openclaw/index.ts index f895ce5f0..10c948646 100644 --- a/openclaw/index.ts +++ b/openclaw/index.ts @@ -616,6 +616,22 @@ const memoryPlugin = { // Track current session ID for tool-level session scoping let currentSessionId: string | undefined; + // Track current agent ID for per-agent memory isolation + let currentAgentId: string | undefined; + + // Helper: extract agentId from session key (pattern: agent::...) + // Returns undefined for the "main" agent to preserve default behavior. + function extractAgentId(sessionKey: string): string | undefined { + const match = sessionKey.match(/^agent:([^:]+):/); + return match && match[1] !== "main" ? match[1] : undefined; + } + + // Helper: get effective userId for Mem0 operations. + // Precedence: explicit override > current agentId (non-main) > configured userId. + function effectiveUserId(userIdOverride?: string): string { + return userIdOverride || currentAgentId || cfg.userId; + } + api.logger.info( `openclaw-mem0: registered (mode: ${cfg.mode}, user: ${cfg.userId}, graph: ${cfg.enableGraph}, autoRecall: ${cfg.autoRecall}, autoCapture: ${cfg.autoCapture})`, ); @@ -623,7 +639,7 @@ const memoryPlugin = { // Helper: build add options function buildAddOptions(userIdOverride?: string, runId?: string): AddOptions { const opts: AddOptions = { - user_id: userIdOverride || cfg.userId, + user_id: effectiveUserId(userIdOverride), source: "OPENCLAW", }; if (runId) opts.run_id = runId; @@ -643,7 +659,7 @@ const memoryPlugin = { runId?: string, ): SearchOptions { const opts: SearchOptions = { - user_id: userIdOverride || cfg.userId, + user_id: effectiveUserId(userIdOverride), top_k: limit ?? cfg.topK, limit: limit ?? cfg.topK, threshold: cfg.searchThreshold, @@ -935,7 +951,7 @@ const memoryPlugin = { try { let memories: MemoryItem[] = []; - const uid = userId || cfg.userId; + const uid = effectiveUserId(userId); if (scope === "session") { if (currentSessionId) { @@ -1236,9 +1252,12 @@ const memoryPlugin = { api.on("before_agent_start", async (event, ctx) => { if (!event.prompt || event.prompt.length < 5) return; - // Track session ID + // Track session ID and agent ID const sessionId = (ctx as any)?.sessionKey ?? undefined; - if (sessionId) currentSessionId = sessionId; + if (sessionId) { + currentSessionId = sessionId; + currentAgentId = extractAgentId(sessionId); + } try { // Search long-term memories (user-scoped) @@ -1303,9 +1322,12 @@ const memoryPlugin = { return; } - // Track session ID + // Track session ID and agent ID const sessionId = (ctx as any)?.sessionKey ?? undefined; - if (sessionId) currentSessionId = sessionId; + if (sessionId) { + currentSessionId = sessionId; + currentAgentId = extractAgentId(sessionId); + } try { // Extract messages, limiting to last 10