@mastra/libsql 1.0.0 → 1.1.0-alpha.0
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 +77 -0
- package/dist/docs/README.md +2 -2
- package/dist/docs/SKILL.md +2 -2
- package/dist/docs/SOURCE_MAP.json +1 -1
- package/dist/docs/agents/01-agent-memory.md +8 -8
- package/dist/docs/agents/02-networks.md +1 -1
- package/dist/docs/agents/03-agent-approval.md +2 -2
- package/dist/docs/agents/04-network-approval.md +2 -2
- package/dist/docs/core/01-reference.md +7 -7
- package/dist/docs/guides/01-ai-sdk.md +9 -30
- package/dist/docs/memory/01-overview.md +22 -53
- package/dist/docs/memory/02-storage.md +115 -87
- package/dist/docs/memory/03-message-history.md +249 -0
- package/dist/docs/memory/{03-working-memory.md → 04-working-memory.md} +22 -1
- package/dist/docs/memory/{04-semantic-recall.md → 05-semantic-recall.md} +45 -22
- package/dist/docs/memory/{05-memory-processors.md → 06-memory-processors.md} +4 -4
- package/dist/docs/memory/{06-reference.md → 07-reference.md} +11 -11
- package/dist/docs/observability/01-overview.md +13 -4
- package/dist/docs/observability/02-default.md +44 -7
- package/dist/docs/rag/01-retrieval.md +4 -4
- package/dist/docs/storage/01-reference.md +31 -17
- package/dist/docs/vectors/01-reference.md +4 -4
- package/dist/docs/workflows/01-snapshots.md +14 -14
- package/dist/index.cjs +271 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +272 -2
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/agents/index.d.ts +10 -1
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +2 -5
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Storage
|
|
4
4
|
|
|
5
|
-
For
|
|
5
|
+
For agents to remember previous interactions, Mastra needs a database. Use a storage adapter for one of the [supported databases](#supported-providers) and pass it to your Mastra instance.
|
|
6
6
|
|
|
7
7
|
```typescript title="src/mastra/index.ts"
|
|
8
8
|
import { Mastra } from "@mastra/core";
|
|
@@ -15,35 +15,37 @@ export const mastra = new Mastra({
|
|
|
15
15
|
}),
|
|
16
16
|
});
|
|
17
17
|
```
|
|
18
|
-
|
|
18
|
+
This configures instance-level storage, which all agents share by default. You can also configure [agent-level storage](#agent-level-storage) for isolated data boundaries.
|
|
19
|
+
|
|
20
|
+
Mastra automatically creates the necessary tables on first interaction. See the [core schema](https://mastra.ai/reference/storage/overview#core-schema) for details on what gets created, including tables for messages, threads, resources, workflows, traces, and evaluation datasets.
|
|
19
21
|
|
|
20
22
|
## Supported providers
|
|
21
23
|
|
|
22
24
|
Each provider page includes installation instructions, configuration parameters, and usage examples:
|
|
23
25
|
|
|
24
|
-
- [libSQL
|
|
25
|
-
- [PostgreSQL
|
|
26
|
-
- [MongoDB
|
|
27
|
-
- [Upstash
|
|
28
|
-
- [Cloudflare D1](https://mastra.ai/reference/
|
|
29
|
-
- [Cloudflare Durable Objects](https://mastra.ai/reference/
|
|
30
|
-
- [Convex](https://mastra.ai/reference/
|
|
31
|
-
- [DynamoDB](https://mastra.ai/reference/
|
|
32
|
-
- [LanceDB](https://mastra.ai/reference/
|
|
33
|
-
- [Microsoft SQL Server](https://mastra.ai/reference/
|
|
26
|
+
- [libSQL](https://mastra.ai/reference/storage/libsql)
|
|
27
|
+
- [PostgreSQL](https://mastra.ai/reference/storage/postgresql)
|
|
28
|
+
- [MongoDB](https://mastra.ai/reference/storage/mongodb)
|
|
29
|
+
- [Upstash](https://mastra.ai/reference/storage/upstash)
|
|
30
|
+
- [Cloudflare D1](https://mastra.ai/reference/storage/cloudflare-d1)
|
|
31
|
+
- [Cloudflare Durable Objects](https://mastra.ai/reference/storage/cloudflare)
|
|
32
|
+
- [Convex](https://mastra.ai/reference/storage/convex)
|
|
33
|
+
- [DynamoDB](https://mastra.ai/reference/storage/dynamodb)
|
|
34
|
+
- [LanceDB](https://mastra.ai/reference/storage/lance)
|
|
35
|
+
- [Microsoft SQL Server](https://mastra.ai/reference/storage/mssql)
|
|
34
36
|
|
|
35
37
|
> **Note:**
|
|
36
|
-
libSQL is the easiest way to get started because it doesn’t require running a separate database server
|
|
38
|
+
libSQL is the easiest way to get started because it doesn’t require running a separate database server.
|
|
37
39
|
|
|
38
40
|
## Configuration scope
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
Storage can be configured at the instance level (shared by all agents) or at the agent level (isolated to a specific agent).
|
|
41
43
|
|
|
42
44
|
### Instance-level storage
|
|
43
45
|
|
|
44
46
|
Add storage to your Mastra instance so all agents, workflows, observability traces and scores share the same memory provider:
|
|
45
47
|
|
|
46
|
-
```typescript
|
|
48
|
+
```typescript title="src/mastra/index.ts"
|
|
47
49
|
import { Mastra } from "@mastra/core";
|
|
48
50
|
import { PostgresStore } from "@mastra/pg";
|
|
49
51
|
|
|
@@ -54,7 +56,7 @@ export const mastra = new Mastra({
|
|
|
54
56
|
}),
|
|
55
57
|
});
|
|
56
58
|
|
|
57
|
-
//
|
|
59
|
+
// Both agents inherit storage from the Mastra instance above
|
|
58
60
|
const agent1 = new Agent({ id: "agent-1", memory: new Memory() });
|
|
59
61
|
const agent2 = new Agent({ id: "agent-2", memory: new Memory() });
|
|
60
62
|
```
|
|
@@ -63,7 +65,7 @@ This is useful when all primitives share the same storage backend and have simil
|
|
|
63
65
|
|
|
64
66
|
#### Composite storage
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
[Composite storage](https://mastra.ai/reference/storage/composite) is an alternative way to configure instance-level storage. Use `MastraCompositeStore` to set the `memory` domain (and any other [domains](https://mastra.ai/reference/storage/composite#storage-domains) you need) to different storage providers.
|
|
67
69
|
|
|
68
70
|
```typescript title="src/mastra/index.ts"
|
|
69
71
|
import { Mastra } from "@mastra/core";
|
|
@@ -76,6 +78,7 @@ export const mastra = new Mastra({
|
|
|
76
78
|
storage: new MastraCompositeStore({
|
|
77
79
|
id: "composite",
|
|
78
80
|
domains: {
|
|
81
|
+
// highlight-next-line
|
|
79
82
|
memory: new MemoryLibSQL({ url: "file:./memory.db" }),
|
|
80
83
|
workflows: new WorkflowsPG({ connectionString: process.env.DATABASE_URL }),
|
|
81
84
|
observability: new ObservabilityStorageClickhouse({
|
|
@@ -90,14 +93,11 @@ export const mastra = new Mastra({
|
|
|
90
93
|
|
|
91
94
|
This is useful when different types of data have different performance or operational requirements, such as low-latency storage for memory, durable storage for workflows, and high-throughput storage for observability.
|
|
92
95
|
|
|
93
|
-
> **Note:**
|
|
94
|
-
See [Storage Domains](https://mastra.ai/reference/v1/storage/composite#storage-domains) for more information.
|
|
95
|
-
|
|
96
96
|
### Agent-level storage
|
|
97
97
|
|
|
98
|
-
Agent-level storage overrides storage configured at the instance
|
|
98
|
+
Agent-level storage overrides storage configured at the instance level. Add storage to a specific agent when you need data boundaries or compliance requirements:
|
|
99
99
|
|
|
100
|
-
```typescript title="src/mastra/agents/
|
|
100
|
+
```typescript title="src/mastra/agents/your-agent.ts"
|
|
101
101
|
import { Agent } from "@mastra/core/agent";
|
|
102
102
|
import { Memory } from "@mastra/memory";
|
|
103
103
|
import { PostgresStore } from "@mastra/pg";
|
|
@@ -113,56 +113,55 @@ export const agent = new Agent({
|
|
|
113
113
|
});
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
> **Mastra Cloud Store limitation**
|
|
119
|
-
Agent-level storage is not supported when using [Mastra Cloud Store](https://mastra.ai/docs/v1/mastra-cloud/deployment#using-mastra-cloud-store). If you use Mastra Cloud Store, configure storage on the Mastra instance instead. This limitation does not apply if you bring your own database.
|
|
116
|
+
> **Note:**
|
|
117
|
+
[Mastra Cloud Store](https://mastra.ai/docs/mastra-cloud/deployment#using-mastra-cloud-store) doesn't support agent-level storage.
|
|
120
118
|
|
|
121
119
|
## Threads and resources
|
|
122
120
|
|
|
123
|
-
Mastra organizes
|
|
121
|
+
Mastra organizes conversations using two identifiers:
|
|
122
|
+
|
|
123
|
+
- **Thread** - a conversation session containing a sequence of messages.
|
|
124
|
+
- **Resource** - the entity that owns the thread, such as a user, organization, project, or any other domain entity in your application.
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
- **Resource**: An identifier for the entity the thread belongs to, typically a user (e.g., `user_123`)
|
|
126
|
+
Both identifiers are required for agents to store information:
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
**generate:**
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
|
-
const
|
|
131
|
+
const response = await agent.generate("hello", {
|
|
132
132
|
memory: {
|
|
133
|
-
thread: "
|
|
133
|
+
thread: "conversation-abc-123",
|
|
134
134
|
resource: "user_123",
|
|
135
135
|
},
|
|
136
136
|
});
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
### Thread and resource relationship
|
|
139
|
+
|
|
140
|
+
**stream:**
|
|
143
141
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
142
|
+
```typescript
|
|
143
|
+
const stream = await agent.stream("hello", {
|
|
144
|
+
memory: {
|
|
145
|
+
thread: "conversation-abc-123",
|
|
146
|
+
resource: "user_123",
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
**Security:** Memory is a storage layer, not an authorization layer. Your application must implement access control before calling memory APIs. The `resourceId` parameter controls both validation and filtering - provide it to validate ownership and filter messages, or omit it for server-side access without validation.
|
|
151
|
+
|
|
154
152
|
|
|
155
|
-
|
|
153
|
+
> **Note:**
|
|
154
|
+
[Studio](https://mastra.ai/docs/getting-started/studio) automatically generates a thread and resource ID for you. When calling `stream()` or `generate()` yourself, remember to provide these identifiers explicitly.
|
|
156
155
|
|
|
157
156
|
### Thread title generation
|
|
158
157
|
|
|
159
|
-
Mastra can automatically generate descriptive thread titles based on the user's first message.
|
|
158
|
+
Mastra can automatically generate descriptive thread titles based on the user's first message when `generateTitle` is enabled.
|
|
160
159
|
|
|
161
160
|
Use this option when implementing a ChatGPT-style chat interface to render a title alongside each thread in the conversation list (for example, in a sidebar) derived from the thread’s initial user message.
|
|
162
161
|
|
|
163
|
-
```typescript
|
|
164
|
-
export const
|
|
165
|
-
id: "
|
|
162
|
+
```typescript title="src/mastra/agents/my-agent.ts"
|
|
163
|
+
export const agent = new Agent({
|
|
164
|
+
id: "agent",
|
|
166
165
|
memory: new Memory({
|
|
167
166
|
options: {
|
|
168
167
|
generateTitle: true,
|
|
@@ -173,16 +172,16 @@ export const testAgent = new Agent({
|
|
|
173
172
|
|
|
174
173
|
Title generation runs asynchronously after the agent responds and does not affect response time.
|
|
175
174
|
|
|
176
|
-
To optimize cost or behavior, provide a smaller `model` and custom `instructions`:
|
|
175
|
+
To optimize cost or behavior, provide a smaller [`model`](/models) and custom `instructions`:
|
|
177
176
|
|
|
178
|
-
```typescript
|
|
179
|
-
export const
|
|
180
|
-
id: "
|
|
177
|
+
```typescript title="src/mastra/agents/my-agent.ts"
|
|
178
|
+
export const agent = new Agent({
|
|
179
|
+
id: "agent",
|
|
181
180
|
memory: new Memory({
|
|
182
181
|
options: {
|
|
183
182
|
generateTitle: {
|
|
184
183
|
model: "openai/gpt-4o-mini",
|
|
185
|
-
instructions: "Generate a
|
|
184
|
+
instructions: "Generate a 1 word title",
|
|
186
185
|
},
|
|
187
186
|
},
|
|
188
187
|
}),
|
|
@@ -191,43 +190,72 @@ export const testAgent = new Agent({
|
|
|
191
190
|
|
|
192
191
|
## Semantic recall
|
|
193
192
|
|
|
194
|
-
Semantic recall
|
|
193
|
+
Semantic recall has different storage requirements - it needs a vector database in addition to the standard storage adapter. See [Semantic recall](https://mastra.ai/docs/memory/semantic-recall) for setup and supported vector providers.
|
|
195
194
|
|
|
196
|
-
|
|
195
|
+
## Handling large attachments
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
import { Mastra } from "@mastra/core";
|
|
200
|
-
import { Agent } from "@mastra/core/agent";
|
|
201
|
-
import { Memory } from "@mastra/memory";
|
|
202
|
-
import { PostgresStore } from "@mastra/pg";
|
|
203
|
-
import { PineconeVector } from "@mastra/pinecone";
|
|
197
|
+
Some storage providers enforce record size limits that base64-encoded file attachments (such as images) can exceed:
|
|
204
198
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}),
|
|
211
|
-
});
|
|
199
|
+
| Provider | Record size limit |
|
|
200
|
+
| -------- | ----------------- |
|
|
201
|
+
| [DynamoDB](https://mastra.ai/reference/storage/dynamodb) | 400 KB |
|
|
202
|
+
| [Convex](https://mastra.ai/reference/storage/convex) | 1 MiB |
|
|
203
|
+
| [Cloudflare D1](https://mastra.ai/reference/storage/cloudflare-d1) | 1 MiB |
|
|
212
204
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
205
|
+
PostgreSQL, MongoDB, and libSQL have higher limits and are generally unaffected.
|
|
206
|
+
|
|
207
|
+
To avoid this, use an input processor to upload attachments to external storage (S3, R2, GCS, [Convex file storage](https://docs.convex.dev/file-storage), etc.) and replace them with URL references before persistence.
|
|
208
|
+
|
|
209
|
+
```typescript title="src/mastra/processors/attachment-uploader.ts"
|
|
210
|
+
import type { Processor } from "@mastra/core/processors";
|
|
211
|
+
import type { MastraDBMessage } from "@mastra/core/memory";
|
|
212
|
+
|
|
213
|
+
export class AttachmentUploader implements Processor {
|
|
214
|
+
id = "attachment-uploader";
|
|
215
|
+
|
|
216
|
+
async processInput({ messages }: { messages: MastraDBMessage[] }) {
|
|
217
|
+
return Promise.all(messages.map((msg) => this.processMessage(msg)));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async processMessage(msg: MastraDBMessage) {
|
|
221
|
+
const attachments = msg.content.experimental_attachments;
|
|
222
|
+
if (!attachments?.length) return msg;
|
|
223
|
+
|
|
224
|
+
const uploaded = await Promise.all(
|
|
225
|
+
attachments.map(async (att) => {
|
|
226
|
+
// Skip if already a URL
|
|
227
|
+
if (!att.url?.startsWith("data:")) return att;
|
|
228
|
+
|
|
229
|
+
// Upload base64 data and replace with URL
|
|
230
|
+
const url = await this.upload(att.url, att.contentType);
|
|
231
|
+
return { ...att, url };
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
return { ...msg, content: { ...msg.content, experimental_attachments: uploaded } };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async upload(dataUri: string, contentType?: string): Promise<string> {
|
|
239
|
+
const base64 = dataUri.split(",")[1];
|
|
240
|
+
const buffer = Buffer.from(base64, "base64");
|
|
241
|
+
|
|
242
|
+
// Replace with your storage provider (S3, R2, GCS, Convex, etc.)
|
|
243
|
+
// return await s3.upload(buffer, contentType);
|
|
244
|
+
throw new Error("Implement upload() with your storage provider");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
229
247
|
```
|
|
230
248
|
|
|
231
|
-
|
|
249
|
+
Use the processor with your agent:
|
|
232
250
|
|
|
233
|
-
|
|
251
|
+
```typescript
|
|
252
|
+
import { Agent } from "@mastra/core/agent";
|
|
253
|
+
import { Memory } from "@mastra/memory";
|
|
254
|
+
import { AttachmentUploader } from "./processors/attachment-uploader";
|
|
255
|
+
|
|
256
|
+
const agent = new Agent({
|
|
257
|
+
id: "my-agent",
|
|
258
|
+
memory: new Memory({ storage: yourStorage }),
|
|
259
|
+
inputProcessors: [new AttachmentUploader()],
|
|
260
|
+
});
|
|
261
|
+
```
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
> Learn how to configure message history in Mastra to store recent messages from the current conversation.
|
|
2
|
+
|
|
3
|
+
# Message History
|
|
4
|
+
|
|
5
|
+
Message history is the most basic and important form of memory. It gives the LLM a view of recent messages in the context window, enabling your agent to reference earlier exchanges and respond coherently.
|
|
6
|
+
|
|
7
|
+
You can also retrieve message history to display past conversations in your UI.
|
|
8
|
+
|
|
9
|
+
> **Note:**
|
|
10
|
+
Each message belongs to a thread (the conversation) and a resource (the user or entity it's associated with). See [Threads and resources](https://mastra.ai/docs/memory/storage#threads-and-resources) for more detail.
|
|
11
|
+
|
|
12
|
+
## Getting started
|
|
13
|
+
|
|
14
|
+
Install the Mastra memory module along with a [storage adapter](https://mastra.ai/docs/memory/storage#supported-providers) for your database. The examples below use `@mastra/libsql`, which stores data locally in a `mastra.db` file.
|
|
15
|
+
|
|
16
|
+
```bash npm2yarn
|
|
17
|
+
npm install @mastra/memory@latest @mastra/libsql@latest
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Message history requires a storage adapter to persist conversations. Configure storage on your Mastra instance if you haven't already:
|
|
21
|
+
|
|
22
|
+
```typescript title="src/mastra/index.ts"
|
|
23
|
+
import { Mastra } from "@mastra/core";
|
|
24
|
+
import { LibSQLStore } from "@mastra/libsql";
|
|
25
|
+
|
|
26
|
+
export const mastra = new Mastra({
|
|
27
|
+
storage: new LibSQLStore({
|
|
28
|
+
id: 'mastra-storage',
|
|
29
|
+
url: "file:./mastra.db",
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Give your agent a `Memory`:
|
|
35
|
+
|
|
36
|
+
```typescript title="src/mastra/agents/your-agent.ts"
|
|
37
|
+
import { Memory } from "@mastra/memory";
|
|
38
|
+
import { Agent } from "@mastra/core/agent";
|
|
39
|
+
|
|
40
|
+
export const agent = new Agent({
|
|
41
|
+
id: "test-agent",
|
|
42
|
+
memory: new Memory({
|
|
43
|
+
options: {
|
|
44
|
+
lastMessages: 10,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
When you call the agent, messages are automatically saved to the database. You can specify a `threadId`, `resourceId`, and optional `metadata`:
|
|
51
|
+
|
|
52
|
+
**generate:**
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
await agent.generate("Hello", {
|
|
56
|
+
memory: {
|
|
57
|
+
thread: {
|
|
58
|
+
id: "thread-123",
|
|
59
|
+
title: "Support conversation",
|
|
60
|
+
metadata: { category: "billing" },
|
|
61
|
+
},
|
|
62
|
+
resource: "user-456",
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
**stream:**
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
await agent.stream("Hello", {
|
|
72
|
+
memory: {
|
|
73
|
+
thread: {
|
|
74
|
+
id: "thread-123",
|
|
75
|
+
title: "Support conversation",
|
|
76
|
+
metadata: { category: "billing" },
|
|
77
|
+
},
|
|
78
|
+
resource: "user-456",
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
> **Note:**
|
|
86
|
+
|
|
87
|
+
Threads and messages are created automatically when you call `agent.generate()` or `agent.stream()`, but you can also create them manually with [`createThread()`](https://mastra.ai/reference/memory/createThread) and [`saveMessages()`](https://mastra.ai/reference/memory/memory-class).
|
|
88
|
+
|
|
89
|
+
There are two ways to use this history:
|
|
90
|
+
|
|
91
|
+
- **Automatic inclusion** - Mastra automatically fetches and includes recent messages in the context window. By default, it includes the last 10 messages, keeping agents grounded in the conversation. You can adjust this number with `lastMessages`, but in most cases you don't need to think about it.
|
|
92
|
+
- [**Manual querying**](#querying) - For more control, use the `recall()` function to query threads and messages directly. This lets you choose exactly which memories are included in the context window, or fetch messages to render conversation history in your UI.
|
|
93
|
+
|
|
94
|
+
## Accessing Memory
|
|
95
|
+
|
|
96
|
+
To access memory functions for querying, cloning, or deleting threads and messages, call `getMemory()` on an agent:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const agent = mastra.getAgent("weatherAgent");
|
|
100
|
+
const memory = await agent.getMemory();
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The `Memory` instance gives you access to functions for listing threads, recalling messages, cloning conversations, and more.
|
|
104
|
+
|
|
105
|
+
## Querying
|
|
106
|
+
|
|
107
|
+
Use these methods to fetch threads and messages for displaying conversation history in your UI or for custom memory retrieval logic.
|
|
108
|
+
|
|
109
|
+
> **Note:**
|
|
110
|
+
The memory system does not enforce access control. Before running any query, verify in your application logic that the current user is authorized to access the `resourceId` being queried.
|
|
111
|
+
|
|
112
|
+
### Threads
|
|
113
|
+
|
|
114
|
+
Use [`listThreads()`](https://mastra.ai/reference/memory/listThreads) to retrieve threads for a resource:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const result = await memory.listThreads({
|
|
118
|
+
filter: { resourceId: "user-123" },
|
|
119
|
+
perPage: false,
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Paginate through threads:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const result = await memory.listThreads({
|
|
127
|
+
filter: { resourceId: "user-123" },
|
|
128
|
+
page: 0,
|
|
129
|
+
perPage: 10,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
console.log(result.threads); // thread objects
|
|
133
|
+
console.log(result.hasMore); // more pages available?
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
You can also filter by metadata and control sort order:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const result = await memory.listThreads({
|
|
140
|
+
filter: {
|
|
141
|
+
resourceId: "user-123",
|
|
142
|
+
metadata: { status: "active" },
|
|
143
|
+
},
|
|
144
|
+
orderBy: { field: "createdAt", direction: "DESC" },
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
To fetch a single thread by ID, use [`getThreadById()`](https://mastra.ai/reference/memory/getThreadById):
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const thread = await memory.getThreadById({ threadId: "thread-123" });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Messages
|
|
155
|
+
|
|
156
|
+
Once you have a thread, use [`recall()`](https://mastra.ai/reference/memory/recall) to retrieve its messages. It supports pagination, date filtering, and [semantic search](https://mastra.ai/docs/memory/semantic-recall).
|
|
157
|
+
|
|
158
|
+
Basic recall returns all messages from a thread:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const { messages } = await memory.recall({
|
|
162
|
+
threadId: "thread-123",
|
|
163
|
+
perPage: false,
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Paginate through messages:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
const { messages } = await memory.recall({
|
|
171
|
+
threadId: "thread-123",
|
|
172
|
+
page: 0,
|
|
173
|
+
perPage: 50,
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Filter by date range:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
const { messages } = await memory.recall({
|
|
181
|
+
threadId: "thread-123",
|
|
182
|
+
filter: {
|
|
183
|
+
dateRange: {
|
|
184
|
+
start: new Date("2025-01-01"),
|
|
185
|
+
end: new Date("2025-06-01"),
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Fetch a single message by ID:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const { messages } = await memory.recall({
|
|
195
|
+
threadId: "thread-123",
|
|
196
|
+
include: [{ id: "msg-123" }],
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Fetch multiple messages by ID with surrounding context:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
const { messages } = await memory.recall({
|
|
204
|
+
threadId: "thread-123",
|
|
205
|
+
include: [
|
|
206
|
+
{ id: "msg-123" },
|
|
207
|
+
{
|
|
208
|
+
id: "msg-456",
|
|
209
|
+
withPreviousMessages: 3,
|
|
210
|
+
withNextMessages: 1,
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Search by meaning (see [Semantic recall](https://mastra.ai/docs/memory/semantic-recall) for setup):
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const { messages } = await memory.recall({
|
|
220
|
+
threadId: "thread-123",
|
|
221
|
+
vectorSearchString: "project deadline discussion",
|
|
222
|
+
threadConfig: {
|
|
223
|
+
semanticRecall: true,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### UI format
|
|
229
|
+
|
|
230
|
+
Message queries return `MastraDBMessage[]` format. To display messages in a frontend, you may need to convert them to a format your UI library expects. For example, [`toAISdkV5Messages`](https://mastra.ai/reference/ai-sdk/to-ai-sdk-v5-messages) converts messages to AI SDK UI format.
|
|
231
|
+
|
|
232
|
+
## Thread cloning
|
|
233
|
+
|
|
234
|
+
Thread cloning creates a copy of an existing thread with its messages. This is useful for branching conversations, creating checkpoints before a potentially destructive operation, or testing variations of a conversation.
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const { thread, clonedMessages } = await memory.cloneThread({
|
|
238
|
+
sourceThreadId: "thread-123",
|
|
239
|
+
title: "Branched conversation",
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
You can filter which messages get cloned (by count or date range), specify custom thread IDs, and use utility methods to inspect clone relationships.
|
|
244
|
+
|
|
245
|
+
See [`cloneThread()`](https://mastra.ai/reference/memory/cloneThread) and [clone utilities](https://mastra.ai/reference/memory/clone-utilities) for the full API.
|
|
246
|
+
|
|
247
|
+
## Deleting messages
|
|
248
|
+
|
|
249
|
+
To remove messages from a thread, use [`deleteMessages()`](https://mastra.ai/reference/memory/deleteMessages). You can delete by message ID or clear all messages from a thread.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Working Memory
|
|
4
4
|
|
|
5
|
-
While [message history](https://mastra.ai/docs/
|
|
5
|
+
While [message history](https://mastra.ai/docs/memory/message-history) and [semantic recall](./semantic-recall) help agents remember conversations, working memory allows them to maintain persistent information about users across interactions.
|
|
6
6
|
|
|
7
7
|
Think of it as the agent's active thoughts or scratchpad – the key information they keep available about the user or task. It's similar to how a person would naturally remember someone's name, preferences, or important details during a conversation.
|
|
8
8
|
|
|
@@ -383,6 +383,27 @@ await memory.updateWorkingMemory({
|
|
|
383
383
|
});
|
|
384
384
|
```
|
|
385
385
|
|
|
386
|
+
## Read-Only Working Memory
|
|
387
|
+
|
|
388
|
+
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:
|
|
389
|
+
|
|
390
|
+
- **Routing agents** that need context but shouldn't update user profiles
|
|
391
|
+
- **Sub agents** in a multi-agent system that should reference but not own the memory
|
|
392
|
+
|
|
393
|
+
To enable read-only mode, set `readOnly: true` in the memory options:
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
const response = await agent.generate("What do you know about me?", {
|
|
397
|
+
memory: {
|
|
398
|
+
thread: "conversation-123",
|
|
399
|
+
resource: "user-alice-456",
|
|
400
|
+
options: {
|
|
401
|
+
readOnly: true, // Working memory is provided but cannot be updated
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
386
407
|
## Examples
|
|
387
408
|
|
|
388
409
|
- [Working memory with template](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-template)
|