agent-memory
Persistent agent memory on 0G Storage — append-only JSONL blobs per namespace with keyword-indexed recall. Memories survive across restarts because they live in 0G Storage, not in-process state.
What it does
The agent-memory kit adds a persistent, namespace-scoped memory store to
your 0G app. On each operation the kit:
- Stores memory entries as append-only JSONL blobs in 0G Storage via
@foundryprotocol/0gkit-storage. Each namespace maps to a separate blob path underOG_STORAGE_NAMESPACE. - Supports two operations — append (add a new memory item) and recall
(retrieve items, optionally filtered by keyword). Both go through the
portable lib injected with a real
Storageadapter. - The
react-appadapter exposesPOST /api/memory(append) andGET /api/memory?q=<keyword>(recall) as Next.js route handlers. Themcp-agentadapter wires the same operations as MCP tools (memory_append,memory_recall).
Recall caveat: keyword filtering is a simple in-memory scan of the decoded
JSONL blob — not a vector index. It scales to moderate memory sizes
(~thousands of entries per namespace). For large corpora use a dedicated vector
store and inject it via the MemoryBackend interface.
Cold-start resume caveat: a new process loads the blob from 0G Storage on
the first recall. If the namespace blob was written by an earlier run, those
entries are recovered. If the blob does not exist (first run, or namespace
cleared), the store starts empty. The same root-pointer caveat applies here as
to durable-agent.
Compatible bases
react-app · chat · storage-app · mcp-agent
Apply
# scaffold-time
npm create 0gkit-app -- --kits agent-memory
# add to an existing project
0g add agent-memory
Environment variables
| Variable | Example | Notes |
|---|---|---|
OG_STORAGE_NAMESPACE | agent-memory | Namespace prefix for memory blobs in 0G Storage |
OG_PRIVATE_KEY | 0x... | Private key for signing 0G Storage transactions (required) |
OG_RPC_URL | https://evmrpc-testnet.0g.ai | 0G chain RPC endpoint |
Quick start
0g add agent-memory
The portable lib/ is storage-agnostic — it takes an injected MemoryStorage
(putBlob(ns, data) / getBlob(ns)). This is the exact bridge the react-app /
mcp-agent adapters build over @foundryprotocol/0gkit-storage:
import { Storage } from "@foundryprotocol/0gkit-storage";
import { createMemory, type MemoryStorage } from "./lib/agent-memory.js";
const storage = new Storage({
privateKey: process.env.OG_PRIVATE_KEY as `0x${string}`,
rpcUrl: process.env.OG_RPC_URL!,
});
// Bridge 0G Storage (content-addressed) to the mutable-namespace MemoryStorage.
const roots = new Map<string, string>();
const memStorage: MemoryStorage = {
async putBlob(ns, data) {
const { root } = await storage.upload(new TextEncoder().encode(data));
roots.set(ns, root);
},
async getBlob(ns) {
const root = roots.get(ns);
if (!root) return undefined;
const bytes = await storage.download(root);
return bytes ? new TextDecoder().decode(bytes) : undefined;
},
};
const memory = createMemory({ storage: memStorage, namespace: "memories" });
await memory.remember("user:favorite-chain", "0G");
const hits = await memory.recall("chain"); // MemoryEntry[] — { key, value, ts }
console.log(hits);
Root-persistence caveat: 0G Storage is content-addressed — every
rememberwrites a new immutable blob with a newroot. Therootsmap above lives in-process and is not durable across restarts. Persist the namespace→root pointer (another 0G blob or a database) if memory must survive a cold start.
Tiers
- lib — portable
createMemory()→AgentMemory(remember/recall/list) over an injectedMemoryStorage(no hard@foundryprotocol/*imports — deps injected by adapters). - adapters —
app/api/memory/route.tsforreact-app/chatbases (POST append + GET recall);src/tools/memory.tsformcp-agent(MCP tool pairmemory_append/memory_recall). - ui —
components/MemoryPanel.tsx(scrollable memory list + append form),hooks/useAgentMemory.ts(React hook —react-app/chatbases only).
0gkit packages used
@foundryprotocol/0gkit-storage—Storage.upload/Storage.downloadfor reading and writing the JSONL blob.
Honesty note
Memory persistence relies on 0G Storage content-addressing. Every append creates a new blob root; the adapter tracks the latest root. Without a persistent pointer to that root, a new process starts with an empty store. The blob never mutates in-place — 0G Storage is append-by-replace (a new upload returns a new root).