Skip to main content

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.

Source: sdk/usage/with-memwal.md
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 maxMemories set in the options (maxMemories: 5 in 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 is 0.3. A value of 0 turns off the relevance filter.
  • autoSave: turns saving after generation on or off. The default is true.

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.