@mastra/pg 1.19.0 → 1.20.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/dist/index.cjs CHANGED
@@ -170,13 +170,23 @@ var PGFilterTranslator = class extends _mastra_core_vector_filter.BaseFilterTran
170
170
  };
171
171
  //#endregion
172
172
  //#region src/vector/sql-builder.ts
173
+ const getTextExtractExpr = (key) => {
174
+ const jsonPathKey = parseJsonPathKey(key);
175
+ if (!key.includes(".")) return `metadata->>'${jsonPathKey}'`;
176
+ return `metadata#>>'{${jsonPathKey}}'`;
177
+ };
178
+ const getJsonExtractExpr = (key) => {
179
+ const jsonPathKey = parseJsonPathKey(key);
180
+ if (!key.includes(".")) return `metadata->'${jsonPathKey}'`;
181
+ return `metadata#>'{${jsonPathKey}}'`;
182
+ };
173
183
  const createBasicOperator = (symbol) => {
174
184
  return (key, paramIndex) => {
175
- const jsonPathKey = parseJsonPathKey(key);
185
+ const textExtract = getTextExtractExpr(key);
176
186
  return {
177
- sql: `CASE
178
- WHEN $${paramIndex}::text IS NULL THEN metadata#>>'{${jsonPathKey}}' IS ${symbol === "=" ? "" : "NOT"} NULL
179
- ELSE metadata#>>'{${jsonPathKey}}' ${symbol} $${paramIndex}::text
187
+ sql: `CASE
188
+ WHEN $${paramIndex}::text IS NULL THEN ${textExtract} IS ${symbol === "=" ? "" : "NOT"} NULL
189
+ ELSE ${textExtract} ${symbol} $${paramIndex}::text
180
190
  END`,
181
191
  needsValue: true
182
192
  };
@@ -184,13 +194,14 @@ const createBasicOperator = (symbol) => {
184
194
  };
185
195
  const createNumericOperator = (symbol) => {
186
196
  return (key, paramIndex, value) => {
187
- const jsonPathKey = parseJsonPathKey(key);
197
+ const textExtract = getTextExtractExpr(key);
198
+ const jsonExtract = getJsonExtractExpr(key);
188
199
  if (typeof value === "number" || typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "") return {
189
- sql: `(CASE WHEN jsonb_typeof(metadata#>'{${jsonPathKey}}') = 'number' THEN (metadata#>>'{${jsonPathKey}}')::numeric ${symbol} $${paramIndex}::numeric ELSE NULL END)`,
200
+ sql: `(CASE WHEN jsonb_typeof(${jsonExtract}) = 'number' THEN (${textExtract})::numeric ${symbol} $${paramIndex}::numeric ELSE NULL END)`,
190
201
  needsValue: true
191
202
  };
192
203
  else return {
193
- sql: `metadata#>>'{${jsonPathKey}}' ${symbol} $${paramIndex}::text`,
204
+ sql: `${textExtract} ${symbol} $${paramIndex}::text`,
194
205
  needsValue: true
195
206
  };
196
207
  };
@@ -221,7 +232,7 @@ function buildElemMatchConditions(value, paramIndex) {
221
232
  const operatorFn = FILTER_OPERATORS[paramOperator];
222
233
  if (!operatorFn) throw new Error(`Invalid operator: ${paramOperator}`);
223
234
  const result = operatorFn(paramKey, nextParamIndex, paramValue);
224
- const sql = result.sql.replaceAll("metadata#>>", "elem#>>").replaceAll("metadata#>", "elem#>");
235
+ const sql = result.sql.replaceAll("metadata->>", "elem->>").replaceAll("metadata->", "elem->").replaceAll("metadata#>>", "elem#>>").replaceAll("metadata#>", "elem#>");
225
236
  conditions.push(sql);
226
237
  if (result.needsValue) values.push(paramValue);
227
238
  });
@@ -238,32 +249,34 @@ const FILTER_OPERATORS = {
238
249
  $lt: createNumericOperator("<"),
239
250
  $lte: createNumericOperator("<="),
240
251
  $in: (key, paramIndex) => {
241
- const jsonPathKey = parseJsonPathKey(key);
252
+ const textExtract = getTextExtractExpr(key);
253
+ const jsonExtract = getJsonExtractExpr(key);
242
254
  return {
243
255
  sql: `(
244
256
  CASE
245
- WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
257
+ WHEN jsonb_typeof(${jsonExtract}) = 'array' THEN
246
258
  EXISTS (
247
- SELECT 1 FROM jsonb_array_elements_text(metadata->'${jsonPathKey}') as elem
259
+ SELECT 1 FROM jsonb_array_elements_text(${jsonExtract}) as elem
248
260
  WHERE elem = ANY($${paramIndex}::text[])
249
261
  )
250
- ELSE metadata#>>'{${jsonPathKey}}' = ANY($${paramIndex}::text[])
262
+ ELSE ${textExtract} = ANY($${paramIndex}::text[])
251
263
  END
252
264
  )`,
253
265
  needsValue: true
254
266
  };
255
267
  },
256
268
  $nin: (key, paramIndex) => {
257
- const jsonPathKey = parseJsonPathKey(key);
269
+ const textExtract = getTextExtractExpr(key);
270
+ const jsonExtract = getJsonExtractExpr(key);
258
271
  return {
259
272
  sql: `(
260
273
  CASE
261
- WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
274
+ WHEN jsonb_typeof(${jsonExtract}) = 'array' THEN
262
275
  NOT EXISTS (
263
- SELECT 1 FROM jsonb_array_elements_text(metadata->'${jsonPathKey}') as elem
276
+ SELECT 1 FROM jsonb_array_elements_text(${jsonExtract}) as elem
264
277
  WHERE elem = ANY($${paramIndex}::text[])
265
278
  )
266
- ELSE metadata#>>'{${jsonPathKey}}' != ALL($${paramIndex}::text[])
279
+ ELSE ${textExtract} != ALL($${paramIndex}::text[])
267
280
  END
268
281
  )`,
269
282
  needsValue: true
@@ -271,21 +284,21 @@ const FILTER_OPERATORS = {
271
284
  },
272
285
  $all: (key, paramIndex) => {
273
286
  return {
274
- sql: `CASE WHEN array_length($${paramIndex}::text[], 1) IS NULL THEN false
275
- ELSE (metadata#>'{${parseJsonPathKey(key)}}')::jsonb ?& $${paramIndex}::text[] END`,
287
+ sql: `CASE WHEN array_length($${paramIndex}::text[], 1) IS NULL THEN false
288
+ ELSE (${getJsonExtractExpr(key)})::jsonb ?& $${paramIndex}::text[] END`,
276
289
  needsValue: true
277
290
  };
278
291
  },
279
292
  $elemMatch: (key, paramIndex, value) => {
280
293
  const { sql, values } = buildElemMatchConditions(value, paramIndex);
281
- const jsonPathKey = parseJsonPathKey(key);
294
+ const jsonExtract = getJsonExtractExpr(key);
282
295
  return {
283
296
  sql: `(
284
297
  CASE
285
- WHEN jsonb_typeof(metadata->'${jsonPathKey}') = 'array' THEN
298
+ WHEN jsonb_typeof(${jsonExtract}) = 'array' THEN
286
299
  EXISTS (
287
- SELECT 1
288
- FROM jsonb_array_elements(metadata->'${jsonPathKey}') as elem
300
+ SELECT 1
301
+ FROM jsonb_array_elements(${jsonExtract}) as elem
289
302
  WHERE ${sql}
290
303
  )
291
304
  ELSE FALSE
@@ -315,7 +328,7 @@ const FILTER_OPERATORS = {
315
328
  needsValue: false
316
329
  }),
317
330
  $not: (key) => ({
318
- sql: `NOT (${key})`,
331
+ sql: `(${key})`,
319
332
  needsValue: false
320
333
  }),
321
334
  $nor: (key) => ({
@@ -324,16 +337,17 @@ const FILTER_OPERATORS = {
324
337
  }),
325
338
  $regex: (key, paramIndex) => {
326
339
  return {
327
- sql: `metadata#>>'{${parseJsonPathKey(key)}}' ~ $${paramIndex}`,
340
+ sql: `${getTextExtractExpr(key)} ~ $${paramIndex}`,
328
341
  needsValue: true
329
342
  };
330
343
  },
331
344
  $contains: (key, paramIndex, value) => {
332
- const jsonPathKey = parseJsonPathKey(key);
345
+ const textExtract = getTextExtractExpr(key);
346
+ const jsonExtract = getJsonExtractExpr(key);
333
347
  let sql;
334
- if (Array.isArray(value)) sql = `(metadata->'${jsonPathKey}') ?& $${paramIndex}`;
335
- else if (typeof value === "string") sql = `metadata->>'${jsonPathKey}' ILIKE '%' || $${paramIndex} || '%' ESCAPE '\\'`;
336
- else sql = `metadata->>'${jsonPathKey}' = $${paramIndex}`;
348
+ if (Array.isArray(value)) sql = `(${jsonExtract}) ?& $${paramIndex}`;
349
+ else if (typeof value === "string") sql = `${textExtract} ILIKE '%' || $${paramIndex} || '%' ESCAPE '\\'`;
350
+ else sql = `${textExtract} = $${paramIndex}`;
337
351
  return {
338
352
  sql,
339
353
  needsValue: true,
@@ -345,12 +359,12 @@ const FILTER_OPERATORS = {
345
359
  * Usage: { field: { $objectContains: { ...subobject } } }
346
360
  */
347
361
  $size: (key, paramIndex) => {
348
- const jsonPathKey = parseJsonPathKey(key);
362
+ const jsonExtract = getJsonExtractExpr(key);
349
363
  return {
350
364
  sql: `(
351
365
  CASE
352
- WHEN jsonb_typeof(metadata#>'{${jsonPathKey}}') = 'array' THEN
353
- jsonb_array_length(metadata#>'{${jsonPathKey}}') = $${paramIndex}
366
+ WHEN jsonb_typeof(${jsonExtract}) = 'array' THEN
367
+ jsonb_array_length(${jsonExtract}) = $${paramIndex}
354
368
  ELSE FALSE
355
369
  END
356
370
  )`,
@@ -378,7 +392,7 @@ function buildDeleteFilterQuery(filter) {
378
392
  ].includes(key)) return handleLogicalOperator(key, value, parentPath);
379
393
  if (!value || typeof value !== "object") {
380
394
  values.push(value);
381
- return `metadata#>>'{${parseJsonPathKey(key)}}' = $${values.length}`;
395
+ return `${getTextExtractExpr(key)} = $${values.length}`;
382
396
  }
383
397
  const entries = Object.entries(value);
384
398
  if (entries.length > 1) return entries.map(([operator, operatorValue]) => {
@@ -469,7 +483,7 @@ function buildFilterQuery(filter, minScore, topK) {
469
483
  ].includes(key)) return handleLogicalOperator(key, value, parentPath);
470
484
  if (!value || typeof value !== "object") {
471
485
  values.push(value);
472
- return `metadata#>>'{${parseJsonPathKey(key)}}' = $${values.length}`;
486
+ return `${getTextExtractExpr(key)} = $${values.length}`;
473
487
  }
474
488
  const entries = Object.entries(value);
475
489
  if (entries.length > 1) return entries.map(([operator, operatorValue]) => {
@@ -1802,16 +1816,21 @@ var PoolAdapter = class {
1802
1816
  const client = await this.$pool.connect();
1803
1817
  try {
1804
1818
  await client.query("BEGIN");
1805
- const result = await callback(new TransactionClient(client));
1806
- await client.query("COMMIT");
1807
- return result;
1808
- } catch (error) {
1819
+ const txClient = new TransactionClient(client);
1809
1820
  try {
1810
- await client.query("ROLLBACK");
1811
- } catch (rollbackError) {
1812
- console.error("Transaction rollback failed:", rollbackError);
1821
+ const result = await callback(txClient);
1822
+ await txClient.drain();
1823
+ await client.query("COMMIT");
1824
+ return result;
1825
+ } catch (error) {
1826
+ await txClient.drain().catch(() => void 0);
1827
+ try {
1828
+ await client.query("ROLLBACK");
1829
+ } catch (rollbackError) {
1830
+ console.error("Transaction rollback failed:", rollbackError);
1831
+ }
1832
+ throw error;
1813
1833
  }
1814
- throw error;
1815
1834
  } finally {
1816
1835
  client.release();
1817
1836
  }
@@ -1819,41 +1838,85 @@ var PoolAdapter = class {
1819
1838
  };
1820
1839
  /**
1821
1840
  * Transaction client that wraps a PoolClient for executing queries within a transaction.
1841
+ *
1842
+ * Query methods are serialized through a tail promise (same pattern as
1843
+ * PinnedClientAdapter). Callers such as memory.updateMessages historically
1844
+ * did `queries.push(t.none(...))` then `await t.batch(queries)` — each
1845
+ * `t.none()` is async and starts `client.query` immediately, so by the time
1846
+ * batch runs, N queries are already in flight on one PoolClient. pg@8 queues
1847
+ * those internally and emits a DeprecationWarning; pg@9 will throw.
1848
+ * (#20820)
1822
1849
  */
1823
1850
  var TransactionClient = class {
1824
1851
  client;
1852
+ /**
1853
+ * Serialization tail. Without this gate, concurrent t.none()/t.query()
1854
+ * from Promise.all / batch land on the same PoolClient at once.
1855
+ */
1856
+ #tail = Promise.resolve();
1857
+ #error;
1825
1858
  constructor(client) {
1826
1859
  this.client = client;
1827
1860
  }
1828
- async none(query, values) {
1829
- await this.client.query(query, values);
1830
- return null;
1861
+ #enqueue(fn) {
1862
+ const next = this.#tail.then(fn);
1863
+ this.#tail = next.then(() => void 0, (error) => {
1864
+ this.#error ??= { value: error };
1865
+ });
1866
+ return next;
1831
1867
  }
1832
- async one(query, values) {
1833
- const result = await this.client.query(query, values);
1834
- if (result.rows.length === 0) throw new Error(`No data returned from query: ${truncateQuery(query)}`);
1835
- if (result.rows.length > 1) throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
1836
- return result.rows[0];
1868
+ /**
1869
+ * Wait until every enqueued query has settled and surface the first failure.
1870
+ * PoolAdapter / PinnedClientAdapter call this before COMMIT/ROLLBACK so
1871
+ * those control statements never overlap in-flight work on the same client.
1872
+ */
1873
+ async drain() {
1874
+ await this.#tail;
1875
+ if (this.#error) {
1876
+ const { value } = this.#error;
1877
+ this.#error = void 0;
1878
+ throw value;
1879
+ }
1837
1880
  }
1838
- async oneOrNone(query, values) {
1839
- const result = await this.client.query(query, values);
1840
- if (result.rows.length === 0) return null;
1841
- if (result.rows.length > 1) throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
1842
- return result.rows[0];
1881
+ none(query, values) {
1882
+ return this.#enqueue(async () => {
1883
+ await this.client.query(query, values);
1884
+ return null;
1885
+ });
1843
1886
  }
1844
- async any(query, values) {
1845
- return (await this.client.query(query, values)).rows;
1887
+ one(query, values) {
1888
+ return this.#enqueue(async () => {
1889
+ const result = await this.client.query(query, values);
1890
+ if (result.rows.length === 0) throw new Error(`No data returned from query: ${truncateQuery(query)}`);
1891
+ if (result.rows.length > 1) throw new Error(`Multiple rows returned when one was expected: ${truncateQuery(query)}`);
1892
+ return result.rows[0];
1893
+ });
1846
1894
  }
1847
- async manyOrNone(query, values) {
1895
+ oneOrNone(query, values) {
1896
+ return this.#enqueue(async () => {
1897
+ const result = await this.client.query(query, values);
1898
+ if (result.rows.length === 0) return null;
1899
+ if (result.rows.length > 1) throw new Error(`Multiple rows returned when one or none was expected: ${truncateQuery(query)}`);
1900
+ return result.rows[0];
1901
+ });
1902
+ }
1903
+ any(query, values) {
1904
+ return this.#enqueue(async () => {
1905
+ return (await this.client.query(query, values)).rows;
1906
+ });
1907
+ }
1908
+ manyOrNone(query, values) {
1848
1909
  return this.any(query, values);
1849
1910
  }
1850
- async many(query, values) {
1851
- const result = await this.client.query(query, values);
1852
- if (result.rows.length === 0) throw new Error(`No data returned from query: ${truncateQuery(query)}`);
1853
- return result.rows;
1911
+ many(query, values) {
1912
+ return this.#enqueue(async () => {
1913
+ const result = await this.client.query(query, values);
1914
+ if (result.rows.length === 0) throw new Error(`No data returned from query: ${truncateQuery(query)}`);
1915
+ return result.rows;
1916
+ });
1854
1917
  }
1855
- async query(query, values) {
1856
- return this.client.query(query, values);
1918
+ query(query, values) {
1919
+ return this.#enqueue(() => this.client.query(query, values));
1857
1920
  }
1858
1921
  async batch(promises) {
1859
1922
  return Promise.all(promises);
@@ -1946,11 +2009,14 @@ var PinnedClientAdapter = class {
1946
2009
  tx(callback) {
1947
2010
  return this.#enqueue(async () => {
1948
2011
  await this.pinnedClient.query("BEGIN");
2012
+ const txClient = new TransactionClient(this.pinnedClient);
1949
2013
  try {
1950
- const result = await callback(new TransactionClient(this.pinnedClient));
2014
+ const result = await callback(txClient);
2015
+ await txClient.drain();
1951
2016
  await this.pinnedClient.query("COMMIT");
1952
2017
  return result;
1953
2018
  } catch (error) {
2019
+ await txClient.drain().catch(() => void 0);
1954
2020
  try {
1955
2021
  await this.pinnedClient.query("ROLLBACK");
1956
2022
  } catch (rollbackError) {
@@ -6440,7 +6506,13 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6440
6506
  ifNotExists: [
6441
6507
  "agentVersion",
6442
6508
  "organizationId",
6443
- "projectId"
6509
+ "projectId",
6510
+ "provenance",
6511
+ "runnerAttestation",
6512
+ "experimentSetId",
6513
+ "comparisonId",
6514
+ "variantId",
6515
+ "trialIndex"
6444
6516
  ]
6445
6517
  });
6446
6518
  await this.#db.alterTable({
@@ -6546,6 +6618,16 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6546
6618
  table: _mastra_core_storage.TABLE_EXPERIMENTS,
6547
6619
  columns: ["datasetId"]
6548
6620
  },
6621
+ {
6622
+ name: "idx_experiments_grouping",
6623
+ table: _mastra_core_storage.TABLE_EXPERIMENTS,
6624
+ columns: [
6625
+ "experimentSetId",
6626
+ "comparisonId",
6627
+ "variantId",
6628
+ "trialIndex"
6629
+ ]
6630
+ },
6549
6631
  {
6550
6632
  name: "idx_experiment_results_experimentid",
6551
6633
  table: _mastra_core_storage.TABLE_EXPERIMENT_RESULTS,
@@ -6591,6 +6673,12 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6591
6673
  name: row.name ?? void 0,
6592
6674
  description: row.description ?? void 0,
6593
6675
  metadata: row.metadata ? (0, _mastra_core_storage.safelyParseJSON)(row.metadata) : void 0,
6676
+ provenance: row.provenance ? (0, _mastra_core_storage.safelyParseJSON)(row.provenance) : null,
6677
+ runnerAttestation: row.runnerAttestation ? (0, _mastra_core_storage.safelyParseJSON)(row.runnerAttestation) : null,
6678
+ experimentSetId: row.experimentSetId ?? null,
6679
+ comparisonId: row.comparisonId ?? null,
6680
+ variantId: row.variantId ?? null,
6681
+ trialIndex: row.trialIndex != null ? row.trialIndex : null,
6594
6682
  datasetId: row.datasetId ?? null,
6595
6683
  datasetVersion: row.datasetVersion != null ? row.datasetVersion : null,
6596
6684
  agentVersion: row.agentVersion ?? null,
@@ -6644,6 +6732,12 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6644
6732
  name: input.name ?? null,
6645
6733
  description: input.description ?? null,
6646
6734
  metadata: input.metadata ?? null,
6735
+ provenance: input.provenance ?? null,
6736
+ runnerAttestation: input.runnerAttestation ?? null,
6737
+ experimentSetId: input.experimentSetId ?? null,
6738
+ comparisonId: input.comparisonId ?? null,
6739
+ variantId: input.variantId ?? null,
6740
+ trialIndex: input.trialIndex ?? null,
6647
6741
  datasetId: input.datasetId ?? null,
6648
6742
  datasetVersion: input.datasetVersion ?? null,
6649
6743
  agentVersion: input.agentVersion ?? null,
@@ -6667,6 +6761,12 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6667
6761
  name: input.name,
6668
6762
  description: input.description,
6669
6763
  metadata: input.metadata,
6764
+ provenance: input.provenance ?? null,
6765
+ runnerAttestation: input.runnerAttestation ?? null,
6766
+ experimentSetId: input.experimentSetId ?? null,
6767
+ comparisonId: input.comparisonId ?? null,
6768
+ variantId: input.variantId ?? null,
6769
+ trialIndex: input.trialIndex ?? null,
6670
6770
  datasetId: input.datasetId ?? null,
6671
6771
  datasetVersion: input.datasetVersion ?? null,
6672
6772
  agentVersion: input.agentVersion ?? null,
@@ -6808,6 +6908,22 @@ var ExperimentsPG = class ExperimentsPG extends _mastra_core_storage.Experiments
6808
6908
  conditions.push(`"status" = $${paramIndex++}`);
6809
6909
  queryParams.push(args.status);
6810
6910
  }
6911
+ if (args.experimentSetId !== void 0) {
6912
+ conditions.push(`"experimentSetId" = $${paramIndex++}`);
6913
+ queryParams.push(args.experimentSetId);
6914
+ }
6915
+ if (args.comparisonId !== void 0) {
6916
+ conditions.push(`"comparisonId" = $${paramIndex++}`);
6917
+ queryParams.push(args.comparisonId);
6918
+ }
6919
+ if (args.variantId !== void 0) {
6920
+ conditions.push(`"variantId" = $${paramIndex++}`);
6921
+ queryParams.push(args.variantId);
6922
+ }
6923
+ if (args.trialIndex !== void 0) {
6924
+ conditions.push(`"trialIndex" = $${paramIndex++}`);
6925
+ queryParams.push(args.trialIndex);
6926
+ }
6811
6927
  if (args.filters) {
6812
6928
  const { organizationId, projectId } = args.filters;
6813
6929
  if (organizationId !== void 0) {
@@ -8589,6 +8705,13 @@ function getTableName$3({ indexName, schemaName }) {
8589
8705
  function inPlaceholders(count, startIndex = 1) {
8590
8706
  return Array.from({ length: count }, (_, i) => `$${i + startIndex}`).join(", ");
8591
8707
  }
8708
+ /**
8709
+ * Bind dates as UTC strings because node-postgres serializes Date parameters
8710
+ * for TIMESTAMP columns using the process's local timezone.
8711
+ */
8712
+ function toUtcISOString(date) {
8713
+ return date.toISOString();
8714
+ }
8592
8715
  function dedupeMessagesForSave(messages) {
8593
8716
  const deduped = /* @__PURE__ */ new Map();
8594
8717
  for (const message of messages) {
@@ -9003,6 +9126,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9003
9126
  hasMore: perPageInput === false ? false : offset + perPage < total
9004
9127
  };
9005
9128
  } catch (error) {
9129
+ if (error instanceof _mastra_core_error.MastraError && error.category === _mastra_core_error.ErrorCategory.USER) throw error;
9006
9130
  const mastraError = new _mastra_core_error.MastraError({
9007
9131
  id: (0, _mastra_core_storage.createStorageErrorId)("PG", "LIST_THREADS", "FAILED"),
9008
9132
  domain: _mastra_core_error.ErrorDomain.STORAGE,
@@ -9015,13 +9139,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9015
9139
  }, error);
9016
9140
  this.logger?.error?.(mastraError.toString());
9017
9141
  this.logger?.trackException(mastraError);
9018
- return {
9019
- threads: [],
9020
- total: 0,
9021
- page,
9022
- perPage: perPageForResponse,
9023
- hasMore: false
9024
- };
9142
+ throw mastraError;
9025
9143
  }
9026
9144
  }
9027
9145
  async saveThread({ thread }) {
@@ -9030,6 +9148,8 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9030
9148
  indexName: _mastra_core_storage.TABLE_THREADS,
9031
9149
  schemaName: getSchemaName$3(this.#schema)
9032
9150
  });
9151
+ const createdAt = toUtcISOString(thread.createdAt);
9152
+ const updatedAt = toUtcISOString(thread.updatedAt);
9033
9153
  await this.#db.client.none(`INSERT INTO ${tableName} (
9034
9154
  id,
9035
9155
  "resourceId",
@@ -9052,10 +9172,10 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9052
9172
  thread.resourceId,
9053
9173
  thread.title,
9054
9174
  thread.metadata ? JSON.stringify(thread.metadata) : null,
9055
- thread.createdAt,
9056
- thread.createdAt,
9057
- thread.updatedAt,
9058
- thread.updatedAt
9175
+ createdAt,
9176
+ createdAt,
9177
+ updatedAt,
9178
+ updatedAt
9059
9179
  ]);
9060
9180
  return thread;
9061
9181
  } catch (error) {
@@ -9088,7 +9208,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9088
9208
  ...metadata
9089
9209
  };
9090
9210
  try {
9091
- const now = /* @__PURE__ */ new Date();
9211
+ const nowStr = toUtcISOString(/* @__PURE__ */ new Date());
9092
9212
  const thread = await this.#db.client.one(`UPDATE ${threadTableName}
9093
9213
  SET
9094
9214
  title = $1,
@@ -9100,8 +9220,8 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9100
9220
  `, [
9101
9221
  title,
9102
9222
  mergedMetadata,
9103
- now,
9104
- now,
9223
+ nowStr,
9224
+ nowStr,
9105
9225
  id
9106
9226
  ]);
9107
9227
  return {
@@ -9290,7 +9410,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9290
9410
  }, error);
9291
9411
  this.logger?.error?.(mastraError.toString());
9292
9412
  this.logger?.trackException(mastraError);
9293
- return { messages: [] };
9413
+ throw mastraError;
9294
9414
  }
9295
9415
  }
9296
9416
  async listMessages(args) {
@@ -9416,6 +9536,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9416
9536
  hasMore
9417
9537
  };
9418
9538
  } catch (error) {
9539
+ if (error instanceof _mastra_core_error.MastraError && error.category === _mastra_core_error.ErrorCategory.USER) throw error;
9419
9540
  const mastraError = new _mastra_core_error.MastraError({
9420
9541
  id: (0, _mastra_core_storage.createStorageErrorId)("PG", "LIST_MESSAGES", "FAILED"),
9421
9542
  domain: _mastra_core_error.ErrorDomain.STORAGE,
@@ -9427,13 +9548,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9427
9548
  }, error);
9428
9549
  this.logger?.error?.(mastraError.toString());
9429
9550
  this.logger?.trackException(mastraError);
9430
- return {
9431
- messages: [],
9432
- total: 0,
9433
- page,
9434
- perPage: perPageForResponse,
9435
- hasMore: false
9436
- };
9551
+ throw mastraError;
9437
9552
  }
9438
9553
  }
9439
9554
  async listMessagesByResourceId(args) {
@@ -9553,6 +9668,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9553
9668
  hasMore
9554
9669
  };
9555
9670
  } catch (error) {
9671
+ if (error instanceof _mastra_core_error.MastraError && error.category === _mastra_core_error.ErrorCategory.USER) throw error;
9556
9672
  const mastraError = new _mastra_core_error.MastraError({
9557
9673
  id: (0, _mastra_core_storage.createStorageErrorId)("PG", "LIST_MESSAGES_BY_RESOURCE_ID", "FAILED"),
9558
9674
  domain: _mastra_core_error.ErrorDomain.STORAGE,
@@ -9561,13 +9677,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9561
9677
  }, error);
9562
9678
  this.logger?.error?.(mastraError.toString());
9563
9679
  this.logger?.trackException(mastraError);
9564
- return {
9565
- messages: [],
9566
- total: 0,
9567
- page,
9568
- perPage: perPageForResponse,
9569
- hasMore: false
9570
- };
9680
+ throw mastraError;
9571
9681
  }
9572
9682
  }
9573
9683
  async saveMessages({ messages }) {
@@ -9603,7 +9713,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9603
9713
  const batch = messagesToSave.slice(offset, offset + MAX_MESSAGES_PER_INSERT);
9604
9714
  const values = [];
9605
9715
  const valuePlaceholders = batch.map((message, messageIndex) => {
9606
- const createdAt = message.createdAt || /* @__PURE__ */ new Date();
9716
+ const createdAt = toUtcISOString(message.createdAt || /* @__PURE__ */ new Date());
9607
9717
  values.push(message.id, message.threadId, typeof message.content === "string" ? message.content : JSON.stringify(message.content), createdAt, createdAt, message.role, message.type || "v2", message.resourceId);
9608
9718
  const paramOffset = messageIndex * MESSAGE_INSERT_BIND_PARAMETERS;
9609
9719
  return `(${Array.from({ length: MESSAGE_INSERT_BIND_PARAMETERS }, (_, paramIndex) => `$${paramOffset + paramIndex + 1}`).join(", ")})`;
@@ -9621,7 +9731,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9621
9731
  indexName: _mastra_core_storage.TABLE_THREADS,
9622
9732
  schemaName: getSchemaName$3(this.#schema)
9623
9733
  });
9624
- const now = /* @__PURE__ */ new Date();
9734
+ const now = toUtcISOString(/* @__PURE__ */ new Date());
9625
9735
  for (const threadIdToUpdate of threadIds) await t.none(`UPDATE ${threadTableName}
9626
9736
  SET
9627
9737
  "updatedAt" = $1,
@@ -9773,11 +9883,15 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9773
9883
  };
9774
9884
  }
9775
9885
  async saveResource({ resource }) {
9886
+ const createdAt = toUtcISOString(resource.createdAt);
9887
+ const updatedAt = toUtcISOString(resource.updatedAt);
9776
9888
  await this.#db.insert({
9777
9889
  tableName: _mastra_core_storage.TABLE_RESOURCES,
9778
9890
  record: {
9779
9891
  ...resource,
9780
- metadata: JSON.stringify(resource.metadata)
9892
+ metadata: JSON.stringify(resource.metadata),
9893
+ createdAt,
9894
+ updatedAt
9781
9895
  }
9782
9896
  });
9783
9897
  return resource;
@@ -9881,6 +9995,7 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9881
9995
  }
9882
9996
  const sourceMessages = await t.manyOrNone(messageQuery, messageParams);
9883
9997
  const now = /* @__PURE__ */ new Date();
9998
+ const nowStr = toUtcISOString(now);
9884
9999
  const lastMessageId = sourceMessages.length > 0 ? sourceMessages[sourceMessages.length - 1].id : void 0;
9885
10000
  const cloneMetadata = {
9886
10001
  sourceThreadId,
@@ -9912,10 +10027,10 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9912
10027
  newThread.resourceId,
9913
10028
  newThread.title,
9914
10029
  newThread.metadata ? JSON.stringify(newThread.metadata) : null,
9915
- now,
9916
- now,
9917
- now,
9918
- now
10030
+ nowStr,
10031
+ nowStr,
10032
+ nowStr,
10033
+ nowStr
9919
10034
  ]);
9920
10035
  const clonedMessages = [];
9921
10036
  const messageIdMap = {};
@@ -9928,13 +10043,14 @@ var MemoryPG = class MemoryPG extends _mastra_core_storage.MemoryStorage {
9928
10043
  try {
9929
10044
  parsedContent = JSON.parse(normalizedMsg.content);
9930
10045
  } catch {}
10046
+ const createdAt = toUtcISOString(new Date(normalizedMsg.createdAt));
9931
10047
  await t.none(`INSERT INTO ${messageTableName} (id, thread_id, content, "createdAt", "createdAtZ", role, type, "resourceId")
9932
10048
  VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [
9933
10049
  newMessageId,
9934
10050
  newThreadId,
9935
10051
  typeof normalizedMsg.content === "string" ? normalizedMsg.content : JSON.stringify(normalizedMsg.content),
9936
- normalizedMsg.createdAt,
9937
- normalizedMsg.createdAt,
10052
+ createdAt,
10053
+ createdAt,
9938
10054
  normalizedMsg.role,
9939
10055
  normalizedMsg.type || "v2",
9940
10056
  targetResourceId