Memory

Memory lets an agent continue a conversation. When you pass the same threadId to later runs, Better Agent loads previous messages from that thread before the new input.

Memory needs storage to survive across requests and deploys.

Add memory

Configure memory with createMemory.

import { betterAgent, createMemory } from "@better-agent/core";

export const app = betterAgent({
  storage,
  memory: createMemory({ lastMessages: 20 }),
  agents: [supportAgent],
});

Use a threadId when you run the agent.

await app.agent("support").run({
  threadId: "thread_123",
  messages: [{ role: "user", content: "My order is late." }],
});

await app.agent("support").run({
  threadId: "thread_123",
  messages: [{ role: "user", content: "What did I ask about?" }],
});

The second run includes recent messages from thread_123.

Storage

Memory stores threads and messages in the app's storage.

import { createInMemoryStorage } from "@better-agent/core";

const storage = createInMemoryStorage();

createInMemoryStorage() is useful for local development and tests. For production, use a database adapter.

See Storage for runtime storage. For production adapters, see Drizzle, Kysely, Prisma, or Redis.

You can also bind storage directly to a memory instance.

const memory = createMemory({
  storage,
  lastMessages: 20,
});

Agent memory

App-level memory applies to every agent. Set memory on an agent when it needs a different history window.

const supportAgent = defineAgent({
  name: "support",
  model: openai("gpt-5.5"),
  instruction: "You help customers.",
  memory: createMemory({ lastMessages: 50 }),
});

Use memory: false when an agent should ignore app-level memory.

const classifier = defineAgent({
  name: "classifier",
  model: openai("gpt-5.5"),
  instruction: "Classify the message.",
  memory: false,
});

History window

lastMessages controls how many previous messages are loaded into the next run. It must be a positive integer.

createMemory({ lastMessages: 10 });

Use a smaller window for fast classifiers and a larger window for chat agents.

Memory options

createMemory accepts:

OptionUse
storageBind this memory instance to a specific storage adapter.
lastMessagesLimit how many previous messages are loaded.
scopeIsolate remote thread access by tenant, user, or another key.
generateIdCustomize thread and stored message ids.

Thread scope

Use scope to isolate thread access for authenticated HTTP requests.

createMemory({
  lastMessages: 20,
  scope: ({ auth }) =>
    auth ? `tenant:${auth.tenant}:subject:${auth.subject}` : null,
});

When app auth is configured, remote thread endpoints only expose threads in the resolved scope. If you do not provide scope, Better Agent uses the authenticated subject and tenant.

Custom ids

Use generateId when thread or message record ids need to follow your own format.

const memory = createMemory({
  generateId(kind) {
    return `${kind}_${crypto.randomUUID()}`;
  },
});

Manage threads

Agent handles expose memory helpers when memory is configured.

const memory = app.agent("support").memory;

const threads = await memory.threads.list({ limit: 20 });
const messages = await memory.messages.list({ threadId: "thread_123" });

Delete a thread when the conversation should be removed.

await memory.threads.delete("thread_123");

Fork a thread to branch a conversation.

await memory.fork("thread_copy", "thread_123");

Pass a transform to copy only the messages you want.

await memory.fork("short_copy", "thread_123", (messages) => messages.slice(-10));