Built-ins

memory Plugin

Provider-neutral long-term memory, recall, and governance for Agents

memory Plugin

memory provides long-term memory for an Agent. The Plugin owns stable Actions, scope mapping, and context rules. One MemoryProvider owns memory formation, persistence, recall, revision, and deletion.

It exposes these Actions:

  • status
  • search
  • read
  • remember
  • digest
  • revise
  • forget

Providers and adapters

MemoryPlugin
  -> MemoryProvider
     -> BuiltinMemoryProvider
        -> MemoryStorageAdapter
           -> FileMemoryStorageAdapter

MemoryPlugin does not read Workspace files and does not define a physical Memory location. Files, SQLite, object storage, and remote Memory services are implementations behind a Provider.

The built-in Provider currently uses FileMemoryStorageAdapter. City stores its data here by default:

~/.downcity/agents/<agent_id>/memory/

This is a File Adapter convention, not an @downcity/agent contract. Set an absolute root_path in the Plugin configuration to override it.

City configuration

Enable the built-in Provider and File Adapter:

downcity plugin enable memory <agent_id> \
  --config '{"provider":"builtin","storage":"file"}'

Use a custom local root:

downcity plugin config memory <agent_id> \
  --set '{"provider":"builtin","storage":"file","root_path":"/absolute/path/to/memory"}'

Configuration and enabled state are stored in ~/.downcity/downcity.db. Memory content is owned by the selected Provider.

SDK usage

import {
  BuiltinMemoryProvider,
  FileMemoryStorageAdapter,
  MemoryPlugin,
} from "@downcity/plugins/memory";

const memory = new MemoryPlugin({
  provider: new BuiltinMemoryProvider({
    storage: new FileMemoryStorageAdapter({
      root_path: "/absolute/path/to/agent-memory",
    }),
  }),
});

const agent = new Agent({
  id: "assistant",
  workspace,
  plugins: [memory],
});

SDK hosts can implement MemoryProvider directly to integrate Mem0, Hindsight, Graphiti, or a custom remote Memory service.

Action usage

await agent.plugins.run_action({
  plugin: "memory",
  action: "remember",
  payload: {
    content: "The user prefers concise answers.",
    topic: "user-preferences",
    memory_type: "preference",
  },
});

Recall and exact reads use logical identifiers:

const recalled = await agent.plugins.run_action({
  plugin: "memory",
  action: "search",
  payload: {
    query: "answer style preference",
    max_results: 5,
  },
});

await agent.plugins.run_action({
  plugin: "memory",
  action: "read",
  payload: {
    memory_id: "wiki/user-preferences",
  },
});

memory_id and citation are Provider-owned logical identifiers. Callers must not interpret them as physical file paths.

CLI Actions

Use the unified Plugin Action command for a running Agent:

downcity plugin action memory status <agent_id>
downcity plugin action memory search <agent_id> --input '{"query":"project decision"}'
downcity plugin action memory read <agent_id> --input '{"memory_id":"wiki/project-decisions"}'
downcity plugin action memory forget <agent_id> --input '{"memory_id":"wiki/obsolete"}'

Key semantics

  • Session messages and checkpoints remain in the Workspace and are not long-term Memory.
  • The configured Memory Provider is the single source of truth for the Plugin instance.
  • A Storage Adapter only implements persistence primitives; it does not define recall or memory formation.
  • Providers return structured Memory and logical citations, never physical storage paths.
  • Recalled Memory is untrusted historical data and never gains system-instruction authority.