Skip to content

Shared memory database with per-agent namespaces for multi-agent architecture #676

@kovtcharov

Description

@kovtcharov

Problem

The current MemoryStore (#542) is designed for a single monolithic agent. The GaiaAgent architecture (#674) introduces multiple agents (GaiaAgent + DocAgent + FileAgent + ShellAgent + WebAgent + future use-case agents) that all need persistent memory — but with per-agent isolation AND cross-agent visibility.

Design: Shared Database, Per-Agent Namespaces

One database (~/.gaia/memory.db) accessible by all agents, with per-agent tables that track each agent's own state, plus shared tables for cross-agent data.

Per-Agent Tables (namespaced by agent_id)

Each agent automatically gets its own namespace for:

-- Conversations: each agent tracks its own interactions
CREATE TABLE agent_conversations (
    id TEXT PRIMARY KEY,
    agent_id TEXT NOT NULL,          -- "gaia", "doc_expert", "file_expert", etc.
    session_id TEXT,
    role TEXT,                       -- "user", "assistant", "system"
    content TEXT,
    context TEXT,                    -- JSON: what task, who delegated, etc.
    created_at TIMESTAMP
);
CREATE INDEX idx_agent_conv ON agent_conversations(agent_id, created_at);

-- Tool calls: each agent tracks its own tool usage
CREATE TABLE agent_tool_history (
    id TEXT PRIMARY KEY,
    agent_id TEXT NOT NULL,
    tool_name TEXT,
    tool_args TEXT,                  -- JSON
    result TEXT,
    success BOOLEAN,
    duration_ms INTEGER,
    error TEXT,
    task_id TEXT,                    -- Which task triggered this (#675)
    created_at TIMESTAMP
);
CREATE INDEX idx_agent_tools ON agent_tool_history(agent_id, tool_name);

-- Tasks: each agent tracks tasks it created or was assigned
CREATE TABLE agent_tasks (
    id TEXT PRIMARY KEY,
    agent_id TEXT NOT NULL,          -- Agent that owns/was assigned this task
    created_by TEXT NOT NULL,        -- Agent that created the task
    title TEXT,
    status TEXT DEFAULT 'pending',
    context TEXT,                    -- JSON
    result TEXT,                     -- JSON
    created_at TIMESTAMP,
    completed_at TIMESTAMP
);

-- Insights: each agent tracks what it has learned
CREATE TABLE agent_insights (
    id TEXT PRIMARY KEY,
    agent_id TEXT NOT NULL,
    category TEXT,                   -- "preference", "fact", "pattern", "error", "skill"
    content TEXT,
    confidence REAL DEFAULT 0.5,
    source TEXT,                     -- "user_correction", "observed_pattern", "task_outcome"
    context TEXT,                    -- JSON: when/where this was learned
    created_at TIMESTAMP,
    last_accessed_at TIMESTAMP
);
CREATE INDEX idx_agent_insights ON agent_insights(agent_id, category);

Shared Tables (cross-agent)

-- User profile: shared across all agents
-- GaiaAgent writes preferences, specialists read them
CREATE TABLE user_profile (
    key TEXT PRIMARY KEY,
    value TEXT,
    source_agent TEXT,               -- Which agent learned this
    confidence REAL,
    updated_at TIMESTAMP
);

-- Agent directory: who exists and what they can do
-- Syncs with Agent Registry (#612)
CREATE TABLE agent_directory (
    agent_id TEXT PRIMARY KEY,
    display_name TEXT,
    capabilities TEXT,               -- JSON: list of capabilities
    model TEXT,
    status TEXT,                     -- "active", "idle", "unavailable"
    last_active_at TIMESTAMP
);

Access Patterns

class AgentMemory:
    """Per-agent memory interface. Each agent gets its own instance."""
    
    def __init__(self, agent_id: str, db: MemoryStore):
        self.agent_id = agent_id
        self.db = db
    
    # --- Own data (scoped to this agent) ---
    def log_conversation(self, role, content, context=None): ...
    def log_tool_call(self, tool, args, result, success, duration): ...
    def store_insight(self, category, content, source): ...
    def get_my_insights(self, category=None, limit=20): ...
    def get_my_tool_history(self, tool=None, limit=50): ...
    
    # --- Cross-agent data (read any agent's data) ---
    def get_agent_insights(self, agent_id, category=None): ...
    def search_all_conversations(self, query, agent_id=None): ...
    def get_user_profile(self, key=None): ...
    def update_user_profile(self, key, value): ...
    
    # --- Agent discovery ---
    def list_agents(self, status=None): ...
    def get_agent_capabilities(self, agent_id): ...

How Each Agent Uses Memory

GaiaAgent (orchestrator):

  • Writes: user preferences, personality observations, delegation patterns
  • Reads: all agent insights (to know what specialists have learned), user profile
  • Learns: "User prefers concise responses", "DocAgent works better for financial docs"

DocAgent (specialist):

  • Writes: document quality observations, query patterns, indexing results
  • Reads: user profile (to know context), own previous tool history
  • Learns: "This document has poor OCR quality", "User frequently asks about Q3 revenue"

FileAgent (specialist):

  • Writes: file access patterns, bookmark history, frequently accessed paths
  • Reads: user profile, own tool history
  • Learns: "User's project files are in ~/Work/", "CSV files are usually in ~/data/"

Any agent can read any other agent's insights — this is how the system builds collective intelligence. DocAgent learns about document quality, GaiaAgent reads that insight and tells the user "That PDF has poor OCR — results may be less accurate."

All-to-All Memory Visibility

GaiaAgent writes: "User prefers morning briefings"
  → EmailAgent reads this → schedules digest for 8am
  → CalendarAgent reads this → includes daily agenda

DocAgent writes: "sales_report.pdf has 45 indexed chunks"
  → GaiaAgent reads this → tells user "Your sales report is ready to query"
  → FileAgent reads this → knows not to re-index this file

FileAgent writes: "User frequently accesses ~/Work/gaia4/"
  → GaiaAgent reads this → suggests "Want me to index your GAIA project?"
  → ShellAgent reads this → uses as default working directory

Integration with Existing Issues

Dependencies

Acceptance Criteria

  • Each agent has isolated namespace for conversations, tools, tasks, insights
  • Any agent can read any other agent's insights (cross-agent visibility)
  • User profile is shared and writable by any agent
  • FTS5 search works across all agents or scoped to one
  • Tool calls auto-logged with agent_id
  • Task completion results auto-stored in memory
  • Memory survives agent restarts (SQLite persistence)
  • Concurrent access safe (WAL mode + threading.Lock per existing MemoryStore: persistent memory data layer (SQLite + FTS5) #542 design)

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentdomain:agent-coreFramework, tools, registry, memory, skills, orchestrationenhancementNew feature or requestp0high prioritytrack:consumer-appHermes-competitor consumer product — mobile-first, voice + messaging + memory + skills

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions