Problem
The memory-lancedb plugin stores all memories in a single shared LanceDB table with no agent scoping. In multi-agent setups, this causes cross-agent memory bleed — Agent A recalls memories from Agent B's conversations, leading to identity confusion and context mixing.
Reproduction
- Configure multiple agents (e.g., Plumber, Kira) with
memory-lancedb enabled
- Have a conversation with Agent A about topic X
- Start a new conversation with Agent B
- Agent B's
before_agent_start auto-recall injects Agent A's memories into context
Root Cause
MemoryEntry has no agentId field
search() returns all memories regardless of which agent stored them
before_agent_start and agent_end hooks ignore ctx.agentId from PluginHookAgentContext
- Tools are registered as static instances, not via the factory pattern that receives
OpenClawPluginToolContext
Proposed Fix
- Add
agentId field to MemoryEntry and LanceDB schema
- Scope
search() with WHERE agentId = ? OR agentId = '' OR agentId IS NULL (backward-compatible — untagged memories remain visible to all)
- Tag
store() with ctx.agentId from lifecycle hooks
- Convert tools to factory pattern (
OpenClawPluginToolFactory) so memory_recall and memory_store receive agent context
- Add migration via
table.addColumns([{ name: "agentId", valueSql: "'' " }]) for existing tables
Migration Strategy
- Existing memories get
agentId = "" (empty string)
- Empty agentId memories are visible to ALL agents (no data loss)
- New memories are tagged with the active agent's ID
- Fully backward-compatible — single-agent setups see no behavior change
Plugin SDK Context
The plugin SDK already provides agent context:
PluginHookAgentContext has agentId?: string (passed to lifecycle hooks)
OpenClawPluginToolContext has agentId?: string (available via tool factory)
The plugin just needs to use these existing fields.
Workaround
We've patched the bundled plugin locally with the approach above and confirmed it works. The migration runs cleanly on existing data, and agent-scoped recall/capture works as expected.
Happy to contribute a PR if helpful.
Problem
The
memory-lancedbplugin stores all memories in a single shared LanceDB table with no agent scoping. In multi-agent setups, this causes cross-agent memory bleed — Agent A recalls memories from Agent B's conversations, leading to identity confusion and context mixing.Reproduction
memory-lancedbenabledbefore_agent_startauto-recall injects Agent A's memories into contextRoot Cause
MemoryEntryhas noagentIdfieldsearch()returns all memories regardless of which agent stored thembefore_agent_startandagent_endhooks ignorectx.agentIdfromPluginHookAgentContextOpenClawPluginToolContextProposed Fix
agentIdfield toMemoryEntryand LanceDB schemasearch()withWHERE agentId = ? OR agentId = '' OR agentId IS NULL(backward-compatible — untagged memories remain visible to all)store()withctx.agentIdfrom lifecycle hooksOpenClawPluginToolFactory) somemory_recallandmemory_storereceive agent contexttable.addColumns([{ name: "agentId", valueSql: "'' " }])for existing tablesMigration Strategy
agentId = ""(empty string)Plugin SDK Context
The plugin SDK already provides agent context:
PluginHookAgentContexthasagentId?: string(passed to lifecycle hooks)OpenClawPluginToolContexthasagentId?: string(available via tool factory)The plugin just needs to use these existing fields.
Workaround
We've patched the bundled plugin locally with the approach above and confirmed it works. The migration runs cleanly on existing data, and agent-scoped recall/capture works as expected.
Happy to contribute a PR if helpful.