withMemWal
withMemWal is drop-in memory middleware for Vercel AI SDK apps. It recalls relevant memories before generation and optionally saves new facts after generation.
import { generateText } from "ai";
import { withMemWal } from "@mysten-incubation/memwal/ai";
import { openai } from "@ai-sdk/openai";
const model = withMemWal(openai("gpt-4o"), {
key: "<your-ed25519-private-key>",
accountId: "<your-memwal-account-id>",
serverUrl: "https://your-relayer-url.com",
namespace: "chatbot-prod",
maxMemories: 5,
autoSave: true,
});
const result = await generateText({
model,
messages: [{ role: "user", content: "What do you know about me?" }],
});
The example sets autoSave: true explicitly, but autoSave is optional and defaults to true.
What it does
Before generation:
- Reads the last user message
- Runs
recall()against Walrus Memory - Filters by relevance, returning at most the
maxMemoriesset in the options (maxMemories: 5in the example above) - Injects memory context into the prompt
After generation:
- Optionally runs
analyze()on the user message - Saves extracted facts asynchronously
Set a namespace explicitly for each product surface that uses the middleware. Otherwise recalled
and auto-saved memories fall back to "default".
When to use direct SDK calls instead
Use direct SDK methods when your app needs precise control over:
- When memory is stored
- Which text is analyzed
- How recall results are displayed or filtered
When does auto-save run?
When autoSave is true, the middleware saves only on the first step of a user turn, when the prompt ends with a user message. It skips intermediate tool steps where the last message comes from a tool or the assistant. On a qualifying step, the middleware takes the last user message and passes it to analyze(). Since SDK 0.1.12, the middleware bounds long messages: it sends analyze() at most 65,536 UTF-8 bytes and the recall query at most 16,384 UTF-8 bytes, keeping both the start and the end of the message for recall. The model still receives the full user turn. The relayer runs LLM-based fact extraction on that message and stores the extracted facts. The save runs fire-and-forget, so it does not delay the generated response. recall() only reads memories before generation. analyze() is the write path that runs after generation.
How do you filter recalled memories?
Beyond the MemWalConfig fields, withMemWal accepts maxMemories, autoSave, minRelevance, and debug. It has no callback-based recall or save filter.
minRelevance: minimum similarity score (0 to 1) that a recalled memory needs to reach the prompt. The default is0.3. A value of0turns off the relevance filter.autoSave: turns saving after generation on or off. The default istrue.
To choose exactly which text the app stores or how it filters recall results, call the SDK methods directly instead of relying on the middleware.