Memory
Configure long-term memory, understand adapter-dependent tiers, and expose the built-in user-tier controls accurately.
Memory retrieves durable background before generation and records new facts after a completed turn. It is off by default and must be bound to the verified user.
Enable Drizzle memory
import { createDrizzleMemory }
from '@mordn/chat-widget/server/memory/drizzle';
export const { GET, POST, DELETE } = createChatHandler({
getUserId: getChatUserId,
model: anthropic('claude-sonnet-4-5'),
store: createDrizzleChatStore(),
memory: {
adapter: createDrizzleMemory({
agentId: 'support-bot',
// Optional AI SDK models:
// embeddingModel: google.textEmbeddingModel('text-embedding-004'),
// extractionModel: anthropic('claude-haiku-4-5'),
}),
inject: true,
extract: true,
limit: 6,
retrieveTimeoutMs: 1500,
},
});
Without an embedding model, the Drizzle adapter uses keyword retrieval. Without an extraction model, it uses heuristic extraction.
Lifecycle
- Retrieve relevant memories before generation under a bounded timeout.
- Inject them as non-authoritative background.
- After answer content settles, extract and record memories during stream finalization.
Recording is fail-soft, but it is intentionally awaited during finalization so a serverless runtime does not freeze before writes finish. It is post-content, not fire-and-forget.
Configuration
adapterMemoryAdapterFactoryrequiredinjectbooleantrueextractbooleantruelimitnumber6minScorenumber0retrieveTimeoutMsnumber1500formatForPrompt(memories, ctx) => stringisEnabledForUser(ctx) => boolean | Promise<boolean>scopesMemoryScope[]['user']autoSaveScopeMemoryScopeuserresolveOrgId(ctx) => string | null | Promise<string | null>Tiers and adapters
session: bound to user, agent, and conversation.user: durable across the bound user’s conversations.org: intentionally shared across users in the same server-verified org and agent namespace.
Org retrieval is not restricted to facts written by the current user; sharing is
the purpose of that tier. resolveOrgId must therefore be server-authoritative.
Built-in user controls
When memory is configured, the handler exposes:
| Route | Effect |
|---|---|
GET /memory |
List the bound user’s user-tier memories |
DELETE /memory |
Delete every memory row owned by the bound user for this agent, across tiers |
DELETE /memory/:id |
Delete one memory row owned by the bound user |
const response = await fetch('/api/chat/memory');
const { memories } = await response.json();
The built-in list route does not expose every session/org memory. The bulk-delete route removes rows owned by the bound user, including session/org rows they wrote, but never removes shared org rows owned by other users. Do not describe the list route as a complete cross-tier transparency view without adding an explicit, authorized admin surface.