@mastra/memory 1.17.6-alpha.0 → 1.18.0-alpha.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 (31) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/{chunk-ZUUSLGY6.cjs → chunk-MJNTQ6GP.cjs} +84 -31
  3. package/dist/chunk-MJNTQ6GP.cjs.map +1 -0
  4. package/dist/{chunk-NUYSX3DD.js → chunk-PBZHHKPE.js} +84 -31
  5. package/dist/chunk-PBZHHKPE.js.map +1 -0
  6. package/dist/docs/SKILL.md +1 -1
  7. package/dist/docs/assets/SOURCE_MAP.json +39 -39
  8. package/dist/docs/references/docs-agents-background-tasks.md +62 -2
  9. package/dist/docs/references/docs-memory-observational-memory.md +7 -2
  10. package/dist/docs/references/docs-memory-overview.md +2 -1
  11. package/dist/docs/references/docs-memory-semantic-recall.md +68 -6
  12. package/dist/index.cjs +329 -177
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +320 -168
  16. package/dist/index.js.map +1 -1
  17. package/dist/{observational-memory-KH7G7Y6B.js → observational-memory-IP2RVQQG.js} +3 -3
  18. package/dist/{observational-memory-KH7G7Y6B.js.map → observational-memory-IP2RVQQG.js.map} +1 -1
  19. package/dist/{observational-memory-BOXSRJOR.cjs → observational-memory-TASIB4PH.cjs} +26 -26
  20. package/dist/{observational-memory-BOXSRJOR.cjs.map → observational-memory-TASIB4PH.cjs.map} +1 -1
  21. package/dist/processors/index.cjs +24 -24
  22. package/dist/processors/index.js +1 -1
  23. package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -1
  24. package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts +9 -0
  25. package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts.map +1 -0
  26. package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
  27. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  28. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  29. package/package.json +4 -4
  30. package/dist/chunk-NUYSX3DD.js.map +0 -1
  31. package/dist/chunk-ZUUSLGY6.cjs.map +0 -1
@@ -3,7 +3,7 @@ name: mastra-memory
3
3
  description: Documentation for @mastra/memory. Use when working with @mastra/memory APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/memory"
6
- version: "1.17.6-alpha.0"
6
+ version: "1.18.0-alpha.2"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,119 +1,119 @@
1
1
  {
2
- "version": "1.17.6-alpha.0",
2
+ "version": "1.18.0-alpha.2",
3
3
  "package": "@mastra/memory",
4
4
  "exports": {
5
5
  "ModelByInputTokens": {
6
6
  "types": "dist/processors/index.d.ts",
7
- "implementation": "dist/chunk-NUYSX3DD.js",
7
+ "implementation": "dist/chunk-PBZHHKPE.js",
8
8
  "line": 745
9
9
  },
10
10
  "OBSERVER_SYSTEM_PROMPT": {
11
11
  "types": "dist/processors/index.d.ts",
12
- "implementation": "dist/chunk-NUYSX3DD.js"
12
+ "implementation": "dist/chunk-PBZHHKPE.js"
13
13
  },
14
14
  "ObservationalMemory": {
15
15
  "types": "dist/processors/index.d.ts",
16
- "implementation": "dist/chunk-NUYSX3DD.js",
17
- "line": 6673
16
+ "implementation": "dist/chunk-PBZHHKPE.js",
17
+ "line": 6690
18
18
  },
19
19
  "ObservationalMemoryProcessor": {
20
20
  "types": "dist/processors/index.d.ts",
21
- "implementation": "dist/chunk-NUYSX3DD.js",
22
- "line": 9215
21
+ "implementation": "dist/chunk-PBZHHKPE.js",
22
+ "line": 9262
23
23
  },
24
24
  "TokenCounter": {
25
25
  "types": "dist/processors/index.d.ts",
26
- "implementation": "dist/chunk-NUYSX3DD.js",
27
- "line": 6143
26
+ "implementation": "dist/chunk-PBZHHKPE.js",
27
+ "line": 6160
28
28
  },
29
29
  "buildObserverPrompt": {
30
30
  "types": "dist/processors/index.d.ts",
31
- "implementation": "dist/chunk-NUYSX3DD.js",
32
- "line": 3642
31
+ "implementation": "dist/chunk-PBZHHKPE.js",
32
+ "line": 3659
33
33
  },
34
34
  "buildObserverSystemPrompt": {
35
35
  "types": "dist/processors/index.d.ts",
36
- "implementation": "dist/chunk-NUYSX3DD.js",
37
- "line": 2950
36
+ "implementation": "dist/chunk-PBZHHKPE.js",
37
+ "line": 2967
38
38
  },
39
39
  "combineObservationGroupRanges": {
40
40
  "types": "dist/processors/index.d.ts",
41
- "implementation": "dist/chunk-NUYSX3DD.js",
41
+ "implementation": "dist/chunk-PBZHHKPE.js",
42
42
  "line": 837
43
43
  },
44
44
  "deriveObservationGroupProvenance": {
45
45
  "types": "dist/processors/index.d.ts",
46
- "implementation": "dist/chunk-NUYSX3DD.js",
46
+ "implementation": "dist/chunk-PBZHHKPE.js",
47
47
  "line": 871
48
48
  },
49
49
  "extractCurrentTask": {
50
50
  "types": "dist/processors/index.d.ts",
51
- "implementation": "dist/chunk-NUYSX3DD.js",
52
- "line": 3756
51
+ "implementation": "dist/chunk-PBZHHKPE.js",
52
+ "line": 3773
53
53
  },
54
54
  "formatMessagesForObserver": {
55
55
  "types": "dist/processors/index.d.ts",
56
- "implementation": "dist/chunk-NUYSX3DD.js",
57
- "line": 3368
56
+ "implementation": "dist/chunk-PBZHHKPE.js",
57
+ "line": 3385
58
58
  },
59
59
  "getObservationsAsOf": {
60
60
  "types": "dist/processors/index.d.ts",
61
- "implementation": "dist/chunk-NUYSX3DD.js",
62
- "line": 9421
61
+ "implementation": "dist/chunk-PBZHHKPE.js",
62
+ "line": 9474
63
63
  },
64
64
  "hasCurrentTaskSection": {
65
65
  "types": "dist/processors/index.d.ts",
66
- "implementation": "dist/chunk-NUYSX3DD.js",
67
- "line": 3744
66
+ "implementation": "dist/chunk-PBZHHKPE.js",
67
+ "line": 3761
68
68
  },
69
69
  "injectAnchorIds": {
70
70
  "types": "dist/processors/index.d.ts",
71
- "implementation": "dist/chunk-NUYSX3DD.js",
72
- "line": 2498
71
+ "implementation": "dist/chunk-PBZHHKPE.js",
72
+ "line": 2515
73
73
  },
74
74
  "optimizeObservationsForContext": {
75
75
  "types": "dist/processors/index.d.ts",
76
- "implementation": "dist/chunk-NUYSX3DD.js",
77
- "line": 3767
76
+ "implementation": "dist/chunk-PBZHHKPE.js",
77
+ "line": 3784
78
78
  },
79
79
  "parseAnchorId": {
80
80
  "types": "dist/processors/index.d.ts",
81
- "implementation": "dist/chunk-NUYSX3DD.js",
82
- "line": 2471
81
+ "implementation": "dist/chunk-PBZHHKPE.js",
82
+ "line": 2488
83
83
  },
84
84
  "parseObservationGroups": {
85
85
  "types": "dist/processors/index.d.ts",
86
- "implementation": "dist/chunk-NUYSX3DD.js",
86
+ "implementation": "dist/chunk-PBZHHKPE.js",
87
87
  "line": 806
88
88
  },
89
89
  "parseObserverOutput": {
90
90
  "types": "dist/processors/index.d.ts",
91
- "implementation": "dist/chunk-NUYSX3DD.js",
92
- "line": 3652
91
+ "implementation": "dist/chunk-PBZHHKPE.js",
92
+ "line": 3669
93
93
  },
94
94
  "reconcileObservationGroupsFromReflection": {
95
95
  "types": "dist/processors/index.d.ts",
96
- "implementation": "dist/chunk-NUYSX3DD.js",
96
+ "implementation": "dist/chunk-PBZHHKPE.js",
97
97
  "line": 895
98
98
  },
99
99
  "renderObservationGroupsForReflection": {
100
100
  "types": "dist/processors/index.d.ts",
101
- "implementation": "dist/chunk-NUYSX3DD.js",
101
+ "implementation": "dist/chunk-PBZHHKPE.js",
102
102
  "line": 851
103
103
  },
104
104
  "stripEphemeralAnchorIds": {
105
105
  "types": "dist/processors/index.d.ts",
106
- "implementation": "dist/chunk-NUYSX3DD.js",
107
- "line": 2528
106
+ "implementation": "dist/chunk-PBZHHKPE.js",
107
+ "line": 2545
108
108
  },
109
109
  "stripObservationGroups": {
110
110
  "types": "dist/processors/index.d.ts",
111
- "implementation": "dist/chunk-NUYSX3DD.js",
111
+ "implementation": "dist/chunk-PBZHHKPE.js",
112
112
  "line": 828
113
113
  },
114
114
  "wrapInObservationGroup": {
115
115
  "types": "dist/processors/index.d.ts",
116
- "implementation": "dist/chunk-NUYSX3DD.js",
116
+ "implementation": "dist/chunk-PBZHHKPE.js",
117
117
  "line": 799
118
118
  },
119
119
  "OBSERVATIONAL_MEMORY_DEFAULTS": {
@@ -149,7 +149,7 @@
149
149
  "processors": {
150
150
  "index": "dist/processors/index.js",
151
151
  "chunks": [
152
- "chunk-NUYSX3DD.js",
152
+ "chunk-PBZHHKPE.js",
153
153
  "chunk-LSJJAJAF.js"
154
154
  ]
155
155
  }
@@ -127,10 +127,12 @@ When a tool call dispatches as a background task, two streams may surface lifecy
127
127
  | `background-task-completed` | The task finished successfully. The `payload.result` matches the eventual tool result. | Manager stream |
128
128
  | `background-task-failed` | The task threw or timed out. | Manager stream |
129
129
  | `background-task-cancelled` | The task was cancelled before completing. | Manager stream |
130
+ | `background-task-suspended` | The tool called `suspend()` from inside its execute. | Manager stream |
131
+ | `background-task-resumed` | A suspended task was resumed via `manager.resume(taskId, resumeData)`. | Manager stream |
130
132
 
131
- `agent.stream().fullStream` only emits the agent-loop chunks (`background-task-started`, `background-task-progress`) on its own. `agent.streamUntilIdle()` emits the same two chunks and additionally subscribes to the manager pubsub for the run's memory scope and pipes the five manager chunks (`background-task-running`, `background-task-output`, `background-task-completed`, `background-task-failed`, `background-task-cancelled`) into the same `fullStream`, so consumers of `streamUntilIdle().fullStream` see all seven types.
133
+ `agent.stream().fullStream` only emits the agent-loop chunks (`background-task-started`, `background-task-progress`) on its own. `agent.streamUntilIdle()` emits the same two chunks and additionally subscribes to the manager pubsub for the run's memory scope and pipes the seven manager chunks (`background-task-running`, `background-task-output`, `background-task-completed`, `background-task-failed`, `background-task-cancelled`, `background-task-suspended`, `background-task-resumed`) into the same `fullStream`.
132
134
 
133
- `backgroundTaskManager.stream()` only emits the five manager chunks.
135
+ `backgroundTaskManager.stream()` only emits the seven manager chunks.
134
136
 
135
137
  The full payload shapes are documented in the [background task chunks reference](https://mastra.ai/reference/streaming/ChunkType).
136
138
 
@@ -210,6 +212,64 @@ When this `researchAgent` is delegated to from a supervisor that has no backgrou
210
212
 
211
213
  Use this pattern when you want a subagent to behave consistently in the background regardless of which supervisor invokes it. Use the supervisor-side opt-in (above) when you want to tune background behavior centrally per supervisor.
212
214
 
215
+ ## Suspending and resuming
216
+
217
+ A background task can pause itself mid-execution and wait for an external signal before continuing. This is useful for human approvals, webhooks, or any flow where the next step depends on data that arrives later.
218
+
219
+ A tool calls `suspend(data)` from inside its `execute`, which:
220
+
221
+ - Persists `status: 'suspended'` and the `data` payload on the task record.
222
+ - Saves the workflow snapshot so the run survives process restarts.
223
+ - Emits a `background-task-suspended` chunk on the manager stream.
224
+ - Releases the concurrency slot so other tasks can run.
225
+
226
+ Resume the task with `mastra.backgroundTaskManager.resume(taskId, resumeData)`. The `resumeData` arrives in the tool's `execute` options on the resumed run, and the task transitions back to `running`.
227
+
228
+ ```typescript
229
+ import { createTool } from '@mastra/core/tools'
230
+ import { z } from 'zod'
231
+
232
+ export const reviewTool = createTool({
233
+ id: 'review',
234
+ description: 'Submit a draft for human review.',
235
+ inputSchema: z.object({ draft: z.string() }),
236
+ outputSchema: z.object({ approvedBy: z.string(), edits: z.string().optional() }),
237
+ background: { enabled: true },
238
+ execute: async ({ draft }, context) => {
239
+ const { suspend, resumeData } = context.agent
240
+ if (!resumeData) {
241
+ await suspend?.({ awaiting: 'approval', draft })
242
+ return { approvedBy: '', edits: undefined }
243
+ }
244
+ const { reviewer, edits } = resumeData as { reviewer: string; edits?: string }
245
+ return { approvedBy: reviewer, edits }
246
+ },
247
+ })
248
+ ```
249
+
250
+ The first invocation of `execute` sees `resumeData === undefined` and calls `suspend`. After the task is resumed, the runtime restarts the tool with `resumeData` populated; the `if` branch falls through and the tool returns its real result.
251
+
252
+ To resume the task once an approval arrives:
253
+
254
+ ```typescript
255
+ await mastra.backgroundTaskManager?.resume(taskId, {
256
+ reviewer: 'alice@example.com',
257
+ edits: 'Reworded paragraph 3.',
258
+ })
259
+ ```
260
+
261
+ ### What happens to the agent loop
262
+
263
+ When a task suspends mid-`streamUntilIdle()`, the wrapper treats it as terminal for the current iteration and closes. To continue the agent immediately when the resume payload is in hand, call `agent.resumeStreamUntilIdle(resumeData, { runId, toolCallId, memory })`: the resumed bg task runs to completion, its result lands in the message list, and the agent runs a follow-up turn — all on the same SSE connection. If you'd rather drive the resume out-of-band, call `mastra.backgroundTaskManager.resume(taskId, resumeData)` directly and the result still writes into the thread for the next user turn to pick up.
264
+
265
+ ### Re-registering the executor on resume
266
+
267
+ The manager keeps tool executors in process memory. If the process restarts while a task is suspended, the executor closure is gone — the caller of `resume()` must re-register it first via `manager.registerTaskContext(taskId, ...)`. Tasks dispatched and resumed inside the same process don't need this.
268
+
269
+ ### Cancelling a suspended task
270
+
271
+ `manager.cancel(taskId)` works against suspended tasks the same way it works for running ones: the row flips to `cancelled`, the workflow snapshot is cleaned up, and a `task.cancelled` event fires.
272
+
213
273
  ## Lifecycle callbacks
214
274
 
215
275
  Each layer can register terminal-state callbacks. They don't replace one another, and success/failure hooks fire for their respective outcomes:
@@ -216,7 +216,7 @@ The Observer and Reflector run in the background. Any model that works with Mast
216
216
 
217
217
  Generally speaking, we recommend using a model that has a large context window (128K+ tokens) and is fast enough to run in the background without slowing down your actions.
218
218
 
219
- If you're unsure which model to use, start with the default `google/gemini-2.5-flash`. We've also successfully tested `openai/gpt-5-mini`, `anthropic/claude-haiku-4-5`, `deepseek/deepseek-reasoner`, `qwen3`, and `glm-4.7`.
219
+ If you're unsure which model to use, start with the default `google/gemini-2.5-flash`. We've also successfully tested `openai/gpt-5-mini`, `anthropic/claude-haiku-4-5`, `deepseek/deepseek-reasoner`, `deepseek/deepseek-v4-pro`, `deepseek/deepseek-v4-flash`, `xai/grok-4-1-fast`, `qwen3`, and `glm-4.7`.
220
220
 
221
221
  ```typescript
222
222
  const memory = new Memory({
@@ -230,6 +230,10 @@ const memory = new Memory({
230
230
 
231
231
  See [model configuration](https://mastra.ai/reference/memory/observational-memory) for using different models per agent.
232
232
 
233
+ > **Note:** `google/gemini-2.5-flash` is unusually good at preserving detail in long output. As a result, the Reflector can produce reflections that stay above the configured `reflection.observationTokens` threshold even after the maximum compression retry. When this happens, the Reflector returns the smallest non-degenerate candidate produced during retries so the loop terminates instead of running forever.
234
+ >
235
+ > If you'd rather have more aggressive compression on the Reflector, swap to a model that condenses more readily, such as `xai/grok-4-1-fast`, `deepseek/deepseek-v4-pro`, or `deepseek/deepseek-v4-flash`. You can keep `google/gemini-2.5-flash` for the Observer and use a different model for the Reflector — see [different models per agent](https://mastra.ai/reference/memory/observational-memory).
236
+
233
237
  ### Token-tiered model selection
234
238
 
235
239
  **Added in:** `@mastra/memory@1.10.0`
@@ -458,4 +462,5 @@ In practical terms, OM replaces both working memory and message history, and has
458
462
  - [Observational Memory Reference](https://mastra.ai/reference/memory/observational-memory)
459
463
  - [Memory Overview](https://mastra.ai/docs/memory/overview)
460
464
  - [Message History](https://mastra.ai/docs/memory/message-history)
461
- - [Memory Processors](https://mastra.ai/docs/memory/memory-processors)
465
+ - [Memory Processors](https://mastra.ai/docs/memory/memory-processors)
466
+ - [Mastra Code](https://code.mastra.ai/): A coding agent using Observational Memory
@@ -237,4 +237,5 @@ export const memoryAgent = new Agent({
237
237
 
238
238
  - [`Memory` reference](https://mastra.ai/reference/memory/memory-class)
239
239
  - [Tracing](https://mastra.ai/docs/observability/tracing/overview)
240
- - [Request Context](https://mastra.ai/docs/server/request-context)
240
+ - [Request Context](https://mastra.ai/docs/server/request-context)
241
+ - [Mastra Code](https://code.mastra.ai/): A coding agent using Mastra's memory system
@@ -121,26 +121,88 @@ Each vector store page below includes installation instructions, configuration p
121
121
 
122
122
  ## Recall configuration
123
123
 
124
- The three main parameters that control semantic recall behavior are:
124
+ The following options control semantic recall behavior:
125
125
 
126
- 1. **topK**: How many semantically similar messages to retrieve
127
- 2. **messageRange**: How much surrounding context to include with each match
128
- 3. **scope**: Whether to search within the current thread or across all threads owned by a resource (the default is resource scope).
126
+ 1. **topK**: The number of similar messages to retrieve
127
+ 2. **messageRange**: The surrounding messages to include with each match
128
+ 3. **scope**: Whether to search the current thread or all threads for a resource
129
+ 4. **filter**: Metadata criteria that restrict search results
129
130
 
130
131
  ```typescript
131
132
  const agent = new Agent({
132
133
  memory: new Memory({
133
134
  options: {
134
135
  semanticRecall: {
135
- topK: 3, // Retrieve 3 most similar messages
136
+ topK: 3, // Retrieve 3 similar messages
136
137
  messageRange: 2, // Include 2 messages before and after each match
137
- scope: 'resource', // Search across all threads for this user (default setting if omitted)
138
+ scope: 'resource', // Search all threads for this resource
139
+ filter: { projectId: { $eq: 'project-a' } },
138
140
  },
139
141
  },
140
142
  }),
141
143
  })
142
144
  ```
143
145
 
146
+ > **Note:** `scope: 'resource'` is supported by the LibSQL, PostgreSQL, and Upstash storage adapters.
147
+
148
+ ### Metadata filtering
149
+
150
+ The `filter` option restricts semantic recall results to messages with matching thread metadata.
151
+
152
+ ```typescript
153
+ const agent = new Agent({
154
+ memory: new Memory({
155
+ options: {
156
+ semanticRecall: {
157
+ scope: 'resource',
158
+ filter: {
159
+ projectId: { $eq: 'project-a' },
160
+ category: { $in: ['work', 'personal'] },
161
+ },
162
+ },
163
+ },
164
+ }),
165
+ })
166
+ ```
167
+
168
+ Filters match metadata stored on message embeddings when messages are saved. If thread metadata changes later, existing embeddings keep their previous metadata until those messages are saved or indexed again.
169
+
170
+ Supported filter operators:
171
+
172
+ - `$and`: Logical AND
173
+ - `$eq`: Equal to
174
+ - `$gt`: Greater than
175
+ - `$gte`: Greater than or equal
176
+ - `$in`: In array
177
+ - `$lt`: Less than
178
+ - `$lte`: Less than or equal
179
+ - `$ne`: Not equal to
180
+ - `$nin`: Not in array
181
+ - `$or`: Logical OR
182
+
183
+ The following example demonstrates metadata filters for common use cases:
184
+
185
+ ```typescript
186
+ // Filter by project
187
+ const options = {
188
+ semanticRecall: { filter: { projectId: { $eq: 'my-project' } } },
189
+ }
190
+
191
+ // Filter by multiple categories
192
+ const options = {
193
+ semanticRecall: { filter: { category: { $in: ['work', 'research'] } } },
194
+ }
195
+
196
+ // Filter by project and priority
197
+ const options = {
198
+ semanticRecall: {
199
+ filter: {
200
+ $and: [{ projectId: { $eq: 'project-a' } }, { priority: { $gte: 3 } }],
201
+ },
202
+ },
203
+ }
204
+ ```
205
+
144
206
  ## Embedder configuration
145
207
 
146
208
  Semantic recall relies on an [embedding model](https://mastra.ai/reference/memory/memory-class) to convert messages into embeddings. Mastra supports embedding models through the model router using `provider/model` strings, or you can use any [embedding model](https://sdk.vercel.ai/docs/ai-sdk-core/embeddings) compatible with the AI SDK.