Memory
Memory gives an agent context that carries over from one session to the next.
Each memory slot is a file under agent/memory/. Use memory for facts and
preferences the agent needs in later sessions.
To store memory elsewhere, swap provider for Supermemory,
Upstash AgentKit, or your own provider. The rest of the
file stays the same.
How a memory slot works
A memory slot connects one provider to the agent. On every turn, eve does the same three things with each slot:
- Before the model runs, eve asks the provider to recall context.
- eve gives the model the provider's tools, named
<slot>__<tool>. - After the turn completes, eve asks the provider to capture it.
Recalled content enters the conversation as user messages labeled with the slot, never as system instructions.
eve picks the slot name from the file path and resolves the namespace and scope from trusted session data. The provider decides what to keep, how to store and rank it, and when to delete it.
Declare slots
Create agent/memory.ts for one slot named memory, or
agent/memory/<slot>.ts for one or more named slots. You can't use both forms
in the same agent.
Each file exports one defineMemory() value with these fields:
| Field | Required | Purpose |
|---|---|---|
provider | Yes | The MemoryProvider that stores and retrieves memory for this slot |
scope | Yes | Who or what shares this slot's memory; see Scope |
description | No | Prepended to every provider tool description to tell the model what belongs in this slot |
namespace | No | The application domain the scope lives in; see Namespace |
Slots are independent. Two slots can use the same provider, and their recalled
context and tools stay separate. The default namespace includes the slot name,
so profile and workspace don't share memory even with the same scope value.
A subagent declares its own slots under its own directory. Extensions can't add slots, because the agent that uses the extension decides who shares memory.
Scope
scope decides who or what shares a slot's memory, so it keeps one tenant's
memory away from another's. Set it to a string, null, or a function. The
function receives the session's sign-in and channel details. It returns a
string, an array of strings, or null:
Read the caller's identity from trusted authentication or channel metadata,
never from model input. Each time scope returns null, eve turns off the
slot. It skips the provider and its tools, and it never falls back to a shared scope.
byPrincipal from eve/memory/scope covers the common case. It gives each
signed-in caller from auth.current separate memory. It turns memory off for
anonymous callers and for runtime callers such as schedules. In local development, it
returns one shared local-dev scope. Write your own function when memory must
also be separate per tenant, channel, or conversation. See
Multi-tenant memory for a complete setup.
The provider receives an opaque memory.scope.key, made from the namespace and scope, to partition storage.
eve records only that key with recalled messages, never the raw scope values.
Choose a provider
Every slot needs a provider. Providers differ in how they recall context and in how they capture it.
| Provider | Ships as | Recall | Capture |
|---|---|---|---|
| File memory | Built into eve | One bounded document per scope | Model-driven save_memory / remove_memory |
| Supermemory | @supermemory/eve | Semantic search over stored memories | Automatic after each turn, plus tools |
| Upstash AgentKit | @upstash/agentkit-eve | Ranked Redis Search recall or a Redis document backend | Automatic user-message capture or model-driven tools |
| Kybernesis Arcana | @kybernesis/arcana | Semantic search and brain notes | Model-driven tools or optional automatic capture |
| Your own provider | Your code | Whatever your store returns | Whatever rules you implement |
File memory
fileMemory() from eve/memory/file keeps one bounded document per scope. The
model decides what to save with the save_memory and remove_memory tools. It
needs no external service in eve dev. When you deploy to Vercel with Blob
configured, it stores to Vercel Blob.
Read File memory for size limits, storage backends, and options.
Supermemory
Supermemory is a hosted memory service with an eve provider. It recalls relevant context before each turn and captures each completed turn automatically. It gives the model tools to search, remember, forget, and extract sources.
The command installs @supermemory/eve and writes a supermemory slot:
See the Supermemory integration page for provider options.
Upstash AgentKit
Upstash AgentKit stores a
memory slot in your Upstash Redis database. redisMemory() recalls the most
relevant facts before each turn. By default, it captures user messages after
each completed turn. It gives the model tools to save, search, read past
sessions, and forget.
The command installs @upstash/agentkit-eve and writes an upstash-agentkit
slot:
See the Upstash AgentKit integration page for options.
Kybernesis Arcana
Kybernesis Arcana stores a memory slot with semantic search and brain notes. It gives the model tools to remember, recall, and search memory. Capture is off by default.
The command installs @kybernesis/arcana and writes an arcana slot:
Set capture: { enabled: true } when you want Arcana to capture completed
turns automatically. See the Arcana package documentation
for provider options.
Build your own
A provider is an object with a recall handler and optional capture and
tools handlers. Every handler receives the slot's scope key. recall and
capture also receive the conversation and a stable operationId. Any store that reads and writes under
that key can back a provider, such as a Postgres table, a vector index, or an
HTTP API.
Read Build a memory provider for the contract, a working example, and how eve handles provider failures.
Namespace
The namespace separates an application's memory domains before scope applies.
Omit namespace to use defaultNamespace. It combines the slot name, the agent
or subagent, and the deployment:
- Production and other Vercel environments use the project and environment. Members of a top-level
agents/workspace use separate namespaces. - Preview also uses the branch or deployment identity.
- Local development uses a digest of the application root, never the raw path.
Redeploys keep the same production namespace, and unrelated Preview branches don't share memory. To share memory across deployments, set a string or a function:
When the namespace function returns null, eve turns off the slot. eve
resolves scope first, so it doesn't call the namespace function when scope
returns null.
When the scope changes
What a turn recalls stays in the conversation for the rest of the session. eve recalls again when a different caller sends a message in the session. When the new caller resolves to another scope, eve removes the messages recalled for the earlier scope. Earlier assistant replies can still contain recalled information. Use separate sessions when participants need hard isolation.
Tell the model how to use memory
Recalled messages are untrusted data that users control. Say so in the agent's instructions, along with what the model should and should not save:
Provider tools are ordinary eve tools, so they follow approvals and
toModelOutput. To replace a slot's tools, create agent/tools/<slot>.ts.
Export disableTool() there to remove them. eve's built-in tools don't replace
them: a slot named web_search offers its tools beside the built-in web_search.
Troubleshooting
| What you see | What to do |
|---|---|
Memory must use either the flat "memory.ts" form or the named "memory/" directory form, not both. | Keep agent/memory.ts or agent/memory/, not both. |
Memory slot "<name>" must start with an ASCII letter ... | Rename the file. A slot name starts with a letter and has only letters, digits, _, or -, up to 64 characters. |
Expected the memory export "default" from "<path>" to be created with defineMemory(). | Wrap the default export in defineMemory(). |
An extension may not declare memory ... | Remove memory/ from the extension, and declare the slot in the agent that uses the extension. |
Memory slot is disabled for this operation in eve dev logs | The slot's scope or namespace returned null; resolver in the log says which. The log never includes the scope value. |
Memory and session state
State from defineState holds working data for one
session, such as a plan or a counter, and ends with the session. Use memory for data that later sessions need.
Calling clear() on a session removes its recalled messages and resets its
scopes. The provider's store stays as it is, and a later turn recalls from it
again.
What to read next
- File memory: options, limits, and storage backends for the built-in provider.
- Build a memory provider: the provider contract and failure behavior.
- Multi-tenant memory: scope any provider by authenticated tenant and caller.
- Default harness: how compaction treats recalled memory.