@mastra/pg 0.1.6-alpha.1 → 0.1.6-alpha.4
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 +11 -6
- package/CHANGELOG.md +32 -0
- package/README.md +22 -17
- package/dist/_tsup-dts-rollup.d.cts +329 -0
- package/dist/_tsup-dts-rollup.d.ts +45 -20
- package/dist/index.cjs +1050 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.js +24 -17
- package/package.json +7 -3
- package/src/storage/index.ts +2 -2
- package/src/vector/filter.ts +5 -5
- package/src/vector/index.test.ts +696 -314
- package/src/vector/index.ts +62 -42
- package/src/vector/performance.helpers.ts +1 -1
- package/src/vector/sql-builder.ts +10 -6
- package/src/vector/vector.performance.test.ts +14 -17
package/dist/index.d.cts
ADDED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MastraVector } from '@mastra/core/vector';
|
|
2
2
|
import pg from 'pg';
|
|
3
|
-
import { BaseFilterTranslator } from '@mastra/core/filter';
|
|
3
|
+
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
4
4
|
import { MastraStorage } from '@mastra/core/storage';
|
|
5
5
|
import pgPromise from 'pg-promise';
|
|
6
6
|
|
|
@@ -264,7 +264,7 @@ function buildFilterQuery(filter, minScore) {
|
|
|
264
264
|
}
|
|
265
265
|
const joinOperator = key === "$or" || key === "$nor" ? "OR" : "AND";
|
|
266
266
|
const conditions2 = value.map((f) => {
|
|
267
|
-
const entries = Object.entries(f);
|
|
267
|
+
const entries = Object.entries(f || {});
|
|
268
268
|
if (entries.length === 0) return "";
|
|
269
269
|
const [firstKey, firstValue] = entries[0] || [];
|
|
270
270
|
if (["$and", "$or", "$not", "$nor"].includes(firstKey)) {
|
|
@@ -307,9 +307,8 @@ var PgVector = class extends MastraVector {
|
|
|
307
307
|
}) ?? basePool;
|
|
308
308
|
}
|
|
309
309
|
transformFilter(filter) {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
return translatedFilter;
|
|
310
|
+
const translator = new PGFilterTranslator();
|
|
311
|
+
return translator.translate(filter);
|
|
313
312
|
}
|
|
314
313
|
async getIndexInfo(indexName) {
|
|
315
314
|
if (!this.indexCache.has(indexName)) {
|
|
@@ -317,7 +316,9 @@ var PgVector = class extends MastraVector {
|
|
|
317
316
|
}
|
|
318
317
|
return this.indexCache.get(indexName);
|
|
319
318
|
}
|
|
320
|
-
async query(
|
|
319
|
+
async query(...args) {
|
|
320
|
+
const params = this.normalizeArgs("query", args, ["minScore", "ef", "probes"]);
|
|
321
|
+
const { indexName, queryVector, topK = 10, filter, includeVector = false, minScore = 0, ef, probes } = params;
|
|
321
322
|
const client = await this.pool.connect();
|
|
322
323
|
try {
|
|
323
324
|
const vectorStr = `[${queryVector.join(",")}]`;
|
|
@@ -325,12 +326,12 @@ var PgVector = class extends MastraVector {
|
|
|
325
326
|
const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter, minScore);
|
|
326
327
|
const indexInfo = await this.getIndexInfo(indexName);
|
|
327
328
|
if (indexInfo.type === "hnsw") {
|
|
328
|
-
const calculatedEf =
|
|
329
|
+
const calculatedEf = ef ?? Math.max(topK, (indexInfo?.config?.m ?? 16) * topK);
|
|
329
330
|
const searchEf = Math.min(1e3, Math.max(1, calculatedEf));
|
|
330
331
|
await client.query(`SET LOCAL hnsw.ef_search = ${searchEf}`);
|
|
331
332
|
}
|
|
332
|
-
if (indexInfo.type === "ivfflat" &&
|
|
333
|
-
await client.query(`SET LOCAL ivfflat.probes = ${
|
|
333
|
+
if (indexInfo.type === "ivfflat" && probes) {
|
|
334
|
+
await client.query(`SET LOCAL ivfflat.probes = ${probes}`);
|
|
334
335
|
}
|
|
335
336
|
const query = `
|
|
336
337
|
WITH vector_scores AS (
|
|
@@ -358,7 +359,9 @@ var PgVector = class extends MastraVector {
|
|
|
358
359
|
client.release();
|
|
359
360
|
}
|
|
360
361
|
}
|
|
361
|
-
async upsert(
|
|
362
|
+
async upsert(...args) {
|
|
363
|
+
const params = this.normalizeArgs("upsert", args);
|
|
364
|
+
const { indexName, vectors, metadata, ids } = params;
|
|
362
365
|
const client = await this.pool.connect();
|
|
363
366
|
try {
|
|
364
367
|
await client.query("BEGIN");
|
|
@@ -384,7 +387,9 @@ var PgVector = class extends MastraVector {
|
|
|
384
387
|
client.release();
|
|
385
388
|
}
|
|
386
389
|
}
|
|
387
|
-
async createIndex(
|
|
390
|
+
async createIndex(...args) {
|
|
391
|
+
const params = this.normalizeArgs("createIndex", args, ["indexConfig", "buildIndex"]);
|
|
392
|
+
const { indexName, dimension, metric = "cosine", indexConfig = {}, buildIndex = true } = params;
|
|
388
393
|
const client = await this.pool.connect();
|
|
389
394
|
try {
|
|
390
395
|
if (!indexName.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)) {
|
|
@@ -410,8 +415,8 @@ var PgVector = class extends MastraVector {
|
|
|
410
415
|
metadata JSONB DEFAULT '{}'::jsonb
|
|
411
416
|
);
|
|
412
417
|
`);
|
|
413
|
-
if (
|
|
414
|
-
await this.
|
|
418
|
+
if (buildIndex) {
|
|
419
|
+
await this.buildIndex({ indexName, metric, indexConfig });
|
|
415
420
|
}
|
|
416
421
|
} catch (error) {
|
|
417
422
|
console.error("Failed to create vector table:", error);
|
|
@@ -424,9 +429,11 @@ var PgVector = class extends MastraVector {
|
|
|
424
429
|
* @deprecated This function is deprecated. Use buildIndex instead
|
|
425
430
|
*/
|
|
426
431
|
async defineIndex(indexName, metric = "cosine", indexConfig) {
|
|
427
|
-
return this.buildIndex(indexName, metric, indexConfig);
|
|
432
|
+
return this.buildIndex({ indexName, metric, indexConfig });
|
|
428
433
|
}
|
|
429
|
-
async buildIndex(
|
|
434
|
+
async buildIndex(...args) {
|
|
435
|
+
const params = this.normalizeArgs("buildIndex", args, ["metric", "indexConfig"]);
|
|
436
|
+
const { indexName, metric = "cosine", indexConfig } = params;
|
|
430
437
|
const client = await this.pool.connect();
|
|
431
438
|
try {
|
|
432
439
|
await client.query(`DROP INDEX IF EXISTS ${indexName}_vector_idx`);
|
|
@@ -898,10 +905,10 @@ var PostgresStore = class extends MastraStorage {
|
|
|
898
905
|
WHERE target.id = ANY($2)
|
|
899
906
|
AND (
|
|
900
907
|
-- Get previous messages based on the max withPreviousMessages
|
|
901
|
-
(m.row_num
|
|
908
|
+
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
902
909
|
OR
|
|
903
910
|
-- Get next messages based on the max withNextMessages
|
|
904
|
-
(m.row_num
|
|
911
|
+
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
905
912
|
)
|
|
906
913
|
)
|
|
907
914
|
ORDER BY m."createdAt" DESC
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/pg",
|
|
3
|
-
"version": "0.1.6-alpha.
|
|
3
|
+
"version": "0.1.6-alpha.4",
|
|
4
4
|
"description": "Postgres provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"import": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.cts",
|
|
16
|
+
"default": "./dist/index.cjs"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
19
|
"./package.json": "./package.json"
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
"dependencies": {
|
|
18
22
|
"pg": "^8.13.1",
|
|
19
23
|
"pg-promise": "^11.5.4",
|
|
20
|
-
"@mastra/core": "^0.4.3-alpha.
|
|
24
|
+
"@mastra/core": "^0.4.3-alpha.4"
|
|
21
25
|
},
|
|
22
26
|
"devDependencies": {
|
|
23
27
|
"@microsoft/api-extractor": "^7.49.2",
|
|
@@ -30,7 +34,7 @@
|
|
|
30
34
|
"@internal/lint": "0.0.0"
|
|
31
35
|
},
|
|
32
36
|
"scripts": {
|
|
33
|
-
"build": "tsup src/index.ts --format esm --experimental-dts --clean --treeshake",
|
|
37
|
+
"build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake",
|
|
34
38
|
"build:watch": "pnpm build --watch",
|
|
35
39
|
"pretest": "docker compose up -d && (for i in $(seq 1 30); do docker compose exec -T db pg_isready -U postgres && break || (sleep 1; [ $i -eq 30 ] && exit 1); done)",
|
|
36
40
|
"test": "vitest run",
|
package/src/storage/index.ts
CHANGED
|
@@ -429,10 +429,10 @@ export class PostgresStore extends MastraStorage {
|
|
|
429
429
|
WHERE target.id = ANY($2)
|
|
430
430
|
AND (
|
|
431
431
|
-- Get previous messages based on the max withPreviousMessages
|
|
432
|
-
(m.row_num
|
|
432
|
+
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
433
433
|
OR
|
|
434
434
|
-- Get next messages based on the max withNextMessages
|
|
435
|
-
(m.row_num
|
|
435
|
+
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
436
436
|
)
|
|
437
437
|
)
|
|
438
438
|
ORDER BY m."createdAt" DESC
|
package/src/vector/filter.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseFilterTranslator } from '@mastra/core/filter';
|
|
2
|
-
import type { FieldCondition,
|
|
1
|
+
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
2
|
+
import type { FieldCondition, VectorFilter, OperatorSupport } from '@mastra/core/vector/filter';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Translates MongoDB-style filters to PG compatible filters.
|
|
@@ -19,7 +19,7 @@ export class PGFilterTranslator extends BaseFilterTranslator {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
translate(filter
|
|
22
|
+
translate(filter?: VectorFilter): VectorFilter {
|
|
23
23
|
if (this.isEmpty(filter)) {
|
|
24
24
|
return filter;
|
|
25
25
|
}
|
|
@@ -27,7 +27,7 @@ export class PGFilterTranslator extends BaseFilterTranslator {
|
|
|
27
27
|
return this.translateNode(filter);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
private translateNode(node:
|
|
30
|
+
private translateNode(node: VectorFilter | FieldCondition, currentPath: string = ''): any {
|
|
31
31
|
// Helper to wrap result with path if needed
|
|
32
32
|
const withPath = (result: any) => (currentPath ? { [currentPath]: result } : result);
|
|
33
33
|
|
|
@@ -68,7 +68,7 @@ export class PGFilterTranslator extends BaseFilterTranslator {
|
|
|
68
68
|
|
|
69
69
|
if (this.isLogicalOperator(key)) {
|
|
70
70
|
result[key] = Array.isArray(value)
|
|
71
|
-
? value.map((filter:
|
|
71
|
+
? value.map((filter: VectorFilter) => this.translateNode(filter))
|
|
72
72
|
: this.translateNode(value);
|
|
73
73
|
} else if (this.isOperator(key)) {
|
|
74
74
|
if (this.isArrayOperator(key) && !Array.isArray(value) && key !== '$elemMatch') {
|