@mastra/pg 0.2.10-alpha.4 → 0.2.10-alpha.5
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 +6 -0
- package/dist/_tsup-dts-rollup.d.cts +17 -1
- package/dist/_tsup-dts-rollup.d.ts +17 -1
- package/dist/index.cjs +154 -39
- package/dist/index.js +154 -39
- package/package.json +1 -1
- package/src/storage/index.test.ts +277 -12
- package/src/storage/index.ts +90 -21
- package/src/vector/index.test.ts +483 -0
- package/src/vector/index.ts +101 -21
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/pg@0.2.10-alpha.
|
|
2
|
+
> @mastra/pg@0.2.10-alpha.5 build /home/runner/work/mastra/mastra/stores/pg
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 10784ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/pg/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 10970ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
21
|
-
[32mCJS[39m ⚡️ Build success in
|
|
22
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
23
|
-
[32mESM[39m ⚡️ Build success in
|
|
20
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m46.10 KB[39m
|
|
21
|
+
[32mCJS[39m ⚡️ Build success in 1339ms
|
|
22
|
+
[32mESM[39m [1mdist/index.js [22m[32m45.68 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 1339ms
|
package/CHANGELOG.md
CHANGED
|
@@ -203,10 +203,18 @@ declare class PgVector extends MastraVector {
|
|
|
203
203
|
private describeIndexCache;
|
|
204
204
|
private createdIndexes;
|
|
205
205
|
private mutexesByName;
|
|
206
|
+
private schema?;
|
|
207
|
+
private setupSchemaPromise;
|
|
206
208
|
private installVectorExtensionPromise;
|
|
207
209
|
private vectorExtensionInstalled;
|
|
210
|
+
private schemaSetupComplete;
|
|
208
211
|
constructor(connectionString: string);
|
|
212
|
+
constructor(config: {
|
|
213
|
+
connectionString: string;
|
|
214
|
+
schemaName?: string;
|
|
215
|
+
});
|
|
209
216
|
private getMutexByName;
|
|
217
|
+
private getTableName;
|
|
210
218
|
transformFilter(filter?: VectorFilter): VectorFilter;
|
|
211
219
|
getIndexInfo(indexName: string): Promise<PGIndexStats>;
|
|
212
220
|
query(...args: ParamsToArgs<PgQueryVectorParams> | PgQueryVectorArgs): Promise<QueryResult[]>;
|
|
@@ -214,6 +222,7 @@ declare class PgVector extends MastraVector {
|
|
|
214
222
|
private hasher;
|
|
215
223
|
private getIndexCacheKey;
|
|
216
224
|
private cachedIndexExists;
|
|
225
|
+
private setupSchema;
|
|
217
226
|
createIndex(...args: ParamsToArgs<PgCreateIndexParams> | PgCreateIndexArgs): Promise<void>;
|
|
218
227
|
/**
|
|
219
228
|
* @deprecated This function is deprecated. Use buildIndex instead
|
|
@@ -237,6 +246,8 @@ export { PgVector }
|
|
|
237
246
|
export { PgVector as PgVector_alias_1 }
|
|
238
247
|
|
|
239
248
|
declare type PostgresConfig = {
|
|
249
|
+
schema?: string;
|
|
250
|
+
} & ({
|
|
240
251
|
host: string;
|
|
241
252
|
port: number;
|
|
242
253
|
database: string;
|
|
@@ -245,14 +256,18 @@ declare type PostgresConfig = {
|
|
|
245
256
|
ssl?: boolean | ISSLConfig;
|
|
246
257
|
} | {
|
|
247
258
|
connectionString: string;
|
|
248
|
-
};
|
|
259
|
+
});
|
|
249
260
|
export { PostgresConfig }
|
|
250
261
|
export { PostgresConfig as PostgresConfig_alias_1 }
|
|
251
262
|
|
|
252
263
|
declare class PostgresStore extends MastraStorage {
|
|
253
264
|
private db;
|
|
254
265
|
private pgp;
|
|
266
|
+
private schema?;
|
|
267
|
+
private setupSchemaPromise;
|
|
268
|
+
private schemaSetupComplete;
|
|
255
269
|
constructor(config: PostgresConfig);
|
|
270
|
+
private getTableName;
|
|
256
271
|
getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
|
|
257
272
|
private transformEvalRow;
|
|
258
273
|
batchInsert({ tableName, records }: {
|
|
@@ -267,6 +282,7 @@ declare class PostgresStore extends MastraStorage {
|
|
|
267
282
|
attributes?: Record<string, string>;
|
|
268
283
|
filters?: Record<string, any>;
|
|
269
284
|
}): Promise<any[]>;
|
|
285
|
+
private setupSchema;
|
|
270
286
|
createTable({ tableName, schema, }: {
|
|
271
287
|
tableName: TABLE_NAMES;
|
|
272
288
|
schema: Record<string, StorageColumn>;
|
|
@@ -203,10 +203,18 @@ declare class PgVector extends MastraVector {
|
|
|
203
203
|
private describeIndexCache;
|
|
204
204
|
private createdIndexes;
|
|
205
205
|
private mutexesByName;
|
|
206
|
+
private schema?;
|
|
207
|
+
private setupSchemaPromise;
|
|
206
208
|
private installVectorExtensionPromise;
|
|
207
209
|
private vectorExtensionInstalled;
|
|
210
|
+
private schemaSetupComplete;
|
|
208
211
|
constructor(connectionString: string);
|
|
212
|
+
constructor(config: {
|
|
213
|
+
connectionString: string;
|
|
214
|
+
schemaName?: string;
|
|
215
|
+
});
|
|
209
216
|
private getMutexByName;
|
|
217
|
+
private getTableName;
|
|
210
218
|
transformFilter(filter?: VectorFilter): VectorFilter;
|
|
211
219
|
getIndexInfo(indexName: string): Promise<PGIndexStats>;
|
|
212
220
|
query(...args: ParamsToArgs<PgQueryVectorParams> | PgQueryVectorArgs): Promise<QueryResult[]>;
|
|
@@ -214,6 +222,7 @@ declare class PgVector extends MastraVector {
|
|
|
214
222
|
private hasher;
|
|
215
223
|
private getIndexCacheKey;
|
|
216
224
|
private cachedIndexExists;
|
|
225
|
+
private setupSchema;
|
|
217
226
|
createIndex(...args: ParamsToArgs<PgCreateIndexParams> | PgCreateIndexArgs): Promise<void>;
|
|
218
227
|
/**
|
|
219
228
|
* @deprecated This function is deprecated. Use buildIndex instead
|
|
@@ -237,6 +246,8 @@ export { PgVector }
|
|
|
237
246
|
export { PgVector as PgVector_alias_1 }
|
|
238
247
|
|
|
239
248
|
declare type PostgresConfig = {
|
|
249
|
+
schema?: string;
|
|
250
|
+
} & ({
|
|
240
251
|
host: string;
|
|
241
252
|
port: number;
|
|
242
253
|
database: string;
|
|
@@ -245,14 +256,18 @@ declare type PostgresConfig = {
|
|
|
245
256
|
ssl?: boolean | ISSLConfig;
|
|
246
257
|
} | {
|
|
247
258
|
connectionString: string;
|
|
248
|
-
};
|
|
259
|
+
});
|
|
249
260
|
export { PostgresConfig }
|
|
250
261
|
export { PostgresConfig as PostgresConfig_alias_1 }
|
|
251
262
|
|
|
252
263
|
declare class PostgresStore extends MastraStorage {
|
|
253
264
|
private db;
|
|
254
265
|
private pgp;
|
|
266
|
+
private schema?;
|
|
267
|
+
private setupSchemaPromise;
|
|
268
|
+
private schemaSetupComplete;
|
|
255
269
|
constructor(config: PostgresConfig);
|
|
270
|
+
private getTableName;
|
|
256
271
|
getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
|
|
257
272
|
private transformEvalRow;
|
|
258
273
|
batchInsert({ tableName, records }: {
|
|
@@ -267,6 +282,7 @@ declare class PostgresStore extends MastraStorage {
|
|
|
267
282
|
attributes?: Record<string, string>;
|
|
268
283
|
filters?: Record<string, any>;
|
|
269
284
|
}): Promise<any[]>;
|
|
285
|
+
private setupSchema;
|
|
270
286
|
createTable({ tableName, schema, }: {
|
|
271
287
|
tableName: TABLE_NAMES;
|
|
272
288
|
schema: Record<string, StorageColumn>;
|
package/dist/index.cjs
CHANGED
|
@@ -299,10 +299,15 @@ var PgVector = class extends vector.MastraVector {
|
|
|
299
299
|
describeIndexCache = /* @__PURE__ */ new Map();
|
|
300
300
|
createdIndexes = /* @__PURE__ */ new Map();
|
|
301
301
|
mutexesByName = /* @__PURE__ */ new Map();
|
|
302
|
+
schema;
|
|
303
|
+
setupSchemaPromise = null;
|
|
302
304
|
installVectorExtensionPromise = null;
|
|
303
305
|
vectorExtensionInstalled = void 0;
|
|
304
|
-
|
|
306
|
+
schemaSetupComplete = void 0;
|
|
307
|
+
constructor(config) {
|
|
305
308
|
super();
|
|
309
|
+
const connectionString = typeof config === "string" ? config : config.connectionString;
|
|
310
|
+
this.schema = typeof config === "string" ? void 0 : config.schemaName;
|
|
306
311
|
const basePool = new pg__default.default.Pool({
|
|
307
312
|
connectionString,
|
|
308
313
|
max: 20,
|
|
@@ -337,6 +342,9 @@ var PgVector = class extends vector.MastraVector {
|
|
|
337
342
|
if (!this.mutexesByName.has(indexName)) this.mutexesByName.set(indexName, new asyncMutex.Mutex());
|
|
338
343
|
return this.mutexesByName.get(indexName);
|
|
339
344
|
}
|
|
345
|
+
getTableName(indexName) {
|
|
346
|
+
return this.schema ? `${this.schema}.${indexName}` : indexName;
|
|
347
|
+
}
|
|
340
348
|
transformFilter(filter) {
|
|
341
349
|
const translator = new PGFilterTranslator();
|
|
342
350
|
return translator.translate(filter);
|
|
@@ -368,6 +376,7 @@ var PgVector = class extends vector.MastraVector {
|
|
|
368
376
|
if (indexInfo.type === "ivfflat" && probes) {
|
|
369
377
|
await client.query(`SET LOCAL ivfflat.probes = ${probes}`);
|
|
370
378
|
}
|
|
379
|
+
const tableName = this.getTableName(indexName);
|
|
371
380
|
const query = `
|
|
372
381
|
WITH vector_scores AS (
|
|
373
382
|
SELECT
|
|
@@ -375,7 +384,7 @@ var PgVector = class extends vector.MastraVector {
|
|
|
375
384
|
1 - (embedding <=> '${vectorStr}'::vector) as score,
|
|
376
385
|
metadata
|
|
377
386
|
${includeVector ? ", embedding" : ""}
|
|
378
|
-
FROM ${
|
|
387
|
+
FROM ${tableName}
|
|
379
388
|
${filterQuery}
|
|
380
389
|
)
|
|
381
390
|
SELECT *
|
|
@@ -397,13 +406,14 @@ var PgVector = class extends vector.MastraVector {
|
|
|
397
406
|
async upsert(...args) {
|
|
398
407
|
const params = this.normalizeArgs("upsert", args);
|
|
399
408
|
const { indexName, vectors, metadata, ids } = params;
|
|
409
|
+
const tableName = this.getTableName(indexName);
|
|
400
410
|
const client = await this.pool.connect();
|
|
401
411
|
try {
|
|
402
412
|
await client.query("BEGIN");
|
|
403
413
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
404
414
|
for (let i = 0; i < vectors.length; i++) {
|
|
405
415
|
const query = `
|
|
406
|
-
INSERT INTO ${
|
|
416
|
+
INSERT INTO ${tableName} (vector_id, embedding, metadata)
|
|
407
417
|
VALUES ($1, $2::vector, $3::jsonb)
|
|
408
418
|
ON CONFLICT (vector_id)
|
|
409
419
|
DO UPDATE SET
|
|
@@ -440,12 +450,54 @@ var PgVector = class extends vector.MastraVector {
|
|
|
440
450
|
const existingIndexCacheKey = this.createdIndexes.get(indexName);
|
|
441
451
|
return existingIndexCacheKey && existingIndexCacheKey === newKey;
|
|
442
452
|
}
|
|
453
|
+
async setupSchema(client) {
|
|
454
|
+
if (!this.schema || this.schemaSetupComplete) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
if (!this.setupSchemaPromise) {
|
|
458
|
+
this.setupSchemaPromise = (async () => {
|
|
459
|
+
try {
|
|
460
|
+
const schemaCheck = await client.query(
|
|
461
|
+
`
|
|
462
|
+
SELECT EXISTS (
|
|
463
|
+
SELECT 1 FROM information_schema.schemata
|
|
464
|
+
WHERE schema_name = $1
|
|
465
|
+
)
|
|
466
|
+
`,
|
|
467
|
+
[this.schema]
|
|
468
|
+
);
|
|
469
|
+
const schemaExists = schemaCheck.rows[0].exists;
|
|
470
|
+
if (!schemaExists) {
|
|
471
|
+
try {
|
|
472
|
+
await client.query(`CREATE SCHEMA IF NOT EXISTS ${this.schema}`);
|
|
473
|
+
this.logger.info(`Schema "${this.schema}" created successfully`);
|
|
474
|
+
} catch (error) {
|
|
475
|
+
this.logger.error(`Failed to create schema "${this.schema}"`, { error });
|
|
476
|
+
throw new Error(
|
|
477
|
+
`Unable to create schema "${this.schema}". This requires CREATE privilege on the database. Either create the schema manually or grant CREATE privilege to the user.`
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
this.schemaSetupComplete = true;
|
|
482
|
+
this.logger.debug(`Schema "${this.schema}" is ready for use`);
|
|
483
|
+
} catch (error) {
|
|
484
|
+
this.schemaSetupComplete = void 0;
|
|
485
|
+
this.setupSchemaPromise = null;
|
|
486
|
+
throw error;
|
|
487
|
+
} finally {
|
|
488
|
+
this.setupSchemaPromise = null;
|
|
489
|
+
}
|
|
490
|
+
})();
|
|
491
|
+
}
|
|
492
|
+
await this.setupSchemaPromise;
|
|
493
|
+
}
|
|
443
494
|
async createIndex(...args) {
|
|
444
495
|
const params = this.normalizeArgs("createIndex", args, [
|
|
445
496
|
"indexConfig",
|
|
446
497
|
"buildIndex"
|
|
447
498
|
]);
|
|
448
499
|
const { indexName, dimension, metric = "cosine", indexConfig = {}, buildIndex = true } = params;
|
|
500
|
+
const tableName = this.getTableName(indexName);
|
|
449
501
|
if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
|
|
450
502
|
throw new Error("Invalid index name format");
|
|
451
503
|
}
|
|
@@ -463,22 +515,22 @@ var PgVector = class extends vector.MastraVector {
|
|
|
463
515
|
}
|
|
464
516
|
const client = await this.pool.connect();
|
|
465
517
|
try {
|
|
518
|
+
await this.setupSchema(client);
|
|
466
519
|
await this.installVectorExtension(client);
|
|
467
520
|
await client.query(`
|
|
468
|
-
CREATE TABLE IF NOT EXISTS ${
|
|
521
|
+
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
469
522
|
id SERIAL PRIMARY KEY,
|
|
470
523
|
vector_id TEXT UNIQUE NOT NULL,
|
|
471
524
|
embedding vector(${dimension}),
|
|
472
525
|
metadata JSONB DEFAULT '{}'::jsonb
|
|
473
526
|
);
|
|
474
|
-
|
|
527
|
+
`);
|
|
475
528
|
this.createdIndexes.set(indexName, indexCacheKey);
|
|
476
529
|
if (buildIndex) {
|
|
477
530
|
await this.setupIndex({ indexName, metric, indexConfig }, client);
|
|
478
531
|
}
|
|
479
532
|
} catch (error) {
|
|
480
533
|
this.createdIndexes.delete(indexName);
|
|
481
|
-
console.error("Failed to create vector table:", error);
|
|
482
534
|
throw error;
|
|
483
535
|
} finally {
|
|
484
536
|
client.release();
|
|
@@ -507,8 +559,9 @@ var PgVector = class extends vector.MastraVector {
|
|
|
507
559
|
async setupIndex({ indexName, metric, indexConfig }, client) {
|
|
508
560
|
const mutex = this.getMutexByName(`build-${indexName}`);
|
|
509
561
|
await mutex.runExclusive(async () => {
|
|
562
|
+
const tableName = this.getTableName(indexName);
|
|
510
563
|
if (this.createdIndexes.has(indexName)) {
|
|
511
|
-
await client.query(`DROP INDEX IF EXISTS ${
|
|
564
|
+
await client.query(`DROP INDEX IF EXISTS ${tableName}_vector_idx`);
|
|
512
565
|
}
|
|
513
566
|
if (indexConfig.type === "flat") {
|
|
514
567
|
this.describeIndexCache.delete(indexName);
|
|
@@ -521,7 +574,7 @@ var PgVector = class extends vector.MastraVector {
|
|
|
521
574
|
const efConstruction = indexConfig.hnsw?.efConstruction ?? 32;
|
|
522
575
|
indexSQL = `
|
|
523
576
|
CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
|
|
524
|
-
ON ${
|
|
577
|
+
ON ${tableName}
|
|
525
578
|
USING hnsw (embedding ${metricOp})
|
|
526
579
|
WITH (
|
|
527
580
|
m = ${m},
|
|
@@ -533,12 +586,12 @@ var PgVector = class extends vector.MastraVector {
|
|
|
533
586
|
if (indexConfig.ivf?.lists) {
|
|
534
587
|
lists = indexConfig.ivf.lists;
|
|
535
588
|
} else {
|
|
536
|
-
const size = (await client.query(`SELECT COUNT(*) FROM ${
|
|
589
|
+
const size = (await client.query(`SELECT COUNT(*) FROM ${tableName}`)).rows[0].count;
|
|
537
590
|
lists = Math.max(100, Math.min(4e3, Math.floor(Math.sqrt(size) * 2)));
|
|
538
591
|
}
|
|
539
592
|
indexSQL = `
|
|
540
593
|
CREATE INDEX IF NOT EXISTS ${indexName}_vector_idx
|
|
541
|
-
ON ${
|
|
594
|
+
ON ${tableName}
|
|
542
595
|
USING ivfflat (embedding ${metricOp})
|
|
543
596
|
WITH (lists = ${lists});
|
|
544
597
|
`;
|
|
@@ -590,10 +643,10 @@ var PgVector = class extends vector.MastraVector {
|
|
|
590
643
|
const vectorTablesQuery = `
|
|
591
644
|
SELECT DISTINCT table_name
|
|
592
645
|
FROM information_schema.columns
|
|
593
|
-
WHERE table_schema =
|
|
646
|
+
WHERE table_schema = $1
|
|
594
647
|
AND udt_name = 'vector';
|
|
595
648
|
`;
|
|
596
|
-
const vectorTables = await client.query(vectorTablesQuery);
|
|
649
|
+
const vectorTables = await client.query(vectorTablesQuery, [this.schema || "public"]);
|
|
597
650
|
return vectorTables.rows.map((row) => row.table_name);
|
|
598
651
|
} finally {
|
|
599
652
|
client.release();
|
|
@@ -602,14 +655,16 @@ var PgVector = class extends vector.MastraVector {
|
|
|
602
655
|
async describeIndex(indexName) {
|
|
603
656
|
const client = await this.pool.connect();
|
|
604
657
|
try {
|
|
658
|
+
const tableName = this.getTableName(indexName);
|
|
605
659
|
const dimensionQuery = `
|
|
606
660
|
SELECT atttypmod as dimension
|
|
607
661
|
FROM pg_attribute
|
|
608
662
|
WHERE attrelid = $1::regclass
|
|
609
663
|
AND attname = 'embedding';
|
|
610
664
|
`;
|
|
611
|
-
const countQuery = `
|
|
612
|
-
|
|
665
|
+
const countQuery = `
|
|
666
|
+
SELECT COUNT(*) as count
|
|
667
|
+
FROM ${tableName};
|
|
613
668
|
`;
|
|
614
669
|
const indexQuery = `
|
|
615
670
|
SELECT
|
|
@@ -620,10 +675,10 @@ var PgVector = class extends vector.MastraVector {
|
|
|
620
675
|
JOIN pg_class c ON i.indexrelid = c.oid
|
|
621
676
|
JOIN pg_am am ON c.relam = am.oid
|
|
622
677
|
JOIN pg_opclass opclass ON i.indclass[0] = opclass.oid
|
|
623
|
-
WHERE c.relname = '${
|
|
678
|
+
WHERE c.relname = '${tableName}_vector_idx';
|
|
624
679
|
`;
|
|
625
680
|
const [dimResult, countResult, indexResult] = await Promise.all([
|
|
626
|
-
client.query(dimensionQuery, [
|
|
681
|
+
client.query(dimensionQuery, [tableName]),
|
|
627
682
|
client.query(countQuery),
|
|
628
683
|
client.query(indexQuery)
|
|
629
684
|
]);
|
|
@@ -660,7 +715,8 @@ var PgVector = class extends vector.MastraVector {
|
|
|
660
715
|
async deleteIndex(indexName) {
|
|
661
716
|
const client = await this.pool.connect();
|
|
662
717
|
try {
|
|
663
|
-
|
|
718
|
+
const tableName = this.getTableName(indexName);
|
|
719
|
+
await client.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`);
|
|
664
720
|
this.createdIndexes.delete(indexName);
|
|
665
721
|
} catch (error) {
|
|
666
722
|
await client.query("ROLLBACK");
|
|
@@ -672,7 +728,8 @@ var PgVector = class extends vector.MastraVector {
|
|
|
672
728
|
async truncateIndex(indexName) {
|
|
673
729
|
const client = await this.pool.connect();
|
|
674
730
|
try {
|
|
675
|
-
|
|
731
|
+
const tableName = this.getTableName(indexName);
|
|
732
|
+
await client.query(`TRUNCATE ${tableName}`);
|
|
676
733
|
} catch (e) {
|
|
677
734
|
await client.query("ROLLBACK");
|
|
678
735
|
throw new Error(`Failed to truncate vector table: ${e.message}`);
|
|
@@ -704,8 +761,9 @@ var PgVector = class extends vector.MastraVector {
|
|
|
704
761
|
if (updateParts.length === 0) {
|
|
705
762
|
return;
|
|
706
763
|
}
|
|
764
|
+
const tableName = this.getTableName(indexName);
|
|
707
765
|
const query = `
|
|
708
|
-
UPDATE ${
|
|
766
|
+
UPDATE ${tableName}
|
|
709
767
|
SET ${updateParts.join(", ")}
|
|
710
768
|
WHERE vector_id = $1
|
|
711
769
|
`;
|
|
@@ -717,8 +775,9 @@ var PgVector = class extends vector.MastraVector {
|
|
|
717
775
|
async deleteIndexById(indexName, id) {
|
|
718
776
|
const client = await this.pool.connect();
|
|
719
777
|
try {
|
|
778
|
+
const tableName = this.getTableName(indexName);
|
|
720
779
|
const query = `
|
|
721
|
-
DELETE FROM ${
|
|
780
|
+
DELETE FROM ${tableName}
|
|
722
781
|
WHERE vector_id = $1
|
|
723
782
|
`;
|
|
724
783
|
await client.query(query, [id]);
|
|
@@ -730,9 +789,13 @@ var PgVector = class extends vector.MastraVector {
|
|
|
730
789
|
var PostgresStore = class extends storage.MastraStorage {
|
|
731
790
|
db;
|
|
732
791
|
pgp;
|
|
792
|
+
schema;
|
|
793
|
+
setupSchemaPromise = null;
|
|
794
|
+
schemaSetupComplete = void 0;
|
|
733
795
|
constructor(config) {
|
|
734
796
|
super({ name: "PostgresStore" });
|
|
735
797
|
this.pgp = pgPromise__default.default();
|
|
798
|
+
this.schema = config.schema;
|
|
736
799
|
this.db = this.pgp(
|
|
737
800
|
`connectionString` in config ? { connectionString: config.connectionString } : {
|
|
738
801
|
host: config.host,
|
|
@@ -744,9 +807,12 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
744
807
|
}
|
|
745
808
|
);
|
|
746
809
|
}
|
|
810
|
+
getTableName(indexName) {
|
|
811
|
+
return this.schema ? `${this.schema}."${indexName}"` : `"${indexName}"`;
|
|
812
|
+
}
|
|
747
813
|
async getEvalsByAgentName(agentName, type) {
|
|
748
814
|
try {
|
|
749
|
-
const baseQuery = `SELECT * FROM ${storage.TABLE_EVALS} WHERE agent_name = $1`;
|
|
815
|
+
const baseQuery = `SELECT * FROM ${this.getTableName(storage.TABLE_EVALS)} WHERE agent_name = $1`;
|
|
750
816
|
const typeCondition = type === "test" ? " AND test_info IS NOT NULL AND test_info->>'testPath' IS NOT NULL" : type === "live" ? " AND (test_info IS NULL OR test_info->>'testPath' IS NULL)" : "";
|
|
751
817
|
const query = `${baseQuery}${typeCondition} ORDER BY created_at DESC`;
|
|
752
818
|
const rows = await this.db.manyOrNone(query, [agentName]);
|
|
@@ -840,7 +906,10 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
840
906
|
args.push(value);
|
|
841
907
|
}
|
|
842
908
|
}
|
|
843
|
-
const result = await this.db.manyOrNone(
|
|
909
|
+
const result = await this.db.manyOrNone(
|
|
910
|
+
`SELECT * FROM ${this.getTableName(storage.TABLE_TRACES)} ${whereClause} ORDER BY "createdAt" DESC LIMIT ${limit} OFFSET ${offset}`,
|
|
911
|
+
args
|
|
912
|
+
);
|
|
844
913
|
if (!result) {
|
|
845
914
|
return [];
|
|
846
915
|
}
|
|
@@ -861,6 +930,46 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
861
930
|
createdAt: row.createdAt
|
|
862
931
|
}));
|
|
863
932
|
}
|
|
933
|
+
async setupSchema() {
|
|
934
|
+
if (!this.schema || this.schemaSetupComplete) {
|
|
935
|
+
return;
|
|
936
|
+
}
|
|
937
|
+
if (!this.setupSchemaPromise) {
|
|
938
|
+
this.setupSchemaPromise = (async () => {
|
|
939
|
+
try {
|
|
940
|
+
const schemaExists = await this.db.oneOrNone(
|
|
941
|
+
`
|
|
942
|
+
SELECT EXISTS (
|
|
943
|
+
SELECT 1 FROM information_schema.schemata
|
|
944
|
+
WHERE schema_name = $1
|
|
945
|
+
)
|
|
946
|
+
`,
|
|
947
|
+
[this.schema]
|
|
948
|
+
);
|
|
949
|
+
if (!schemaExists?.exists) {
|
|
950
|
+
try {
|
|
951
|
+
await this.db.none(`CREATE SCHEMA IF NOT EXISTS ${this.schema}`);
|
|
952
|
+
this.logger.info(`Schema "${this.schema}" created successfully`);
|
|
953
|
+
} catch (error) {
|
|
954
|
+
this.logger.error(`Failed to create schema "${this.schema}"`, { error });
|
|
955
|
+
throw new Error(
|
|
956
|
+
`Unable to create schema "${this.schema}". This requires CREATE privilege on the database. Either create the schema manually or grant CREATE privilege to the user.`
|
|
957
|
+
);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
this.schemaSetupComplete = true;
|
|
961
|
+
this.logger.debug(`Schema "${this.schema}" is ready for use`);
|
|
962
|
+
} catch (error) {
|
|
963
|
+
this.schemaSetupComplete = void 0;
|
|
964
|
+
this.setupSchemaPromise = null;
|
|
965
|
+
throw error;
|
|
966
|
+
} finally {
|
|
967
|
+
this.setupSchemaPromise = null;
|
|
968
|
+
}
|
|
969
|
+
})();
|
|
970
|
+
}
|
|
971
|
+
await this.setupSchemaPromise;
|
|
972
|
+
}
|
|
864
973
|
async createTable({
|
|
865
974
|
tableName,
|
|
866
975
|
schema
|
|
@@ -872,8 +981,11 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
872
981
|
if (!def.nullable) constraints.push("NOT NULL");
|
|
873
982
|
return `"${name}" ${def.type.toUpperCase()} ${constraints.join(" ")}`;
|
|
874
983
|
}).join(",\n");
|
|
984
|
+
if (this.schema) {
|
|
985
|
+
await this.setupSchema();
|
|
986
|
+
}
|
|
875
987
|
const sql = `
|
|
876
|
-
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
988
|
+
CREATE TABLE IF NOT EXISTS ${this.getTableName(tableName)} (
|
|
877
989
|
${columns}
|
|
878
990
|
);
|
|
879
991
|
${tableName === storage.TABLE_WORKFLOW_SNAPSHOT ? `
|
|
@@ -881,7 +993,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
881
993
|
IF NOT EXISTS (
|
|
882
994
|
SELECT 1 FROM pg_constraint WHERE conname = 'mastra_workflow_snapshot_workflow_name_run_id_key'
|
|
883
995
|
) THEN
|
|
884
|
-
ALTER TABLE ${tableName}
|
|
996
|
+
ALTER TABLE ${this.getTableName(tableName)}
|
|
885
997
|
ADD CONSTRAINT mastra_workflow_snapshot_workflow_name_run_id_key
|
|
886
998
|
UNIQUE (workflow_name, run_id);
|
|
887
999
|
END IF;
|
|
@@ -896,7 +1008,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
896
1008
|
}
|
|
897
1009
|
async clearTable({ tableName }) {
|
|
898
1010
|
try {
|
|
899
|
-
await this.db.none(`TRUNCATE TABLE ${tableName} CASCADE`);
|
|
1011
|
+
await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
|
|
900
1012
|
} catch (error) {
|
|
901
1013
|
console.error(`Error clearing table ${tableName}:`, error);
|
|
902
1014
|
throw error;
|
|
@@ -908,7 +1020,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
908
1020
|
const values = Object.values(record);
|
|
909
1021
|
const placeholders = values.map((_, i) => `$${i + 1}`).join(", ");
|
|
910
1022
|
await this.db.none(
|
|
911
|
-
`INSERT INTO ${tableName} (${columns.map((c) => `"${c}"`).join(", ")}) VALUES (${placeholders})`,
|
|
1023
|
+
`INSERT INTO ${this.getTableName(tableName)} (${columns.map((c) => `"${c}"`).join(", ")}) VALUES (${placeholders})`,
|
|
912
1024
|
values
|
|
913
1025
|
);
|
|
914
1026
|
} catch (error) {
|
|
@@ -921,7 +1033,10 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
921
1033
|
const keyEntries = Object.entries(keys);
|
|
922
1034
|
const conditions = keyEntries.map(([key], index) => `"${key}" = $${index + 1}`).join(" AND ");
|
|
923
1035
|
const values = keyEntries.map(([_, value]) => value);
|
|
924
|
-
const result = await this.db.oneOrNone(
|
|
1036
|
+
const result = await this.db.oneOrNone(
|
|
1037
|
+
`SELECT * FROM ${this.getTableName(tableName)} WHERE ${conditions}`,
|
|
1038
|
+
values
|
|
1039
|
+
);
|
|
925
1040
|
if (!result) {
|
|
926
1041
|
return null;
|
|
927
1042
|
}
|
|
@@ -948,7 +1063,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
948
1063
|
metadata,
|
|
949
1064
|
"createdAt",
|
|
950
1065
|
"updatedAt"
|
|
951
|
-
FROM
|
|
1066
|
+
FROM ${this.getTableName(storage.TABLE_THREADS)}
|
|
952
1067
|
WHERE id = $1`,
|
|
953
1068
|
[threadId]
|
|
954
1069
|
);
|
|
@@ -976,7 +1091,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
976
1091
|
metadata,
|
|
977
1092
|
"createdAt",
|
|
978
1093
|
"updatedAt"
|
|
979
|
-
FROM
|
|
1094
|
+
FROM ${this.getTableName(storage.TABLE_THREADS)}
|
|
980
1095
|
WHERE "resourceId" = $1`,
|
|
981
1096
|
[resourceId]
|
|
982
1097
|
);
|
|
@@ -994,7 +1109,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
994
1109
|
async saveThread({ thread }) {
|
|
995
1110
|
try {
|
|
996
1111
|
await this.db.none(
|
|
997
|
-
`INSERT INTO
|
|
1112
|
+
`INSERT INTO ${this.getTableName(storage.TABLE_THREADS)} (
|
|
998
1113
|
id,
|
|
999
1114
|
"resourceId",
|
|
1000
1115
|
title,
|
|
@@ -1038,7 +1153,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1038
1153
|
...metadata
|
|
1039
1154
|
};
|
|
1040
1155
|
const thread = await this.db.one(
|
|
1041
|
-
`UPDATE
|
|
1156
|
+
`UPDATE ${this.getTableName(storage.TABLE_THREADS)}
|
|
1042
1157
|
SET title = $1,
|
|
1043
1158
|
metadata = $2,
|
|
1044
1159
|
"updatedAt" = $3
|
|
@@ -1060,8 +1175,8 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1060
1175
|
async deleteThread({ threadId }) {
|
|
1061
1176
|
try {
|
|
1062
1177
|
await this.db.tx(async (t) => {
|
|
1063
|
-
await t.none(`DELETE FROM
|
|
1064
|
-
await t.none(`DELETE FROM
|
|
1178
|
+
await t.none(`DELETE FROM ${this.getTableName(storage.TABLE_MESSAGES)} WHERE thread_id = $1`, [threadId]);
|
|
1179
|
+
await t.none(`DELETE FROM ${this.getTableName(storage.TABLE_THREADS)} WHERE id = $1`, [threadId]);
|
|
1065
1180
|
});
|
|
1066
1181
|
} catch (error) {
|
|
1067
1182
|
console.error("Error deleting thread:", error);
|
|
@@ -1080,7 +1195,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1080
1195
|
SELECT
|
|
1081
1196
|
*,
|
|
1082
1197
|
ROW_NUMBER() OVER (ORDER BY "createdAt" DESC) as row_num
|
|
1083
|
-
FROM
|
|
1198
|
+
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
1084
1199
|
WHERE thread_id = $1
|
|
1085
1200
|
)
|
|
1086
1201
|
SELECT
|
|
@@ -1123,7 +1238,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1123
1238
|
type,
|
|
1124
1239
|
"createdAt",
|
|
1125
1240
|
thread_id AS "threadId"
|
|
1126
|
-
FROM
|
|
1241
|
+
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
1127
1242
|
WHERE thread_id = $1
|
|
1128
1243
|
AND id != ALL($2)
|
|
1129
1244
|
ORDER BY "createdAt" DESC
|
|
@@ -1161,7 +1276,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1161
1276
|
await this.db.tx(async (t) => {
|
|
1162
1277
|
for (const message of messages) {
|
|
1163
1278
|
await t.none(
|
|
1164
|
-
`INSERT INTO
|
|
1279
|
+
`INSERT INTO ${this.getTableName(storage.TABLE_MESSAGES)} (id, thread_id, content, "createdAt", role, type)
|
|
1165
1280
|
VALUES ($1, $2, $3, $4, $5, $6)`,
|
|
1166
1281
|
[
|
|
1167
1282
|
message.id,
|
|
@@ -1188,7 +1303,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1188
1303
|
try {
|
|
1189
1304
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1190
1305
|
await this.db.none(
|
|
1191
|
-
`INSERT INTO
|
|
1306
|
+
`INSERT INTO ${this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT)} (
|
|
1192
1307
|
workflow_name,
|
|
1193
1308
|
run_id,
|
|
1194
1309
|
snapshot,
|
|
@@ -1255,13 +1370,13 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1255
1370
|
let total = 0;
|
|
1256
1371
|
if (limit !== void 0 && offset !== void 0) {
|
|
1257
1372
|
const countResult = await this.db.one(
|
|
1258
|
-
`SELECT COUNT(*) as count FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
|
|
1373
|
+
`SELECT COUNT(*) as count FROM ${this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT)} ${whereClause}`,
|
|
1259
1374
|
values
|
|
1260
1375
|
);
|
|
1261
1376
|
total = Number(countResult.count);
|
|
1262
1377
|
}
|
|
1263
1378
|
const query = `
|
|
1264
|
-
SELECT * FROM ${storage.TABLE_WORKFLOW_SNAPSHOT}
|
|
1379
|
+
SELECT * FROM ${this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT)}
|
|
1265
1380
|
${whereClause}
|
|
1266
1381
|
ORDER BY "createdAt" DESC
|
|
1267
1382
|
${limit !== void 0 && offset !== void 0 ? ` LIMIT $${paramIndex} OFFSET $${paramIndex + 1}` : ""}
|