@mastra/libsql 0.0.0-error-handler-fix-20251020202607 → 0.0.0-esbuild-bundle-worker-20260807182016
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 +4789 -3
- package/LICENSE.md +15 -0
- package/README.md +30 -20
- package/dist/docs/SKILL.md +52 -0
- package/dist/docs/assets/SOURCE_MAP.json +6 -0
- package/dist/docs/references/docs-agents-agent-approval.md +664 -0
- package/dist/docs/references/docs-agents-networks.md +184 -0
- package/dist/docs/references/docs-deployment-workers.md +137 -0
- package/dist/docs/references/docs-editor-overview.md +349 -0
- package/dist/docs/references/docs-memory-memory-processors.md +385 -0
- package/dist/docs/references/docs-memory-message-history.md +348 -0
- package/dist/docs/references/docs-memory-multi-user-threads.md +208 -0
- package/dist/docs/references/docs-memory-overview.md +266 -0
- package/dist/docs/references/docs-memory-semantic-recall.md +401 -0
- package/dist/docs/references/docs-memory-working-memory.md +431 -0
- package/dist/docs/references/docs-storage-overview.md +214 -0
- package/dist/docs/references/docs-workflows-snapshots.md +240 -0
- package/dist/docs/references/guides-agent-frameworks-ai-sdk.md +142 -0
- package/dist/docs/references/guides-rag-retrieval.md +520 -0
- package/dist/docs/references/reference-core-getMemory.md +51 -0
- package/dist/docs/references/reference-core-listMemory.md +57 -0
- package/dist/docs/references/reference-core-mastra-class.md +153 -0
- package/dist/docs/references/reference-file-based-agents-memory.md +58 -0
- package/dist/docs/references/reference-file-based-agents-storage.md +30 -0
- package/dist/docs/references/reference-memory-memory-class.md +148 -0
- package/dist/docs/references/reference-storage-composite.md +397 -0
- package/dist/docs/references/reference-storage-dynamodb.md +284 -0
- package/dist/docs/references/reference-storage-libsql.md +143 -0
- package/dist/docs/references/reference-storage-retention.md +248 -0
- package/dist/docs/references/reference-vectors-libsql.md +307 -0
- package/dist/index.cjs +13164 -3390
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +13134 -3383
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +389 -0
- package/dist/storage/db/index.d.ts.map +1 -0
- package/dist/storage/db/utils.d.ts +84 -0
- package/dist/storage/db/utils.d.ts.map +1 -0
- package/dist/storage/db/write-lock.d.ts +8 -0
- package/dist/storage/db/write-lock.d.ts.map +1 -0
- package/dist/storage/domains/agents/index.d.ts +30 -0
- package/dist/storage/domains/agents/index.d.ts.map +1 -0
- package/dist/storage/domains/background-tasks/index.d.ts +27 -0
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -0
- package/dist/storage/domains/blobs/index.d.ts +17 -0
- package/dist/storage/domains/blobs/index.d.ts.map +1 -0
- package/dist/storage/domains/channels/index.d.ts +20 -0
- package/dist/storage/domains/channels/index.d.ts.map +1 -0
- package/dist/storage/domains/datasets/index.d.ts +43 -0
- package/dist/storage/domains/datasets/index.d.ts.map +1 -0
- package/dist/storage/domains/experiments/index.d.ts +54 -0
- package/dist/storage/domains/experiments/index.d.ts.map +1 -0
- package/dist/storage/domains/favorites/index.d.ts +17 -0
- package/dist/storage/domains/favorites/index.d.ts.map +1 -0
- package/dist/storage/domains/harness/index.d.ts +17 -0
- package/dist/storage/domains/harness/index.d.ts.map +1 -0
- package/dist/storage/domains/mcp-clients/index.d.ts +26 -0
- package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -0
- package/dist/storage/domains/mcp-servers/index.d.ts +26 -0
- package/dist/storage/domains/mcp-servers/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +58 -54
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/notifications/index.d.ts +23 -0
- package/dist/storage/domains/notifications/index.d.ts.map +1 -0
- package/dist/storage/domains/observability/index.d.ts +49 -29
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/prompt-blocks/index.d.ts +25 -0
- package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -0
- package/dist/storage/domains/schedules/index.d.ts +27 -0
- package/dist/storage/domains/schedules/index.d.ts.map +1 -0
- package/dist/storage/domains/scorer-definitions/index.d.ts +26 -0
- package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -0
- package/dist/storage/domains/scores/index.d.ts +29 -31
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/skills/index.d.ts +26 -0
- package/dist/storage/domains/skills/index.d.ts.map +1 -0
- package/dist/storage/domains/thread-state/index.d.ts +38 -0
- package/dist/storage/domains/thread-state/index.d.ts.map +1 -0
- package/dist/storage/domains/tool-provider-connections/index.d.ts +14 -0
- package/dist/storage/domains/tool-provider-connections/index.d.ts.map +1 -0
- package/dist/storage/domains/utils.d.ts +28 -54
- package/dist/storage/domains/utils.d.ts.map +1 -1
- package/dist/storage/domains/workflow-definitions/index.d.ts +14 -0
- package/dist/storage/domains/workflow-definitions/index.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +27 -32
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/domains/workspaces/index.d.ts +26 -0
- package/dist/storage/domains/workspaces/index.d.ts.map +1 -0
- package/dist/storage/factory-storage.d.ts +28 -0
- package/dist/storage/factory-storage.d.ts.map +1 -0
- package/dist/storage/index.d.ts +128 -255
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/retention.d.ts +77 -0
- package/dist/storage/retention.d.ts.map +1 -0
- package/dist/vector/index.d.ts +31 -4
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/sql-builder.d.ts.map +1 -1
- package/package.json +22 -16
- package/dist/storage/domains/legacy-evals/index.d.ts +0 -18
- package/dist/storage/domains/legacy-evals/index.d.ts.map +0 -1
- package/dist/storage/domains/operations/index.d.ts +0 -110
- package/dist/storage/domains/operations/index.d.ts.map +0 -1
- package/dist/storage/domains/traces/index.d.ts +0 -21
- package/dist/storage/domains/traces/index.d.ts.map +0 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Memory
|
|
4
|
+
|
|
5
|
+
Memory enables your agent to remember user messages and agent replies, and tool results across interactions, giving it the context it needs to stay consistent, maintain conversation flow, plus produce better answers over time.
|
|
6
|
+
|
|
7
|
+
Mastra agents can be configured to store [message history](https://mastra.ai/docs/memory/message-history). Additionally, you can enable:
|
|
8
|
+
|
|
9
|
+
- [Observational Memory](https://mastra.ai/docs/memory/observational-memory) (Recommended): Uses background agents to maintain a dense observation log that replaces raw message history as it grows. This keeps the context window small while preserving long-term memory.
|
|
10
|
+
- [Working memory](https://mastra.ai/docs/memory/working-memory): Stores persistent, structured user data such as names, preferences, and goals.
|
|
11
|
+
- [Semantic recall](https://mastra.ai/docs/memory/semantic-recall): Retrieves relevant past messages based on semantic meaning rather than exact keywords.
|
|
12
|
+
- [Multi-user threads](https://mastra.ai/docs/memory/multi-user-threads): Share one thread between multiple users.
|
|
13
|
+
|
|
14
|
+
If the combined memory exceeds the model's context limit, [memory processors](https://mastra.ai/docs/memory/memory-processors) can filter, trim, or prioritize content so the most relevant information is preserved.
|
|
15
|
+
|
|
16
|
+
Memory results will be stored in one or more of your configured [storage providers](https://mastra.ai/docs/storage/overview).
|
|
17
|
+
|
|
18
|
+
> **📹 Watch:** Watch [Mastra memory concepts](https://www.youtube.com/watch?v=18iIHQtIPmc) for a conceptual overview of the memory layers agents can use.
|
|
19
|
+
|
|
20
|
+
## When to use memory
|
|
21
|
+
|
|
22
|
+
Use memory when your agent needs to maintain multi-turn conversations that reference prior exchanges or recall user preferences or facts from earlier in a session, or alternatively build context over time within a conversation thread. Skip memory for single-turn requests where each interaction is independent.
|
|
23
|
+
|
|
24
|
+
## Quickstart
|
|
25
|
+
|
|
26
|
+
1. Install the `@mastra/memory` package.
|
|
27
|
+
|
|
28
|
+
**npm**:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @mastra/memory@latest
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**pnpm**:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add @mastra/memory@latest
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Yarn**:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
yarn add @mastra/memory@latest
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Bun**:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bun add @mastra/memory@latest
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. Memory **requires** a storage provider to persist message history, including user messages and agent responses.
|
|
53
|
+
|
|
54
|
+
For the purposes of this quickstart, use `@mastra/libsql`.
|
|
55
|
+
|
|
56
|
+
**npm**:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install @mastra/libsql@latest
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**pnpm**:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pnpm add @mastra/libsql@latest
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Yarn**:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
yarn add @mastra/libsql@latest
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Bun**:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
bun add @mastra/libsql@latest
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For more details on available providers and how storage works in Mastra, visit the [storage](https://mastra.ai/docs/storage/overview) documentation.
|
|
81
|
+
|
|
82
|
+
3. Add the storage provider to your main Mastra instance to enable memory across all configured agents.
|
|
83
|
+
|
|
84
|
+
**For AI agents:** Important: Add `id` to `LibSQLStore`.
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Mastra } from '@mastra/core'
|
|
88
|
+
import { LibSQLStore } from '@mastra/libsql'
|
|
89
|
+
|
|
90
|
+
export const mastra = new Mastra({
|
|
91
|
+
storage: new LibSQLStore({
|
|
92
|
+
id: 'mastra-storage',
|
|
93
|
+
url: ':memory:',
|
|
94
|
+
}),
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
4. Create a `Memory` instance and pass it to the agent's `memory` option.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { Agent } from '@mastra/core/agent'
|
|
102
|
+
import { Memory } from '@mastra/memory'
|
|
103
|
+
|
|
104
|
+
export const memoryAgent = new Agent({
|
|
105
|
+
id: 'memory-agent',
|
|
106
|
+
name: 'Memory Agent',
|
|
107
|
+
memory: new Memory({
|
|
108
|
+
options: {
|
|
109
|
+
lastMessages: 20,
|
|
110
|
+
},
|
|
111
|
+
}),
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Visit [Memory Class](https://mastra.ai/reference/memory/memory-class) for a full list of configuration options.
|
|
116
|
+
|
|
117
|
+
5. Call your agent, for example in [Studio](https://mastra.ai/docs/studio/overview). Inside Studio, start a new chat with your agent and take a look at the right sidebar. It'll now display various memory-related information.
|
|
118
|
+
|
|
119
|
+
## Message history
|
|
120
|
+
|
|
121
|
+
Pass a `memory` object with `resource` and `thread` to track message history.
|
|
122
|
+
|
|
123
|
+
- `resource`: A stable identifier for the user or entity.
|
|
124
|
+
- `thread`: An ID that isolates a specific conversation or session.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
const response = await memoryAgent.generate('Remember my favorite color is blue.', {
|
|
128
|
+
memory: {
|
|
129
|
+
resource: 'user-123',
|
|
130
|
+
thread: 'conversation-123',
|
|
131
|
+
},
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
To recall information stored in memory, call the agent with the same `resource` and `thread` values used in the original conversation.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const response = await memoryAgent.generate("What's my favorite color?", {
|
|
139
|
+
memory: {
|
|
140
|
+
resource: 'user-123',
|
|
141
|
+
thread: 'conversation-123',
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// Response: "Your favorite color is blue."
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
> **Warning:** Each thread has an owner (`resourceId`) that can't be changed after creation. Avoid reusing the same thread ID for threads with different owners, as this will cause errors when querying.
|
|
149
|
+
|
|
150
|
+
To list all threads for a resource, or retrieve a specific thread, [use the memory API directly](https://mastra.ai/docs/memory/message-history).
|
|
151
|
+
|
|
152
|
+
## Observational Memory
|
|
153
|
+
|
|
154
|
+
For long-running conversations, raw message history grows until it fills the context window, degrading agent performance. [Observational Memory](https://mastra.ai/docs/memory/observational-memory) solves this by running background agents that compress old messages into dense observations, keeping the context window small while preserving long-term memory.
|
|
155
|
+
|
|
156
|
+
**For AI agents:** Using Observational Memory requires a storage provider! You either need to set it on the Mastra instance at `src/mastra/index.ts` or pass it to the Agent constructor.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { Agent } from '@mastra/core/agent'
|
|
160
|
+
import { Memory } from '@mastra/memory'
|
|
161
|
+
|
|
162
|
+
export const memoryAgent = new Agent({
|
|
163
|
+
id: 'memory-agent',
|
|
164
|
+
name: 'Memory Agent',
|
|
165
|
+
memory: new Memory({
|
|
166
|
+
options: {
|
|
167
|
+
observationalMemory: true,
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
See [Observational Memory](https://mastra.ai/docs/memory/observational-memory) for details on how observations and reflections work, and [the reference](https://mastra.ai/reference/memory/observational-memory) for all configuration options.
|
|
174
|
+
|
|
175
|
+
## What the model sees
|
|
176
|
+
|
|
177
|
+
Each memory feature is added to either the system messages or the conversation messages in the request sent to the model. The layers depend on the features you've enabled. Working memory and semantic recall only appear when configured. The same applies to Observational Memory, while message history is on by default. The diagram shows where each enabled layer is placed in the request. The list below describes what each layer contributes:
|
|
178
|
+
|
|
179
|
+

|
|
180
|
+
|
|
181
|
+
- [Working memory](https://mastra.ai/docs/memory/working-memory) is injected as a system message containing the template and the stored data. With `useStateSignals`, it's delivered as a state signal instead.
|
|
182
|
+
- [Semantic recall](https://mastra.ai/docs/memory/semantic-recall) matches from the current thread are inserted as regular messages and interleave with message history by timestamp. Matches from other threads are formatted into a system message instead.
|
|
183
|
+
- [Message history](https://mastra.ai/docs/memory/message-history) adds the last N messages in chronological order. Your new message always comes last.
|
|
184
|
+
- [Observational Memory](https://mastra.ai/docs/memory/observational-memory) replaces old raw history: reflections and observations live in a system message, and only messages that haven't been observed yet remain in the conversation. A short continuation reminder is placed at the start of the conversation messages.
|
|
185
|
+
- Context messages are the optional `context` array passed on a call, for example `agent.generate(msg, { context: [...] })`. Use them for one-off background such as app state or your own RAG results. They appear as regular conversation messages for that request only and are never saved to memory.
|
|
186
|
+
|
|
187
|
+
Conversation messages are ordered by timestamp and deduplicated by message ID, so recalled older messages appear before recent history. Context messages passed at call time are stamped with the current time, which places them after history and recall but before your new message. To inspect the exact context for a real request, use [Tracing](https://mastra.ai/docs/observability/tracing/overview) and open the LLM call spans, see [Observability](#observability) below.
|
|
188
|
+
|
|
189
|
+
## Memory in multi-agent systems
|
|
190
|
+
|
|
191
|
+
When a [supervisor agent](https://mastra.ai/docs/capabilities/subagents) delegates to a subagent, Mastra isolates subagent memory automatically. No flag enables this as it happens on every delegation. Understanding how this scoping works lets you decide what stays private and what to share intentionally.
|
|
192
|
+
|
|
193
|
+
### How delegation scopes memory
|
|
194
|
+
|
|
195
|
+
Each delegation creates a fresh `threadId` and a deterministic `resourceId` for the subagent:
|
|
196
|
+
|
|
197
|
+
- **Thread ID**: Unique per delegation. The subagent starts with a clean message history every time it's called.
|
|
198
|
+
- **Resource ID**: Derived as `{parentResourceId}-{agentName}`. Because the resource ID is stable across delegations, resource-scoped memory persists between calls. A subagent remembers facts from previous delegations by the same user.
|
|
199
|
+
- **Memory instance**: A subagent without its own memory inherits the supervisor's `Memory` instance and all configured options. If the subagent defines its own, that takes precedence.
|
|
200
|
+
|
|
201
|
+
> **Note:** Title generation (`generateTitle`) is a top-level thread concern and **isn't** applied to inherited subagent threads. Because each delegation creates an ephemeral thread that no one sees, running title generation for it would waste an LLM call per delegation. To generate titles for a subagent's own threads, give that subagent its own memory configuration.
|
|
202
|
+
|
|
203
|
+
The supervisor forwards its conversation context to the subagent so it has enough background to complete the task. Only the delegation prompt and the subagent's response are saved, the full parent conversation isn't stored. You can control which messages reach the subagent with the [`messageFilter`](https://mastra.ai/docs/capabilities/subagents) callback.
|
|
204
|
+
|
|
205
|
+
> **Note:** Subagent resource IDs are always suffixed with the agent name (`{parentResourceId}-{agentName}`). Different subagents under the same supervisor never share a resource ID through delegation.
|
|
206
|
+
|
|
207
|
+
To go beyond this default isolation, you can share memory between agents by passing matching identifiers when you call them directly.
|
|
208
|
+
|
|
209
|
+
### Share memory between agents
|
|
210
|
+
|
|
211
|
+
When you call agents directly (outside the delegation flow), memory sharing is controlled by two identifiers: `resourceId` and `threadId`. Agents that use the same values read and write to the same data. This is useful when agents collaborate on a shared context, for example, a researcher that saves notes and a writer that reads them.
|
|
212
|
+
|
|
213
|
+
**Resource-scoped sharing** is the most common pattern. [Working memory](https://mastra.ai/docs/memory/working-memory) and [semantic recall](https://mastra.ai/docs/memory/semantic-recall) default to `scope: 'resource'`. If two agents share a `resourceId`, they share observations, working memory, and embeddings, even across different threads:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// Both agents share the same resource-scoped memory
|
|
217
|
+
await researcher.generate('Find information about quantum computing.', {
|
|
218
|
+
memory: { resource: 'project-42', thread: 'research-session' },
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
await writer.generate('Write a summary from the research notes.', {
|
|
222
|
+
memory: { resource: 'project-42', thread: 'writing-session' },
|
|
223
|
+
})
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Because both calls use `resource: 'project-42'`, the writer can access the researcher's observations and working memory. Semantic embeddings are also shared through the resource. Each agent still has its own thread, so message histories stay separate.
|
|
227
|
+
|
|
228
|
+
**Thread-scoped sharing** gives tighter coupling. [Observational Memory](https://mastra.ai/docs/memory/observational-memory) uses `scope: 'thread'` by default. If two agents use the same `resource` and `thread`, they share the full message history. Each agent sees every message the other has written. This is useful when agents need to build on each other's exact outputs.
|
|
229
|
+
|
|
230
|
+
## Observability
|
|
231
|
+
|
|
232
|
+
Enable [Tracing](https://mastra.ai/docs/observability/tracing/overview) to monitor and debug memory in action. Traces show you exactly which messages and observations the agent included in its context for each request, helping you understand agent behavior and verify that memory retrieval is working as expected.
|
|
233
|
+
|
|
234
|
+
Open [Studio](https://mastra.ai/docs/studio/overview) and select the **Observability** tab in the sidebar. Open the trace of a recent agent request and look for its LLM call spans.
|
|
235
|
+
|
|
236
|
+
## Switch memory per request
|
|
237
|
+
|
|
238
|
+
Use [`RequestContext`](https://mastra.ai/docs/server/request-context) to access request-specific values. This lets you conditionally select different memory or storage configurations based on the context of the request.
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
export type UserTier = {
|
|
242
|
+
'user-tier': 'enterprise' | 'pro'
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const premiumMemory = new Memory()
|
|
246
|
+
const standardMemory = new Memory()
|
|
247
|
+
|
|
248
|
+
export const memoryAgent = new Agent({
|
|
249
|
+
id: 'memory-agent',
|
|
250
|
+
name: 'Memory Agent',
|
|
251
|
+
memory: ({ requestContext }) => {
|
|
252
|
+
const userTier = requestContext.get('user-tier') as UserTier['user-tier']
|
|
253
|
+
|
|
254
|
+
return userTier === 'enterprise' ? premiumMemory : standardMemory
|
|
255
|
+
},
|
|
256
|
+
})
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Visit [Request Context](https://mastra.ai/docs/server/request-context) for more information.
|
|
260
|
+
|
|
261
|
+
## Related
|
|
262
|
+
|
|
263
|
+
- [`Memory` reference](https://mastra.ai/reference/memory/memory-class)
|
|
264
|
+
- [Tracing](https://mastra.ai/docs/observability/tracing/overview)
|
|
265
|
+
- [Request Context](https://mastra.ai/docs/server/request-context)
|
|
266
|
+
- [Mastra Code](https://code.mastra.ai/): A coding agent using Mastra's memory system
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
> Discover all available pages from the documentation index: https://mastra.ai/llms.txt
|
|
2
|
+
|
|
3
|
+
# Semantic recall
|
|
4
|
+
|
|
5
|
+
If you ask your friend what they did last weekend, they will search in their memory for events associated with "last weekend" and then tell you what they did. That's sort of like how semantic recall works in Mastra.
|
|
6
|
+
|
|
7
|
+
> **📹 Watch:** Watch [Mastra semantic recall](https://www.youtube.com/watch?v=UVZtK8cK8xQ\&pp=ygUVbWFzdHJhIHdvcmtpbmcgbWVtb3J5) to see how agents retrieve relevant messages from past conversations.
|
|
8
|
+
|
|
9
|
+
## How semantic recall works
|
|
10
|
+
|
|
11
|
+
Semantic recall is RAG-based search that helps agents maintain context across longer interactions when messages are no longer within [recent message history](https://mastra.ai/docs/memory/message-history).
|
|
12
|
+
|
|
13
|
+
It uses vector embeddings of messages for similarity search and integrates with vector stores, plus has configurable context windows around retrieved messages.
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
When it's enabled, new messages are used to query a vector DB for semantically similar messages.
|
|
18
|
+
|
|
19
|
+
After getting a response from the LLM, all new messages (user, assistant, and tool calls/results) are inserted into the vector DB to be recalled in later interactions.
|
|
20
|
+
|
|
21
|
+
## Quickstart
|
|
22
|
+
|
|
23
|
+
Semantic recall is disabled by default. To enable it, set `semanticRecall: true` in `options` and provide a `vector` store and `embedder`:
|
|
24
|
+
|
|
25
|
+
**LibSQL**:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Agent } from '@mastra/core/agent'
|
|
29
|
+
import { Memory } from '@mastra/memory'
|
|
30
|
+
import { LibSQLStore, LibSQLVector } from '@mastra/libsql'
|
|
31
|
+
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
|
|
32
|
+
|
|
33
|
+
const agent = new Agent({
|
|
34
|
+
id: 'support-agent',
|
|
35
|
+
name: 'SupportAgent',
|
|
36
|
+
instructions: 'You are a helpful support agent.',
|
|
37
|
+
model: 'openai/gpt-5.6-sol',
|
|
38
|
+
memory: new Memory({
|
|
39
|
+
storage: new LibSQLStore({
|
|
40
|
+
id: 'agent-storage',
|
|
41
|
+
url: 'file:./local.db',
|
|
42
|
+
}),
|
|
43
|
+
vector: new LibSQLVector({
|
|
44
|
+
id: 'agent-vector',
|
|
45
|
+
url: 'file:./local.db',
|
|
46
|
+
}),
|
|
47
|
+
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
48
|
+
options: {
|
|
49
|
+
semanticRecall: true,
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**MongoDB**:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { Agent } from '@mastra/core/agent'
|
|
59
|
+
import { Memory } from '@mastra/memory'
|
|
60
|
+
import { MongoDBStore, MongoDBVector } from '@mastra/mongodb'
|
|
61
|
+
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
|
|
62
|
+
|
|
63
|
+
const agent = new Agent({
|
|
64
|
+
id: 'support-agent',
|
|
65
|
+
name: 'SupportAgent',
|
|
66
|
+
instructions: 'You are a helpful support agent.',
|
|
67
|
+
model: 'openai/gpt-5.6-sol',
|
|
68
|
+
memory: new Memory({
|
|
69
|
+
storage: new MongoDBStore({
|
|
70
|
+
id: 'agent-storage',
|
|
71
|
+
uri: process.env.MONGODB_URI,
|
|
72
|
+
dbName: process.env.MONGODB_DB_NAME,
|
|
73
|
+
}),
|
|
74
|
+
vector: new MongoDBVector({
|
|
75
|
+
id: 'agent-vector',
|
|
76
|
+
uri: process.env.MONGODB_URI,
|
|
77
|
+
dbName: process.env.MONGODB_DB_NAME,
|
|
78
|
+
}),
|
|
79
|
+
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
80
|
+
options: {
|
|
81
|
+
semanticRecall: true,
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Using the `recall()` method
|
|
88
|
+
|
|
89
|
+
While `listMessages` retrieves messages by thread ID with basic pagination, [`recall()`](https://mastra.ai/reference/memory/recall) adds support for **semantic search**. When you need to find messages by meaning rather than recency, use `recall()` with a `vectorSearchString`:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const memory = await agent.getMemory()
|
|
93
|
+
|
|
94
|
+
// Basic recall - similar to listMessages
|
|
95
|
+
const { messages } = await memory!.recall({
|
|
96
|
+
threadId: 'thread-123',
|
|
97
|
+
perPage: 50,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Semantic recall - find messages by meaning
|
|
101
|
+
const { messages: relevantMessages } = await memory!.recall({
|
|
102
|
+
threadId: 'thread-123',
|
|
103
|
+
vectorSearchString: 'What did we discuss about the project deadline?',
|
|
104
|
+
threadConfig: {
|
|
105
|
+
semanticRecall: true,
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Storage configuration
|
|
111
|
+
|
|
112
|
+
Semantic recall relies on a [storage and vector db](https://mastra.ai/reference/memory/memory-class) to store messages and their embeddings.
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { Memory } from '@mastra/memory'
|
|
116
|
+
import { Agent } from '@mastra/core/agent'
|
|
117
|
+
import { LibSQLStore, LibSQLVector } from '@mastra/libsql'
|
|
118
|
+
|
|
119
|
+
const agent = new Agent({
|
|
120
|
+
memory: new Memory({
|
|
121
|
+
// this is the default storage db if omitted
|
|
122
|
+
storage: new LibSQLStore({
|
|
123
|
+
id: 'agent-storage',
|
|
124
|
+
url: 'file:./local.db',
|
|
125
|
+
}),
|
|
126
|
+
// this is the default vector db if omitted
|
|
127
|
+
vector: new LibSQLVector({
|
|
128
|
+
id: 'agent-vector',
|
|
129
|
+
url: 'file:./local.db',
|
|
130
|
+
}),
|
|
131
|
+
options: {
|
|
132
|
+
semanticRecall: true,
|
|
133
|
+
},
|
|
134
|
+
}),
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Each vector store page below includes installation instructions, configuration parameters, and usage examples:
|
|
139
|
+
|
|
140
|
+
- [Astra](https://mastra.ai/reference/vectors/astra)
|
|
141
|
+
- [Chroma](https://mastra.ai/reference/vectors/chroma)
|
|
142
|
+
- [Cloudflare Vectorize](https://mastra.ai/reference/vectors/vectorize)
|
|
143
|
+
- [Convex](https://mastra.ai/reference/vectors/convex)
|
|
144
|
+
- [Couchbase](https://mastra.ai/reference/vectors/couchbase)
|
|
145
|
+
- [DuckDB](https://mastra.ai/reference/vectors/duckdb)
|
|
146
|
+
- [Elasticsearch](https://mastra.ai/reference/vectors/elasticsearch)
|
|
147
|
+
- [LanceDB](https://mastra.ai/reference/vectors/lance)
|
|
148
|
+
- [libSQL](https://mastra.ai/reference/vectors/libsql)
|
|
149
|
+
- [MongoDB](https://mastra.ai/reference/vectors/mongodb)
|
|
150
|
+
- [OpenSearch](https://mastra.ai/reference/vectors/opensearch)
|
|
151
|
+
- [Pinecone](https://mastra.ai/reference/vectors/pinecone)
|
|
152
|
+
- [PostgreSQL](https://mastra.ai/reference/vectors/pg)
|
|
153
|
+
- [Qdrant](https://mastra.ai/reference/vectors/qdrant)
|
|
154
|
+
- [S3 Vectors](https://mastra.ai/reference/vectors/s3vectors)
|
|
155
|
+
- [Turbopuffer](https://mastra.ai/reference/vectors/turbopuffer)
|
|
156
|
+
- [Upstash](https://mastra.ai/reference/vectors/upstash)
|
|
157
|
+
|
|
158
|
+
## Recall configuration
|
|
159
|
+
|
|
160
|
+
The following options control semantic recall behavior:
|
|
161
|
+
|
|
162
|
+
1. **topK**: The number of similar messages to retrieve
|
|
163
|
+
2. **messageRange**: The surrounding messages to include with each match
|
|
164
|
+
3. **scope**: Whether to search the current thread or all threads for a resource
|
|
165
|
+
4. **filter**: Metadata criteria that restrict search results
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const agent = new Agent({
|
|
169
|
+
id: 'agent',
|
|
170
|
+
memory: new Memory({
|
|
171
|
+
options: {
|
|
172
|
+
semanticRecall: {
|
|
173
|
+
topK: 3, // Retrieve 3 similar messages
|
|
174
|
+
messageRange: 2, // Include 2 messages before and after each match
|
|
175
|
+
scope: 'resource', // Search all threads for this resource
|
|
176
|
+
filter: { projectId: { $eq: 'project-a' } },
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
}),
|
|
180
|
+
})
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> **Note:** `scope: 'resource'` is supported by the LibSQL, PostgreSQL, MongoDB, and Upstash storage adapters.
|
|
184
|
+
|
|
185
|
+
### Metadata filtering
|
|
186
|
+
|
|
187
|
+
The `filter` option restricts semantic recall results to messages with matching thread metadata.
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const agent = new Agent({
|
|
191
|
+
id: 'agent',
|
|
192
|
+
memory: new Memory({
|
|
193
|
+
options: {
|
|
194
|
+
semanticRecall: {
|
|
195
|
+
scope: 'resource',
|
|
196
|
+
filter: {
|
|
197
|
+
projectId: { $eq: 'project-a' },
|
|
198
|
+
category: { $in: ['work', 'personal'] },
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
}),
|
|
203
|
+
})
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
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.
|
|
207
|
+
|
|
208
|
+
Supported filter operators:
|
|
209
|
+
|
|
210
|
+
- `$and`: Logical AND
|
|
211
|
+
- `$eq`: Equal to
|
|
212
|
+
- `$gt`: Greater than
|
|
213
|
+
- `$gte`: Greater than or equal
|
|
214
|
+
- `$in`: In array
|
|
215
|
+
- `$lt`: Less than
|
|
216
|
+
- `$lte`: Less than or equal
|
|
217
|
+
- `$ne`: Not equal to
|
|
218
|
+
- `$nin`: Not in array
|
|
219
|
+
- `$or`: Logical OR
|
|
220
|
+
|
|
221
|
+
The following example demonstrates metadata filters for common use cases:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// Filter by project
|
|
225
|
+
const options = {
|
|
226
|
+
semanticRecall: { filter: { projectId: { $eq: 'my-project' } } },
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Filter by multiple categories
|
|
230
|
+
const options = {
|
|
231
|
+
semanticRecall: { filter: { category: { $in: ['work', 'research'] } } },
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Filter by project and priority
|
|
235
|
+
const options = {
|
|
236
|
+
semanticRecall: {
|
|
237
|
+
filter: {
|
|
238
|
+
$and: [{ projectId: { $eq: 'project-a' } }, { priority: { $gte: 3 } }],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Embedder configuration
|
|
245
|
+
|
|
246
|
+
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.
|
|
247
|
+
|
|
248
|
+
### Using the Model Router (Recommended)
|
|
249
|
+
|
|
250
|
+
The simplest way is to use a `provider/model` string with autocomplete support:
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { Memory } from '@mastra/memory'
|
|
254
|
+
import { Agent } from '@mastra/core/agent'
|
|
255
|
+
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
|
|
256
|
+
|
|
257
|
+
const agent = new Agent({
|
|
258
|
+
id: 'agent',
|
|
259
|
+
memory: new Memory({
|
|
260
|
+
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
261
|
+
options: {
|
|
262
|
+
semanticRecall: true,
|
|
263
|
+
},
|
|
264
|
+
}),
|
|
265
|
+
})
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Supported embedding models:
|
|
269
|
+
|
|
270
|
+
- **OpenAI**: `text-embedding-3-small`, `text-embedding-3-large`, `text-embedding-ada-002`
|
|
271
|
+
- **Google**: `gemini-embedding-001`
|
|
272
|
+
- **OpenRouter**: Access embedding models from various providers
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { Agent } from '@mastra/core/agent'
|
|
276
|
+
import { Memory } from '@mastra/memory'
|
|
277
|
+
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
|
|
278
|
+
|
|
279
|
+
const agent = new Agent({
|
|
280
|
+
id: 'agent',
|
|
281
|
+
memory: new Memory({
|
|
282
|
+
embedder: new ModelRouterEmbeddingModel({
|
|
283
|
+
providerId: 'openrouter',
|
|
284
|
+
modelId: 'openai/text-embedding-3-small',
|
|
285
|
+
}),
|
|
286
|
+
}),
|
|
287
|
+
})
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
The model router automatically handles API key detection from environment variables (`OPENAI_API_KEY`, `GOOGLE_API_KEY`, `OPENROUTER_API_KEY`). Google models also fall back to `GOOGLE_GENERATIVE_AI_API_KEY`.
|
|
291
|
+
|
|
292
|
+
### Using AI SDK Packages
|
|
293
|
+
|
|
294
|
+
You can also use AI SDK embedding models directly:
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
import { Memory } from '@mastra/memory'
|
|
298
|
+
import { Agent } from '@mastra/core/agent'
|
|
299
|
+
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
|
|
300
|
+
|
|
301
|
+
const agent = new Agent({
|
|
302
|
+
id: 'agent',
|
|
303
|
+
memory: new Memory({
|
|
304
|
+
embedder: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
305
|
+
}),
|
|
306
|
+
})
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Using FastEmbed (local)
|
|
310
|
+
|
|
311
|
+
To use FastEmbed (a local embedding model), install `@mastra/fastembed`:
|
|
312
|
+
|
|
313
|
+
**npm**:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
npm install @mastra/fastembed@latest
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
**pnpm**:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
pnpm add @mastra/fastembed@latest
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Yarn**:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
yarn add @mastra/fastembed@latest
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
**Bun**:
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
bun add @mastra/fastembed@latest
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Then configure it in your memory:
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
import { Memory } from '@mastra/memory'
|
|
341
|
+
import { Agent } from '@mastra/core/agent'
|
|
342
|
+
import { fastembed } from '@mastra/fastembed'
|
|
343
|
+
|
|
344
|
+
const agent = new Agent({
|
|
345
|
+
id: 'agent',
|
|
346
|
+
memory: new Memory({
|
|
347
|
+
embedder: fastembed,
|
|
348
|
+
}),
|
|
349
|
+
})
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## PostgreSQL index optimization
|
|
353
|
+
|
|
354
|
+
When using PostgreSQL as your vector store, you can optimize semantic recall performance by configuring the vector index. This is particularly important for large-scale deployments with thousands of messages.
|
|
355
|
+
|
|
356
|
+
PostgreSQL supports both IVFFlat and HNSW indexes. By default, Mastra creates an IVFFlat index, but HNSW indexes typically provide better performance, especially with OpenAI embeddings which use inner product distance.
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { Memory } from '@mastra/memory'
|
|
360
|
+
import { PgStore, PgVector } from '@mastra/pg'
|
|
361
|
+
|
|
362
|
+
const agent = new Agent({
|
|
363
|
+
memory: new Memory({
|
|
364
|
+
storage: new PgStore({
|
|
365
|
+
id: 'agent-storage',
|
|
366
|
+
connectionString: process.env.DATABASE_URL,
|
|
367
|
+
}),
|
|
368
|
+
vector: new PgVector({
|
|
369
|
+
id: 'agent-vector',
|
|
370
|
+
connectionString: process.env.DATABASE_URL,
|
|
371
|
+
}),
|
|
372
|
+
options: {
|
|
373
|
+
semanticRecall: {
|
|
374
|
+
topK: 5,
|
|
375
|
+
messageRange: 2,
|
|
376
|
+
indexConfig: {
|
|
377
|
+
type: 'hnsw', // Use HNSW for better performance
|
|
378
|
+
metric: 'dotproduct', // Best for OpenAI embeddings
|
|
379
|
+
m: 16, // Number of bi-directional links (default: 16)
|
|
380
|
+
efConstruction: 64, // Size of candidate list during construction (default: 64)
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
}),
|
|
385
|
+
})
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
For detailed information about index configuration options and performance tuning, see the [PgVector configuration guide](https://mastra.ai/reference/vectors/pg).
|
|
389
|
+
|
|
390
|
+
## Disable semantic recall
|
|
391
|
+
|
|
392
|
+
Semantic recall is disabled by default (`semanticRecall: false`). Each call adds latency because new messages are converted into embeddings and used to query a vector database before the LLM receives them.
|
|
393
|
+
|
|
394
|
+
Keep semantic recall disabled when:
|
|
395
|
+
|
|
396
|
+
- Message history provides sufficient context for the current conversation.
|
|
397
|
+
- You're building performance-sensitive applications, like realtime two-way audio, where embedding and vector query latency is noticeable.
|
|
398
|
+
|
|
399
|
+
## Viewing recalled messages
|
|
400
|
+
|
|
401
|
+
When tracing is enabled, any messages retrieved via semantic recall will appear in the agent's trace output, alongside recent message history (if configured).
|