@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.
- package/CHANGELOG.md +22 -0
- package/dist/{chunk-ZUUSLGY6.cjs → chunk-MJNTQ6GP.cjs} +84 -31
- package/dist/chunk-MJNTQ6GP.cjs.map +1 -0
- package/dist/{chunk-NUYSX3DD.js → chunk-PBZHHKPE.js} +84 -31
- package/dist/chunk-PBZHHKPE.js.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +39 -39
- package/dist/docs/references/docs-agents-background-tasks.md +62 -2
- package/dist/docs/references/docs-memory-observational-memory.md +7 -2
- package/dist/docs/references/docs-memory-overview.md +2 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +68 -6
- package/dist/index.cjs +329 -177
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +320 -168
- package/dist/index.js.map +1 -1
- package/dist/{observational-memory-KH7G7Y6B.js → observational-memory-IP2RVQQG.js} +3 -3
- package/dist/{observational-memory-KH7G7Y6B.js.map → observational-memory-IP2RVQQG.js.map} +1 -1
- package/dist/{observational-memory-BOXSRJOR.cjs → observational-memory-TASIB4PH.cjs} +26 -26
- package/dist/{observational-memory-BOXSRJOR.cjs.map → observational-memory-TASIB4PH.cjs.map} +1 -1
- package/dist/processors/index.cjs +24 -24
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts +9 -0
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-NUYSX3DD.js.map +0 -1
- package/dist/chunk-ZUUSLGY6.cjs.map +0 -1
package/dist/docs/SKILL.md
CHANGED
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
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-
|
|
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-
|
|
12
|
+
"implementation": "dist/chunk-PBZHHKPE.js"
|
|
13
13
|
},
|
|
14
14
|
"ObservationalMemory": {
|
|
15
15
|
"types": "dist/processors/index.d.ts",
|
|
16
|
-
"implementation": "dist/chunk-
|
|
17
|
-
"line":
|
|
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-
|
|
22
|
-
"line":
|
|
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-
|
|
27
|
-
"line":
|
|
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-
|
|
32
|
-
"line":
|
|
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-
|
|
37
|
-
"line":
|
|
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-
|
|
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-
|
|
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-
|
|
52
|
-
"line":
|
|
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-
|
|
57
|
-
"line":
|
|
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-
|
|
62
|
-
"line":
|
|
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-
|
|
67
|
-
"line":
|
|
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-
|
|
72
|
-
"line":
|
|
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-
|
|
77
|
-
"line":
|
|
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-
|
|
82
|
-
"line":
|
|
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-
|
|
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-
|
|
92
|
-
"line":
|
|
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-
|
|
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-
|
|
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-
|
|
107
|
-
"line":
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
124
|
+
The following options control semantic recall behavior:
|
|
125
125
|
|
|
126
|
-
1. **topK**:
|
|
127
|
-
2. **messageRange**:
|
|
128
|
-
3. **scope**: Whether to search
|
|
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
|
|
136
|
+
topK: 3, // Retrieve 3 similar messages
|
|
136
137
|
messageRange: 2, // Include 2 messages before and after each match
|
|
137
|
-
scope: 'resource', // Search
|
|
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.
|