0Gkitdocs↗ HomePlaygroundGitHub

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:

  1. Stores memory entries as append-only JSONL blobs in 0G Storage via @foundryprotocol/0gkit-storage. Each namespace maps to a separate blob path under OG_STORAGE_NAMESPACE.
  2. 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 Storage adapter.
  3. The react-app adapter exposes POST /api/memory (append) and GET /api/memory?q=<keyword> (recall) as Next.js route handlers. The mcp-agent adapter 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

VariableExampleNotes
OG_STORAGE_NAMESPACEagent-memoryNamespace prefix for memory blobs in 0G Storage
OG_PRIVATE_KEY0x...Private key for signing 0G Storage transactions (required)
OG_RPC_URLhttps://evmrpc-testnet.0g.ai0G 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 remember writes a new immutable blob with a new root. The roots map 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 injected MemoryStorage (no hard @foundryprotocol/* imports — deps injected by adapters).
  • adaptersapp/api/memory/route.ts for react-app/chat bases (POST append + GET recall); src/tools/memory.ts for mcp-agent (MCP tool pair memory_append / memory_recall).
  • uicomponents/MemoryPanel.tsx (scrollable memory list + append form), hooks/useAgentMemory.ts (React hook — react-app / chat bases only).

0gkit packages used

  • @foundryprotocol/0gkit-storageStorage.upload / Storage.download for 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).