Skip to main content
pb.memory stores memory as graph state, so what an agent learns is queryable structure rather than opaque text. Memory lives on its own plane, separate from your canonical graph. The loop is remember (write one), observe (learn from a completed interaction), recall (read as a graph), synthesize (turn recalled memory into a briefing), and archive (retire stale memory).

remember

Write a single memory. The default memory shape governs the fields (kind, scope, subject, dateObserved, sourceContext, and more). To capture memory specific to your domain, fork that shape and pass its shapeId.
await pb.memory.remember({
  kind: "preference",
  content: "The user prefers short briefings with explicit caveats.",
});
The write commits immediately. Pass apply: false to stage it as a delta first. For memory that should expire, pass forget_after (a timestamp) and an optional forget_reason. The memory stays recallable until then, with the reason on the record.
Over REST this is the /v1/memories facade: POST /v1/memories to write (a single memory or a batch of up to 100), POST /v1/memories/search to read. recall is the SDK and agent-tool verb; the public REST verb is search. Both read the same memory plane.

observe

Learn from a completed interaction: pass the transcript or events and a perspective shape to extract memory from it.
await pb.memory.observe({
  source: { kind: "interaction", text: conversationTranscript },
  perspective: { shapeId: "shp_user_preferences" },
});
observe runs a full extraction under the hood — it is the model-spend path, in exchange for pulling many memories out of one transcript. Use remember for single, explicit writes.

recall

Read relevant memory back as a graph object.
const memory = await pb.memory.recall({
  query: "what should be known before continuing?",
  limit: 5,
});

console.log(memory.toMarkdown());
console.log(memory.nodes, memory.edges);
recall returns a MemoryGraph with nodes, edges, and count, plus toMarkdown(), toYAML(), and toJSON() renderings. By default it reads the memory plane; pass planes to widen it (for example planes: ["memory", "archival"]).

synthesize

Turn recalled memory into a prose briefing, optionally shaped to a target type.
const briefing = await pb.memory.synthesize({
  query: "what should be known before the next step?",
  as: { type: "SituationBriefing", purpose: "agent-handoff" },
});

console.log(briefing.toMarkdown());
synthesize returns a MemoryBriefing with text, markdown, and the underlying graph. You can pass a briefing straight into pb.dq.trace to check its evidence coverage.

archive

Retire a memory that is stale or no longer true.
await pb.memory.archive(memoryNodeId, {
  reason: "Superseded by a newer preference.",
});
remember, observe, and archive are writes: they commit through a governed delta, like everything else that changes the graph. Pass apply: false to stage one without committing.