Grafting memory
Select broader topic context, preview it as a prompt, and copy active memory into another agent with traceable provenance.
Overview
Grafting works with topic nodes rather than only individual facts. You can assemble prompt context from explicit topics, find topics semantically, or absorb selected topic and memory nodes into another agent session.
When to use this
What you’ll build
Two agents: a research agent that learns travel preferences and a writing agent that absorbs only the relevant travel topics before composing a response.
Grafting flow
Previewing is read-only. Absorption copies active source topic nodes and their active memory rows into the target, assigns fresh IDs, and records their origin in the graft registry.
Step 1: Preview explicit topics
const topics = await sourceAgent.getActiveNodes();
const preview = await sourceAgent.graft([topics[0]!.id]);
console.log(preview.systemPrompt);Step 2: Select topics by meaning
Use expansionStrategy: none to keep only the semantic seed nodes. Graph expansion can add related temporal, semantic, or reentry neighbours.
const preview = await sourceAgent.graftByRelevance(
"Japan travel preferences",
{ topK: 5, minSimilarity: 0.6, hopDepth: 1, expansionStrategy: "graph" },
);Step 3: Absorb selected memory
const copied = await targetAgent.absorbFromAgent(sourceAgent, {
prompt: "Japan travel preferences",
minSimilarity: 0.6,
limit: 3,
});
console.log("Copied topics:", copied.length);Step 4: Inspect provenance
const registry = await targetAgent.getGraftRegistry();
console.log(registry.map(({ nodeId, sourceSessionId, sourceNodeId }) => ({
nodeId,
sourceSessionId,
sourceNodeId,
})));Full example
const research = new MemoGrafterAgent(config);
const writer = new MemoGrafterAgent(config);
await research.initialize();
await writer.initialize();
try {
await research.invoke("I am planning a Japan trip.");
await research.invoke("I prefer quiet towns, bookstores, and local cafes.");
await writer.absorbFromAgent(research, {
prompt: "Japan travel preferences",
minSimilarity: 0.55,
limit: 3,
});
console.log(await writer.invoke("Draft a short trip introduction."));
} finally {
await Promise.all([research.close(), writer.close()]);
}What is copied
Removing a graft
removeGraft() is scoped to the current agent session and only accepts nodes registered as grafts there.
const [entry] = await targetAgent.getGraftRegistry();
if (entry) await targetAgent.removeGraft(entry.nodeId);