@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 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
@@ -3,7 +3,7 @@ name: mastra-pg
3
3
  description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/pg"
6
- version: "1.10.0"
6
+ version: "1.10.1-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.10.0",
2
+ "version": "1.10.1-alpha.1",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -121,26 +121,88 @@ Each vector store page below includes installation instructions, configuration p
121
121
 
122
122
  ## Recall configuration
123
123
 
124
- The three main parameters that control semantic recall behavior are:
124
+ The following options control semantic recall behavior:
125
125
 
126
- 1. **topK**: How many semantically similar messages to retrieve
127
- 2. **messageRange**: How much surrounding context to include with each match
128
- 3. **scope**: Whether to search within the current thread or across all threads owned by a resource (the default is resource scope).
126
+ 1. **topK**: The number of similar messages to retrieve
127
+ 2. **messageRange**: The surrounding messages to include with each match
128
+ 3. **scope**: Whether to search the current thread or all threads for a resource
129
+ 4. **filter**: Metadata criteria that restrict search results
129
130
 
130
131
  ```typescript
131
132
  const agent = new Agent({
132
133
  memory: new Memory({
133
134
  options: {
134
135
  semanticRecall: {
135
- topK: 3, // Retrieve 3 most similar messages
136
+ topK: 3, // Retrieve 3 similar messages
136
137
  messageRange: 2, // Include 2 messages before and after each match
137
- scope: 'resource', // Search across all threads for this user (default setting if omitted)
138
+ scope: 'resource', // Search all threads for this resource
139
+ filter: { projectId: { $eq: 'project-a' } },
138
140
  },
139
141
  },
140
142
  }),
141
143
  })
142
144
  ```
143
145
 
146
+ > **Note:** `scope: 'resource'` is supported by the LibSQL, PostgreSQL, and Upstash storage adapters.
147
+
148
+ ### Metadata filtering
149
+
150
+ The `filter` option restricts semantic recall results to messages with matching thread metadata.
151
+
152
+ ```typescript
153
+ const agent = new Agent({
154
+ memory: new Memory({
155
+ options: {
156
+ semanticRecall: {
157
+ scope: 'resource',
158
+ filter: {
159
+ projectId: { $eq: 'project-a' },
160
+ category: { $in: ['work', 'personal'] },
161
+ },
162
+ },
163
+ },
164
+ }),
165
+ })
166
+ ```
167
+
168
+ Filters match metadata stored on message embeddings when messages are saved. If thread metadata changes later, existing embeddings keep their previous metadata until those messages are saved or indexed again.
169
+
170
+ Supported filter operators:
171
+
172
+ - `$and`: Logical AND
173
+ - `$eq`: Equal to
174
+ - `$gt`: Greater than
175
+ - `$gte`: Greater than or equal
176
+ - `$in`: In array
177
+ - `$lt`: Less than
178
+ - `$lte`: Less than or equal
179
+ - `$ne`: Not equal to
180
+ - `$nin`: Not in array
181
+ - `$or`: Logical OR
182
+
183
+ The following example demonstrates metadata filters for common use cases:
184
+
185
+ ```typescript
186
+ // Filter by project
187
+ const options = {
188
+ semanticRecall: { filter: { projectId: { $eq: 'my-project' } } },
189
+ }
190
+
191
+ // Filter by multiple categories
192
+ const options = {
193
+ semanticRecall: { filter: { category: { $in: ['work', 'research'] } } },
194
+ }
195
+
196
+ // Filter by project and priority
197
+ const options = {
198
+ semanticRecall: {
199
+ filter: {
200
+ $and: [{ projectId: { $eq: 'project-a' } }, { priority: { $gte: 3 } }],
201
+ },
202
+ },
203
+ }
204
+ ```
205
+
144
206
  ## Embedder configuration
145
207
 
146
208
  Semantic recall relies on an [embedding model](https://mastra.ai/reference/memory/memory-class) to convert messages into embeddings. Mastra supports embedding models through the model router using `provider/model` strings, or you can use any [embedding model](https://sdk.vercel.ai/docs/ai-sdk-core/embeddings) compatible with the AI SDK.
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
- const dateCol = filter.dateFilterBy === "startedAt" ? '"startedAt"' : filter.dateFilterBy === "completedAt" ? '"completedAt"' : '"createdAt"';
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({ threadId }) {
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
- `SELECT * FROM ${tableName} WHERE id = $1`,
7867
- [threadId]
7896
+ query,
7897
+ params
7868
7898
  );
7869
7899
  if (!thread) {
7870
7900
  return null;