Vercel AI SDK & OpenAI SDK
One line gives an existing agent MindGraph memory: withMindGraph() recalls relevant memory before every model call and captures the exchange after it, and it never blocks or breaks the call — if MindGraph is slow or down the request proceeds without memory within a fixed deadline (5 seconds by default).
Everything captured lands in the same typed, versioned, cited graph the dashboard, SDKs and MCP server use. Every memory has a uid you can open in the Explorer.
npm install mindgraph-tools mindgraph
Set MINDGRAPH_API_KEY (an organization API key with the write scope) and optionally MINDGRAPH_URL.
Vercel AI SDK
withMindGraph(model, options) wraps any language model with middleware. It works with generateText, streamText, agents and tool loops.
import { generateText } from "ai"
import { openai } from "@ai-sdk/openai"
import { withMindGraph } from "mindgraph-tools"
const model = withMindGraph(openai("gpt-5.4-mini"), { agentId: "support-bot" })
const { text } = await generateText({
model,
prompt: "Where do we deploy the API?",
})
What happens on each call:
- Recall. The latest user message becomes a bounded
/retrieve/contextquery (12 graph nodes, cheapest-first graph expansion, no raw chunks). The result is rendered compactly (labels, summaries, relationships, supersession flags) and inserted as a user-role message immediately before the latest user turn, wrapped in<mindgraph-memory>tags. Useinject: "system"to append it to the system prompt instead. - Model call. Unchanged.
- Capture. The user/assistant exchange is stored through
POST /memory/rememberwith a deterministiccustom_id(a hash of the exchange), so a retried or replayed call upserts the same memory instead of duplicating it. Captures are batched (10 items or 2 seconds).
A tool loop calls the model several times with the same last user message; recall runs once for it and is reused.
Serverless: flush before the function freezes
import { MindGraphMemory, withMindGraph } from "mindgraph-tools"
const memory = new MindGraphMemory({ agentId: "support-bot" })
const model = withMindGraph(openai("gpt-5.4-mini"), memory)
// ... after generateText / streamText:
waitUntil(memory.flush())
Options
| Option | Default | Meaning |
|---|---|---|
mode | "query" | profile and full are accepted and degrade to query (with one onError warning) until the /memory/profile endpoint ships. |
inject | "user" | Where the memory block goes: a user-role message before the latest user turn, or appended to the system prompt. |
capture | true | false disables capture; { minChars, batchSize, batchDelayMs } tunes it. Exchanges under 32 characters combined are skipped. |
nodeLimit, maxChars | 12, 4000 | Recall size: graph nodes requested and rendered-character cap (whole items only; an omission marker says how many were dropped). |
timeoutMs | 5000 | Per-request deadline; past it the call proceeds without memory. |
projectUid | — | Restrict recall to a Project's corpus. |
spaceUid | — | Write memories into an explicit Space (for example space:agent:<id>). |
principalId | — | Recorded on captured memories for per-user provenance. |
agentId | "mindgraph-tools" | Attribution on writes (authority comes from the API key). |
onError, onRecall | — | Observe swallowed errors and every recall (misses included). |
OpenAI SDK
The same wrapper, as a proxy over the OpenAI client. It intercepts chat.completions.create and responses.create (streaming included); everything else on the client passes through untouched.
import OpenAI from "openai"
import { withMindGraph } from "mindgraph-tools/openai"
const openai = withMindGraph(new OpenAI(), { agentId: "support-bot" })
const response = await openai.responses.create({
model: "gpt-5.4",
input: "Where do we deploy the API?",
})
console.log(response.output_text)
For responses.create, a string input becomes [memory, input]; an array input gets the memory item before the latest user item; with inject: "system" the block is appended to instructions.
Honest limits
- Recall proves MindGraph returned context; it does not prove the model used it. Ask the model to cite when it matters.
profilemode is a placeholder until M1 ships; today every mode is query recall.- The wrapper runs on Node (Vercel functions, servers); it uses
node:cryptofor the deterministic ids, so it is not for edge runtimes yet.
See also
- Remember & Forget — the fast path the wrapper writes through.
- eve provider — the same core as a memory slot for Vercel's eve.
- Retrieval latency, measured — what the recall step costs in production.