@mastra/pg 0.11.1-alpha.0 → 0.11.1-alpha.2

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.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
1
2
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
2
3
  import { MastraVector } from '@mastra/core/vector';
3
4
  import { Mutex } from 'async-mutex';
@@ -5,7 +6,7 @@ import pg from 'pg';
5
6
  import xxhash from 'xxhash-wasm';
6
7
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
7
8
  import { MessageList } from '@mastra/core/agent';
8
- import { MastraStorage, TABLE_EVALS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS, TABLE_MESSAGES } from '@mastra/core/storage';
9
+ import { MastraStorage, TABLE_EVALS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES } from '@mastra/core/storage';
9
10
  import pgPromise from 'pg-promise';
10
11
 
11
12
  // src/vector/index.ts
@@ -36,10 +37,10 @@ var PGFilterTranslator = class extends BaseFilterTranslator {
36
37
  }
37
38
  const entries = Object.entries(node);
38
39
  const result = {};
39
- if ("$options" in node && !("$regex" in node)) {
40
+ if (node && "$options" in node && !("$regex" in node)) {
40
41
  throw new Error("$options is not valid without $regex");
41
42
  }
42
- if ("$regex" in node) {
43
+ if (node && "$regex" in node) {
43
44
  const options = node.$options || "";
44
45
  return withPath(this.translateRegexPattern(node.$regex, options));
45
46
  }
@@ -368,43 +369,57 @@ var PgVector = class extends MastraVector {
368
369
  schemaName,
369
370
  pgPoolOptions
370
371
  }) {
371
- if (!connectionString || connectionString.trim() === "") {
372
- throw new Error(
373
- "PgVector: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
374
- );
375
- }
376
- super();
377
- this.schema = schemaName;
378
- const basePool = new pg.Pool({
379
- connectionString,
380
- max: 20,
381
- // Maximum number of clients in the pool
382
- idleTimeoutMillis: 3e4,
383
- // Close idle connections after 30 seconds
384
- connectionTimeoutMillis: 2e3,
385
- // Fail fast if can't connect
386
- ...pgPoolOptions
387
- });
388
- const telemetry = this.__getTelemetry();
389
- this.pool = telemetry?.traceClass(basePool, {
390
- spanNamePrefix: "pg-vector",
391
- attributes: {
392
- "vector.type": "postgres"
372
+ try {
373
+ if (!connectionString || connectionString.trim() === "") {
374
+ throw new Error(
375
+ "PgVector: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
376
+ );
393
377
  }
394
- }) ?? basePool;
395
- void (async () => {
396
- const existingIndexes = await this.listIndexes();
397
- void existingIndexes.map(async (indexName) => {
398
- const info = await this.getIndexInfo({ indexName });
399
- const key = await this.getIndexCacheKey({
400
- indexName,
401
- metric: info.metric,
402
- dimension: info.dimension,
403
- type: info.type
404
- });
405
- this.createdIndexes.set(indexName, key);
378
+ super();
379
+ this.schema = schemaName;
380
+ const basePool = new pg.Pool({
381
+ connectionString,
382
+ max: 20,
383
+ // Maximum number of clients in the pool
384
+ idleTimeoutMillis: 3e4,
385
+ // Close idle connections after 30 seconds
386
+ connectionTimeoutMillis: 2e3,
387
+ // Fail fast if can't connect
388
+ ...pgPoolOptions
406
389
  });
407
- })();
390
+ const telemetry = this.__getTelemetry();
391
+ this.pool = telemetry?.traceClass(basePool, {
392
+ spanNamePrefix: "pg-vector",
393
+ attributes: {
394
+ "vector.type": "postgres"
395
+ }
396
+ }) ?? basePool;
397
+ void (async () => {
398
+ const existingIndexes = await this.listIndexes();
399
+ void existingIndexes.map(async (indexName) => {
400
+ const info = await this.getIndexInfo({ indexName });
401
+ const key = await this.getIndexCacheKey({
402
+ indexName,
403
+ metric: info.metric,
404
+ dimension: info.dimension,
405
+ type: info.type
406
+ });
407
+ this.createdIndexes.set(indexName, key);
408
+ });
409
+ })();
410
+ } catch (error) {
411
+ throw new MastraError(
412
+ {
413
+ id: "MASTRA_STORAGE_PG_VECTOR_INITIALIZATION_FAILED",
414
+ domain: ErrorDomain.MASTRA_VECTOR,
415
+ category: ErrorCategory.THIRD_PARTY,
416
+ details: {
417
+ schemaName: schemaName ?? ""
418
+ }
419
+ },
420
+ error
421
+ );
422
+ }
408
423
  }
409
424
  getMutexByName(indexName) {
410
425
  if (!this.mutexesByName.has(indexName)) this.mutexesByName.set(indexName, new Mutex());
@@ -443,11 +458,27 @@ var PgVector = class extends MastraVector {
443
458
  ef,
444
459
  probes
445
460
  }) {
446
- if (!Number.isInteger(topK) || topK <= 0) {
447
- throw new Error("topK must be a positive integer");
448
- }
449
- if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
450
- throw new Error("queryVector must be an array of finite numbers");
461
+ try {
462
+ if (!Number.isInteger(topK) || topK <= 0) {
463
+ throw new Error("topK must be a positive integer");
464
+ }
465
+ if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
466
+ throw new Error("queryVector must be an array of finite numbers");
467
+ }
468
+ } catch (error) {
469
+ const mastraError = new MastraError(
470
+ {
471
+ id: "MASTRA_STORAGE_PG_VECTOR_QUERY_INVALID_INPUT",
472
+ domain: ErrorDomain.MASTRA_VECTOR,
473
+ category: ErrorCategory.USER,
474
+ details: {
475
+ indexName
476
+ }
477
+ },
478
+ error
479
+ );
480
+ this.logger?.trackException(mastraError);
481
+ throw mastraError;
451
482
  }
452
483
  const client = await this.pool.connect();
453
484
  try {
@@ -486,6 +517,20 @@ var PgVector = class extends MastraVector {
486
517
  metadata,
487
518
  ...includeVector && embedding && { vector: JSON.parse(embedding) }
488
519
  }));
520
+ } catch (error) {
521
+ const mastraError = new MastraError(
522
+ {
523
+ id: "MASTRA_STORAGE_PG_VECTOR_QUERY_FAILED",
524
+ domain: ErrorDomain.MASTRA_VECTOR,
525
+ category: ErrorCategory.THIRD_PARTY,
526
+ details: {
527
+ indexName
528
+ }
529
+ },
530
+ error
531
+ );
532
+ this.logger?.trackException(mastraError);
533
+ throw mastraError;
489
534
  } finally {
490
535
  client.release();
491
536
  }
@@ -516,12 +561,37 @@ var PgVector = class extends MastraVector {
516
561
  const match = error.message.match(/expected (\d+) dimensions, not (\d+)/);
517
562
  if (match) {
518
563
  const [, expected, actual] = match;
519
- throw new Error(
520
- `Vector dimension mismatch: Index "${indexName}" expects ${expected} dimensions but got ${actual} dimensions. Either use a matching embedding model or delete and recreate the index with the new dimension.`
564
+ const mastraError2 = new MastraError(
565
+ {
566
+ id: "MASTRA_STORAGE_PG_VECTOR_UPSERT_INVALID_INPUT",
567
+ domain: ErrorDomain.MASTRA_VECTOR,
568
+ category: ErrorCategory.USER,
569
+ text: `Vector dimension mismatch: Index "${indexName}" expects ${expected} dimensions but got ${actual} dimensions. Either use a matching embedding model or delete and recreate the index with the new dimension.`,
570
+ details: {
571
+ indexName,
572
+ expected: expected ?? "",
573
+ actual: actual ?? ""
574
+ }
575
+ },
576
+ error
521
577
  );
578
+ this.logger?.trackException(mastraError2);
579
+ throw mastraError2;
522
580
  }
523
581
  }
524
- throw error;
582
+ const mastraError = new MastraError(
583
+ {
584
+ id: "MASTRA_STORAGE_PG_VECTOR_UPSERT_FAILED",
585
+ domain: ErrorDomain.MASTRA_VECTOR,
586
+ category: ErrorCategory.THIRD_PARTY,
587
+ details: {
588
+ indexName
589
+ }
590
+ },
591
+ error
592
+ );
593
+ this.logger?.trackException(mastraError);
594
+ throw mastraError;
525
595
  } finally {
526
596
  client.release();
527
597
  }
@@ -589,11 +659,27 @@ var PgVector = class extends MastraVector {
589
659
  buildIndex = true
590
660
  }) {
591
661
  const { tableName } = this.getTableName(indexName);
592
- if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
593
- throw new Error("Invalid index name format");
594
- }
595
- if (!Number.isInteger(dimension) || dimension <= 0) {
596
- throw new Error("Dimension must be a positive integer");
662
+ try {
663
+ if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
664
+ throw new Error("Invalid index name format");
665
+ }
666
+ if (!Number.isInteger(dimension) || dimension <= 0) {
667
+ throw new Error("Dimension must be a positive integer");
668
+ }
669
+ } catch (error) {
670
+ const mastraError = new MastraError(
671
+ {
672
+ id: "MASTRA_STORAGE_PG_VECTOR_CREATE_INDEX_INVALID_INPUT",
673
+ domain: ErrorDomain.MASTRA_VECTOR,
674
+ category: ErrorCategory.USER,
675
+ details: {
676
+ indexName
677
+ }
678
+ },
679
+ error
680
+ );
681
+ this.logger?.trackException(mastraError);
682
+ throw mastraError;
597
683
  }
598
684
  const indexCacheKey = await this.getIndexCacheKey({ indexName, dimension, type: indexConfig.type, metric });
599
685
  if (this.cachedIndexExists(indexName, indexCacheKey)) {
@@ -626,12 +712,40 @@ var PgVector = class extends MastraVector {
626
712
  } finally {
627
713
  client.release();
628
714
  }
715
+ }).catch((error) => {
716
+ const mastraError = new MastraError(
717
+ {
718
+ id: "MASTRA_STORAGE_PG_VECTOR_CREATE_INDEX_FAILED",
719
+ domain: ErrorDomain.MASTRA_VECTOR,
720
+ category: ErrorCategory.THIRD_PARTY,
721
+ details: {
722
+ indexName
723
+ }
724
+ },
725
+ error
726
+ );
727
+ this.logger?.trackException(mastraError);
728
+ throw mastraError;
629
729
  });
630
730
  }
631
731
  async buildIndex({ indexName, metric = "cosine", indexConfig }) {
632
732
  const client = await this.pool.connect();
633
733
  try {
634
734
  await this.setupIndex({ indexName, metric, indexConfig }, client);
735
+ } catch (error) {
736
+ const mastraError = new MastraError(
737
+ {
738
+ id: "MASTRA_STORAGE_PG_VECTOR_BUILD_INDEX_FAILED",
739
+ domain: ErrorDomain.MASTRA_VECTOR,
740
+ category: ErrorCategory.THIRD_PARTY,
741
+ details: {
742
+ indexName
743
+ }
744
+ },
745
+ error
746
+ );
747
+ this.logger?.trackException(mastraError);
748
+ throw mastraError;
635
749
  } finally {
636
750
  client.release();
637
751
  }
@@ -728,6 +842,17 @@ var PgVector = class extends MastraVector {
728
842
  `;
729
843
  const vectorTables = await client.query(vectorTablesQuery, [this.schema || "public"]);
730
844
  return vectorTables.rows.map((row) => row.table_name);
845
+ } catch (e) {
846
+ const mastraError = new MastraError(
847
+ {
848
+ id: "MASTRA_STORAGE_PG_VECTOR_LIST_INDEXES_FAILED",
849
+ domain: ErrorDomain.MASTRA_VECTOR,
850
+ category: ErrorCategory.THIRD_PARTY
851
+ },
852
+ e
853
+ );
854
+ this.logger?.trackException(mastraError);
855
+ throw mastraError;
731
856
  } finally {
732
857
  client.release();
733
858
  }
@@ -807,7 +932,19 @@ var PgVector = class extends MastraVector {
807
932
  };
808
933
  } catch (e) {
809
934
  await client.query("ROLLBACK");
810
- throw new Error(`Failed to describe vector table: ${e.message}`);
935
+ const mastraError = new MastraError(
936
+ {
937
+ id: "MASTRA_STORAGE_PG_VECTOR_DESCRIBE_INDEX_FAILED",
938
+ domain: ErrorDomain.MASTRA_VECTOR,
939
+ category: ErrorCategory.THIRD_PARTY,
940
+ details: {
941
+ indexName
942
+ }
943
+ },
944
+ e
945
+ );
946
+ this.logger?.trackException(mastraError);
947
+ throw mastraError;
811
948
  } finally {
812
949
  client.release();
813
950
  }
@@ -820,7 +957,19 @@ var PgVector = class extends MastraVector {
820
957
  this.createdIndexes.delete(indexName);
821
958
  } catch (error) {
822
959
  await client.query("ROLLBACK");
823
- throw new Error(`Failed to delete vector table: ${error.message}`);
960
+ const mastraError = new MastraError(
961
+ {
962
+ id: "MASTRA_STORAGE_PG_VECTOR_DELETE_INDEX_FAILED",
963
+ domain: ErrorDomain.MASTRA_VECTOR,
964
+ category: ErrorCategory.THIRD_PARTY,
965
+ details: {
966
+ indexName
967
+ }
968
+ },
969
+ error
970
+ );
971
+ this.logger?.trackException(mastraError);
972
+ throw mastraError;
824
973
  } finally {
825
974
  client.release();
826
975
  }
@@ -832,7 +981,19 @@ var PgVector = class extends MastraVector {
832
981
  await client.query(`TRUNCATE ${tableName}`);
833
982
  } catch (e) {
834
983
  await client.query("ROLLBACK");
835
- throw new Error(`Failed to truncate vector table: ${e.message}`);
984
+ const mastraError = new MastraError(
985
+ {
986
+ id: "MASTRA_STORAGE_PG_VECTOR_TRUNCATE_INDEX_FAILED",
987
+ domain: ErrorDomain.MASTRA_VECTOR,
988
+ category: ErrorCategory.THIRD_PARTY,
989
+ details: {
990
+ indexName
991
+ }
992
+ },
993
+ e
994
+ );
995
+ this.logger?.trackException(mastraError);
996
+ throw mastraError;
836
997
  } finally {
837
998
  client.release();
838
999
  }
@@ -851,11 +1012,12 @@ var PgVector = class extends MastraVector {
851
1012
  * @throws Will throw an error if no updates are provided or if the update operation fails.
852
1013
  */
853
1014
  async updateVector({ indexName, id, update }) {
854
- if (!update.vector && !update.metadata) {
855
- throw new Error("No updates provided");
856
- }
857
- const client = await this.pool.connect();
1015
+ let client;
858
1016
  try {
1017
+ if (!update.vector && !update.metadata) {
1018
+ throw new Error("No updates provided");
1019
+ }
1020
+ client = await this.pool.connect();
859
1021
  let updateParts = [];
860
1022
  let values = [id];
861
1023
  let valueIndex = 2;
@@ -879,9 +1041,22 @@ var PgVector = class extends MastraVector {
879
1041
  `;
880
1042
  await client.query(query, values);
881
1043
  } catch (error) {
882
- throw new Error(`Failed to update vector by id: ${id} for index: ${indexName}: ${error.message}`);
1044
+ const mastraError = new MastraError(
1045
+ {
1046
+ id: "MASTRA_STORAGE_PG_VECTOR_UPDATE_VECTOR_FAILED",
1047
+ domain: ErrorDomain.MASTRA_VECTOR,
1048
+ category: ErrorCategory.THIRD_PARTY,
1049
+ details: {
1050
+ indexName,
1051
+ id
1052
+ }
1053
+ },
1054
+ error
1055
+ );
1056
+ this.logger?.trackException(mastraError);
1057
+ throw mastraError;
883
1058
  } finally {
884
- client.release();
1059
+ client?.release();
885
1060
  }
886
1061
  }
887
1062
  /**
@@ -892,8 +1067,9 @@ var PgVector = class extends MastraVector {
892
1067
  * @throws Will throw an error if the deletion operation fails.
893
1068
  */
894
1069
  async deleteVector({ indexName, id }) {
895
- const client = await this.pool.connect();
1070
+ let client;
896
1071
  try {
1072
+ client = await this.pool.connect();
897
1073
  const { tableName } = this.getTableName(indexName);
898
1074
  const query = `
899
1075
  DELETE FROM ${tableName}
@@ -901,9 +1077,22 @@ var PgVector = class extends MastraVector {
901
1077
  `;
902
1078
  await client.query(query, [id]);
903
1079
  } catch (error) {
904
- throw new Error(`Failed to delete vector by id: ${id} for index: ${indexName}: ${error.message}`);
1080
+ const mastraError = new MastraError(
1081
+ {
1082
+ id: "MASTRA_STORAGE_PG_VECTOR_DELETE_VECTOR_FAILED",
1083
+ domain: ErrorDomain.MASTRA_VECTOR,
1084
+ category: ErrorCategory.THIRD_PARTY,
1085
+ details: {
1086
+ indexName,
1087
+ id
1088
+ }
1089
+ },
1090
+ error
1091
+ );
1092
+ this.logger?.trackException(mastraError);
1093
+ throw mastraError;
905
1094
  } finally {
906
- client.release();
1095
+ client?.release();
907
1096
  }
908
1097
  }
909
1098
  };
@@ -914,39 +1103,51 @@ var PostgresStore = class extends MastraStorage {
914
1103
  setupSchemaPromise = null;
915
1104
  schemaSetupComplete = void 0;
916
1105
  constructor(config) {
917
- if ("connectionString" in config) {
918
- if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
919
- throw new Error(
920
- "PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
921
- );
922
- }
923
- } else {
924
- const required = ["host", "database", "user", "password"];
925
- for (const key of required) {
926
- if (!(key in config) || typeof config[key] !== "string" || config[key].trim() === "") {
1106
+ try {
1107
+ if ("connectionString" in config) {
1108
+ if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
927
1109
  throw new Error(
928
- `PostgresStore: ${key} must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`
1110
+ "PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
929
1111
  );
930
1112
  }
1113
+ } else {
1114
+ const required = ["host", "database", "user", "password"];
1115
+ for (const key of required) {
1116
+ if (!(key in config) || typeof config[key] !== "string" || config[key].trim() === "") {
1117
+ throw new Error(
1118
+ `PostgresStore: ${key} must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`
1119
+ );
1120
+ }
1121
+ }
931
1122
  }
1123
+ super({ name: "PostgresStore" });
1124
+ this.pgp = pgPromise();
1125
+ this.schema = config.schemaName;
1126
+ this.db = this.pgp(
1127
+ `connectionString` in config ? { connectionString: config.connectionString } : {
1128
+ host: config.host,
1129
+ port: config.port,
1130
+ database: config.database,
1131
+ user: config.user,
1132
+ password: config.password,
1133
+ ssl: config.ssl
1134
+ }
1135
+ );
1136
+ } catch (e) {
1137
+ throw new MastraError(
1138
+ {
1139
+ id: "MASTRA_STORAGE_PG_STORE_INITIALIZATION_FAILED",
1140
+ domain: ErrorDomain.STORAGE,
1141
+ category: ErrorCategory.USER
1142
+ },
1143
+ e
1144
+ );
932
1145
  }
933
- super({ name: "PostgresStore" });
934
- this.pgp = pgPromise();
935
- this.schema = config.schemaName;
936
- this.db = this.pgp(
937
- `connectionString` in config ? { connectionString: config.connectionString } : {
938
- host: config.host,
939
- port: config.port,
940
- database: config.database,
941
- user: config.user,
942
- password: config.password,
943
- ssl: config.ssl
944
- }
945
- );
946
1146
  }
947
1147
  get supports() {
948
1148
  return {
949
- selectByIncludeResourceScope: true
1149
+ selectByIncludeResourceScope: true,
1150
+ resourceWorkingMemory: true
950
1151
  };
951
1152
  }
952
1153
  getTableName(indexName) {
@@ -1004,9 +1205,19 @@ var PostgresStore = class extends MastraStorage {
1004
1205
  }
1005
1206
  await this.db.query("COMMIT");
1006
1207
  } catch (error) {
1007
- console.error(`Error inserting into ${tableName}:`, error);
1008
1208
  await this.db.query("ROLLBACK");
1009
- throw error;
1209
+ throw new MastraError(
1210
+ {
1211
+ id: "MASTRA_STORAGE_PG_STORE_BATCH_INSERT_FAILED",
1212
+ domain: ErrorDomain.STORAGE,
1213
+ category: ErrorCategory.THIRD_PARTY,
1214
+ details: {
1215
+ tableName,
1216
+ numberOfRecords: records.length
1217
+ }
1218
+ },
1219
+ error
1220
+ );
1010
1221
  }
1011
1222
  }
1012
1223
  /**
@@ -1063,8 +1274,24 @@ var PostgresStore = class extends MastraStorage {
1063
1274
  }
1064
1275
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1065
1276
  const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_TRACES)} ${whereClause}`;
1066
- const countResult = await this.db.one(countQuery, queryParams);
1067
- const total = parseInt(countResult.count, 10);
1277
+ let total = 0;
1278
+ try {
1279
+ const countResult = await this.db.one(countQuery, queryParams);
1280
+ total = parseInt(countResult.count, 10);
1281
+ } catch (error) {
1282
+ throw new MastraError(
1283
+ {
1284
+ id: "MASTRA_STORAGE_PG_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TOTAL_COUNT",
1285
+ domain: ErrorDomain.STORAGE,
1286
+ category: ErrorCategory.THIRD_PARTY,
1287
+ details: {
1288
+ name: args.name ?? "",
1289
+ scope: args.scope ?? ""
1290
+ }
1291
+ },
1292
+ error
1293
+ );
1294
+ }
1068
1295
  if (total === 0) {
1069
1296
  return {
1070
1297
  traces: [],
@@ -1078,30 +1305,45 @@ var PostgresStore = class extends MastraStorage {
1078
1305
  TABLE_TRACES
1079
1306
  )} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1080
1307
  const finalQueryParams = [...queryParams, perPage, currentOffset];
1081
- const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
1082
- const traces = rows.map((row) => ({
1083
- id: row.id,
1084
- parentSpanId: row.parentSpanId,
1085
- traceId: row.traceId,
1086
- name: row.name,
1087
- scope: row.scope,
1088
- kind: row.kind,
1089
- status: row.status,
1090
- events: row.events,
1091
- links: row.links,
1092
- attributes: row.attributes,
1093
- startTime: row.startTime,
1094
- endTime: row.endTime,
1095
- other: row.other,
1096
- createdAt: row.createdAt
1097
- }));
1098
- return {
1099
- traces,
1100
- total,
1101
- page,
1102
- perPage,
1103
- hasMore: currentOffset + traces.length < total
1104
- };
1308
+ try {
1309
+ const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
1310
+ const traces = rows.map((row) => ({
1311
+ id: row.id,
1312
+ parentSpanId: row.parentSpanId,
1313
+ traceId: row.traceId,
1314
+ name: row.name,
1315
+ scope: row.scope,
1316
+ kind: row.kind,
1317
+ status: row.status,
1318
+ events: row.events,
1319
+ links: row.links,
1320
+ attributes: row.attributes,
1321
+ startTime: row.startTime,
1322
+ endTime: row.endTime,
1323
+ other: row.other,
1324
+ createdAt: row.createdAt
1325
+ }));
1326
+ return {
1327
+ traces,
1328
+ total,
1329
+ page,
1330
+ perPage,
1331
+ hasMore: currentOffset + traces.length < total
1332
+ };
1333
+ } catch (error) {
1334
+ throw new MastraError(
1335
+ {
1336
+ id: "MASTRA_STORAGE_PG_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TRACES",
1337
+ domain: ErrorDomain.STORAGE,
1338
+ category: ErrorCategory.THIRD_PARTY,
1339
+ details: {
1340
+ name: args.name ?? "",
1341
+ scope: args.scope ?? ""
1342
+ }
1343
+ },
1344
+ error
1345
+ );
1346
+ }
1105
1347
  }
1106
1348
  async setupSchema() {
1107
1349
  if (!this.schema || this.schemaSetupComplete) {
@@ -1176,8 +1418,17 @@ var PostgresStore = class extends MastraStorage {
1176
1418
  `;
1177
1419
  await this.db.none(sql);
1178
1420
  } catch (error) {
1179
- console.error(`Error creating table ${tableName}:`, error);
1180
- throw error;
1421
+ throw new MastraError(
1422
+ {
1423
+ id: "MASTRA_STORAGE_PG_STORE_CREATE_TABLE_FAILED",
1424
+ domain: ErrorDomain.STORAGE,
1425
+ category: ErrorCategory.THIRD_PARTY,
1426
+ details: {
1427
+ tableName
1428
+ }
1429
+ },
1430
+ error
1431
+ );
1181
1432
  }
1182
1433
  }
1183
1434
  getDefaultValue(type) {
@@ -1216,18 +1467,34 @@ var PostgresStore = class extends MastraStorage {
1216
1467
  }
1217
1468
  }
1218
1469
  } catch (error) {
1219
- this.logger?.error?.(
1220
- `Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
1470
+ throw new MastraError(
1471
+ {
1472
+ id: "MASTRA_STORAGE_PG_STORE_ALTER_TABLE_FAILED",
1473
+ domain: ErrorDomain.STORAGE,
1474
+ category: ErrorCategory.THIRD_PARTY,
1475
+ details: {
1476
+ tableName
1477
+ }
1478
+ },
1479
+ error
1221
1480
  );
1222
- throw new Error(`Failed to alter table ${tableName}: ${error}`);
1223
1481
  }
1224
1482
  }
1225
1483
  async clearTable({ tableName }) {
1226
1484
  try {
1227
1485
  await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
1228
1486
  } catch (error) {
1229
- console.error(`Error clearing table ${tableName}:`, error);
1230
- throw error;
1487
+ throw new MastraError(
1488
+ {
1489
+ id: "MASTRA_STORAGE_PG_STORE_CLEAR_TABLE_FAILED",
1490
+ domain: ErrorDomain.STORAGE,
1491
+ category: ErrorCategory.THIRD_PARTY,
1492
+ details: {
1493
+ tableName
1494
+ }
1495
+ },
1496
+ error
1497
+ );
1231
1498
  }
1232
1499
  }
1233
1500
  async insert({ tableName, record }) {
@@ -1240,8 +1507,17 @@ var PostgresStore = class extends MastraStorage {
1240
1507
  values
1241
1508
  );
1242
1509
  } catch (error) {
1243
- console.error(`Error inserting into ${tableName}:`, error);
1244
- throw error;
1510
+ throw new MastraError(
1511
+ {
1512
+ id: "MASTRA_STORAGE_PG_STORE_INSERT_FAILED",
1513
+ domain: ErrorDomain.STORAGE,
1514
+ category: ErrorCategory.THIRD_PARTY,
1515
+ details: {
1516
+ tableName
1517
+ }
1518
+ },
1519
+ error
1520
+ );
1245
1521
  }
1246
1522
  }
1247
1523
  async load({ tableName, keys }) {
@@ -1265,8 +1541,17 @@ var PostgresStore = class extends MastraStorage {
1265
1541
  }
1266
1542
  return result;
1267
1543
  } catch (error) {
1268
- console.error(`Error loading from ${tableName}:`, error);
1269
- throw error;
1544
+ throw new MastraError(
1545
+ {
1546
+ id: "MASTRA_STORAGE_PG_STORE_LOAD_FAILED",
1547
+ domain: ErrorDomain.STORAGE,
1548
+ category: ErrorCategory.THIRD_PARTY,
1549
+ details: {
1550
+ tableName
1551
+ }
1552
+ },
1553
+ error
1554
+ );
1270
1555
  }
1271
1556
  }
1272
1557
  async getThreadById({ threadId }) {
@@ -1293,8 +1578,17 @@ var PostgresStore = class extends MastraStorage {
1293
1578
  updatedAt: thread.updatedAt
1294
1579
  };
1295
1580
  } catch (error) {
1296
- console.error(`Error getting thread ${threadId}:`, error);
1297
- throw error;
1581
+ throw new MastraError(
1582
+ {
1583
+ id: "MASTRA_STORAGE_PG_STORE_GET_THREAD_BY_ID_FAILED",
1584
+ domain: ErrorDomain.STORAGE,
1585
+ category: ErrorCategory.THIRD_PARTY,
1586
+ details: {
1587
+ threadId
1588
+ }
1589
+ },
1590
+ error
1591
+ );
1298
1592
  }
1299
1593
  }
1300
1594
  /**
@@ -1354,7 +1648,20 @@ var PostgresStore = class extends MastraStorage {
1354
1648
  hasMore: currentOffset + threads.length < total
1355
1649
  };
1356
1650
  } catch (error) {
1357
- this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
1651
+ const mastraError = new MastraError(
1652
+ {
1653
+ id: "MASTRA_STORAGE_PG_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1654
+ domain: ErrorDomain.STORAGE,
1655
+ category: ErrorCategory.THIRD_PARTY,
1656
+ details: {
1657
+ resourceId,
1658
+ page
1659
+ }
1660
+ },
1661
+ error
1662
+ );
1663
+ this.logger?.error?.(mastraError.toString());
1664
+ this.logger?.trackException(mastraError);
1358
1665
  return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
1359
1666
  }
1360
1667
  }
@@ -1386,8 +1693,17 @@ var PostgresStore = class extends MastraStorage {
1386
1693
  );
1387
1694
  return thread;
1388
1695
  } catch (error) {
1389
- console.error("Error saving thread:", error);
1390
- throw error;
1696
+ throw new MastraError(
1697
+ {
1698
+ id: "MASTRA_STORAGE_PG_STORE_SAVE_THREAD_FAILED",
1699
+ domain: ErrorDomain.STORAGE,
1700
+ category: ErrorCategory.THIRD_PARTY,
1701
+ details: {
1702
+ threadId: thread.id
1703
+ }
1704
+ },
1705
+ error
1706
+ );
1391
1707
  }
1392
1708
  }
1393
1709
  async updateThread({
@@ -1395,20 +1711,29 @@ var PostgresStore = class extends MastraStorage {
1395
1711
  title,
1396
1712
  metadata
1397
1713
  }) {
1714
+ const existingThread = await this.getThreadById({ threadId: id });
1715
+ if (!existingThread) {
1716
+ throw new MastraError({
1717
+ id: "MASTRA_STORAGE_PG_STORE_UPDATE_THREAD_FAILED",
1718
+ domain: ErrorDomain.STORAGE,
1719
+ category: ErrorCategory.USER,
1720
+ text: `Thread ${id} not found`,
1721
+ details: {
1722
+ threadId: id,
1723
+ title
1724
+ }
1725
+ });
1726
+ }
1727
+ const mergedMetadata = {
1728
+ ...existingThread.metadata,
1729
+ ...metadata
1730
+ };
1398
1731
  try {
1399
- const existingThread = await this.getThreadById({ threadId: id });
1400
- if (!existingThread) {
1401
- throw new Error(`Thread ${id} not found`);
1402
- }
1403
- const mergedMetadata = {
1404
- ...existingThread.metadata,
1405
- ...metadata
1406
- };
1407
1732
  const thread = await this.db.one(
1408
1733
  `UPDATE ${this.getTableName(TABLE_THREADS)}
1409
1734
  SET title = $1,
1410
- metadata = $2,
1411
- "updatedAt" = $3
1735
+ metadata = $2,
1736
+ "updatedAt" = $3
1412
1737
  WHERE id = $4
1413
1738
  RETURNING *`,
1414
1739
  [title, mergedMetadata, (/* @__PURE__ */ new Date()).toISOString(), id]
@@ -1420,8 +1745,18 @@ var PostgresStore = class extends MastraStorage {
1420
1745
  updatedAt: thread.updatedAt
1421
1746
  };
1422
1747
  } catch (error) {
1423
- console.error("Error updating thread:", error);
1424
- throw error;
1748
+ throw new MastraError(
1749
+ {
1750
+ id: "MASTRA_STORAGE_PG_STORE_UPDATE_THREAD_FAILED",
1751
+ domain: ErrorDomain.STORAGE,
1752
+ category: ErrorCategory.THIRD_PARTY,
1753
+ details: {
1754
+ threadId: id,
1755
+ title
1756
+ }
1757
+ },
1758
+ error
1759
+ );
1425
1760
  }
1426
1761
  }
1427
1762
  async deleteThread({ threadId }) {
@@ -1431,26 +1766,34 @@ var PostgresStore = class extends MastraStorage {
1431
1766
  await t.none(`DELETE FROM ${this.getTableName(TABLE_THREADS)} WHERE id = $1`, [threadId]);
1432
1767
  });
1433
1768
  } catch (error) {
1434
- console.error("Error deleting thread:", error);
1435
- throw error;
1769
+ throw new MastraError(
1770
+ {
1771
+ id: "MASTRA_STORAGE_PG_STORE_DELETE_THREAD_FAILED",
1772
+ domain: ErrorDomain.STORAGE,
1773
+ category: ErrorCategory.THIRD_PARTY,
1774
+ details: {
1775
+ threadId
1776
+ }
1777
+ },
1778
+ error
1779
+ );
1436
1780
  }
1437
1781
  }
1438
- async getMessages(args) {
1439
- const { threadId, format, selectBy } = args;
1440
- const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
1441
- const orderByStatement = `ORDER BY "createdAt" DESC`;
1442
- try {
1443
- let rows = [];
1444
- const include = selectBy?.include || [];
1445
- if (include.length) {
1446
- const unionQueries = [];
1447
- const params = [];
1448
- let paramIdx = 1;
1449
- for (const inc of include) {
1450
- const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1451
- const searchId = inc.threadId || threadId;
1452
- unionQueries.push(
1453
- `
1782
+ async _getIncludedMessages({
1783
+ threadId,
1784
+ selectBy,
1785
+ orderByStatement
1786
+ }) {
1787
+ const include = selectBy?.include;
1788
+ if (!include) return null;
1789
+ const unionQueries = [];
1790
+ const params = [];
1791
+ let paramIdx = 1;
1792
+ for (const inc of include) {
1793
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1794
+ const searchId = inc.threadId || threadId;
1795
+ unionQueries.push(
1796
+ `
1454
1797
  SELECT * FROM (
1455
1798
  WITH ordered_messages AS (
1456
1799
  SELECT
@@ -1482,34 +1825,45 @@ var PostgresStore = class extends MastraStorage {
1482
1825
  )
1483
1826
  ) AS query_${paramIdx}
1484
1827
  `
1485
- // Keep ASC for final sorting after fetching context
1486
- );
1487
- params.push(searchId, id, withPreviousMessages, withNextMessages);
1488
- paramIdx += 4;
1489
- }
1490
- const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
1491
- const includedRows = await this.db.manyOrNone(finalQuery, params);
1492
- const seen = /* @__PURE__ */ new Set();
1493
- const dedupedRows = includedRows.filter((row) => {
1494
- if (seen.has(row.id)) return false;
1495
- seen.add(row.id);
1496
- return true;
1497
- });
1498
- rows = dedupedRows;
1499
- } else {
1500
- const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
1501
- if (limit === 0 && selectBy?.last !== false) ; else {
1502
- let query = `${selectStatement} FROM ${this.getTableName(
1503
- TABLE_MESSAGES
1504
- )} WHERE thread_id = $1 ${orderByStatement}`;
1505
- const queryParams = [threadId];
1506
- if (limit !== void 0 && selectBy?.last !== false) {
1507
- query += ` LIMIT $2`;
1508
- queryParams.push(limit);
1509
- }
1510
- rows = await this.db.manyOrNone(query, queryParams);
1828
+ // Keep ASC for final sorting after fetching context
1829
+ );
1830
+ params.push(searchId, id, withPreviousMessages, withNextMessages);
1831
+ paramIdx += 4;
1832
+ }
1833
+ const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
1834
+ const includedRows = await this.db.manyOrNone(finalQuery, params);
1835
+ const seen = /* @__PURE__ */ new Set();
1836
+ const dedupedRows = includedRows.filter((row) => {
1837
+ if (seen.has(row.id)) return false;
1838
+ seen.add(row.id);
1839
+ return true;
1840
+ });
1841
+ return dedupedRows;
1842
+ }
1843
+ async getMessages(args) {
1844
+ const { threadId, format, selectBy } = args;
1845
+ const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
1846
+ const orderByStatement = `ORDER BY "createdAt" DESC`;
1847
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
1848
+ try {
1849
+ let rows = [];
1850
+ const include = selectBy?.include || [];
1851
+ if (include?.length) {
1852
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
1853
+ if (includeMessages) {
1854
+ rows.push(...includeMessages);
1511
1855
  }
1512
1856
  }
1857
+ const excludeIds = rows.map((m) => m.id);
1858
+ const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + 2}`).join(", ");
1859
+ let query = `${selectStatement} FROM ${this.getTableName(TABLE_MESSAGES)} WHERE thread_id = $1
1860
+ ${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ""}
1861
+ ${orderByStatement}
1862
+ LIMIT $${excludeIds.length + 2}
1863
+ `;
1864
+ const queryParams = [threadId, ...excludeIds, limit];
1865
+ const remainingRows = await this.db.manyOrNone(query, queryParams);
1866
+ rows.push(...remainingRows);
1513
1867
  const fetchedMessages = (rows || []).map((message) => {
1514
1868
  if (typeof message.content === "string") {
1515
1869
  try {
@@ -1527,7 +1881,19 @@ var PostgresStore = class extends MastraStorage {
1527
1881
  (m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
1528
1882
  ) : sortedMessages;
1529
1883
  } catch (error) {
1530
- this.logger.error("Error getting messages:", error);
1884
+ const mastraError = new MastraError(
1885
+ {
1886
+ id: "MASTRA_STORAGE_PG_STORE_GET_MESSAGES_FAILED",
1887
+ domain: ErrorDomain.STORAGE,
1888
+ category: ErrorCategory.THIRD_PARTY,
1889
+ details: {
1890
+ threadId
1891
+ }
1892
+ },
1893
+ error
1894
+ );
1895
+ this.logger?.error?.(mastraError.toString());
1896
+ this.logger?.trackException(mastraError);
1531
1897
  return [];
1532
1898
  }
1533
1899
  }
@@ -1538,8 +1904,15 @@ var PostgresStore = class extends MastraStorage {
1538
1904
  const toDate = dateRange?.end;
1539
1905
  const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
1540
1906
  const orderByStatement = `ORDER BY "createdAt" DESC`;
1907
+ const messages = [];
1908
+ if (selectBy?.include?.length) {
1909
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
1910
+ if (includeMessages) {
1911
+ messages.push(...includeMessages);
1912
+ }
1913
+ }
1541
1914
  try {
1542
- const perPage = perPageInput !== void 0 ? perPageInput : 40;
1915
+ const perPage = perPageInput !== void 0 ? perPageInput : this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
1543
1916
  const currentOffset = page * perPage;
1544
1917
  const conditions = [`thread_id = $1`];
1545
1918
  const queryParams = [threadId];
@@ -1556,7 +1929,7 @@ var PostgresStore = class extends MastraStorage {
1556
1929
  const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_MESSAGES)} ${whereClause}`;
1557
1930
  const countResult = await this.db.one(countQuery, queryParams);
1558
1931
  const total = parseInt(countResult.count, 10);
1559
- if (total === 0) {
1932
+ if (total === 0 && messages.length === 0) {
1560
1933
  return {
1561
1934
  messages: [],
1562
1935
  total: 0,
@@ -1565,11 +1938,15 @@ var PostgresStore = class extends MastraStorage {
1565
1938
  hasMore: false
1566
1939
  };
1567
1940
  }
1941
+ const excludeIds = messages.map((m) => m.id);
1942
+ const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + paramIndex}`).join(", ");
1943
+ paramIndex += excludeIds.length;
1568
1944
  const dataQuery = `${selectStatement} FROM ${this.getTableName(
1569
1945
  TABLE_MESSAGES
1570
- )} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1571
- const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1572
- const list = new MessageList().add(rows || [], "memory");
1946
+ )} ${whereClause} ${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ""}${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1947
+ const rows = await this.db.manyOrNone(dataQuery, [...queryParams, ...excludeIds, perPage, currentOffset]);
1948
+ messages.push(...rows || []);
1949
+ const list = new MessageList().add(messages, "memory");
1573
1950
  const messagesToReturn = format === `v2` ? list.get.all.v2() : list.get.all.v1();
1574
1951
  return {
1575
1952
  messages: messagesToReturn,
@@ -1579,7 +1956,20 @@ var PostgresStore = class extends MastraStorage {
1579
1956
  hasMore: currentOffset + rows.length < total
1580
1957
  };
1581
1958
  } catch (error) {
1582
- this.logger.error("Error getting messages:", error);
1959
+ const mastraError = new MastraError(
1960
+ {
1961
+ id: "MASTRA_STORAGE_PG_STORE_GET_MESSAGES_PAGINATED_FAILED",
1962
+ domain: ErrorDomain.STORAGE,
1963
+ category: ErrorCategory.THIRD_PARTY,
1964
+ details: {
1965
+ threadId,
1966
+ page
1967
+ }
1968
+ },
1969
+ error
1970
+ );
1971
+ this.logger?.error?.(mastraError.toString());
1972
+ this.logger?.trackException(mastraError);
1583
1973
  return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
1584
1974
  }
1585
1975
  }
@@ -1588,15 +1978,28 @@ var PostgresStore = class extends MastraStorage {
1588
1978
  format
1589
1979
  }) {
1590
1980
  if (messages.length === 0) return messages;
1981
+ const threadId = messages[0]?.threadId;
1982
+ if (!threadId) {
1983
+ throw new MastraError({
1984
+ id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
1985
+ domain: ErrorDomain.STORAGE,
1986
+ category: ErrorCategory.THIRD_PARTY,
1987
+ text: `Thread ID is required`
1988
+ });
1989
+ }
1990
+ const thread = await this.getThreadById({ threadId });
1991
+ if (!thread) {
1992
+ throw new MastraError({
1993
+ id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
1994
+ domain: ErrorDomain.STORAGE,
1995
+ category: ErrorCategory.THIRD_PARTY,
1996
+ text: `Thread ${threadId} not found`,
1997
+ details: {
1998
+ threadId
1999
+ }
2000
+ });
2001
+ }
1591
2002
  try {
1592
- const threadId = messages[0]?.threadId;
1593
- if (!threadId) {
1594
- throw new Error("Thread ID is required");
1595
- }
1596
- const thread = await this.getThreadById({ threadId });
1597
- if (!thread) {
1598
- throw new Error(`Thread ${threadId} not found`);
1599
- }
1600
2003
  await this.db.tx(async (t) => {
1601
2004
  const messageInserts = messages.map((message) => {
1602
2005
  if (!message.threadId) {
@@ -1611,7 +2014,13 @@ var PostgresStore = class extends MastraStorage {
1611
2014
  }
1612
2015
  return t.none(
1613
2016
  `INSERT INTO ${this.getTableName(TABLE_MESSAGES)} (id, thread_id, content, "createdAt", role, type, "resourceId")
1614
- VALUES ($1, $2, $3, $4, $5, $6, $7)`,
2017
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
2018
+ ON CONFLICT (id) DO UPDATE SET
2019
+ thread_id = EXCLUDED.thread_id,
2020
+ content = EXCLUDED.content,
2021
+ role = EXCLUDED.role,
2022
+ type = EXCLUDED.type,
2023
+ "resourceId" = EXCLUDED."resourceId"`,
1615
2024
  [
1616
2025
  message.id,
1617
2026
  message.threadId,
@@ -1635,8 +2044,17 @@ var PostgresStore = class extends MastraStorage {
1635
2044
  if (format === `v2`) return list.get.all.v2();
1636
2045
  return list.get.all.v1();
1637
2046
  } catch (error) {
1638
- console.error("Error saving messages:", error);
1639
- throw error;
2047
+ throw new MastraError(
2048
+ {
2049
+ id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
2050
+ domain: ErrorDomain.STORAGE,
2051
+ category: ErrorCategory.THIRD_PARTY,
2052
+ details: {
2053
+ threadId
2054
+ }
2055
+ },
2056
+ error
2057
+ );
1640
2058
  }
1641
2059
  }
1642
2060
  async persistWorkflowSnapshot({
@@ -1660,8 +2078,18 @@ var PostgresStore = class extends MastraStorage {
1660
2078
  [workflowName, runId, JSON.stringify(snapshot), now, now]
1661
2079
  );
1662
2080
  } catch (error) {
1663
- console.error("Error persisting workflow snapshot:", error);
1664
- throw error;
2081
+ throw new MastraError(
2082
+ {
2083
+ id: "MASTRA_STORAGE_PG_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
2084
+ domain: ErrorDomain.STORAGE,
2085
+ category: ErrorCategory.THIRD_PARTY,
2086
+ details: {
2087
+ workflowName,
2088
+ runId
2089
+ }
2090
+ },
2091
+ error
2092
+ );
1665
2093
  }
1666
2094
  }
1667
2095
  async loadWorkflowSnapshot({
@@ -1681,8 +2109,18 @@ var PostgresStore = class extends MastraStorage {
1681
2109
  }
1682
2110
  return result.snapshot;
1683
2111
  } catch (error) {
1684
- console.error("Error loading workflow snapshot:", error);
1685
- throw error;
2112
+ throw new MastraError(
2113
+ {
2114
+ id: "MASTRA_STORAGE_PG_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
2115
+ domain: ErrorDomain.STORAGE,
2116
+ category: ErrorCategory.THIRD_PARTY,
2117
+ details: {
2118
+ workflowName,
2119
+ runId
2120
+ }
2121
+ },
2122
+ error
2123
+ );
1686
2124
  }
1687
2125
  }
1688
2126
  async hasColumn(table, column) {
@@ -1770,8 +2208,17 @@ var PostgresStore = class extends MastraStorage {
1770
2208
  });
1771
2209
  return { runs, total: total || runs.length };
1772
2210
  } catch (error) {
1773
- console.error("Error getting workflow runs:", error);
1774
- throw error;
2211
+ throw new MastraError(
2212
+ {
2213
+ id: "MASTRA_STORAGE_PG_STORE_GET_WORKFLOW_RUNS_FAILED",
2214
+ domain: ErrorDomain.STORAGE,
2215
+ category: ErrorCategory.THIRD_PARTY,
2216
+ details: {
2217
+ workflowName: workflowName || "all"
2218
+ }
2219
+ },
2220
+ error
2221
+ );
1775
2222
  }
1776
2223
  }
1777
2224
  async getWorkflowRunById({
@@ -1804,8 +2251,18 @@ var PostgresStore = class extends MastraStorage {
1804
2251
  }
1805
2252
  return this.parseWorkflowRun(result);
1806
2253
  } catch (error) {
1807
- console.error("Error getting workflow run by ID:", error);
1808
- throw error;
2254
+ throw new MastraError(
2255
+ {
2256
+ id: "MASTRA_STORAGE_PG_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2257
+ domain: ErrorDomain.STORAGE,
2258
+ category: ErrorCategory.THIRD_PARTY,
2259
+ details: {
2260
+ runId,
2261
+ workflowName: workflowName || ""
2262
+ }
2263
+ },
2264
+ error
2265
+ );
1809
2266
  }
1810
2267
  }
1811
2268
  async close() {
@@ -1837,29 +2294,49 @@ var PostgresStore = class extends MastraStorage {
1837
2294
  }
1838
2295
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1839
2296
  const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_EVALS)} ${whereClause}`;
1840
- const countResult = await this.db.one(countQuery, queryParams);
1841
- const total = parseInt(countResult.count, 10);
1842
- const currentOffset = page * perPage;
1843
- if (total === 0) {
2297
+ try {
2298
+ const countResult = await this.db.one(countQuery, queryParams);
2299
+ const total = parseInt(countResult.count, 10);
2300
+ const currentOffset = page * perPage;
2301
+ if (total === 0) {
2302
+ return {
2303
+ evals: [],
2304
+ total: 0,
2305
+ page,
2306
+ perPage,
2307
+ hasMore: false
2308
+ };
2309
+ }
2310
+ const dataQuery = `SELECT * FROM ${this.getTableName(
2311
+ TABLE_EVALS
2312
+ )} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
2313
+ const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1844
2314
  return {
1845
- evals: [],
1846
- total: 0,
2315
+ evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
2316
+ total,
1847
2317
  page,
1848
2318
  perPage,
1849
- hasMore: false
2319
+ hasMore: currentOffset + (rows?.length ?? 0) < total
1850
2320
  };
2321
+ } catch (error) {
2322
+ const mastraError = new MastraError(
2323
+ {
2324
+ id: "MASTRA_STORAGE_PG_STORE_GET_EVALS_FAILED",
2325
+ domain: ErrorDomain.STORAGE,
2326
+ category: ErrorCategory.THIRD_PARTY,
2327
+ details: {
2328
+ agentName: agentName || "all",
2329
+ type: type || "all",
2330
+ page,
2331
+ perPage
2332
+ }
2333
+ },
2334
+ error
2335
+ );
2336
+ this.logger?.error?.(mastraError.toString());
2337
+ this.logger?.trackException(mastraError);
2338
+ throw mastraError;
1851
2339
  }
1852
- const dataQuery = `SELECT * FROM ${this.getTableName(
1853
- TABLE_EVALS
1854
- )} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1855
- const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1856
- return {
1857
- evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
1858
- total,
1859
- page,
1860
- perPage,
1861
- hasMore: currentOffset + (rows?.length ?? 0) < total
1862
- };
1863
2340
  }
1864
2341
  async updateMessages({
1865
2342
  messages
@@ -1956,6 +2433,82 @@ var PostgresStore = class extends MastraStorage {
1956
2433
  return message;
1957
2434
  });
1958
2435
  }
2436
+ async getResourceById({ resourceId }) {
2437
+ const tableName = this.getTableName(TABLE_RESOURCES);
2438
+ const result = await this.db.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [
2439
+ resourceId
2440
+ ]);
2441
+ if (!result) {
2442
+ return null;
2443
+ }
2444
+ return {
2445
+ ...result,
2446
+ // Ensure workingMemory is always returned as a string, regardless of automatic parsing
2447
+ workingMemory: typeof result.workingMemory === "object" ? JSON.stringify(result.workingMemory) : result.workingMemory,
2448
+ metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
2449
+ };
2450
+ }
2451
+ async saveResource({ resource }) {
2452
+ const tableName = this.getTableName(TABLE_RESOURCES);
2453
+ await this.db.none(
2454
+ `INSERT INTO ${tableName} (id, "workingMemory", metadata, "createdAt", "updatedAt")
2455
+ VALUES ($1, $2, $3, $4, $5)`,
2456
+ [
2457
+ resource.id,
2458
+ resource.workingMemory,
2459
+ JSON.stringify(resource.metadata),
2460
+ resource.createdAt.toISOString(),
2461
+ resource.updatedAt.toISOString()
2462
+ ]
2463
+ );
2464
+ return resource;
2465
+ }
2466
+ async updateResource({
2467
+ resourceId,
2468
+ workingMemory,
2469
+ metadata
2470
+ }) {
2471
+ const existingResource = await this.getResourceById({ resourceId });
2472
+ if (!existingResource) {
2473
+ const newResource = {
2474
+ id: resourceId,
2475
+ workingMemory,
2476
+ metadata: metadata || {},
2477
+ createdAt: /* @__PURE__ */ new Date(),
2478
+ updatedAt: /* @__PURE__ */ new Date()
2479
+ };
2480
+ return this.saveResource({ resource: newResource });
2481
+ }
2482
+ const updatedResource = {
2483
+ ...existingResource,
2484
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
2485
+ metadata: {
2486
+ ...existingResource.metadata,
2487
+ ...metadata
2488
+ },
2489
+ updatedAt: /* @__PURE__ */ new Date()
2490
+ };
2491
+ const tableName = this.getTableName(TABLE_RESOURCES);
2492
+ const updates = [];
2493
+ const values = [];
2494
+ let paramIndex = 1;
2495
+ if (workingMemory !== void 0) {
2496
+ updates.push(`"workingMemory" = $${paramIndex}`);
2497
+ values.push(workingMemory);
2498
+ paramIndex++;
2499
+ }
2500
+ if (metadata) {
2501
+ updates.push(`metadata = $${paramIndex}`);
2502
+ values.push(JSON.stringify(updatedResource.metadata));
2503
+ paramIndex++;
2504
+ }
2505
+ updates.push(`"updatedAt" = $${paramIndex}`);
2506
+ values.push(updatedResource.updatedAt.toISOString());
2507
+ paramIndex++;
2508
+ values.push(resourceId);
2509
+ await this.db.none(`UPDATE ${tableName} SET ${updates.join(", ")} WHERE id = $${paramIndex}`, values);
2510
+ return updatedResource;
2511
+ }
1959
2512
  };
1960
2513
 
1961
2514
  // src/vector/prompt.ts