@mastra/pg 0.11.0 → 0.11.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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +24 -0
- package/dist/_tsup-dts-rollup.d.cts +11 -0
- package/dist/_tsup-dts-rollup.d.ts +11 -0
- package/dist/index.cjs +809 -247
- package/dist/index.js +785 -223
- package/package.json +3 -3
- package/src/storage/index.test.ts +242 -12
- package/src/storage/index.ts +606 -191
- package/src/vector/index.ts +279 -86
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var error = require('@mastra/core/error');
|
|
3
4
|
var utils = require('@mastra/core/utils');
|
|
4
5
|
var vector = require('@mastra/core/vector');
|
|
5
6
|
var asyncMutex = require('async-mutex');
|
|
@@ -376,43 +377,57 @@ var PgVector = class extends vector.MastraVector {
|
|
|
376
377
|
schemaName,
|
|
377
378
|
pgPoolOptions
|
|
378
379
|
}) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
super();
|
|
385
|
-
this.schema = schemaName;
|
|
386
|
-
const basePool = new pg__default.default.Pool({
|
|
387
|
-
connectionString,
|
|
388
|
-
max: 20,
|
|
389
|
-
// Maximum number of clients in the pool
|
|
390
|
-
idleTimeoutMillis: 3e4,
|
|
391
|
-
// Close idle connections after 30 seconds
|
|
392
|
-
connectionTimeoutMillis: 2e3,
|
|
393
|
-
// Fail fast if can't connect
|
|
394
|
-
...pgPoolOptions
|
|
395
|
-
});
|
|
396
|
-
const telemetry = this.__getTelemetry();
|
|
397
|
-
this.pool = telemetry?.traceClass(basePool, {
|
|
398
|
-
spanNamePrefix: "pg-vector",
|
|
399
|
-
attributes: {
|
|
400
|
-
"vector.type": "postgres"
|
|
380
|
+
try {
|
|
381
|
+
if (!connectionString || connectionString.trim() === "") {
|
|
382
|
+
throw new Error(
|
|
383
|
+
"PgVector: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
|
|
384
|
+
);
|
|
401
385
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
this.createdIndexes.set(indexName, key);
|
|
386
|
+
super();
|
|
387
|
+
this.schema = schemaName;
|
|
388
|
+
const basePool = new pg__default.default.Pool({
|
|
389
|
+
connectionString,
|
|
390
|
+
max: 20,
|
|
391
|
+
// Maximum number of clients in the pool
|
|
392
|
+
idleTimeoutMillis: 3e4,
|
|
393
|
+
// Close idle connections after 30 seconds
|
|
394
|
+
connectionTimeoutMillis: 2e3,
|
|
395
|
+
// Fail fast if can't connect
|
|
396
|
+
...pgPoolOptions
|
|
414
397
|
});
|
|
415
|
-
|
|
398
|
+
const telemetry = this.__getTelemetry();
|
|
399
|
+
this.pool = telemetry?.traceClass(basePool, {
|
|
400
|
+
spanNamePrefix: "pg-vector",
|
|
401
|
+
attributes: {
|
|
402
|
+
"vector.type": "postgres"
|
|
403
|
+
}
|
|
404
|
+
}) ?? basePool;
|
|
405
|
+
void (async () => {
|
|
406
|
+
const existingIndexes = await this.listIndexes();
|
|
407
|
+
void existingIndexes.map(async (indexName) => {
|
|
408
|
+
const info = await this.getIndexInfo({ indexName });
|
|
409
|
+
const key = await this.getIndexCacheKey({
|
|
410
|
+
indexName,
|
|
411
|
+
metric: info.metric,
|
|
412
|
+
dimension: info.dimension,
|
|
413
|
+
type: info.type
|
|
414
|
+
});
|
|
415
|
+
this.createdIndexes.set(indexName, key);
|
|
416
|
+
});
|
|
417
|
+
})();
|
|
418
|
+
} catch (error$1) {
|
|
419
|
+
throw new error.MastraError(
|
|
420
|
+
{
|
|
421
|
+
id: "MASTRA_STORAGE_PG_VECTOR_INITIALIZATION_FAILED",
|
|
422
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
423
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
424
|
+
details: {
|
|
425
|
+
schemaName: schemaName ?? ""
|
|
426
|
+
}
|
|
427
|
+
},
|
|
428
|
+
error$1
|
|
429
|
+
);
|
|
430
|
+
}
|
|
416
431
|
}
|
|
417
432
|
getMutexByName(indexName) {
|
|
418
433
|
if (!this.mutexesByName.has(indexName)) this.mutexesByName.set(indexName, new asyncMutex.Mutex());
|
|
@@ -451,11 +466,27 @@ var PgVector = class extends vector.MastraVector {
|
|
|
451
466
|
ef,
|
|
452
467
|
probes
|
|
453
468
|
}) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
469
|
+
try {
|
|
470
|
+
if (!Number.isInteger(topK) || topK <= 0) {
|
|
471
|
+
throw new Error("topK must be a positive integer");
|
|
472
|
+
}
|
|
473
|
+
if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
|
|
474
|
+
throw new Error("queryVector must be an array of finite numbers");
|
|
475
|
+
}
|
|
476
|
+
} catch (error$1) {
|
|
477
|
+
const mastraError = new error.MastraError(
|
|
478
|
+
{
|
|
479
|
+
id: "MASTRA_STORAGE_PG_VECTOR_QUERY_INVALID_INPUT",
|
|
480
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
481
|
+
category: error.ErrorCategory.USER,
|
|
482
|
+
details: {
|
|
483
|
+
indexName
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
error$1
|
|
487
|
+
);
|
|
488
|
+
this.logger?.trackException(mastraError);
|
|
489
|
+
throw mastraError;
|
|
459
490
|
}
|
|
460
491
|
const client = await this.pool.connect();
|
|
461
492
|
try {
|
|
@@ -494,6 +525,20 @@ var PgVector = class extends vector.MastraVector {
|
|
|
494
525
|
metadata,
|
|
495
526
|
...includeVector && embedding && { vector: JSON.parse(embedding) }
|
|
496
527
|
}));
|
|
528
|
+
} catch (error$1) {
|
|
529
|
+
const mastraError = new error.MastraError(
|
|
530
|
+
{
|
|
531
|
+
id: "MASTRA_STORAGE_PG_VECTOR_QUERY_FAILED",
|
|
532
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
533
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
534
|
+
details: {
|
|
535
|
+
indexName
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
error$1
|
|
539
|
+
);
|
|
540
|
+
this.logger?.trackException(mastraError);
|
|
541
|
+
throw mastraError;
|
|
497
542
|
} finally {
|
|
498
543
|
client.release();
|
|
499
544
|
}
|
|
@@ -518,18 +563,43 @@ var PgVector = class extends vector.MastraVector {
|
|
|
518
563
|
}
|
|
519
564
|
await client.query("COMMIT");
|
|
520
565
|
return vectorIds;
|
|
521
|
-
} catch (error) {
|
|
566
|
+
} catch (error$1) {
|
|
522
567
|
await client.query("ROLLBACK");
|
|
523
|
-
if (error instanceof Error && error.message?.includes("expected") && error.message?.includes("dimensions")) {
|
|
524
|
-
const match = error.message.match(/expected (\d+) dimensions, not (\d+)/);
|
|
568
|
+
if (error$1 instanceof Error && error$1.message?.includes("expected") && error$1.message?.includes("dimensions")) {
|
|
569
|
+
const match = error$1.message.match(/expected (\d+) dimensions, not (\d+)/);
|
|
525
570
|
if (match) {
|
|
526
571
|
const [, expected, actual] = match;
|
|
527
|
-
|
|
528
|
-
|
|
572
|
+
const mastraError2 = new error.MastraError(
|
|
573
|
+
{
|
|
574
|
+
id: "MASTRA_STORAGE_PG_VECTOR_UPSERT_INVALID_INPUT",
|
|
575
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
576
|
+
category: error.ErrorCategory.USER,
|
|
577
|
+
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.`,
|
|
578
|
+
details: {
|
|
579
|
+
indexName,
|
|
580
|
+
expected: expected ?? "",
|
|
581
|
+
actual: actual ?? ""
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
error$1
|
|
529
585
|
);
|
|
586
|
+
this.logger?.trackException(mastraError2);
|
|
587
|
+
throw mastraError2;
|
|
530
588
|
}
|
|
531
589
|
}
|
|
532
|
-
|
|
590
|
+
const mastraError = new error.MastraError(
|
|
591
|
+
{
|
|
592
|
+
id: "MASTRA_STORAGE_PG_VECTOR_UPSERT_FAILED",
|
|
593
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
594
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
595
|
+
details: {
|
|
596
|
+
indexName
|
|
597
|
+
}
|
|
598
|
+
},
|
|
599
|
+
error$1
|
|
600
|
+
);
|
|
601
|
+
this.logger?.trackException(mastraError);
|
|
602
|
+
throw mastraError;
|
|
533
603
|
} finally {
|
|
534
604
|
client.release();
|
|
535
605
|
}
|
|
@@ -597,11 +667,27 @@ var PgVector = class extends vector.MastraVector {
|
|
|
597
667
|
buildIndex = true
|
|
598
668
|
}) {
|
|
599
669
|
const { tableName } = this.getTableName(indexName);
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
670
|
+
try {
|
|
671
|
+
if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
|
|
672
|
+
throw new Error("Invalid index name format");
|
|
673
|
+
}
|
|
674
|
+
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
675
|
+
throw new Error("Dimension must be a positive integer");
|
|
676
|
+
}
|
|
677
|
+
} catch (error$1) {
|
|
678
|
+
const mastraError = new error.MastraError(
|
|
679
|
+
{
|
|
680
|
+
id: "MASTRA_STORAGE_PG_VECTOR_CREATE_INDEX_INVALID_INPUT",
|
|
681
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
682
|
+
category: error.ErrorCategory.USER,
|
|
683
|
+
details: {
|
|
684
|
+
indexName
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
error$1
|
|
688
|
+
);
|
|
689
|
+
this.logger?.trackException(mastraError);
|
|
690
|
+
throw mastraError;
|
|
605
691
|
}
|
|
606
692
|
const indexCacheKey = await this.getIndexCacheKey({ indexName, dimension, type: indexConfig.type, metric });
|
|
607
693
|
if (this.cachedIndexExists(indexName, indexCacheKey)) {
|
|
@@ -634,12 +720,40 @@ var PgVector = class extends vector.MastraVector {
|
|
|
634
720
|
} finally {
|
|
635
721
|
client.release();
|
|
636
722
|
}
|
|
723
|
+
}).catch((error$1) => {
|
|
724
|
+
const mastraError = new error.MastraError(
|
|
725
|
+
{
|
|
726
|
+
id: "MASTRA_STORAGE_PG_VECTOR_CREATE_INDEX_FAILED",
|
|
727
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
728
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
729
|
+
details: {
|
|
730
|
+
indexName
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
error$1
|
|
734
|
+
);
|
|
735
|
+
this.logger?.trackException(mastraError);
|
|
736
|
+
throw mastraError;
|
|
637
737
|
});
|
|
638
738
|
}
|
|
639
739
|
async buildIndex({ indexName, metric = "cosine", indexConfig }) {
|
|
640
740
|
const client = await this.pool.connect();
|
|
641
741
|
try {
|
|
642
742
|
await this.setupIndex({ indexName, metric, indexConfig }, client);
|
|
743
|
+
} catch (error$1) {
|
|
744
|
+
const mastraError = new error.MastraError(
|
|
745
|
+
{
|
|
746
|
+
id: "MASTRA_STORAGE_PG_VECTOR_BUILD_INDEX_FAILED",
|
|
747
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
748
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
749
|
+
details: {
|
|
750
|
+
indexName
|
|
751
|
+
}
|
|
752
|
+
},
|
|
753
|
+
error$1
|
|
754
|
+
);
|
|
755
|
+
this.logger?.trackException(mastraError);
|
|
756
|
+
throw mastraError;
|
|
643
757
|
} finally {
|
|
644
758
|
client.release();
|
|
645
759
|
}
|
|
@@ -736,6 +850,17 @@ var PgVector = class extends vector.MastraVector {
|
|
|
736
850
|
`;
|
|
737
851
|
const vectorTables = await client.query(vectorTablesQuery, [this.schema || "public"]);
|
|
738
852
|
return vectorTables.rows.map((row) => row.table_name);
|
|
853
|
+
} catch (e) {
|
|
854
|
+
const mastraError = new error.MastraError(
|
|
855
|
+
{
|
|
856
|
+
id: "MASTRA_STORAGE_PG_VECTOR_LIST_INDEXES_FAILED",
|
|
857
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
858
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
859
|
+
},
|
|
860
|
+
e
|
|
861
|
+
);
|
|
862
|
+
this.logger?.trackException(mastraError);
|
|
863
|
+
throw mastraError;
|
|
739
864
|
} finally {
|
|
740
865
|
client.release();
|
|
741
866
|
}
|
|
@@ -815,7 +940,19 @@ var PgVector = class extends vector.MastraVector {
|
|
|
815
940
|
};
|
|
816
941
|
} catch (e) {
|
|
817
942
|
await client.query("ROLLBACK");
|
|
818
|
-
|
|
943
|
+
const mastraError = new error.MastraError(
|
|
944
|
+
{
|
|
945
|
+
id: "MASTRA_STORAGE_PG_VECTOR_DESCRIBE_INDEX_FAILED",
|
|
946
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
947
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
948
|
+
details: {
|
|
949
|
+
indexName
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
e
|
|
953
|
+
);
|
|
954
|
+
this.logger?.trackException(mastraError);
|
|
955
|
+
throw mastraError;
|
|
819
956
|
} finally {
|
|
820
957
|
client.release();
|
|
821
958
|
}
|
|
@@ -826,9 +963,21 @@ var PgVector = class extends vector.MastraVector {
|
|
|
826
963
|
const { tableName } = this.getTableName(indexName);
|
|
827
964
|
await client.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`);
|
|
828
965
|
this.createdIndexes.delete(indexName);
|
|
829
|
-
} catch (error) {
|
|
966
|
+
} catch (error$1) {
|
|
830
967
|
await client.query("ROLLBACK");
|
|
831
|
-
|
|
968
|
+
const mastraError = new error.MastraError(
|
|
969
|
+
{
|
|
970
|
+
id: "MASTRA_STORAGE_PG_VECTOR_DELETE_INDEX_FAILED",
|
|
971
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
972
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
973
|
+
details: {
|
|
974
|
+
indexName
|
|
975
|
+
}
|
|
976
|
+
},
|
|
977
|
+
error$1
|
|
978
|
+
);
|
|
979
|
+
this.logger?.trackException(mastraError);
|
|
980
|
+
throw mastraError;
|
|
832
981
|
} finally {
|
|
833
982
|
client.release();
|
|
834
983
|
}
|
|
@@ -840,7 +989,19 @@ var PgVector = class extends vector.MastraVector {
|
|
|
840
989
|
await client.query(`TRUNCATE ${tableName}`);
|
|
841
990
|
} catch (e) {
|
|
842
991
|
await client.query("ROLLBACK");
|
|
843
|
-
|
|
992
|
+
const mastraError = new error.MastraError(
|
|
993
|
+
{
|
|
994
|
+
id: "MASTRA_STORAGE_PG_VECTOR_TRUNCATE_INDEX_FAILED",
|
|
995
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
996
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
997
|
+
details: {
|
|
998
|
+
indexName
|
|
999
|
+
}
|
|
1000
|
+
},
|
|
1001
|
+
e
|
|
1002
|
+
);
|
|
1003
|
+
this.logger?.trackException(mastraError);
|
|
1004
|
+
throw mastraError;
|
|
844
1005
|
} finally {
|
|
845
1006
|
client.release();
|
|
846
1007
|
}
|
|
@@ -859,11 +1020,12 @@ var PgVector = class extends vector.MastraVector {
|
|
|
859
1020
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
860
1021
|
*/
|
|
861
1022
|
async updateVector({ indexName, id, update }) {
|
|
862
|
-
|
|
863
|
-
throw new Error("No updates provided");
|
|
864
|
-
}
|
|
865
|
-
const client = await this.pool.connect();
|
|
1023
|
+
let client;
|
|
866
1024
|
try {
|
|
1025
|
+
if (!update.vector && !update.metadata) {
|
|
1026
|
+
throw new Error("No updates provided");
|
|
1027
|
+
}
|
|
1028
|
+
client = await this.pool.connect();
|
|
867
1029
|
let updateParts = [];
|
|
868
1030
|
let values = [id];
|
|
869
1031
|
let valueIndex = 2;
|
|
@@ -886,10 +1048,23 @@ var PgVector = class extends vector.MastraVector {
|
|
|
886
1048
|
WHERE vector_id = $1
|
|
887
1049
|
`;
|
|
888
1050
|
await client.query(query, values);
|
|
889
|
-
} catch (error) {
|
|
890
|
-
|
|
1051
|
+
} catch (error$1) {
|
|
1052
|
+
const mastraError = new error.MastraError(
|
|
1053
|
+
{
|
|
1054
|
+
id: "MASTRA_STORAGE_PG_VECTOR_UPDATE_VECTOR_FAILED",
|
|
1055
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
1056
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1057
|
+
details: {
|
|
1058
|
+
indexName,
|
|
1059
|
+
id
|
|
1060
|
+
}
|
|
1061
|
+
},
|
|
1062
|
+
error$1
|
|
1063
|
+
);
|
|
1064
|
+
this.logger?.trackException(mastraError);
|
|
1065
|
+
throw mastraError;
|
|
891
1066
|
} finally {
|
|
892
|
-
client
|
|
1067
|
+
client?.release();
|
|
893
1068
|
}
|
|
894
1069
|
}
|
|
895
1070
|
/**
|
|
@@ -900,18 +1075,32 @@ var PgVector = class extends vector.MastraVector {
|
|
|
900
1075
|
* @throws Will throw an error if the deletion operation fails.
|
|
901
1076
|
*/
|
|
902
1077
|
async deleteVector({ indexName, id }) {
|
|
903
|
-
|
|
1078
|
+
let client;
|
|
904
1079
|
try {
|
|
1080
|
+
client = await this.pool.connect();
|
|
905
1081
|
const { tableName } = this.getTableName(indexName);
|
|
906
1082
|
const query = `
|
|
907
1083
|
DELETE FROM ${tableName}
|
|
908
1084
|
WHERE vector_id = $1
|
|
909
1085
|
`;
|
|
910
1086
|
await client.query(query, [id]);
|
|
911
|
-
} catch (error) {
|
|
912
|
-
|
|
1087
|
+
} catch (error$1) {
|
|
1088
|
+
const mastraError = new error.MastraError(
|
|
1089
|
+
{
|
|
1090
|
+
id: "MASTRA_STORAGE_PG_VECTOR_DELETE_VECTOR_FAILED",
|
|
1091
|
+
domain: error.ErrorDomain.MASTRA_VECTOR,
|
|
1092
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1093
|
+
details: {
|
|
1094
|
+
indexName,
|
|
1095
|
+
id
|
|
1096
|
+
}
|
|
1097
|
+
},
|
|
1098
|
+
error$1
|
|
1099
|
+
);
|
|
1100
|
+
this.logger?.trackException(mastraError);
|
|
1101
|
+
throw mastraError;
|
|
913
1102
|
} finally {
|
|
914
|
-
client
|
|
1103
|
+
client?.release();
|
|
915
1104
|
}
|
|
916
1105
|
}
|
|
917
1106
|
};
|
|
@@ -922,35 +1111,46 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
922
1111
|
setupSchemaPromise = null;
|
|
923
1112
|
schemaSetupComplete = void 0;
|
|
924
1113
|
constructor(config) {
|
|
925
|
-
|
|
926
|
-
if (
|
|
927
|
-
|
|
928
|
-
"PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
|
-
} else {
|
|
932
|
-
const required = ["host", "database", "user", "password"];
|
|
933
|
-
for (const key of required) {
|
|
934
|
-
if (!(key in config) || typeof config[key] !== "string" || config[key].trim() === "") {
|
|
1114
|
+
try {
|
|
1115
|
+
if ("connectionString" in config) {
|
|
1116
|
+
if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
|
|
935
1117
|
throw new Error(
|
|
936
|
-
|
|
1118
|
+
"PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
|
|
937
1119
|
);
|
|
938
1120
|
}
|
|
1121
|
+
} else {
|
|
1122
|
+
const required = ["host", "database", "user", "password"];
|
|
1123
|
+
for (const key of required) {
|
|
1124
|
+
if (!(key in config) || typeof config[key] !== "string" || config[key].trim() === "") {
|
|
1125
|
+
throw new Error(
|
|
1126
|
+
`PostgresStore: ${key} must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
939
1130
|
}
|
|
1131
|
+
super({ name: "PostgresStore" });
|
|
1132
|
+
this.pgp = pgPromise__default.default();
|
|
1133
|
+
this.schema = config.schemaName;
|
|
1134
|
+
this.db = this.pgp(
|
|
1135
|
+
`connectionString` in config ? { connectionString: config.connectionString } : {
|
|
1136
|
+
host: config.host,
|
|
1137
|
+
port: config.port,
|
|
1138
|
+
database: config.database,
|
|
1139
|
+
user: config.user,
|
|
1140
|
+
password: config.password,
|
|
1141
|
+
ssl: config.ssl
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
1144
|
+
} catch (e) {
|
|
1145
|
+
throw new error.MastraError(
|
|
1146
|
+
{
|
|
1147
|
+
id: "MASTRA_STORAGE_PG_STORE_INITIALIZATION_FAILED",
|
|
1148
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1149
|
+
category: error.ErrorCategory.USER
|
|
1150
|
+
},
|
|
1151
|
+
e
|
|
1152
|
+
);
|
|
940
1153
|
}
|
|
941
|
-
super({ name: "PostgresStore" });
|
|
942
|
-
this.pgp = pgPromise__default.default();
|
|
943
|
-
this.schema = config.schemaName;
|
|
944
|
-
this.db = this.pgp(
|
|
945
|
-
`connectionString` in config ? { connectionString: config.connectionString } : {
|
|
946
|
-
host: config.host,
|
|
947
|
-
port: config.port,
|
|
948
|
-
database: config.database,
|
|
949
|
-
user: config.user,
|
|
950
|
-
password: config.password,
|
|
951
|
-
ssl: config.ssl
|
|
952
|
-
}
|
|
953
|
-
);
|
|
954
1154
|
}
|
|
955
1155
|
get supports() {
|
|
956
1156
|
return {
|
|
@@ -1011,10 +1211,20 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1011
1211
|
await this.insert({ tableName, record });
|
|
1012
1212
|
}
|
|
1013
1213
|
await this.db.query("COMMIT");
|
|
1014
|
-
} catch (error) {
|
|
1015
|
-
console.error(`Error inserting into ${tableName}:`, error);
|
|
1214
|
+
} catch (error$1) {
|
|
1016
1215
|
await this.db.query("ROLLBACK");
|
|
1017
|
-
throw error
|
|
1216
|
+
throw new error.MastraError(
|
|
1217
|
+
{
|
|
1218
|
+
id: "MASTRA_STORAGE_PG_STORE_BATCH_INSERT_FAILED",
|
|
1219
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1220
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1221
|
+
details: {
|
|
1222
|
+
tableName,
|
|
1223
|
+
numberOfRecords: records.length
|
|
1224
|
+
}
|
|
1225
|
+
},
|
|
1226
|
+
error$1
|
|
1227
|
+
);
|
|
1018
1228
|
}
|
|
1019
1229
|
}
|
|
1020
1230
|
/**
|
|
@@ -1071,8 +1281,24 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1071
1281
|
}
|
|
1072
1282
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1073
1283
|
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(storage.TABLE_TRACES)} ${whereClause}`;
|
|
1074
|
-
|
|
1075
|
-
|
|
1284
|
+
let total = 0;
|
|
1285
|
+
try {
|
|
1286
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1287
|
+
total = parseInt(countResult.count, 10);
|
|
1288
|
+
} catch (error$1) {
|
|
1289
|
+
throw new error.MastraError(
|
|
1290
|
+
{
|
|
1291
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TOTAL_COUNT",
|
|
1292
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1293
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1294
|
+
details: {
|
|
1295
|
+
name: args.name ?? "",
|
|
1296
|
+
scope: args.scope ?? ""
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
error$1
|
|
1300
|
+
);
|
|
1301
|
+
}
|
|
1076
1302
|
if (total === 0) {
|
|
1077
1303
|
return {
|
|
1078
1304
|
traces: [],
|
|
@@ -1086,30 +1312,45 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1086
1312
|
storage.TABLE_TRACES
|
|
1087
1313
|
)} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1088
1314
|
const finalQueryParams = [...queryParams, perPage, currentOffset];
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1315
|
+
try {
|
|
1316
|
+
const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
|
|
1317
|
+
const traces = rows.map((row) => ({
|
|
1318
|
+
id: row.id,
|
|
1319
|
+
parentSpanId: row.parentSpanId,
|
|
1320
|
+
traceId: row.traceId,
|
|
1321
|
+
name: row.name,
|
|
1322
|
+
scope: row.scope,
|
|
1323
|
+
kind: row.kind,
|
|
1324
|
+
status: row.status,
|
|
1325
|
+
events: row.events,
|
|
1326
|
+
links: row.links,
|
|
1327
|
+
attributes: row.attributes,
|
|
1328
|
+
startTime: row.startTime,
|
|
1329
|
+
endTime: row.endTime,
|
|
1330
|
+
other: row.other,
|
|
1331
|
+
createdAt: row.createdAt
|
|
1332
|
+
}));
|
|
1333
|
+
return {
|
|
1334
|
+
traces,
|
|
1335
|
+
total,
|
|
1336
|
+
page,
|
|
1337
|
+
perPage,
|
|
1338
|
+
hasMore: currentOffset + traces.length < total
|
|
1339
|
+
};
|
|
1340
|
+
} catch (error$1) {
|
|
1341
|
+
throw new error.MastraError(
|
|
1342
|
+
{
|
|
1343
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_TRACES_PAGINATED_FAILED_TO_RETRIEVE_TRACES",
|
|
1344
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1345
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1346
|
+
details: {
|
|
1347
|
+
name: args.name ?? "",
|
|
1348
|
+
scope: args.scope ?? ""
|
|
1349
|
+
}
|
|
1350
|
+
},
|
|
1351
|
+
error$1
|
|
1352
|
+
);
|
|
1353
|
+
}
|
|
1113
1354
|
}
|
|
1114
1355
|
async setupSchema() {
|
|
1115
1356
|
if (!this.schema || this.schemaSetupComplete) {
|
|
@@ -1183,9 +1424,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1183
1424
|
` : ""}
|
|
1184
1425
|
`;
|
|
1185
1426
|
await this.db.none(sql);
|
|
1186
|
-
} catch (error) {
|
|
1187
|
-
|
|
1188
|
-
|
|
1427
|
+
} catch (error$1) {
|
|
1428
|
+
throw new error.MastraError(
|
|
1429
|
+
{
|
|
1430
|
+
id: "MASTRA_STORAGE_PG_STORE_CREATE_TABLE_FAILED",
|
|
1431
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1432
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1433
|
+
details: {
|
|
1434
|
+
tableName
|
|
1435
|
+
}
|
|
1436
|
+
},
|
|
1437
|
+
error$1
|
|
1438
|
+
);
|
|
1189
1439
|
}
|
|
1190
1440
|
}
|
|
1191
1441
|
getDefaultValue(type) {
|
|
@@ -1223,19 +1473,35 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1223
1473
|
this.logger?.debug?.(`Ensured column ${parsedColumnName} exists in table ${fullTableName}`);
|
|
1224
1474
|
}
|
|
1225
1475
|
}
|
|
1226
|
-
} catch (error) {
|
|
1227
|
-
|
|
1228
|
-
|
|
1476
|
+
} catch (error$1) {
|
|
1477
|
+
throw new error.MastraError(
|
|
1478
|
+
{
|
|
1479
|
+
id: "MASTRA_STORAGE_PG_STORE_ALTER_TABLE_FAILED",
|
|
1480
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1481
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1482
|
+
details: {
|
|
1483
|
+
tableName
|
|
1484
|
+
}
|
|
1485
|
+
},
|
|
1486
|
+
error$1
|
|
1229
1487
|
);
|
|
1230
|
-
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
1231
1488
|
}
|
|
1232
1489
|
}
|
|
1233
1490
|
async clearTable({ tableName }) {
|
|
1234
1491
|
try {
|
|
1235
1492
|
await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
|
|
1236
|
-
} catch (error) {
|
|
1237
|
-
|
|
1238
|
-
|
|
1493
|
+
} catch (error$1) {
|
|
1494
|
+
throw new error.MastraError(
|
|
1495
|
+
{
|
|
1496
|
+
id: "MASTRA_STORAGE_PG_STORE_CLEAR_TABLE_FAILED",
|
|
1497
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1498
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1499
|
+
details: {
|
|
1500
|
+
tableName
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1503
|
+
error$1
|
|
1504
|
+
);
|
|
1239
1505
|
}
|
|
1240
1506
|
}
|
|
1241
1507
|
async insert({ tableName, record }) {
|
|
@@ -1247,9 +1513,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1247
1513
|
`INSERT INTO ${this.getTableName(tableName)} (${columns.map((c) => `"${c}"`).join(", ")}) VALUES (${placeholders})`,
|
|
1248
1514
|
values
|
|
1249
1515
|
);
|
|
1250
|
-
} catch (error) {
|
|
1251
|
-
|
|
1252
|
-
|
|
1516
|
+
} catch (error$1) {
|
|
1517
|
+
throw new error.MastraError(
|
|
1518
|
+
{
|
|
1519
|
+
id: "MASTRA_STORAGE_PG_STORE_INSERT_FAILED",
|
|
1520
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1521
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1522
|
+
details: {
|
|
1523
|
+
tableName
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
error$1
|
|
1527
|
+
);
|
|
1253
1528
|
}
|
|
1254
1529
|
}
|
|
1255
1530
|
async load({ tableName, keys }) {
|
|
@@ -1272,9 +1547,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1272
1547
|
return snapshot;
|
|
1273
1548
|
}
|
|
1274
1549
|
return result;
|
|
1275
|
-
} catch (error) {
|
|
1276
|
-
|
|
1277
|
-
|
|
1550
|
+
} catch (error$1) {
|
|
1551
|
+
throw new error.MastraError(
|
|
1552
|
+
{
|
|
1553
|
+
id: "MASTRA_STORAGE_PG_STORE_LOAD_FAILED",
|
|
1554
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1555
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1556
|
+
details: {
|
|
1557
|
+
tableName
|
|
1558
|
+
}
|
|
1559
|
+
},
|
|
1560
|
+
error$1
|
|
1561
|
+
);
|
|
1278
1562
|
}
|
|
1279
1563
|
}
|
|
1280
1564
|
async getThreadById({ threadId }) {
|
|
@@ -1300,9 +1584,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1300
1584
|
createdAt: thread.createdAt,
|
|
1301
1585
|
updatedAt: thread.updatedAt
|
|
1302
1586
|
};
|
|
1303
|
-
} catch (error) {
|
|
1304
|
-
|
|
1305
|
-
|
|
1587
|
+
} catch (error$1) {
|
|
1588
|
+
throw new error.MastraError(
|
|
1589
|
+
{
|
|
1590
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_THREAD_BY_ID_FAILED",
|
|
1591
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1592
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1593
|
+
details: {
|
|
1594
|
+
threadId
|
|
1595
|
+
}
|
|
1596
|
+
},
|
|
1597
|
+
error$1
|
|
1598
|
+
);
|
|
1306
1599
|
}
|
|
1307
1600
|
}
|
|
1308
1601
|
/**
|
|
@@ -1361,8 +1654,21 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1361
1654
|
perPage,
|
|
1362
1655
|
hasMore: currentOffset + threads.length < total
|
|
1363
1656
|
};
|
|
1364
|
-
} catch (error) {
|
|
1365
|
-
|
|
1657
|
+
} catch (error$1) {
|
|
1658
|
+
const mastraError = new error.MastraError(
|
|
1659
|
+
{
|
|
1660
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
|
|
1661
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1662
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1663
|
+
details: {
|
|
1664
|
+
resourceId,
|
|
1665
|
+
page
|
|
1666
|
+
}
|
|
1667
|
+
},
|
|
1668
|
+
error$1
|
|
1669
|
+
);
|
|
1670
|
+
this.logger?.error?.(mastraError.toString());
|
|
1671
|
+
this.logger?.trackException(mastraError);
|
|
1366
1672
|
return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
|
|
1367
1673
|
}
|
|
1368
1674
|
}
|
|
@@ -1393,9 +1699,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1393
1699
|
]
|
|
1394
1700
|
);
|
|
1395
1701
|
return thread;
|
|
1396
|
-
} catch (error) {
|
|
1397
|
-
|
|
1398
|
-
|
|
1702
|
+
} catch (error$1) {
|
|
1703
|
+
throw new error.MastraError(
|
|
1704
|
+
{
|
|
1705
|
+
id: "MASTRA_STORAGE_PG_STORE_SAVE_THREAD_FAILED",
|
|
1706
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1707
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1708
|
+
details: {
|
|
1709
|
+
threadId: thread.id
|
|
1710
|
+
}
|
|
1711
|
+
},
|
|
1712
|
+
error$1
|
|
1713
|
+
);
|
|
1399
1714
|
}
|
|
1400
1715
|
}
|
|
1401
1716
|
async updateThread({
|
|
@@ -1403,20 +1718,29 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1403
1718
|
title,
|
|
1404
1719
|
metadata
|
|
1405
1720
|
}) {
|
|
1721
|
+
const existingThread = await this.getThreadById({ threadId: id });
|
|
1722
|
+
if (!existingThread) {
|
|
1723
|
+
throw new error.MastraError({
|
|
1724
|
+
id: "MASTRA_STORAGE_PG_STORE_UPDATE_THREAD_FAILED",
|
|
1725
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1726
|
+
category: error.ErrorCategory.USER,
|
|
1727
|
+
text: `Thread ${id} not found`,
|
|
1728
|
+
details: {
|
|
1729
|
+
threadId: id,
|
|
1730
|
+
title
|
|
1731
|
+
}
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
const mergedMetadata = {
|
|
1735
|
+
...existingThread.metadata,
|
|
1736
|
+
...metadata
|
|
1737
|
+
};
|
|
1406
1738
|
try {
|
|
1407
|
-
const existingThread = await this.getThreadById({ threadId: id });
|
|
1408
|
-
if (!existingThread) {
|
|
1409
|
-
throw new Error(`Thread ${id} not found`);
|
|
1410
|
-
}
|
|
1411
|
-
const mergedMetadata = {
|
|
1412
|
-
...existingThread.metadata,
|
|
1413
|
-
...metadata
|
|
1414
|
-
};
|
|
1415
1739
|
const thread = await this.db.one(
|
|
1416
1740
|
`UPDATE ${this.getTableName(storage.TABLE_THREADS)}
|
|
1417
1741
|
SET title = $1,
|
|
1418
|
-
|
|
1419
|
-
|
|
1742
|
+
metadata = $2,
|
|
1743
|
+
"updatedAt" = $3
|
|
1420
1744
|
WHERE id = $4
|
|
1421
1745
|
RETURNING *`,
|
|
1422
1746
|
[title, mergedMetadata, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
@@ -1427,9 +1751,19 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1427
1751
|
createdAt: thread.createdAt,
|
|
1428
1752
|
updatedAt: thread.updatedAt
|
|
1429
1753
|
};
|
|
1430
|
-
} catch (error) {
|
|
1431
|
-
|
|
1432
|
-
|
|
1754
|
+
} catch (error$1) {
|
|
1755
|
+
throw new error.MastraError(
|
|
1756
|
+
{
|
|
1757
|
+
id: "MASTRA_STORAGE_PG_STORE_UPDATE_THREAD_FAILED",
|
|
1758
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1759
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1760
|
+
details: {
|
|
1761
|
+
threadId: id,
|
|
1762
|
+
title
|
|
1763
|
+
}
|
|
1764
|
+
},
|
|
1765
|
+
error$1
|
|
1766
|
+
);
|
|
1433
1767
|
}
|
|
1434
1768
|
}
|
|
1435
1769
|
async deleteThread({ threadId }) {
|
|
@@ -1438,27 +1772,35 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1438
1772
|
await t.none(`DELETE FROM ${this.getTableName(storage.TABLE_MESSAGES)} WHERE thread_id = $1`, [threadId]);
|
|
1439
1773
|
await t.none(`DELETE FROM ${this.getTableName(storage.TABLE_THREADS)} WHERE id = $1`, [threadId]);
|
|
1440
1774
|
});
|
|
1441
|
-
} catch (error) {
|
|
1442
|
-
|
|
1443
|
-
|
|
1775
|
+
} catch (error$1) {
|
|
1776
|
+
throw new error.MastraError(
|
|
1777
|
+
{
|
|
1778
|
+
id: "MASTRA_STORAGE_PG_STORE_DELETE_THREAD_FAILED",
|
|
1779
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1780
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1781
|
+
details: {
|
|
1782
|
+
threadId
|
|
1783
|
+
}
|
|
1784
|
+
},
|
|
1785
|
+
error$1
|
|
1786
|
+
);
|
|
1444
1787
|
}
|
|
1445
1788
|
}
|
|
1446
|
-
async
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
`
|
|
1789
|
+
async _getIncludedMessages({
|
|
1790
|
+
threadId,
|
|
1791
|
+
selectBy,
|
|
1792
|
+
orderByStatement
|
|
1793
|
+
}) {
|
|
1794
|
+
const include = selectBy?.include;
|
|
1795
|
+
if (!include) return null;
|
|
1796
|
+
const unionQueries = [];
|
|
1797
|
+
const params = [];
|
|
1798
|
+
let paramIdx = 1;
|
|
1799
|
+
for (const inc of include) {
|
|
1800
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
1801
|
+
const searchId = inc.threadId || threadId;
|
|
1802
|
+
unionQueries.push(
|
|
1803
|
+
`
|
|
1462
1804
|
SELECT * FROM (
|
|
1463
1805
|
WITH ordered_messages AS (
|
|
1464
1806
|
SELECT
|
|
@@ -1490,34 +1832,45 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1490
1832
|
)
|
|
1491
1833
|
) AS query_${paramIdx}
|
|
1492
1834
|
`
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1835
|
+
// Keep ASC for final sorting after fetching context
|
|
1836
|
+
);
|
|
1837
|
+
params.push(searchId, id, withPreviousMessages, withNextMessages);
|
|
1838
|
+
paramIdx += 4;
|
|
1839
|
+
}
|
|
1840
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
|
|
1841
|
+
const includedRows = await this.db.manyOrNone(finalQuery, params);
|
|
1842
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1843
|
+
const dedupedRows = includedRows.filter((row) => {
|
|
1844
|
+
if (seen.has(row.id)) return false;
|
|
1845
|
+
seen.add(row.id);
|
|
1846
|
+
return true;
|
|
1847
|
+
});
|
|
1848
|
+
return dedupedRows;
|
|
1849
|
+
}
|
|
1850
|
+
async getMessages(args) {
|
|
1851
|
+
const { threadId, format, selectBy } = args;
|
|
1852
|
+
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1853
|
+
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1854
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
1855
|
+
try {
|
|
1856
|
+
let rows = [];
|
|
1857
|
+
const include = selectBy?.include || [];
|
|
1858
|
+
if (include?.length) {
|
|
1859
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
|
|
1860
|
+
if (includeMessages) {
|
|
1861
|
+
rows.push(...includeMessages);
|
|
1519
1862
|
}
|
|
1520
1863
|
}
|
|
1864
|
+
const excludeIds = rows.map((m) => m.id);
|
|
1865
|
+
const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + 2}`).join(", ");
|
|
1866
|
+
let query = `${selectStatement} FROM ${this.getTableName(storage.TABLE_MESSAGES)} WHERE thread_id = $1
|
|
1867
|
+
${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ""}
|
|
1868
|
+
${orderByStatement}
|
|
1869
|
+
LIMIT $${excludeIds.length + 2}
|
|
1870
|
+
`;
|
|
1871
|
+
const queryParams = [threadId, ...excludeIds, limit];
|
|
1872
|
+
const remainingRows = await this.db.manyOrNone(query, queryParams);
|
|
1873
|
+
rows.push(...remainingRows);
|
|
1521
1874
|
const fetchedMessages = (rows || []).map((message) => {
|
|
1522
1875
|
if (typeof message.content === "string") {
|
|
1523
1876
|
try {
|
|
@@ -1534,8 +1887,20 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1534
1887
|
return format === "v2" ? sortedMessages.map(
|
|
1535
1888
|
(m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
|
|
1536
1889
|
) : sortedMessages;
|
|
1537
|
-
} catch (error) {
|
|
1538
|
-
|
|
1890
|
+
} catch (error$1) {
|
|
1891
|
+
const mastraError = new error.MastraError(
|
|
1892
|
+
{
|
|
1893
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_MESSAGES_FAILED",
|
|
1894
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1895
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1896
|
+
details: {
|
|
1897
|
+
threadId
|
|
1898
|
+
}
|
|
1899
|
+
},
|
|
1900
|
+
error$1
|
|
1901
|
+
);
|
|
1902
|
+
this.logger?.error?.(mastraError.toString());
|
|
1903
|
+
this.logger?.trackException(mastraError);
|
|
1539
1904
|
return [];
|
|
1540
1905
|
}
|
|
1541
1906
|
}
|
|
@@ -1546,6 +1911,13 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1546
1911
|
const toDate = dateRange?.end;
|
|
1547
1912
|
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1548
1913
|
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1914
|
+
const messages = [];
|
|
1915
|
+
if (selectBy?.include?.length) {
|
|
1916
|
+
const includeMessages = await this._getIncludedMessages({ threadId, selectBy, orderByStatement });
|
|
1917
|
+
if (includeMessages) {
|
|
1918
|
+
messages.push(...includeMessages);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1549
1921
|
try {
|
|
1550
1922
|
const perPage = perPageInput !== void 0 ? perPageInput : 40;
|
|
1551
1923
|
const currentOffset = page * perPage;
|
|
@@ -1577,7 +1949,8 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1577
1949
|
storage.TABLE_MESSAGES
|
|
1578
1950
|
)} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1579
1951
|
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1580
|
-
|
|
1952
|
+
messages.push(...rows || []);
|
|
1953
|
+
const list = new agent.MessageList().add(messages, "memory");
|
|
1581
1954
|
const messagesToReturn = format === `v2` ? list.get.all.v2() : list.get.all.v1();
|
|
1582
1955
|
return {
|
|
1583
1956
|
messages: messagesToReturn,
|
|
@@ -1586,8 +1959,21 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1586
1959
|
perPage,
|
|
1587
1960
|
hasMore: currentOffset + rows.length < total
|
|
1588
1961
|
};
|
|
1589
|
-
} catch (error) {
|
|
1590
|
-
|
|
1962
|
+
} catch (error$1) {
|
|
1963
|
+
const mastraError = new error.MastraError(
|
|
1964
|
+
{
|
|
1965
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_MESSAGES_PAGINATED_FAILED",
|
|
1966
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1967
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1968
|
+
details: {
|
|
1969
|
+
threadId,
|
|
1970
|
+
page
|
|
1971
|
+
}
|
|
1972
|
+
},
|
|
1973
|
+
error$1
|
|
1974
|
+
);
|
|
1975
|
+
this.logger?.error?.(mastraError.toString());
|
|
1976
|
+
this.logger?.trackException(mastraError);
|
|
1591
1977
|
return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
|
|
1592
1978
|
}
|
|
1593
1979
|
}
|
|
@@ -1596,15 +1982,28 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1596
1982
|
format
|
|
1597
1983
|
}) {
|
|
1598
1984
|
if (messages.length === 0) return messages;
|
|
1985
|
+
const threadId = messages[0]?.threadId;
|
|
1986
|
+
if (!threadId) {
|
|
1987
|
+
throw new error.MastraError({
|
|
1988
|
+
id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
|
|
1989
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1990
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1991
|
+
text: `Thread ID is required`
|
|
1992
|
+
});
|
|
1993
|
+
}
|
|
1994
|
+
const thread = await this.getThreadById({ threadId });
|
|
1995
|
+
if (!thread) {
|
|
1996
|
+
throw new error.MastraError({
|
|
1997
|
+
id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
|
|
1998
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1999
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2000
|
+
text: `Thread ${threadId} not found`,
|
|
2001
|
+
details: {
|
|
2002
|
+
threadId
|
|
2003
|
+
}
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
1599
2006
|
try {
|
|
1600
|
-
const threadId = messages[0]?.threadId;
|
|
1601
|
-
if (!threadId) {
|
|
1602
|
-
throw new Error("Thread ID is required");
|
|
1603
|
-
}
|
|
1604
|
-
const thread = await this.getThreadById({ threadId });
|
|
1605
|
-
if (!thread) {
|
|
1606
|
-
throw new Error(`Thread ${threadId} not found`);
|
|
1607
|
-
}
|
|
1608
2007
|
await this.db.tx(async (t) => {
|
|
1609
2008
|
const messageInserts = messages.map((message) => {
|
|
1610
2009
|
if (!message.threadId) {
|
|
@@ -1642,9 +2041,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1642
2041
|
const list = new agent.MessageList().add(messages, "memory");
|
|
1643
2042
|
if (format === `v2`) return list.get.all.v2();
|
|
1644
2043
|
return list.get.all.v1();
|
|
1645
|
-
} catch (error) {
|
|
1646
|
-
|
|
1647
|
-
|
|
2044
|
+
} catch (error$1) {
|
|
2045
|
+
throw new error.MastraError(
|
|
2046
|
+
{
|
|
2047
|
+
id: "MASTRA_STORAGE_PG_STORE_SAVE_MESSAGES_FAILED",
|
|
2048
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2049
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2050
|
+
details: {
|
|
2051
|
+
threadId
|
|
2052
|
+
}
|
|
2053
|
+
},
|
|
2054
|
+
error$1
|
|
2055
|
+
);
|
|
1648
2056
|
}
|
|
1649
2057
|
}
|
|
1650
2058
|
async persistWorkflowSnapshot({
|
|
@@ -1667,9 +2075,19 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1667
2075
|
"updatedAt" = EXCLUDED."updatedAt"`,
|
|
1668
2076
|
[workflowName, runId, JSON.stringify(snapshot), now, now]
|
|
1669
2077
|
);
|
|
1670
|
-
} catch (error) {
|
|
1671
|
-
|
|
1672
|
-
|
|
2078
|
+
} catch (error$1) {
|
|
2079
|
+
throw new error.MastraError(
|
|
2080
|
+
{
|
|
2081
|
+
id: "MASTRA_STORAGE_PG_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
|
|
2082
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2083
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2084
|
+
details: {
|
|
2085
|
+
workflowName,
|
|
2086
|
+
runId
|
|
2087
|
+
}
|
|
2088
|
+
},
|
|
2089
|
+
error$1
|
|
2090
|
+
);
|
|
1673
2091
|
}
|
|
1674
2092
|
}
|
|
1675
2093
|
async loadWorkflowSnapshot({
|
|
@@ -1688,9 +2106,19 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1688
2106
|
return null;
|
|
1689
2107
|
}
|
|
1690
2108
|
return result.snapshot;
|
|
1691
|
-
} catch (error) {
|
|
1692
|
-
|
|
1693
|
-
|
|
2109
|
+
} catch (error$1) {
|
|
2110
|
+
throw new error.MastraError(
|
|
2111
|
+
{
|
|
2112
|
+
id: "MASTRA_STORAGE_PG_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
|
|
2113
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2114
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2115
|
+
details: {
|
|
2116
|
+
workflowName,
|
|
2117
|
+
runId
|
|
2118
|
+
}
|
|
2119
|
+
},
|
|
2120
|
+
error$1
|
|
2121
|
+
);
|
|
1694
2122
|
}
|
|
1695
2123
|
}
|
|
1696
2124
|
async hasColumn(table, column) {
|
|
@@ -1777,9 +2205,18 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1777
2205
|
return this.parseWorkflowRun(row);
|
|
1778
2206
|
});
|
|
1779
2207
|
return { runs, total: total || runs.length };
|
|
1780
|
-
} catch (error) {
|
|
1781
|
-
|
|
1782
|
-
|
|
2208
|
+
} catch (error$1) {
|
|
2209
|
+
throw new error.MastraError(
|
|
2210
|
+
{
|
|
2211
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_WORKFLOW_RUNS_FAILED",
|
|
2212
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2213
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2214
|
+
details: {
|
|
2215
|
+
workflowName: workflowName || "all"
|
|
2216
|
+
}
|
|
2217
|
+
},
|
|
2218
|
+
error$1
|
|
2219
|
+
);
|
|
1783
2220
|
}
|
|
1784
2221
|
}
|
|
1785
2222
|
async getWorkflowRunById({
|
|
@@ -1811,9 +2248,19 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1811
2248
|
return null;
|
|
1812
2249
|
}
|
|
1813
2250
|
return this.parseWorkflowRun(result);
|
|
1814
|
-
} catch (error) {
|
|
1815
|
-
|
|
1816
|
-
|
|
2251
|
+
} catch (error$1) {
|
|
2252
|
+
throw new error.MastraError(
|
|
2253
|
+
{
|
|
2254
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
|
|
2255
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2256
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2257
|
+
details: {
|
|
2258
|
+
runId,
|
|
2259
|
+
workflowName: workflowName || ""
|
|
2260
|
+
}
|
|
2261
|
+
},
|
|
2262
|
+
error$1
|
|
2263
|
+
);
|
|
1817
2264
|
}
|
|
1818
2265
|
}
|
|
1819
2266
|
async close() {
|
|
@@ -1845,29 +2292,144 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1845
2292
|
}
|
|
1846
2293
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1847
2294
|
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(storage.TABLE_EVALS)} ${whereClause}`;
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
2295
|
+
try {
|
|
2296
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
2297
|
+
const total = parseInt(countResult.count, 10);
|
|
2298
|
+
const currentOffset = page * perPage;
|
|
2299
|
+
if (total === 0) {
|
|
2300
|
+
return {
|
|
2301
|
+
evals: [],
|
|
2302
|
+
total: 0,
|
|
2303
|
+
page,
|
|
2304
|
+
perPage,
|
|
2305
|
+
hasMore: false
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
const dataQuery = `SELECT * FROM ${this.getTableName(
|
|
2309
|
+
storage.TABLE_EVALS
|
|
2310
|
+
)} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
2311
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1852
2312
|
return {
|
|
1853
|
-
evals: [],
|
|
1854
|
-
total
|
|
2313
|
+
evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
|
|
2314
|
+
total,
|
|
1855
2315
|
page,
|
|
1856
2316
|
perPage,
|
|
1857
|
-
hasMore:
|
|
2317
|
+
hasMore: currentOffset + (rows?.length ?? 0) < total
|
|
1858
2318
|
};
|
|
2319
|
+
} catch (error$1) {
|
|
2320
|
+
const mastraError = new error.MastraError(
|
|
2321
|
+
{
|
|
2322
|
+
id: "MASTRA_STORAGE_PG_STORE_GET_EVALS_FAILED",
|
|
2323
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2324
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2325
|
+
details: {
|
|
2326
|
+
agentName: agentName || "all",
|
|
2327
|
+
type: type || "all",
|
|
2328
|
+
page,
|
|
2329
|
+
perPage
|
|
2330
|
+
}
|
|
2331
|
+
},
|
|
2332
|
+
error$1
|
|
2333
|
+
);
|
|
2334
|
+
this.logger?.error?.(mastraError.toString());
|
|
2335
|
+
this.logger?.trackException(mastraError);
|
|
2336
|
+
throw mastraError;
|
|
1859
2337
|
}
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
}
|
|
2338
|
+
}
|
|
2339
|
+
async updateMessages({
|
|
2340
|
+
messages
|
|
2341
|
+
}) {
|
|
2342
|
+
if (messages.length === 0) {
|
|
2343
|
+
return [];
|
|
2344
|
+
}
|
|
2345
|
+
const messageIds = messages.map((m) => m.id);
|
|
2346
|
+
const selectQuery = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId" FROM ${this.getTableName(
|
|
2347
|
+
storage.TABLE_MESSAGES
|
|
2348
|
+
)} WHERE id IN ($1:list)`;
|
|
2349
|
+
const existingMessagesDb = await this.db.manyOrNone(selectQuery, [messageIds]);
|
|
2350
|
+
if (existingMessagesDb.length === 0) {
|
|
2351
|
+
return [];
|
|
2352
|
+
}
|
|
2353
|
+
const existingMessages = existingMessagesDb.map((msg) => {
|
|
2354
|
+
if (typeof msg.content === "string") {
|
|
2355
|
+
try {
|
|
2356
|
+
msg.content = JSON.parse(msg.content);
|
|
2357
|
+
} catch {
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
return msg;
|
|
2361
|
+
});
|
|
2362
|
+
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
2363
|
+
await this.db.tx(async (t) => {
|
|
2364
|
+
const queries = [];
|
|
2365
|
+
const columnMapping = {
|
|
2366
|
+
threadId: "thread_id"
|
|
2367
|
+
};
|
|
2368
|
+
for (const existingMessage of existingMessages) {
|
|
2369
|
+
const updatePayload = messages.find((m) => m.id === existingMessage.id);
|
|
2370
|
+
if (!updatePayload) continue;
|
|
2371
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
2372
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
2373
|
+
threadIdsToUpdate.add(existingMessage.threadId);
|
|
2374
|
+
if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
2375
|
+
threadIdsToUpdate.add(updatePayload.threadId);
|
|
2376
|
+
}
|
|
2377
|
+
const setClauses = [];
|
|
2378
|
+
const values = [];
|
|
2379
|
+
let paramIndex = 1;
|
|
2380
|
+
const updatableFields = { ...fieldsToUpdate };
|
|
2381
|
+
if (updatableFields.content) {
|
|
2382
|
+
const newContent = {
|
|
2383
|
+
...existingMessage.content,
|
|
2384
|
+
...updatableFields.content,
|
|
2385
|
+
// Deep merge metadata if it exists on both
|
|
2386
|
+
...existingMessage.content?.metadata && updatableFields.content.metadata ? {
|
|
2387
|
+
metadata: {
|
|
2388
|
+
...existingMessage.content.metadata,
|
|
2389
|
+
...updatableFields.content.metadata
|
|
2390
|
+
}
|
|
2391
|
+
} : {}
|
|
2392
|
+
};
|
|
2393
|
+
setClauses.push(`content = $${paramIndex++}`);
|
|
2394
|
+
values.push(newContent);
|
|
2395
|
+
delete updatableFields.content;
|
|
2396
|
+
}
|
|
2397
|
+
for (const key in updatableFields) {
|
|
2398
|
+
if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
|
|
2399
|
+
const dbColumn = columnMapping[key] || key;
|
|
2400
|
+
setClauses.push(`"${dbColumn}" = $${paramIndex++}`);
|
|
2401
|
+
values.push(updatableFields[key]);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
if (setClauses.length > 0) {
|
|
2405
|
+
values.push(id);
|
|
2406
|
+
const sql = `UPDATE ${this.getTableName(
|
|
2407
|
+
storage.TABLE_MESSAGES
|
|
2408
|
+
)} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`;
|
|
2409
|
+
queries.push(t.none(sql, values));
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
if (threadIdsToUpdate.size > 0) {
|
|
2413
|
+
queries.push(
|
|
2414
|
+
t.none(`UPDATE ${this.getTableName(storage.TABLE_THREADS)} SET "updatedAt" = NOW() WHERE id IN ($1:list)`, [
|
|
2415
|
+
Array.from(threadIdsToUpdate)
|
|
2416
|
+
])
|
|
2417
|
+
);
|
|
2418
|
+
}
|
|
2419
|
+
if (queries.length > 0) {
|
|
2420
|
+
await t.batch(queries);
|
|
2421
|
+
}
|
|
2422
|
+
});
|
|
2423
|
+
const updatedMessages = await this.db.manyOrNone(selectQuery, [messageIds]);
|
|
2424
|
+
return (updatedMessages || []).map((message) => {
|
|
2425
|
+
if (typeof message.content === "string") {
|
|
2426
|
+
try {
|
|
2427
|
+
message.content = JSON.parse(message.content);
|
|
2428
|
+
} catch {
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
return message;
|
|
2432
|
+
});
|
|
1871
2433
|
}
|
|
1872
2434
|
};
|
|
1873
2435
|
|