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:
statussearchreadrememberdigestreviseforget
Providers and adapters
MemoryPlugin
-> MemoryProvider
-> BuiltinMemoryProvider
-> MemoryStorageAdapter
-> FileMemoryStorageAdapterMemoryPlugin 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.