@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.
Files changed (62) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/{chunk-GBBQIJQF.js → chunk-3CM4XQJO.js} +1940 -463
  3. package/dist/chunk-3CM4XQJO.js.map +1 -0
  4. package/dist/{chunk-D6II7EP4.cjs → chunk-5W5463NI.cjs} +1939 -461
  5. package/dist/chunk-5W5463NI.cjs.map +1 -0
  6. package/dist/docs/SKILL.md +24 -24
  7. package/dist/docs/assets/SOURCE_MAP.json +25 -25
  8. package/dist/docs/references/docs-agents-agent-approval.md +3 -3
  9. package/dist/docs/references/docs-agents-agent-memory.md +3 -3
  10. package/dist/docs/references/docs-agents-network-approval.md +5 -2
  11. package/dist/docs/references/docs-agents-networks.md +2 -2
  12. package/dist/docs/references/docs-agents-supervisor-agents.md +3 -3
  13. package/dist/docs/references/docs-memory-memory-processors.md +9 -9
  14. package/dist/docs/references/docs-memory-message-history.md +4 -4
  15. package/dist/docs/references/docs-memory-observational-memory.md +11 -7
  16. package/dist/docs/references/docs-memory-semantic-recall.md +9 -9
  17. package/dist/docs/references/docs-memory-storage.md +1 -1
  18. package/dist/docs/references/docs-memory-working-memory.md +20 -20
  19. package/dist/docs/references/reference-core-getMemory.md +1 -1
  20. package/dist/docs/references/reference-core-listMemory.md +1 -1
  21. package/dist/docs/references/reference-memory-clone-utilities.md +7 -7
  22. package/dist/docs/references/reference-memory-cloneThread.md +5 -5
  23. package/dist/docs/references/reference-memory-createThread.md +1 -1
  24. package/dist/docs/references/reference-memory-getThreadById.md +1 -1
  25. package/dist/docs/references/reference-memory-listThreads.md +3 -3
  26. package/dist/docs/references/reference-memory-memory-class.md +1 -1
  27. package/dist/docs/references/reference-memory-observational-memory.md +8 -6
  28. package/dist/docs/references/reference-processors-token-limiter-processor.md +2 -2
  29. package/dist/docs/references/reference-storage-dynamodb.md +7 -7
  30. package/dist/docs/references/reference-storage-libsql.md +1 -1
  31. package/dist/docs/references/reference-storage-mongodb.md +6 -6
  32. package/dist/docs/references/reference-storage-postgresql.md +7 -7
  33. package/dist/docs/references/reference-storage-upstash.md +4 -4
  34. package/dist/docs/references/reference-vectors-libsql.md +15 -15
  35. package/dist/docs/references/reference-vectors-mongodb.md +18 -18
  36. package/dist/docs/references/reference-vectors-pg.md +23 -21
  37. package/dist/docs/references/reference-vectors-upstash.md +15 -15
  38. package/dist/index.cjs +48 -25
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/index.d.ts +14 -14
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +44 -21
  43. package/dist/index.js.map +1 -1
  44. package/dist/{observational-memory-AHVELJX4.cjs → observational-memory-C5LO7RBR.cjs} +17 -17
  45. package/dist/{observational-memory-AHVELJX4.cjs.map → observational-memory-C5LO7RBR.cjs.map} +1 -1
  46. package/dist/{observational-memory-QFQUF5EY.js → observational-memory-OYK4MEUD.js} +3 -3
  47. package/dist/{observational-memory-QFQUF5EY.js.map → observational-memory-OYK4MEUD.js.map} +1 -1
  48. package/dist/processors/index.cjs +15 -15
  49. package/dist/processors/index.js +1 -1
  50. package/dist/processors/observational-memory/observational-memory.d.ts +33 -2
  51. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  52. package/dist/processors/observational-memory/observer-agent.d.ts +7 -4
  53. package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
  54. package/dist/processors/observational-memory/repro-capture.d.ts +23 -0
  55. package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -0
  56. package/dist/processors/observational-memory/token-counter.d.ts +28 -3
  57. package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
  58. package/dist/tools/working-memory.d.ts +6 -10
  59. package/dist/tools/working-memory.d.ts.map +1 -1
  60. package/package.json +16 -11
  61. package/dist/chunk-D6II7EP4.cjs.map +0 -1
  62. 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 Start
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 Works
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 Persistence Scopes
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 Adapter Support
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 Templates
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 Info
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 State
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 Effective Templates
171
+ ## Designing effective templates
172
172
 
173
- A well-structured template keeps the information easy for the agent to parse and update. Treat the template as a short form that you want the assistant to keep up to date.
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 easy to read and less likely to be truncated.
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 simple.** Use hints such as `[e.g., Formal]` or `[Date]` to help the LLM fill in the correct spots.
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 Working Memory
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 are not merged element-by-element)
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 Between Template and Schema
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` is not supported.
272
+ - Only one mode can be active at a time: setting both `template` and `schema` isn't supported.
273
273
 
274
- ## Example: Multi-step Retention
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 Info
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 is not 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.
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 Initial Working Memory
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-Only Working Memory
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 Retrieving Memory
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 Registered Memory
23
+ ## Example: Checking registered memory
24
24
 
25
25
  ```typescript
26
26
  import { Mastra } from '@mastra/core'
@@ -1,8 +1,8 @@
1
- # Cloned Thread Utilities
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 Example
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 Example
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 Usage Example
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 Embeddings
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 Memory
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 are not copied. Transient processing state (observation/reflection in-progress flags) is reset on the cloned record.
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 Example
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 `.getThreadById()` method retrieves a specific thread by its ID.
4
4
 
5
- ## Usage Example
5
+ ## Usage example
6
6
 
7
7
  ```typescript
8
8
  await memory?.getThreadById({ threadId: 'thread-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 Examples
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 Filtering
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 Class
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 Memory
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 does not match.
84
- - Per-message and per-conversation overhead are always recomputed at runtime and are not cached.
85
- - `data-*` and `reasoning` parts are skipped and do not receive cache entries.
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 is not supported with `scope: 'resource'` and is automatically disabled in resource scope.
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 cannot 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 cannot send an LLM request with only system messages and no user/assistant messages.
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 Storage
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 **does not support the observability domain**. Traces from the `DefaultExporter` cannot 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.
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 (Time To Live) Configuration
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)", click "Manage 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 Permissions
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 Considerations
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 Approach
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
- # libSQL Storage
1
+ # libSQL storage
2
2
 
3
3
  [libSQL](https://docs.turso.tech/libsql) is an open-source, SQLite-compatible database that supports both local and remote deployments. It can be used to store message history, workflow snapshots, traces, and eval scores.
4
4
 
@@ -1,4 +1,4 @@
1
- # MongoDB Storage
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 Examples
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 Notes
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()` is not called, collections won't be created and storage operations will fail silently or throw errors.
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 Search Capabilities
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 Example
193
+ ## Usage example
194
194
 
195
195
  ### Adding memory to an agent
196
196
 
@@ -1,4 +1,4 @@
1
- # PostgreSQL Storage
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 Examples
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 Notes
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()` is not called, tables won't be created and storage operations will fail silently or throw errors.
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 does **not** close it when `store.close()` is called. You manage the pool lifecycle.
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 Example
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 Management
390
+ ## Index management
391
391
 
392
392
  PostgreSQL storage provides index management to optimize query performance.
393
393
 
@@ -1,10 +1,10 @@
1
- # Upstash Storage
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 **does not support the observability domain**. Traces from the `DefaultExporter` cannot 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.
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 Notes
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 Example
90
+ ## Usage example
91
91
 
92
92
  ### Adding memory to an agent
93
93