Skip to content

memory-lancedb: add per-agent memory isolation (agentId scoping) #15325

Description

@komalamee

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

  1. Configure multiple agents (e.g., Plumber, Kira) with memory-lancedb enabled
  2. Have a conversation with Agent A about topic X
  3. Start a new conversation with Agent B
  4. 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

  1. Add agentId field to MemoryEntry and LanceDB schema
  2. Scope search() with WHERE agentId = ? OR agentId = '' OR agentId IS NULL (backward-compatible — untagged memories remain visible to all)
  3. Tag store() with ctx.agentId from lifecycle hooks
  4. Convert tools to factory pattern (OpenClawPluginToolFactory) so memory_recall and memory_store receive agent context
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions