@mastra/memory 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/{chunk-GBBQIJQF.js → chunk-3CM4XQJO.js} +1940 -463
- package/dist/chunk-3CM4XQJO.js.map +1 -0
- package/dist/{chunk-D6II7EP4.cjs → chunk-5W5463NI.cjs} +1939 -461
- package/dist/chunk-5W5463NI.cjs.map +1 -0
- package/dist/docs/SKILL.md +24 -24
- package/dist/docs/assets/SOURCE_MAP.json +25 -25
- package/dist/docs/references/docs-agents-agent-approval.md +3 -3
- package/dist/docs/references/docs-agents-agent-memory.md +3 -3
- package/dist/docs/references/docs-agents-network-approval.md +5 -2
- package/dist/docs/references/docs-agents-networks.md +2 -2
- package/dist/docs/references/docs-agents-supervisor-agents.md +3 -3
- package/dist/docs/references/docs-memory-memory-processors.md +9 -9
- package/dist/docs/references/docs-memory-message-history.md +4 -4
- package/dist/docs/references/docs-memory-observational-memory.md +11 -7
- package/dist/docs/references/docs-memory-semantic-recall.md +9 -9
- package/dist/docs/references/docs-memory-storage.md +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +20 -20
- package/dist/docs/references/reference-core-getMemory.md +1 -1
- package/dist/docs/references/reference-core-listMemory.md +1 -1
- package/dist/docs/references/reference-memory-clone-utilities.md +7 -7
- package/dist/docs/references/reference-memory-cloneThread.md +5 -5
- package/dist/docs/references/reference-memory-createThread.md +1 -1
- package/dist/docs/references/reference-memory-getThreadById.md +1 -1
- package/dist/docs/references/reference-memory-listThreads.md +3 -3
- package/dist/docs/references/reference-memory-memory-class.md +1 -1
- package/dist/docs/references/reference-memory-observational-memory.md +8 -6
- package/dist/docs/references/reference-processors-token-limiter-processor.md +2 -2
- package/dist/docs/references/reference-storage-dynamodb.md +7 -7
- package/dist/docs/references/reference-storage-libsql.md +1 -1
- package/dist/docs/references/reference-storage-mongodb.md +6 -6
- package/dist/docs/references/reference-storage-postgresql.md +7 -7
- package/dist/docs/references/reference-storage-upstash.md +4 -4
- package/dist/docs/references/reference-vectors-libsql.md +15 -15
- package/dist/docs/references/reference-vectors-mongodb.md +18 -18
- package/dist/docs/references/reference-vectors-pg.md +23 -21
- package/dist/docs/references/reference-vectors-upstash.md +15 -15
- package/dist/index.cjs +48 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -21
- package/dist/index.js.map +1 -1
- package/dist/{observational-memory-AHVELJX4.cjs → observational-memory-C5LO7RBR.cjs} +17 -17
- package/dist/{observational-memory-AHVELJX4.cjs.map → observational-memory-C5LO7RBR.cjs.map} +1 -1
- package/dist/{observational-memory-QFQUF5EY.js → observational-memory-OYK4MEUD.js} +3 -3
- package/dist/{observational-memory-QFQUF5EY.js.map → observational-memory-OYK4MEUD.js.map} +1 -1
- package/dist/processors/index.cjs +15 -15
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +33 -2
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-agent.d.ts +7 -4
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/repro-capture.d.ts +23 -0
- package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -0
- package/dist/processors/observational-memory/token-counter.d.ts +28 -3
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/dist/tools/working-memory.d.ts +6 -10
- package/dist/tools/working-memory.d.ts.map +1 -1
- package/package.json +16 -11
- package/dist/chunk-D6II7EP4.cjs.map +0 -1
- package/dist/chunk-GBBQIJQF.js.map +0 -1
|
@@ -13,7 +13,7 @@ Working memory can persist at two different scopes:
|
|
|
13
13
|
|
|
14
14
|
**Important:** Switching between scopes means the agent won't see memory from the other scope - thread-scoped memory is completely separate from resource-scoped memory.
|
|
15
15
|
|
|
16
|
-
## Quick
|
|
16
|
+
## Quick start
|
|
17
17
|
|
|
18
18
|
Here's a minimal example of setting up an agent with working memory:
|
|
19
19
|
|
|
@@ -37,13 +37,13 @@ const agent = new Agent({
|
|
|
37
37
|
})
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
## How it
|
|
40
|
+
## How it works
|
|
41
41
|
|
|
42
42
|
Working memory is a block of Markdown text that the agent is able to update over time to store continuously relevant information:
|
|
43
43
|
|
|
44
44
|
[YouTube video player](https://www.youtube-nocookie.com/embed/UMy_JHLf1n8)
|
|
45
45
|
|
|
46
|
-
## Memory
|
|
46
|
+
## Memory persistence scopes
|
|
47
47
|
|
|
48
48
|
Working memory can operate in two different scopes, allowing you to choose how memory persists across conversations:
|
|
49
49
|
|
|
@@ -117,7 +117,7 @@ const memory = new Memory({
|
|
|
117
117
|
- Temporary or session-specific information
|
|
118
118
|
- Workflows where each thread needs working memory but threads are ephemeral and not related to each other
|
|
119
119
|
|
|
120
|
-
## Storage
|
|
120
|
+
## Storage adapter support
|
|
121
121
|
|
|
122
122
|
Resource-scoped working memory requires specific storage adapters that support the `mastra_resources` table:
|
|
123
123
|
|
|
@@ -128,7 +128,7 @@ Resource-scoped working memory requires specific storage adapters that support t
|
|
|
128
128
|
- **Upstash** (`@mastra/upstash`)
|
|
129
129
|
- **MongoDB** (`@mastra/mongodb`)
|
|
130
130
|
|
|
131
|
-
## Custom
|
|
131
|
+
## Custom templates
|
|
132
132
|
|
|
133
133
|
Templates guide the agent on what information to track and update in working memory. While a default template is used if none is provided, you'll typically want to define a custom template tailored to your agent's specific use case to ensure it remembers the most relevant information.
|
|
134
134
|
|
|
@@ -142,7 +142,7 @@ const memory = new Memory({
|
|
|
142
142
|
template: `
|
|
143
143
|
# User Profile
|
|
144
144
|
|
|
145
|
-
## Personal
|
|
145
|
+
## Personal info
|
|
146
146
|
|
|
147
147
|
- Name:
|
|
148
148
|
- Location:
|
|
@@ -156,7 +156,7 @@ const memory = new Memory({
|
|
|
156
156
|
- [Deadline 1]: [Date]
|
|
157
157
|
- [Deadline 2]: [Date]
|
|
158
158
|
|
|
159
|
-
## Session
|
|
159
|
+
## Session state
|
|
160
160
|
|
|
161
161
|
- Last Task Discussed:
|
|
162
162
|
- Open Questions:
|
|
@@ -168,13 +168,13 @@ const memory = new Memory({
|
|
|
168
168
|
})
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
## Designing
|
|
171
|
+
## Designing effective templates
|
|
172
172
|
|
|
173
|
-
A well-structured template keeps the information
|
|
173
|
+
A well-structured template keeps the information straightforward for the agent to parse and update. Treat the template as a short form that you want the assistant to keep up to date.
|
|
174
174
|
|
|
175
|
-
- **Short, focused labels.** Avoid paragraphs or very long headings. Keep labels brief (for example `## Personal Info` or `- Name:`) so updates are
|
|
175
|
+
- **Short, focused labels.** Avoid paragraphs or very long headings. Keep labels brief (for example `## Personal Info` or `- Name:`) so updates are readable and less likely to be truncated.
|
|
176
176
|
- **Use consistent casing.** Inconsistent capitalization (`Timezone:` vs `timezone:`) can cause messy updates. Stick to Title Case or lower case for headings and bullet labels.
|
|
177
|
-
- **Keep placeholder text
|
|
177
|
+
- **Keep placeholder text minimal.** Use hints such as `[e.g., Formal]` or `[Date]` to help the LLM fill in the correct spots.
|
|
178
178
|
- **Abbreviate very long values.** If you only need a short form, include guidance like `- Name: [First name or nickname]` or `- Address (short):` rather than the full legal text.
|
|
179
179
|
- **Mention update rules in `instructions`.** You can instruct how and when to fill or clear parts of the template directly in the agent's `instructions` field.
|
|
180
180
|
|
|
@@ -206,7 +206,7 @@ const paragraphMemory = new Memory({
|
|
|
206
206
|
})
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
-
## Structured
|
|
209
|
+
## Structured working memory
|
|
210
210
|
|
|
211
211
|
Working memory can also be defined using a structured schema instead of a Markdown template. This allows you to specify the exact fields and types that should be tracked, using a [Zod](https://zod.dev/) schema. When using a schema, the agent will see and update working memory as a JSON object matching your schema.
|
|
212
212
|
|
|
@@ -263,22 +263,22 @@ Schema-based working memory uses **merge semantics**, meaning the agent only nee
|
|
|
263
263
|
|
|
264
264
|
- **Object fields are deep merged:** Only provided fields are updated; others remain unchanged
|
|
265
265
|
- **Set a field to `null` to delete it:** This explicitly removes the field from memory
|
|
266
|
-
- **Arrays are replaced entirely:** When an array field is provided, it replaces the existing array (arrays
|
|
266
|
+
- **Arrays are replaced entirely:** When an array field is provided, it replaces the existing array (arrays aren't merged element-by-element)
|
|
267
267
|
|
|
268
|
-
## Choosing
|
|
268
|
+
## Choosing between template and schema
|
|
269
269
|
|
|
270
270
|
- Use a **template** (Markdown) if you want the agent to maintain memory as a free-form text block, such as a user profile or scratchpad. Templates use **replace semantics** — the agent must provide the complete memory content on each update.
|
|
271
271
|
- Use a **schema** if you need structured, type-safe data that can be validated and programmatically accessed as JSON. Schemas use **merge semantics** — the agent only provides fields to update, and existing fields are preserved.
|
|
272
|
-
- Only one mode can be active at a time: setting both `template` and `schema`
|
|
272
|
+
- Only one mode can be active at a time: setting both `template` and `schema` isn't supported.
|
|
273
273
|
|
|
274
|
-
## Example: Multi-step
|
|
274
|
+
## Example: Multi-step retention
|
|
275
275
|
|
|
276
276
|
Below is a simplified view of how the `User Profile` template updates across a short user conversation:
|
|
277
277
|
|
|
278
278
|
```nohighlight
|
|
279
279
|
# User Profile
|
|
280
280
|
|
|
281
|
-
## Personal
|
|
281
|
+
## Personal info
|
|
282
282
|
|
|
283
283
|
- Name:
|
|
284
284
|
- Location:
|
|
@@ -301,9 +301,9 @@ Below is a simplified view of how the `User Profile` template updates across a s
|
|
|
301
301
|
|
|
302
302
|
The agent can now refer to `Sam` or `Berlin` in later responses without requesting the information again because it has been stored in working memory.
|
|
303
303
|
|
|
304
|
-
If your agent
|
|
304
|
+
If your agent isn't properly updating working memory when you expect it to, you can add system instructions on _how_ and _when_ to use this template in your agent's `instructions` setting.
|
|
305
305
|
|
|
306
|
-
## Setting
|
|
306
|
+
## Setting initial working memory
|
|
307
307
|
|
|
308
308
|
While agents typically update working memory through the `updateWorkingMemory` tool, you can also set initial working memory programmatically when creating or updating threads. This is useful for injecting user data (like their name, preferences, or other info) that you want available to the agent without passing it in every request.
|
|
309
309
|
|
|
@@ -372,7 +372,7 @@ await memory.updateWorkingMemory({
|
|
|
372
372
|
})
|
|
373
373
|
```
|
|
374
374
|
|
|
375
|
-
## Read-
|
|
375
|
+
## Read-only working memory
|
|
376
376
|
|
|
377
377
|
In some scenarios, you may want an agent to have access to working memory data without the ability to modify it. This is useful for:
|
|
378
378
|
|
|
@@ -22,7 +22,7 @@ const thread = await memory.createThread({
|
|
|
22
22
|
|
|
23
23
|
**memory** (`TMemory[TMemoryKey]`): The memory instance with the specified key. Throws an error if the memory is not found.
|
|
24
24
|
|
|
25
|
-
## Example: Registering and
|
|
25
|
+
## Example: Registering and retrieving memory
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
import { Mastra } from '@mastra/core'
|
|
@@ -20,7 +20,7 @@ This method takes no parameters.
|
|
|
20
20
|
|
|
21
21
|
**memory** (`Record<string, MastraMemory>`): An object containing all registered memory instances, keyed by their registry keys.
|
|
22
22
|
|
|
23
|
-
## Example: Checking
|
|
23
|
+
## Example: Checking registered memory
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
26
|
import { Mastra } from '@mastra/core'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# Cloned
|
|
1
|
+
# Cloned thread utilities
|
|
2
2
|
|
|
3
3
|
The Memory class provides utility methods for working with cloned threads. These methods help you check clone status, retrieve clone metadata, navigate clone relationships, and track clone history.
|
|
4
4
|
|
|
5
|
-
## isClone()
|
|
5
|
+
## `isClone()`
|
|
6
6
|
|
|
7
7
|
Checks whether a thread is a clone of another thread.
|
|
8
8
|
|
|
@@ -28,7 +28,7 @@ if (memory.isClone(thread)) {
|
|
|
28
28
|
}
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
## getCloneMetadata()
|
|
31
|
+
## `getCloneMetadata()`
|
|
32
32
|
|
|
33
33
|
Retrieves the clone metadata from a thread if it exists.
|
|
34
34
|
|
|
@@ -54,7 +54,7 @@ if (cloneInfo) {
|
|
|
54
54
|
}
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
## getSourceThread()
|
|
57
|
+
## `getSourceThread()`
|
|
58
58
|
|
|
59
59
|
Retrieves the original source thread that a cloned thread was created from.
|
|
60
60
|
|
|
@@ -79,7 +79,7 @@ if (sourceThread) {
|
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
## listClones()
|
|
82
|
+
## `listClones()`
|
|
83
83
|
|
|
84
84
|
Lists all threads that were cloned from a specific source thread.
|
|
85
85
|
|
|
@@ -104,7 +104,7 @@ for (const clone of clones) {
|
|
|
104
104
|
}
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
## getCloneHistory()
|
|
107
|
+
## `getCloneHistory()`
|
|
108
108
|
|
|
109
109
|
Retrieves the full clone history chain for a thread, tracing back to the original.
|
|
110
110
|
|
|
@@ -136,7 +136,7 @@ for (let i = 0; i < history.length; i++) {
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
## Complete
|
|
139
|
+
## Complete example
|
|
140
140
|
|
|
141
141
|
```typescript
|
|
142
142
|
import { mastra } from './mastra'
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `.cloneThread()` method creates a copy of an existing conversation thread, including all its messages. This enables creating divergent conversation paths from a specific point in a conversation. When semantic recall is enabled, the method also creates vector embeddings for the cloned messages.
|
|
4
4
|
|
|
5
|
-
## Usage
|
|
5
|
+
## Usage example
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
8
|
const { thread, clonedMessages } = await memory.cloneThread({
|
|
@@ -52,7 +52,7 @@ The cloned thread's metadata includes a `clone` property with:
|
|
|
52
52
|
|
|
53
53
|
**lastMessageId** (`string`): The ID of the last message in the source thread at the time of cloning.
|
|
54
54
|
|
|
55
|
-
## Extended
|
|
55
|
+
## Extended usage example
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
58
|
import { mastra } from './mastra'
|
|
@@ -98,7 +98,7 @@ const response = await agent.generate("Let's try a different approach", {
|
|
|
98
98
|
})
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
## Vector
|
|
101
|
+
## Vector embeddings
|
|
102
102
|
|
|
103
103
|
When the Memory instance has semantic recall enabled (with a vector store and embedder configured), `cloneThread()` automatically creates vector embeddings for all cloned messages. This ensures that semantic search works correctly on the cloned thread.
|
|
104
104
|
|
|
@@ -127,7 +127,7 @@ const results = await memory.recall({
|
|
|
127
127
|
})
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
## Observational
|
|
130
|
+
## Observational memory
|
|
131
131
|
|
|
132
132
|
When [Observational Memory](https://mastra.ai/docs/memory/observational-memory) is enabled, `cloneThread()` automatically clones the OM records associated with the source thread. The behavior depends on the OM scope:
|
|
133
133
|
|
|
@@ -135,4 +135,4 @@ When [Observational Memory](https://mastra.ai/docs/memory/observational-memory)
|
|
|
135
135
|
- **Resource-scoped OM (same `resourceId`)**: The OM record is shared between the source and cloned threads since they belong to the same resource. No duplication occurs.
|
|
136
136
|
- **Resource-scoped OM (different `resourceId`)**: The OM record is cloned to the new resource. Message IDs are remapped and any thread-identifying tags within observations are updated to reference the cloned thread.
|
|
137
137
|
|
|
138
|
-
Only the current (most recent) OM generation is cloned — older history generations
|
|
138
|
+
Only the current (most recent) OM generation is cloned — older history generations aren't copied. Transient processing state (observation/reflection in-progress flags) is reset on the cloned record.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `.createThread()` method creates a new conversation thread in the memory system. Each thread represents a distinct conversation or context and can contain multiple messages.
|
|
4
4
|
|
|
5
|
-
## Usage
|
|
5
|
+
## Usage example
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
8
|
await memory?.createThread({ resourceId: 'user-123' })
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `listThreads()` method retrieves threads with pagination support and optional filtering by `resourceId`, `metadata`, or both.
|
|
4
4
|
|
|
5
|
-
## Usage
|
|
5
|
+
## Usage examples
|
|
6
6
|
|
|
7
7
|
### List all threads with pagination
|
|
8
8
|
|
|
@@ -26,7 +26,7 @@ const result = await memory.listThreads({
|
|
|
26
26
|
})
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
### Filter by resourceId
|
|
29
|
+
### Filter by `resourceId`
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
32
|
const result = await memory.listThreads({
|
|
@@ -119,7 +119,7 @@ while (hasMorePages) {
|
|
|
119
119
|
}
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
## Metadata
|
|
122
|
+
## Metadata filtering
|
|
123
123
|
|
|
124
124
|
The metadata filter uses AND logic - all specified key-value pairs must match for a thread to be included in the results:
|
|
125
125
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Memory
|
|
1
|
+
# Memory class
|
|
2
2
|
|
|
3
3
|
The `Memory` class provides a robust system for managing conversation history and thread-based message storage in Mastra. It enables persistent storage of conversations, semantic search capabilities, and efficient message retrieval. You must configure a storage provider for conversation history, and if you enable semantic recall you will also need to provide a vector store and embedder.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Observational
|
|
1
|
+
# Observational memory
|
|
2
2
|
|
|
3
3
|
**Added in:** `@mastra/memory@1.1.0`
|
|
4
4
|
|
|
@@ -26,6 +26,8 @@ export const agent = new Agent({
|
|
|
26
26
|
|
|
27
27
|
The `observationalMemory` option accepts `true`, a configuration object, or `false`. Setting `true` enables OM with `google/gemini-2.5-flash` as the default model. When passing a config object, a `model` must be explicitly set — either at the top level, or on `observation.model` and/or `reflection.model`.
|
|
28
28
|
|
|
29
|
+
Observer input is multimodal-aware. OM keeps text placeholders like `[Image #1: screenshot.png]` in the transcript it builds for the Observer, and also sends the underlying image parts when possible. This applies to both single-thread observation and batched multi-thread observation. Non-image files appear as placeholders only.
|
|
30
|
+
|
|
29
31
|
**enabled** (`boolean`): Enable or disable Observational Memory. When omitted from a config object, defaults to \`true\`. Only \`enabled: false\` explicitly disables it. (Default: `true`)
|
|
30
32
|
|
|
31
33
|
**model** (`string | LanguageModel | DynamicModel | ModelWithRetries[]`): Model for both the Observer and Reflector agents. Sets the model for both at once. Cannot be used together with \`observation.model\` or \`reflection.model\` — an error will be thrown if both are set. When using \`observationalMemory: true\`, defaults to \`google/gemini-2.5-flash\`. When passing a config object, this or \`observation.model\`/\`reflection.model\` must be set. Use \`"default"\` to explicitly use the default model (\`google/gemini-2.5-flash\`). (Default: `'google/gemini-2.5-flash' (when using observationalMemory: true)`)
|
|
@@ -40,7 +42,7 @@ The `observationalMemory` option accepts `true`, a configuration object, or `fal
|
|
|
40
42
|
|
|
41
43
|
**observation.instruction** (`string`): Custom instruction appended to the Observer's system prompt. Use this to customize what the Observer focuses on, such as domain-specific preferences or priorities.
|
|
42
44
|
|
|
43
|
-
**observation.messageTokens** (`number`): Token count of unobserved messages that triggers observation. When unobserved message tokens exceed this threshold, the Observer agent is called.
|
|
45
|
+
**observation.messageTokens** (`number`): Token count of unobserved messages that triggers observation. When unobserved message tokens exceed this threshold, the Observer agent is called. Image parts are included with model-aware estimates when possible, with deterministic fallbacks when image metadata is incomplete. Image-like \`file\` parts are counted the same way when uploads are normalized as files.
|
|
44
46
|
|
|
45
47
|
**observation.maxTokensPerBatch** (`number`): Maximum tokens per batch when observing multiple threads in resource scope. Threads are chunked into batches of this size and processed in parallel. Lower values mean more parallelism but more API calls.
|
|
46
48
|
|
|
@@ -80,9 +82,9 @@ OM persists token payload estimates so repeated counting can reuse prior tiktoke
|
|
|
80
82
|
|
|
81
83
|
- Part-level cache: `part.providerMetadata.mastra`.
|
|
82
84
|
- String-content fallback cache: message-level metadata when no parts exist.
|
|
83
|
-
- Cache entries are ignored and recomputed if cache version/tokenizer source
|
|
84
|
-
- Per-message and per-conversation overhead are always recomputed at runtime and
|
|
85
|
-
- `data-*` and `reasoning` parts are skipped and
|
|
85
|
+
- Cache entries are ignored and recomputed if cache version/tokenizer source doesn't match.
|
|
86
|
+
- Per-message and per-conversation overhead are always recomputed at runtime and aren't cached.
|
|
87
|
+
- `data-*` and `reasoning` parts are skipped and don't receive cache entries.
|
|
86
88
|
|
|
87
89
|
## Examples
|
|
88
90
|
|
|
@@ -283,7 +285,7 @@ observationalMemory: {
|
|
|
283
285
|
|
|
284
286
|
Setting `bufferTokens: false` disables both observation and reflection async buffering. Observations and reflections will run synchronously when their thresholds are reached.
|
|
285
287
|
|
|
286
|
-
> **Note:** Async buffering
|
|
288
|
+
> **Note:** Async buffering isn't supported with `scope: 'resource'` and is automatically disabled in resource scope.
|
|
287
289
|
|
|
288
290
|
## Streaming data parts
|
|
289
291
|
|
|
@@ -47,8 +47,8 @@ const processor = new TokenLimiterProcessor({
|
|
|
47
47
|
|
|
48
48
|
When used as an input processor, `TokenLimiterProcessor` throws a `TripWire` error in the following cases:
|
|
49
49
|
|
|
50
|
-
- **Empty messages**: If there are no messages to process, a TripWire is thrown because you
|
|
51
|
-
- **System messages exceed limit**: If system messages alone exceed the token limit, a TripWire is thrown because you
|
|
50
|
+
- **Empty messages**: If there are no messages to process, a TripWire is thrown because you can't send an LLM request with no messages.
|
|
51
|
+
- **System messages exceed limit**: If system messages alone exceed the token limit, a TripWire is thrown because you can't send an LLM request with only system messages and no user/assistant messages.
|
|
52
52
|
|
|
53
53
|
```typescript
|
|
54
54
|
import { TripWire } from '@mastra/core/agent'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# DynamoDB
|
|
1
|
+
# DynamoDB storage
|
|
2
2
|
|
|
3
3
|
The DynamoDB storage implementation provides a scalable and performant NoSQL database solution for Mastra, leveraging a single-table design pattern with [ElectroDB](https://electrodb.dev/).
|
|
4
4
|
|
|
5
|
-
> **Observability Not Supported:** DynamoDB storage **
|
|
5
|
+
> **Observability Not Supported:** DynamoDB storage **doesn't support the observability domain**. Traces from the `DefaultExporter` can't be persisted to DynamoDB, and Mastra Studio's observability features won't work with DynamoDB as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
|
|
6
6
|
|
|
7
7
|
> **Item Size Limit:** DynamoDB enforces a **400 KB maximum item size**. This limit can be exceeded when storing messages with base64-encoded attachments such as images. See [Handling large attachments](https://mastra.ai/docs/memory/storage) for workarounds including uploading attachments to external storage.
|
|
8
8
|
|
|
@@ -120,7 +120,7 @@ For local development, you can use [DynamoDB Local](https://docs.aws.amazon.com/
|
|
|
120
120
|
|
|
121
121
|
**config.ttl** (`object`): TTL (Time To Live) configuration for automatic data expiration. Configure per entity type: thread, message, trace, eval, workflow\_snapshot, resource, score. Each entity config includes: enabled (boolean), attributeName (string, default: 'ttl'), defaultTtlSeconds (number).
|
|
122
122
|
|
|
123
|
-
## TTL (
|
|
123
|
+
## TTL (time to live) configuration
|
|
124
124
|
|
|
125
125
|
DynamoDB TTL allows you to automatically delete items after a specified time period. This is useful for:
|
|
126
126
|
|
|
@@ -211,12 +211,12 @@ aws dynamodb update-time-to-live \
|
|
|
211
211
|
1. Go to the DynamoDB console
|
|
212
212
|
2. Select your table
|
|
213
213
|
3. Go to "Additional settings" tab
|
|
214
|
-
4. Under "Time to Live (TTL)",
|
|
214
|
+
4. Under "Time to Live (TTL)", select "Manage TTL"
|
|
215
215
|
5. Enable TTL and specify the attribute name (default: `ttl`)
|
|
216
216
|
|
|
217
217
|
> **Note:** DynamoDB deletes expired items within 48 hours after expiration. Items remain queryable until actually deleted.
|
|
218
218
|
|
|
219
|
-
## AWS IAM
|
|
219
|
+
## AWS IAM permissions
|
|
220
220
|
|
|
221
221
|
The IAM role or user executing the code needs appropriate permissions to interact with the specified DynamoDB table and its indexes. Below is a sample policy. Replace `${YOUR_TABLE_NAME}` with your actual table name and `${YOUR_AWS_REGION}` and `${YOUR_AWS_ACCOUNT_ID}` with appropriate values.
|
|
222
222
|
|
|
@@ -246,7 +246,7 @@ The IAM role or user executing the code needs appropriate permissions to interac
|
|
|
246
246
|
}
|
|
247
247
|
```
|
|
248
248
|
|
|
249
|
-
## Key
|
|
249
|
+
## Key considerations
|
|
250
250
|
|
|
251
251
|
Before diving into the architectural details, keep these key points in mind when working with the DynamoDB storage adapter:
|
|
252
252
|
|
|
@@ -255,7 +255,7 @@ Before diving into the architectural details, keep these key points in mind when
|
|
|
255
255
|
- **Understanding GSIs:** Familiarity with how the GSIs are structured (as per `TABLE_SETUP.md`) is important for understanding data retrieval and potential query patterns.
|
|
256
256
|
- **ElectroDB:** The adapter uses ElectroDB to manage interactions with DynamoDB, providing a layer of abstraction and type safety over raw DynamoDB operations.
|
|
257
257
|
|
|
258
|
-
## Architectural
|
|
258
|
+
## Architectural approach
|
|
259
259
|
|
|
260
260
|
This storage adapter utilizes a **single-table design pattern** leveraging [ElectroDB](https://electrodb.dev/), a common and recommended approach for DynamoDB. This differs architecturally from relational database adapters (like `@mastra/pg` or `@mastra/libsql`) that typically use multiple tables, each dedicated to a specific entity (threads, messages, etc.).
|
|
261
261
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# MongoDB
|
|
1
|
+
# MongoDB storage
|
|
2
2
|
|
|
3
3
|
The MongoDB storage implementation provides a scalable storage solution using MongoDB databases with support for both document storage and vector operations.
|
|
4
4
|
|
|
@@ -56,7 +56,7 @@ const storage = new MongoDBStore({
|
|
|
56
56
|
|
|
57
57
|
> **Deprecation Notice:** The `url` parameter is deprecated but still supported for backward compatibility. Please use `uri` instead in all new code.
|
|
58
58
|
|
|
59
|
-
## Constructor
|
|
59
|
+
## Constructor examples
|
|
60
60
|
|
|
61
61
|
You can instantiate `MongoDBStore` in the following ways:
|
|
62
62
|
|
|
@@ -84,7 +84,7 @@ const store2 = new MongoDBStore({
|
|
|
84
84
|
})
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
## Additional
|
|
87
|
+
## Additional notes
|
|
88
88
|
|
|
89
89
|
### Collection Management
|
|
90
90
|
|
|
@@ -136,9 +136,9 @@ const memoryStore = await storage.getStore('memory')
|
|
|
136
136
|
const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
> **Warning:** If `init()`
|
|
139
|
+
> **Warning:** If `init()` isn't called, collections won't be created and storage operations will fail silently or throw errors.
|
|
140
140
|
|
|
141
|
-
## Vector
|
|
141
|
+
## Vector search capabilities
|
|
142
142
|
|
|
143
143
|
MongoDB storage includes built-in vector search capabilities for AI applications:
|
|
144
144
|
|
|
@@ -190,7 +190,7 @@ const results = await vectorStore.query({
|
|
|
190
190
|
});
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
## Usage
|
|
193
|
+
## Usage example
|
|
194
194
|
|
|
195
195
|
### Adding memory to an agent
|
|
196
196
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# PostgreSQL
|
|
1
|
+
# PostgreSQL storage
|
|
2
2
|
|
|
3
3
|
The PostgreSQL storage implementation provides a production-ready storage solution using PostgreSQL databases.
|
|
4
4
|
|
|
@@ -71,7 +71,7 @@ const storage = new PostgresStore({
|
|
|
71
71
|
|
|
72
72
|
**indexes** (`CreateIndexOptions[]`): Custom indexes to create during initialization.
|
|
73
73
|
|
|
74
|
-
## Constructor
|
|
74
|
+
## Constructor examples
|
|
75
75
|
|
|
76
76
|
You can instantiate `PostgresStore` in the following ways:
|
|
77
77
|
|
|
@@ -119,7 +119,7 @@ const store4 = new PostgresStore({
|
|
|
119
119
|
})
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
## Additional
|
|
122
|
+
## Additional notes
|
|
123
123
|
|
|
124
124
|
### Schema Management
|
|
125
125
|
|
|
@@ -177,7 +177,7 @@ const memoryStore = await storage.getStore('memory')
|
|
|
177
177
|
const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
> **Warning:** If `init()`
|
|
180
|
+
> **Warning:** If `init()` isn't called, tables won't be created and storage operations will fail silently or throw errors.
|
|
181
181
|
|
|
182
182
|
### Using an Existing Pool
|
|
183
183
|
|
|
@@ -201,7 +201,7 @@ const storage = new PostgresStore({
|
|
|
201
201
|
|
|
202
202
|
**Pool lifecycle behavior:**
|
|
203
203
|
|
|
204
|
-
- When you **provide a pool**: Mastra uses your pool but
|
|
204
|
+
- When you **provide a pool**: Mastra uses your pool but **doesn't** close it when `store.close()` is called. You manage the pool lifecycle.
|
|
205
205
|
- When Mastra **creates a pool**: Mastra owns the pool and will close it when `store.close()` is called.
|
|
206
206
|
|
|
207
207
|
### Direct Database and Pool Access
|
|
@@ -316,7 +316,7 @@ This pattern ensures only one `PostgresStore` instance is created regardless of
|
|
|
316
316
|
|
|
317
317
|
> **Tip:** This singleton pattern is only necessary during local development with HMR. In production builds, modules are only loaded once.
|
|
318
318
|
|
|
319
|
-
## Usage
|
|
319
|
+
## Usage example
|
|
320
320
|
|
|
321
321
|
### Adding memory to an agent
|
|
322
322
|
|
|
@@ -387,7 +387,7 @@ for await (const chunk of stream.textStream) {
|
|
|
387
387
|
}
|
|
388
388
|
```
|
|
389
389
|
|
|
390
|
-
## Index
|
|
390
|
+
## Index management
|
|
391
391
|
|
|
392
392
|
PostgreSQL storage provides index management to optimize query performance.
|
|
393
393
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# Upstash
|
|
1
|
+
# Upstash storage
|
|
2
2
|
|
|
3
3
|
The Upstash storage implementation provides a serverless-friendly storage solution using Upstash's Redis-compatible key-value store.
|
|
4
4
|
|
|
5
5
|
> **Pricing:** When using Mastra with Upstash, the pay-as-you-go model can result in unexpectedly high costs due to the high volume of Redis commands generated during agent conversations. We strongly recommend using a **fixed pricing plan** for predictable costs. See [Upstash pricing](https://upstash.com/pricing/redis) for details and [GitHub issue #5850](https://github.com/mastra-ai/mastra/issues/5850) for context.
|
|
6
6
|
|
|
7
|
-
> **Observability Not Supported:** Upstash storage **
|
|
7
|
+
> **Observability Not Supported:** Upstash storage **doesn't support the observability domain**. Traces from the `DefaultExporter` can't be persisted to Upstash, and Mastra Studio's observability features won't work with Upstash as your only storage provider. To enable observability, use [composite storage](https://mastra.ai/reference/storage/composite) to route observability data to a supported provider like ClickHouse or PostgreSQL.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -52,7 +52,7 @@ const storage = new UpstashStore({
|
|
|
52
52
|
|
|
53
53
|
**prefix** (`string`): Key prefix for all stored items (Default: `mastra:`)
|
|
54
54
|
|
|
55
|
-
## Additional
|
|
55
|
+
## Additional notes
|
|
56
56
|
|
|
57
57
|
### Key Structure
|
|
58
58
|
|
|
@@ -87,7 +87,7 @@ For optimal performance:
|
|
|
87
87
|
- Monitor Redis memory usage
|
|
88
88
|
- Consider data expiration policies if needed
|
|
89
89
|
|
|
90
|
-
## Usage
|
|
90
|
+
## Usage example
|
|
91
91
|
|
|
92
92
|
### Adding memory to an agent
|
|
93
93
|
|