JavaScript
Memory Layers
Create a memory layer
Give an agent knowledge it pulls on demand. Skills layers advertise what they hold; episodic layers let the agent write notes to itself.
POST
JavaScript
Nothing in a memory layer lands in the context window up front. The agent reaches for what it needs, when it needs it. That is the whole design: you can hand an agent a thousand pages of policy without paying for a single token until it asks.
Both
For a body too large to inline, upload it first and set
Give both layers a
Pin a single entry rather than a whole layer by passing
Every objective for that customer now reads and writes the same memory. The agent remembers the last conversation without you threading a transcript through your application. Set
Entries follow the same create, retrieve, list, update, delete shape, nested under their layer.
spec.type is required, and it decides everything about how the layer behaves.
Two types, two mechanics
A skills layer is a reference library you curate. An episodic layer is a diary the agent keeps. They are not interchangeable.
Either way the agent reads with the same two tools:
get_memory to pull an entry by its exact key, and search_memory to find a key it does not know. Only an episodic layer grants store_memory.
metadata.name and spec.type are enforced: omit either and the request fails with a 400.
Write the entry description for the model
An entry’sdescription is the only thing the model sees before it decides whether to read the body, and it is the text search_memory matches against. It is not a note to your teammates. It is the “when to use this” line.
Write When a customer asks for a refund, not Refund policy v3 (updated by Dana). The first tells a model when to reach for the entry, and gives search something to hit. The second tells it nothing it can act on.
Search matters more than it looks. search_memory runs trigram similarity over keys and descriptions only, never over content. An entry whose body is full of the right words but whose description is vague stays invisible to the agent.
The entry key is what the model passes to get_memory. Slashes are conventional, not structural: policy/refunds reads like a path but lookups are flat, and the key is one opaque string.
Content comes back only on a detail read
Listing entries gives you the summary view:key, description, and metadata. Read a single entry and you get a top-level content field alongside it. That keeps a list of a thousand entries from dragging their bodies along.
spec.type to uploadId with the upload’s ID, instead of content with an inline body. The type field names which source you chose, and the matching field must ride along with it.
Sizes to keep in mind. An inline content caps at 1 MiB. A single get_memory call returns at most 500 lines or 100 KB, and the agent pages through anything longer. So a 1 MiB entry is legal and slow to read: split it into entries the agent can pick between.
The cascade decides who wins
An objective resolves keys against an ordered list of layers. The first layer holding a key wins, and everything behind it is shadowed. Think CSS specificity: the most specific source takes the key. Order, most specific first:- The episodic layer, when the objective carries an episodic key.
- The objective’s
memoryCascade, in array order. Earlier elements are more specific. - The variation’s assigned layers, by ascending
position. Lower position is more specific.
policy/refunds entry and the enterprise one wins, because it sits earlier in the array.
You never have to reason about this from memory. Read the objective back with includeInfo and info.effectiveMemoryCascade shows you the resolved order, index 0 first:
memoryEntryId alongside its memoryLayerId. That entry then behaves as a one-entry layer at that position. The entry must belong to the layer you name.
The total effective cascade, your memoryCascade plus the variation’s assignments, caps at 10 entries. A request that would exceed it is rejected.
System-managed layers cannot be named in
memoryCascade. The episodic layer attaches itself, at the most specific end, whenever an objective carries an episodic key.Episodic memory: the agent’s own notes
An episodic layer is not something you create and fill. Turn onenableEpisodicMemory on the agent, then give each objective an episodicMemory.key. Objectives sharing that key, for that agent, share one system-managed layer, and the agent writes into it with store_memory.
episodicMemoryTtl on the agent and the expiry slides forward each time a new objective touches the key. Leave the TTL unset and memories are kept indefinitely.
The flag and the key are a matched pair, and the API enforces both directions. Pass an episodicMemory.key to an agent without enableEpisodicMemory and the request fails. Omit the key for an agent that has it enabled, and it fails too.
Because the episodic layer sits at the most specific end of the cascade, what the agent learned about this customer beats whatever the general playbook says.
Episodic layers are system-managed. They appear in
list (filter by type, agentId, or episodicKeyPrefix), but you cannot attach one to a variation, name one in memoryCascade, or edit it. It attaches itself.Lifecycle
Related
Memory cascade
How layers stack, and what happens on a key clash.
Give your agent memory
The hands-on lesson, from empty layer to an agent that remembers.
Create an objective
Where
memoryCascade and episodicMemory get set per run.Preventing tool bloat
The same on-demand idea, applied to tools instead of knowledge.
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Example:
"workspace_01HXKD2E5NQM3T9AYWCF133E3Q"
Body
application/json
Response
OK
MemoryLayer is a named container of memory entries that can be composed into an objective's memory cascade. Layers are workspace-scoped resources. The layer type controls how its entries participate in the agent loop — see MemoryLayerType for details.
See "Memory cascade composition" above for how layers compose at lookup time.