@mastra/pg 0.15.2 → 0.15.3-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/CHANGELOG.md +18 -0
- package/README.md +123 -0
- package/dist/index.cjs +353 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +354 -17
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/operations/index.d.ts +23 -1
- package/dist/storage/domains/operations/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +2 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +7 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/performance-indexes/performance-test.d.ts +46 -0
- package/dist/storage/performance-indexes/performance-test.d.ts.map +1 -0
- package/dist/storage/test-utils.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Mutex } from 'async-mutex';
|
|
|
5
5
|
import pg from 'pg';
|
|
6
6
|
import xxhash from 'xxhash-wasm';
|
|
7
7
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
8
|
-
import { MastraStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, ScoresStorage, TABLE_SCORERS, TracesStorage, safelyParseJSON,
|
|
8
|
+
import { MastraStorage, StoreOperations, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_EVALS, ScoresStorage, TABLE_SCORERS, TracesStorage, safelyParseJSON, WorkflowsStorage, LegacyEvalsStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES } from '@mastra/core/storage';
|
|
9
9
|
import pgPromise from 'pg-promise';
|
|
10
10
|
import { MessageList } from '@mastra/core/agent';
|
|
11
11
|
|
|
@@ -2366,6 +2366,303 @@ var StoreOperationsPG = class extends StoreOperations {
|
|
|
2366
2366
|
);
|
|
2367
2367
|
}
|
|
2368
2368
|
}
|
|
2369
|
+
/**
|
|
2370
|
+
* Create a new index on a table
|
|
2371
|
+
*/
|
|
2372
|
+
async createIndex(options) {
|
|
2373
|
+
try {
|
|
2374
|
+
const {
|
|
2375
|
+
name,
|
|
2376
|
+
table,
|
|
2377
|
+
columns,
|
|
2378
|
+
unique = false,
|
|
2379
|
+
concurrent = true,
|
|
2380
|
+
where,
|
|
2381
|
+
method = "btree",
|
|
2382
|
+
opclass,
|
|
2383
|
+
storage,
|
|
2384
|
+
tablespace
|
|
2385
|
+
} = options;
|
|
2386
|
+
const schemaName = this.schemaName || "public";
|
|
2387
|
+
const fullTableName = getTableName({
|
|
2388
|
+
indexName: table,
|
|
2389
|
+
schemaName: getSchemaName(this.schemaName)
|
|
2390
|
+
});
|
|
2391
|
+
const indexExists = await this.client.oneOrNone(
|
|
2392
|
+
`SELECT 1 FROM pg_indexes
|
|
2393
|
+
WHERE indexname = $1
|
|
2394
|
+
AND schemaname = $2`,
|
|
2395
|
+
[name, schemaName]
|
|
2396
|
+
);
|
|
2397
|
+
if (indexExists) {
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2400
|
+
const uniqueStr = unique ? "UNIQUE " : "";
|
|
2401
|
+
const concurrentStr = concurrent ? "CONCURRENTLY " : "";
|
|
2402
|
+
const methodStr = method !== "btree" ? `USING ${method} ` : "";
|
|
2403
|
+
const columnsStr = columns.map((col) => {
|
|
2404
|
+
if (col.includes(" DESC") || col.includes(" ASC")) {
|
|
2405
|
+
const [colName, ...modifiers] = col.split(" ");
|
|
2406
|
+
if (!colName) {
|
|
2407
|
+
throw new Error(`Invalid column specification: ${col}`);
|
|
2408
|
+
}
|
|
2409
|
+
const quotedCol2 = `"${parseSqlIdentifier(colName, "column name")}" ${modifiers.join(" ")}`;
|
|
2410
|
+
return opclass ? `${quotedCol2} ${opclass}` : quotedCol2;
|
|
2411
|
+
}
|
|
2412
|
+
const quotedCol = `"${parseSqlIdentifier(col, "column name")}"`;
|
|
2413
|
+
return opclass ? `${quotedCol} ${opclass}` : quotedCol;
|
|
2414
|
+
}).join(", ");
|
|
2415
|
+
const whereStr = where ? ` WHERE ${where}` : "";
|
|
2416
|
+
const tablespaceStr = tablespace ? ` TABLESPACE ${tablespace}` : "";
|
|
2417
|
+
let withStr = "";
|
|
2418
|
+
if (storage && Object.keys(storage).length > 0) {
|
|
2419
|
+
const storageParams = Object.entries(storage).map(([key, value]) => `${key} = ${value}`).join(", ");
|
|
2420
|
+
withStr = ` WITH (${storageParams})`;
|
|
2421
|
+
}
|
|
2422
|
+
const sql = `CREATE ${uniqueStr}INDEX ${concurrentStr}${name} ON ${fullTableName} ${methodStr}(${columnsStr})${withStr}${tablespaceStr}${whereStr}`;
|
|
2423
|
+
await this.client.none(sql);
|
|
2424
|
+
} catch (error) {
|
|
2425
|
+
if (error instanceof Error && error.message.includes("CONCURRENTLY")) {
|
|
2426
|
+
const retryOptions = { ...options, concurrent: false };
|
|
2427
|
+
return this.createIndex(retryOptions);
|
|
2428
|
+
}
|
|
2429
|
+
throw new MastraError(
|
|
2430
|
+
{
|
|
2431
|
+
id: "MASTRA_STORAGE_PG_INDEX_CREATE_FAILED",
|
|
2432
|
+
domain: ErrorDomain.STORAGE,
|
|
2433
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2434
|
+
details: {
|
|
2435
|
+
indexName: options.name,
|
|
2436
|
+
tableName: options.table
|
|
2437
|
+
}
|
|
2438
|
+
},
|
|
2439
|
+
error
|
|
2440
|
+
);
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Drop an existing index
|
|
2445
|
+
*/
|
|
2446
|
+
async dropIndex(indexName) {
|
|
2447
|
+
try {
|
|
2448
|
+
const schemaName = this.schemaName || "public";
|
|
2449
|
+
const indexExists = await this.client.oneOrNone(
|
|
2450
|
+
`SELECT 1 FROM pg_indexes
|
|
2451
|
+
WHERE indexname = $1
|
|
2452
|
+
AND schemaname = $2`,
|
|
2453
|
+
[indexName, schemaName]
|
|
2454
|
+
);
|
|
2455
|
+
if (!indexExists) {
|
|
2456
|
+
return;
|
|
2457
|
+
}
|
|
2458
|
+
const sql = `DROP INDEX IF EXISTS ${getSchemaName(this.schemaName)}.${indexName}`;
|
|
2459
|
+
await this.client.none(sql);
|
|
2460
|
+
} catch (error) {
|
|
2461
|
+
throw new MastraError(
|
|
2462
|
+
{
|
|
2463
|
+
id: "MASTRA_STORAGE_PG_INDEX_DROP_FAILED",
|
|
2464
|
+
domain: ErrorDomain.STORAGE,
|
|
2465
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2466
|
+
details: {
|
|
2467
|
+
indexName
|
|
2468
|
+
}
|
|
2469
|
+
},
|
|
2470
|
+
error
|
|
2471
|
+
);
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
/**
|
|
2475
|
+
* List indexes for a specific table or all tables
|
|
2476
|
+
*/
|
|
2477
|
+
async listIndexes(tableName) {
|
|
2478
|
+
try {
|
|
2479
|
+
const schemaName = this.schemaName || "public";
|
|
2480
|
+
let query;
|
|
2481
|
+
let params;
|
|
2482
|
+
if (tableName) {
|
|
2483
|
+
query = `
|
|
2484
|
+
SELECT
|
|
2485
|
+
i.indexname as name,
|
|
2486
|
+
i.tablename as table,
|
|
2487
|
+
i.indexdef as definition,
|
|
2488
|
+
ix.indisunique as is_unique,
|
|
2489
|
+
pg_size_pretty(pg_relation_size(c.oid)) as size,
|
|
2490
|
+
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns
|
|
2491
|
+
FROM pg_indexes i
|
|
2492
|
+
JOIN pg_class c ON c.relname = i.indexname AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = i.schemaname)
|
|
2493
|
+
JOIN pg_index ix ON ix.indexrelid = c.oid
|
|
2494
|
+
JOIN pg_attribute a ON a.attrelid = ix.indrelid AND a.attnum = ANY(ix.indkey)
|
|
2495
|
+
WHERE i.schemaname = $1
|
|
2496
|
+
AND i.tablename = $2
|
|
2497
|
+
GROUP BY i.indexname, i.tablename, i.indexdef, ix.indisunique, c.oid
|
|
2498
|
+
`;
|
|
2499
|
+
params = [schemaName, tableName];
|
|
2500
|
+
} else {
|
|
2501
|
+
query = `
|
|
2502
|
+
SELECT
|
|
2503
|
+
i.indexname as name,
|
|
2504
|
+
i.tablename as table,
|
|
2505
|
+
i.indexdef as definition,
|
|
2506
|
+
ix.indisunique as is_unique,
|
|
2507
|
+
pg_size_pretty(pg_relation_size(c.oid)) as size,
|
|
2508
|
+
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns
|
|
2509
|
+
FROM pg_indexes i
|
|
2510
|
+
JOIN pg_class c ON c.relname = i.indexname AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = i.schemaname)
|
|
2511
|
+
JOIN pg_index ix ON ix.indexrelid = c.oid
|
|
2512
|
+
JOIN pg_attribute a ON a.attrelid = ix.indrelid AND a.attnum = ANY(ix.indkey)
|
|
2513
|
+
WHERE i.schemaname = $1
|
|
2514
|
+
GROUP BY i.indexname, i.tablename, i.indexdef, ix.indisunique, c.oid
|
|
2515
|
+
`;
|
|
2516
|
+
params = [schemaName];
|
|
2517
|
+
}
|
|
2518
|
+
const results = await this.client.manyOrNone(query, params);
|
|
2519
|
+
return results.map((row) => {
|
|
2520
|
+
let columns = [];
|
|
2521
|
+
if (typeof row.columns === "string" && row.columns.startsWith("{") && row.columns.endsWith("}")) {
|
|
2522
|
+
const arrayContent = row.columns.slice(1, -1);
|
|
2523
|
+
columns = arrayContent ? arrayContent.split(",") : [];
|
|
2524
|
+
} else if (Array.isArray(row.columns)) {
|
|
2525
|
+
columns = row.columns;
|
|
2526
|
+
}
|
|
2527
|
+
return {
|
|
2528
|
+
name: row.name,
|
|
2529
|
+
table: row.table,
|
|
2530
|
+
columns,
|
|
2531
|
+
unique: row.is_unique || false,
|
|
2532
|
+
size: row.size || "0",
|
|
2533
|
+
definition: row.definition || ""
|
|
2534
|
+
};
|
|
2535
|
+
});
|
|
2536
|
+
} catch (error) {
|
|
2537
|
+
throw new MastraError(
|
|
2538
|
+
{
|
|
2539
|
+
id: "MASTRA_STORAGE_PG_INDEX_LIST_FAILED",
|
|
2540
|
+
domain: ErrorDomain.STORAGE,
|
|
2541
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2542
|
+
details: tableName ? {
|
|
2543
|
+
tableName
|
|
2544
|
+
} : {}
|
|
2545
|
+
},
|
|
2546
|
+
error
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* Creates automatic indexes for optimal query performance
|
|
2552
|
+
* These composite indexes cover both filtering and sorting in single index
|
|
2553
|
+
*/
|
|
2554
|
+
async createAutomaticIndexes() {
|
|
2555
|
+
try {
|
|
2556
|
+
const schemaPrefix = this.schemaName ? `${this.schemaName}_` : "";
|
|
2557
|
+
const indexes = [
|
|
2558
|
+
// Composite index for threads (filter + sort)
|
|
2559
|
+
{
|
|
2560
|
+
name: `${schemaPrefix}mastra_threads_resourceid_createdat_idx`,
|
|
2561
|
+
table: TABLE_THREADS,
|
|
2562
|
+
columns: ["resourceId", "createdAt DESC"]
|
|
2563
|
+
},
|
|
2564
|
+
// Composite index for messages (filter + sort)
|
|
2565
|
+
{
|
|
2566
|
+
name: `${schemaPrefix}mastra_messages_thread_id_createdat_idx`,
|
|
2567
|
+
table: TABLE_MESSAGES,
|
|
2568
|
+
columns: ["thread_id", "createdAt DESC"]
|
|
2569
|
+
},
|
|
2570
|
+
// Composite index for traces (filter + sort)
|
|
2571
|
+
{
|
|
2572
|
+
name: `${schemaPrefix}mastra_traces_name_starttime_idx`,
|
|
2573
|
+
table: TABLE_TRACES,
|
|
2574
|
+
columns: ["name", "startTime DESC"]
|
|
2575
|
+
},
|
|
2576
|
+
// Composite index for evals (filter + sort)
|
|
2577
|
+
{
|
|
2578
|
+
name: `${schemaPrefix}mastra_evals_agent_name_created_at_idx`,
|
|
2579
|
+
table: TABLE_EVALS,
|
|
2580
|
+
columns: ["agent_name", "created_at DESC"]
|
|
2581
|
+
}
|
|
2582
|
+
];
|
|
2583
|
+
for (const indexOptions of indexes) {
|
|
2584
|
+
try {
|
|
2585
|
+
await this.createIndex(indexOptions);
|
|
2586
|
+
} catch (error) {
|
|
2587
|
+
this.logger?.warn?.(`Failed to create index ${indexOptions.name}:`, error);
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
} catch (error) {
|
|
2591
|
+
throw new MastraError(
|
|
2592
|
+
{
|
|
2593
|
+
id: "MASTRA_STORAGE_PG_STORE_CREATE_PERFORMANCE_INDEXES_FAILED",
|
|
2594
|
+
domain: ErrorDomain.STORAGE,
|
|
2595
|
+
category: ErrorCategory.THIRD_PARTY
|
|
2596
|
+
},
|
|
2597
|
+
error
|
|
2598
|
+
);
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
/**
|
|
2602
|
+
* Get detailed statistics for a specific index
|
|
2603
|
+
*/
|
|
2604
|
+
async describeIndex(indexName) {
|
|
2605
|
+
try {
|
|
2606
|
+
const schemaName = this.schemaName || "public";
|
|
2607
|
+
const query = `
|
|
2608
|
+
SELECT
|
|
2609
|
+
i.indexname as name,
|
|
2610
|
+
i.tablename as table,
|
|
2611
|
+
i.indexdef as definition,
|
|
2612
|
+
ix.indisunique as is_unique,
|
|
2613
|
+
pg_size_pretty(pg_relation_size(c.oid)) as size,
|
|
2614
|
+
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns,
|
|
2615
|
+
am.amname as method,
|
|
2616
|
+
s.idx_scan as scans,
|
|
2617
|
+
s.idx_tup_read as tuples_read,
|
|
2618
|
+
s.idx_tup_fetch as tuples_fetched
|
|
2619
|
+
FROM pg_indexes i
|
|
2620
|
+
JOIN pg_class c ON c.relname = i.indexname AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = i.schemaname)
|
|
2621
|
+
JOIN pg_index ix ON ix.indexrelid = c.oid
|
|
2622
|
+
JOIN pg_attribute a ON a.attrelid = ix.indrelid AND a.attnum = ANY(ix.indkey)
|
|
2623
|
+
JOIN pg_am am ON c.relam = am.oid
|
|
2624
|
+
LEFT JOIN pg_stat_user_indexes s ON s.indexrelname = i.indexname AND s.schemaname = i.schemaname
|
|
2625
|
+
WHERE i.schemaname = $1
|
|
2626
|
+
AND i.indexname = $2
|
|
2627
|
+
GROUP BY i.indexname, i.tablename, i.indexdef, ix.indisunique, c.oid, am.amname, s.idx_scan, s.idx_tup_read, s.idx_tup_fetch
|
|
2628
|
+
`;
|
|
2629
|
+
const result = await this.client.oneOrNone(query, [schemaName, indexName]);
|
|
2630
|
+
if (!result) {
|
|
2631
|
+
throw new Error(`Index "${indexName}" not found in schema "${schemaName}"`);
|
|
2632
|
+
}
|
|
2633
|
+
let columns = [];
|
|
2634
|
+
if (typeof result.columns === "string" && result.columns.startsWith("{") && result.columns.endsWith("}")) {
|
|
2635
|
+
const arrayContent = result.columns.slice(1, -1);
|
|
2636
|
+
columns = arrayContent ? arrayContent.split(",") : [];
|
|
2637
|
+
} else if (Array.isArray(result.columns)) {
|
|
2638
|
+
columns = result.columns;
|
|
2639
|
+
}
|
|
2640
|
+
return {
|
|
2641
|
+
name: result.name,
|
|
2642
|
+
table: result.table,
|
|
2643
|
+
columns,
|
|
2644
|
+
unique: result.is_unique || false,
|
|
2645
|
+
size: result.size || "0",
|
|
2646
|
+
definition: result.definition || "",
|
|
2647
|
+
method: result.method || "btree",
|
|
2648
|
+
scans: parseInt(result.scans) || 0,
|
|
2649
|
+
tuples_read: parseInt(result.tuples_read) || 0,
|
|
2650
|
+
tuples_fetched: parseInt(result.tuples_fetched) || 0
|
|
2651
|
+
};
|
|
2652
|
+
} catch (error) {
|
|
2653
|
+
throw new MastraError(
|
|
2654
|
+
{
|
|
2655
|
+
id: "MASTRA_STORAGE_PG_INDEX_DESCRIBE_FAILED",
|
|
2656
|
+
domain: ErrorDomain.STORAGE,
|
|
2657
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2658
|
+
details: {
|
|
2659
|
+
indexName
|
|
2660
|
+
}
|
|
2661
|
+
},
|
|
2662
|
+
error
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2369
2666
|
};
|
|
2370
2667
|
function transformScoreRow(row) {
|
|
2371
2668
|
return {
|
|
@@ -2800,16 +3097,17 @@ var WorkflowsPG = class extends WorkflowsStorage {
|
|
|
2800
3097
|
async persistWorkflowSnapshot({
|
|
2801
3098
|
workflowName,
|
|
2802
3099
|
runId,
|
|
3100
|
+
resourceId,
|
|
2803
3101
|
snapshot
|
|
2804
3102
|
}) {
|
|
2805
3103
|
try {
|
|
2806
3104
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2807
3105
|
await this.client.none(
|
|
2808
|
-
`INSERT INTO ${getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: this.schema })} (workflow_name, run_id, snapshot, "createdAt", "updatedAt")
|
|
2809
|
-
VALUES ($1, $2, $3, $4, $5)
|
|
3106
|
+
`INSERT INTO ${getTableName({ indexName: TABLE_WORKFLOW_SNAPSHOT, schemaName: this.schema })} (workflow_name, run_id, "resourceId", snapshot, "createdAt", "updatedAt")
|
|
3107
|
+
VALUES ($1, $2, $3, $4, $5, $6)
|
|
2810
3108
|
ON CONFLICT (workflow_name, run_id) DO UPDATE
|
|
2811
|
-
SET
|
|
2812
|
-
[workflowName, runId, JSON.stringify(snapshot), now, now]
|
|
3109
|
+
SET "resourceId" = $3, snapshot = $4, "updatedAt" = $6`,
|
|
3110
|
+
[workflowName, runId, resourceId, JSON.stringify(snapshot), now, now]
|
|
2813
3111
|
);
|
|
2814
3112
|
} catch (error) {
|
|
2815
3113
|
throw new MastraError(
|
|
@@ -2971,37 +3269,68 @@ var PostgresStore = class extends MastraStorage {
|
|
|
2971
3269
|
isConnected = false;
|
|
2972
3270
|
stores;
|
|
2973
3271
|
constructor(config) {
|
|
3272
|
+
const isConnectionStringConfig = (cfg) => {
|
|
3273
|
+
return "connectionString" in cfg;
|
|
3274
|
+
};
|
|
3275
|
+
const isHostConfig = (cfg) => {
|
|
3276
|
+
return "host" in cfg && "database" in cfg && "user" in cfg && "password" in cfg;
|
|
3277
|
+
};
|
|
3278
|
+
const isCloudSqlConfig = (cfg) => {
|
|
3279
|
+
return "stream" in cfg || "password" in cfg && typeof cfg.password === "function";
|
|
3280
|
+
};
|
|
2974
3281
|
try {
|
|
2975
|
-
if (
|
|
3282
|
+
if (isConnectionStringConfig(config)) {
|
|
2976
3283
|
if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") {
|
|
2977
3284
|
throw new Error(
|
|
2978
3285
|
"PostgresStore: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults."
|
|
2979
3286
|
);
|
|
2980
3287
|
}
|
|
2981
|
-
} else {
|
|
3288
|
+
} else if (isCloudSqlConfig(config)) ; else if (isHostConfig(config)) {
|
|
2982
3289
|
const required = ["host", "database", "user", "password"];
|
|
2983
3290
|
for (const key of required) {
|
|
2984
|
-
if (!
|
|
3291
|
+
if (!config[key] || typeof config[key] !== "string" || config[key].trim() === "") {
|
|
2985
3292
|
throw new Error(
|
|
2986
3293
|
`PostgresStore: ${key} must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`
|
|
2987
3294
|
);
|
|
2988
3295
|
}
|
|
2989
3296
|
}
|
|
3297
|
+
} else {
|
|
3298
|
+
throw new Error(
|
|
3299
|
+
"PostgresStore: invalid config. Provide either {connectionString}, {host,port,database,user,password}, or a pg ClientConfig (e.g., Cloud SQL connector with `stream`)."
|
|
3300
|
+
);
|
|
2990
3301
|
}
|
|
2991
3302
|
super({ name: "PostgresStore" });
|
|
2992
3303
|
this.schema = config.schemaName || "public";
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3304
|
+
if (isConnectionStringConfig(config)) {
|
|
3305
|
+
this.#config = {
|
|
3306
|
+
connectionString: config.connectionString,
|
|
3307
|
+
max: config.max,
|
|
3308
|
+
idleTimeoutMillis: config.idleTimeoutMillis
|
|
3309
|
+
};
|
|
3310
|
+
} else if (isCloudSqlConfig(config)) {
|
|
3311
|
+
this.#config = {
|
|
3312
|
+
...config,
|
|
3313
|
+
max: config.max,
|
|
3314
|
+
idleTimeoutMillis: config.idleTimeoutMillis
|
|
3315
|
+
};
|
|
3316
|
+
} else if (isHostConfig(config)) {
|
|
3317
|
+
this.#config = {
|
|
2997
3318
|
host: config.host,
|
|
2998
3319
|
port: config.port,
|
|
2999
3320
|
database: config.database,
|
|
3000
3321
|
user: config.user,
|
|
3001
3322
|
password: config.password,
|
|
3002
|
-
ssl: config.ssl
|
|
3003
|
-
|
|
3004
|
-
|
|
3323
|
+
ssl: config.ssl,
|
|
3324
|
+
max: config.max,
|
|
3325
|
+
idleTimeoutMillis: config.idleTimeoutMillis
|
|
3326
|
+
};
|
|
3327
|
+
} else {
|
|
3328
|
+
this.#config = {
|
|
3329
|
+
...config,
|
|
3330
|
+
max: config.max,
|
|
3331
|
+
idleTimeoutMillis: config.idleTimeoutMillis
|
|
3332
|
+
};
|
|
3333
|
+
}
|
|
3005
3334
|
this.stores = {};
|
|
3006
3335
|
} catch (e) {
|
|
3007
3336
|
throw new MastraError(
|
|
@@ -3037,6 +3366,11 @@ var PostgresStore = class extends MastraStorage {
|
|
|
3037
3366
|
memory
|
|
3038
3367
|
};
|
|
3039
3368
|
await super.init();
|
|
3369
|
+
try {
|
|
3370
|
+
await operations.createAutomaticIndexes();
|
|
3371
|
+
} catch (indexError) {
|
|
3372
|
+
console.warn("Failed to create indexes:", indexError);
|
|
3373
|
+
}
|
|
3040
3374
|
} catch (error) {
|
|
3041
3375
|
this.isConnected = false;
|
|
3042
3376
|
throw new MastraError(
|
|
@@ -3067,7 +3401,9 @@ var PostgresStore = class extends MastraStorage {
|
|
|
3067
3401
|
resourceWorkingMemory: true,
|
|
3068
3402
|
hasColumn: true,
|
|
3069
3403
|
createTable: true,
|
|
3070
|
-
deleteMessages: true
|
|
3404
|
+
deleteMessages: true,
|
|
3405
|
+
aiTracing: false,
|
|
3406
|
+
indexManagement: true
|
|
3071
3407
|
};
|
|
3072
3408
|
}
|
|
3073
3409
|
/** @deprecated use getEvals instead */
|
|
@@ -3203,9 +3539,10 @@ var PostgresStore = class extends MastraStorage {
|
|
|
3203
3539
|
async persistWorkflowSnapshot({
|
|
3204
3540
|
workflowName,
|
|
3205
3541
|
runId,
|
|
3542
|
+
resourceId,
|
|
3206
3543
|
snapshot
|
|
3207
3544
|
}) {
|
|
3208
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
|
|
3545
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
3209
3546
|
}
|
|
3210
3547
|
async loadWorkflowSnapshot({
|
|
3211
3548
|
workflowName,
|