Chatbot memory
Give a server-side chatbot durable, relevant memory that is recalled before later responses and learned incrementally after each exchange.
Overview
MemoGrafterAgent combines conversational history with graph-backed long-term memory. Each call to invoke() can recall relevant active facts, send them to the configured language model, and schedule the completed exchange for incremental ingestion.
The agent owns one generated session ID. Reuse the same agent instance for the active conversation; creating a new agent creates an independent session.
When to use this
What you’ll build
Request lifecycle
The foreground response and write-side memory pipeline are connected but distinct. The first turn may have nothing to recall; later turns can use graph memory after ingestion has created it.
Step 1: Create one agent
Construct the agent in server code and initialize it after the database has been migrated. Keep the instance alive for the active conversation.
import {
MemoGrafterAgent,
OpenAIEmbedAdapter,
OpenAILLMAdapter,
} from "memo-grafter";
const llm = new OpenAILLMAdapter("gpt-4o");
const embedder = new OpenAIEmbedAdapter("text-embedding-3-small");
const agent = new MemoGrafterAgent({
db: { connectionString: process.env.DATABASE_URL! },
llm,
embedder,
});
await agent.initialize();Step 2: Send turns through invoke()
invoke() owns the normal chat path. Do not manually ingest the same user and assistant turns afterward; that exchange is already scheduled for ingestion.
const first = await agent.invoke("My name is Alice.");
const second = await agent.invoke("I prefer concise answers.");
const answer = await agent.invoke("What is my name, and how should you answer?");
console.log(answer);Step 3: Close cleanly
Close the agent during graceful shutdown. Reads that depend on memory state and close() wait for the agent’s pending ingestion work.
process.once("SIGTERM", async () => {
await agent.close();
process.exit(0);
});Full example
import {
MemoGrafterAgent,
OpenAIEmbedAdapter,
OpenAILLMAdapter,
} from "memo-grafter";
const llm = new OpenAILLMAdapter("gpt-4o");
const embedder = new OpenAIEmbedAdapter("text-embedding-3-small");
const agent = new MemoGrafterAgent({
db: { connectionString: process.env.DATABASE_URL! },
llm,
embedder,
});
await agent.initialize();
try {
console.log(await agent.invoke("My name is Alice."));
console.log(await agent.invoke("I prefer concise answers."));
console.log(await agent.invoke("What is my name, and how should you answer?"));
} finally {
await agent.close();
}Expected conversation
Alice first supplies an identity fact, then a response preference. On a later question, the agent can retrieve those active memories and the assistant can answer that her name is Alice and that replies should be concise.
How invoke() works
Best practices
MemoGrafterAgent for the active conversation.close() during graceful shutdown.MemoGrafter directly when the application must supply and reopen explicit session IDs.Common mistakes
ingestText() for the same exchange after invoke().