@mastra/pg 1.10.0 → 1.10.1-alpha.1
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 +28 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +68 -6
- package/dist/index.cjs +36 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -6
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @mastra/pg
|
|
2
2
|
|
|
3
|
+
## 1.10.1-alpha.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Respect optional `resourceId` in `getThreadById` so scoped thread lookups return `null` when the thread belongs to a different resource. ([#14237](https://github.com/mastra-ai/mastra/pull/14237))
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const thread = await memory.getThreadById({
|
|
13
|
+
threadId: 'my-thread-id',
|
|
14
|
+
resourceId: 'my-user-id',
|
|
15
|
+
});
|
|
16
|
+
// Returns null if the thread does not belong to 'my-user-id'.
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [[`7c275a8`](https://github.com/mastra-ai/mastra/commit/7c275a810595e1a6c41ccc39720531ab65734700), [`890b24c`](https://github.com/mastra-ai/mastra/commit/890b24cc7d32ed6aa4dfe253e54dc6bf4099f690), [`0f48ebf`](https://github.com/mastra-ai/mastra/commit/0f48ebfc7ac7897b2092a189f45751924cf56d1c), [`f180e49`](https://github.com/mastra-ai/mastra/commit/f180e4990e71b04c9a475b523584071712f0048f), [`9260e01`](https://github.com/mastra-ai/mastra/commit/9260e015276fb1b500f7878ee452b47476bf1583), [`2f6c54e`](https://github.com/mastra-ai/mastra/commit/2f6c54e17c041cac1def54baaa6b771647836414), [`e06a159`](https://github.com/mastra-ai/mastra/commit/e06a1598ca07a6c3778aefc2a2d288363c6294ff), [`db34bc6`](https://github.com/mastra-ai/mastra/commit/db34bc6fb36cf125bda0c46be4d3fdc774b70cc4)]:
|
|
20
|
+
- @mastra/core@1.33.0-alpha.8
|
|
21
|
+
|
|
22
|
+
## 1.10.1-alpha.0
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Track `suspendedAt` and `suspendPayload` on background tasks. SQL adapters auto-migrate the new columns via `alterTable`. ([#16260](https://github.com/mastra-ai/mastra/pull/16260))
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [[`9f17410`](https://github.com/mastra-ai/mastra/commit/9f1741080def23d42ee50b39887a385ae316a3c6), [`c6eb39e`](https://github.com/mastra-ai/mastra/commit/c6eb39ea6dca381c6563cb240237fbe608e02f93), [`900d086`](https://github.com/mastra-ai/mastra/commit/900d086bb737b9cf2fcf68f11b0389b801a2738c), [`4c0e286`](https://github.com/mastra-ai/mastra/commit/4c0e28637c9cfb4f416549b55e97ebfa13319dfc), [`25184ff`](https://github.com/mastra-ai/mastra/commit/25184ffaf1293ec95119426eb1a1f8d38831b96c), [`aebde9c`](https://github.com/mastra-ai/mastra/commit/aebde9cfacf56592c6b6350cae721740fe090b8a)]:
|
|
29
|
+
- @mastra/core@1.33.0-alpha.4
|
|
30
|
+
|
|
3
31
|
## 1.10.0
|
|
4
32
|
|
|
5
33
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -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.
|
package/dist/index.cjs
CHANGED
|
@@ -4314,11 +4314,13 @@ function rowToTask(row) {
|
|
|
4314
4314
|
runId: row.run_id,
|
|
4315
4315
|
result: parseJson(row.result),
|
|
4316
4316
|
error: parseJson(row.error),
|
|
4317
|
+
suspendPayload: parseJson(row.suspend_payload),
|
|
4317
4318
|
retryCount: Number(row.retry_count),
|
|
4318
4319
|
maxRetries: Number(row.max_retries),
|
|
4319
4320
|
timeoutMs: Number(row.timeout_ms),
|
|
4320
4321
|
createdAt: row.createdAt instanceof Date ? row.createdAt : new Date(row.createdAt),
|
|
4321
4322
|
startedAt: row.startedAt ? row.startedAt instanceof Date ? row.startedAt : new Date(row.startedAt) : void 0,
|
|
4323
|
+
suspendedAt: row.suspendedAt ? row.suspendedAt instanceof Date ? row.suspendedAt : new Date(row.suspendedAt) : void 0,
|
|
4322
4324
|
completedAt: row.completedAt ? row.completedAt instanceof Date ? row.completedAt : new Date(row.completedAt) : void 0
|
|
4323
4325
|
};
|
|
4324
4326
|
}
|
|
@@ -4341,6 +4343,11 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4341
4343
|
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
4342
4344
|
schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS]
|
|
4343
4345
|
});
|
|
4346
|
+
await this.#db.alterTable({
|
|
4347
|
+
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
4348
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS],
|
|
4349
|
+
ifNotExists: ["suspend_payload", "suspendedAt"]
|
|
4350
|
+
});
|
|
4344
4351
|
await this.createDefaultIndexes();
|
|
4345
4352
|
await this.createCustomIndexes();
|
|
4346
4353
|
}
|
|
@@ -4427,11 +4434,13 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4427
4434
|
args: serializeJson(task.args),
|
|
4428
4435
|
result: serializeJson(task.result),
|
|
4429
4436
|
error: serializeJson(task.error),
|
|
4437
|
+
suspend_payload: serializeJson(task.suspendPayload),
|
|
4430
4438
|
retry_count: task.retryCount,
|
|
4431
4439
|
max_retries: task.maxRetries,
|
|
4432
4440
|
timeout_ms: task.timeoutMs,
|
|
4433
4441
|
createdAt: task.createdAt.toISOString(),
|
|
4434
4442
|
startedAt: task.startedAt?.toISOString() ?? null,
|
|
4443
|
+
suspendedAt: task.suspendedAt?.toISOString() ?? null,
|
|
4435
4444
|
completedAt: task.completedAt?.toISOString() ?? null
|
|
4436
4445
|
}
|
|
4437
4446
|
});
|
|
@@ -4452,6 +4461,10 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4452
4461
|
setClauses.push(`"error" = $${paramIdx++}`);
|
|
4453
4462
|
params.push(serializeJson(update.error));
|
|
4454
4463
|
}
|
|
4464
|
+
if ("suspendPayload" in update) {
|
|
4465
|
+
setClauses.push(`"suspend_payload" = $${paramIdx++}`);
|
|
4466
|
+
params.push(serializeJson(update.suspendPayload));
|
|
4467
|
+
}
|
|
4455
4468
|
if ("retryCount" in update) {
|
|
4456
4469
|
setClauses.push(`"retry_count" = $${paramIdx++}`);
|
|
4457
4470
|
params.push(update.retryCount);
|
|
@@ -4460,6 +4473,10 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4460
4473
|
setClauses.push(`"startedAt" = $${paramIdx++}`);
|
|
4461
4474
|
params.push(update.startedAt?.toISOString() ?? null);
|
|
4462
4475
|
}
|
|
4476
|
+
if ("suspendedAt" in update) {
|
|
4477
|
+
setClauses.push(`"suspendedAt" = $${paramIdx++}`);
|
|
4478
|
+
params.push(update.suspendedAt?.toISOString() ?? null);
|
|
4479
|
+
}
|
|
4463
4480
|
if ("completedAt" in update) {
|
|
4464
4481
|
setClauses.push(`"completedAt" = $${paramIdx++}`);
|
|
4465
4482
|
params.push(update.completedAt?.toISOString() ?? null);
|
|
@@ -4505,7 +4522,11 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4505
4522
|
conditions.push(`"tool_name" = $${paramIdx++}`);
|
|
4506
4523
|
params.push(filter.toolName);
|
|
4507
4524
|
}
|
|
4508
|
-
|
|
4525
|
+
if (filter.toolCallId) {
|
|
4526
|
+
conditions.push(`"tool_call_id" = $${paramIdx++}`);
|
|
4527
|
+
params.push(filter.toolCallId);
|
|
4528
|
+
}
|
|
4529
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? '"startedAt"' : filter.dateFilterBy === "suspendedAt" ? '"suspendedAt"' : filter.dateFilterBy === "completedAt" ? '"completedAt"' : '"createdAt"';
|
|
4509
4530
|
if (filter.fromDate) {
|
|
4510
4531
|
conditions.push(`${dateCol} >= $${paramIdx++}`);
|
|
4511
4532
|
params.push(filter.fromDate.toISOString());
|
|
@@ -4520,7 +4541,7 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4520
4541
|
params.slice(0, paramIdx - 1)
|
|
4521
4542
|
);
|
|
4522
4543
|
const total = Number(countResult?.count ?? 0);
|
|
4523
|
-
const orderCol = filter.orderBy === "startedAt" ? '"startedAt"' : filter.orderBy === "completedAt" ? '"completedAt"' : '"createdAt"';
|
|
4544
|
+
const orderCol = filter.orderBy === "startedAt" ? '"startedAt"' : filter.orderBy === "suspendedAt" ? '"suspendedAt"' : filter.orderBy === "completedAt" ? '"completedAt"' : '"createdAt"';
|
|
4524
4545
|
const direction = filter.orderDirection === "desc" ? "DESC" : "ASC";
|
|
4525
4546
|
let sql = `SELECT * FROM ${table} ${where} ORDER BY ${orderCol} ${direction}`;
|
|
4526
4547
|
if (filter.perPage != null) {
|
|
@@ -4549,7 +4570,7 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends storage.BackgroundTasks
|
|
|
4549
4570
|
conditions.push(`"status" IN (${placeholders.join(", ")})`);
|
|
4550
4571
|
params.push(...statuses);
|
|
4551
4572
|
}
|
|
4552
|
-
const dateCol = filter.dateFilterBy === "startedAt" ? '"startedAt"' : filter.dateFilterBy === "completedAt" ? '"completedAt"' : '"createdAt"';
|
|
4573
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? '"startedAt"' : filter.dateFilterBy === "suspendedAt" ? '"suspendedAt"' : filter.dateFilterBy === "completedAt" ? '"completedAt"' : '"createdAt"';
|
|
4553
4574
|
if (filter.fromDate) {
|
|
4554
4575
|
conditions.push(`${dateCol} >= $${paramIdx++}`);
|
|
4555
4576
|
params.push(filter.fromDate.toISOString());
|
|
@@ -7859,12 +7880,21 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
|
|
|
7859
7880
|
resourceId: row.resourceId
|
|
7860
7881
|
};
|
|
7861
7882
|
}
|
|
7862
|
-
async getThreadById({
|
|
7883
|
+
async getThreadById({
|
|
7884
|
+
threadId,
|
|
7885
|
+
resourceId
|
|
7886
|
+
}) {
|
|
7863
7887
|
try {
|
|
7864
7888
|
const tableName = getTableName4({ indexName: storage.TABLE_THREADS, schemaName: getSchemaName4(this.#schema) });
|
|
7889
|
+
let query = `SELECT * FROM ${tableName} WHERE id = $1`;
|
|
7890
|
+
let params = [threadId];
|
|
7891
|
+
if (resourceId !== void 0) {
|
|
7892
|
+
query += ` AND "resourceId" = $2`;
|
|
7893
|
+
params.push(resourceId);
|
|
7894
|
+
}
|
|
7865
7895
|
const thread = await this.#db.client.oneOrNone(
|
|
7866
|
-
|
|
7867
|
-
|
|
7896
|
+
query,
|
|
7897
|
+
params
|
|
7868
7898
|
);
|
|
7869
7899
|
if (!thread) {
|
|
7870
7900
|
return null;
|