@mastra/pg 1.3.0 → 1.4.0
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 +128 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +2423 -180
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2422 -182
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +23 -4
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/agents/index.d.ts +5 -0
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts +48 -0
- package/dist/storage/domains/datasets/index.d.ts.map +1 -0
- package/dist/storage/domains/experiments/index.d.ts +34 -0
- package/dist/storage/domains/experiments/index.d.ts.map +1 -0
- package/dist/storage/domains/mcp-clients/index.d.ts +33 -0
- package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +10 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +10 -0
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/prompt-blocks/index.d.ts +10 -0
- package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
- package/dist/storage/domains/scorer-definitions/index.d.ts +10 -0
- package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +10 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +5 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +10 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/test-utils.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
|
-
import { createVectorErrorId,
|
|
2
|
+
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, DATASETS_SCHEMA, TABLE_CONFIGS, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, ensureDate, safelyParseJSON, ExperimentsStorage, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MastraCompositeStore, TraceStatus, getDefaultValue, transformScoreRow as transformScoreRow$1, getSqlType } from '@mastra/core/storage';
|
|
3
3
|
import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
|
|
4
4
|
import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
|
|
5
5
|
import { Mutex } from 'async-mutex';
|
|
@@ -12,7 +12,12 @@ import { randomUUID } from 'crypto';
|
|
|
12
12
|
import { MessageList } from '@mastra/core/agent';
|
|
13
13
|
import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
16
21
|
|
|
17
22
|
// src/shared/config.ts
|
|
18
23
|
var isPoolConfig = (cfg) => {
|
|
@@ -1972,8 +1977,17 @@ function generateTableSQL({
|
|
|
1972
1977
|
tableName,
|
|
1973
1978
|
schema,
|
|
1974
1979
|
schemaName,
|
|
1980
|
+
compositePrimaryKey,
|
|
1975
1981
|
includeAllConstraints = false
|
|
1976
1982
|
}) {
|
|
1983
|
+
if (compositePrimaryKey) {
|
|
1984
|
+
for (const col of compositePrimaryKey) {
|
|
1985
|
+
if (!(col in schema)) {
|
|
1986
|
+
throw new Error(`compositePrimaryKey column "${col}" does not exist in schema for table "${tableName}"`);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
}
|
|
1990
|
+
const compositePKSet = compositePrimaryKey ? new Set(compositePrimaryKey) : null;
|
|
1977
1991
|
const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
|
|
1978
1992
|
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1979
1993
|
return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
|
|
@@ -1981,11 +1995,16 @@ function generateTableSQL({
|
|
|
1981
1995
|
const columns = Object.entries(schema).map(([name, def]) => {
|
|
1982
1996
|
const parsedName = parseSqlIdentifier(name, "column name");
|
|
1983
1997
|
const constraints = [];
|
|
1984
|
-
if (def.primaryKey) constraints.push("PRIMARY KEY");
|
|
1998
|
+
if (def.primaryKey && !compositePKSet?.has(name)) constraints.push("PRIMARY KEY");
|
|
1985
1999
|
if (!def.nullable) constraints.push("NOT NULL");
|
|
1986
2000
|
return `"${parsedName}" ${mapToSqlType(def.type)} ${constraints.join(" ")}`;
|
|
1987
2001
|
});
|
|
1988
|
-
const
|
|
2002
|
+
const tableConstraints = [];
|
|
2003
|
+
if (compositePrimaryKey) {
|
|
2004
|
+
const pkCols = compositePrimaryKey.map((c) => `"${parseSqlIdentifier(c, "column name")}"`).join(", ");
|
|
2005
|
+
tableConstraints.push(`PRIMARY KEY (${pkCols})`);
|
|
2006
|
+
}
|
|
2007
|
+
const finalColumns = [...columns, ...timeZColumns, ...tableConstraints].join(",\n");
|
|
1989
2008
|
const parsedSchemaName = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
1990
2009
|
const workflowSnapshotConstraint = buildConstraintName({
|
|
1991
2010
|
baseName: "mastra_workflow_snapshot_workflow_name_run_id_key",
|
|
@@ -2029,27 +2048,55 @@ function generateTableSQL({
|
|
|
2029
2048
|
`;
|
|
2030
2049
|
return sql;
|
|
2031
2050
|
}
|
|
2032
|
-
function
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2051
|
+
function generateIndexSQL(options, schemaName) {
|
|
2052
|
+
const { name, table, columns, unique = false, where, method = "btree" } = options;
|
|
2053
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
2054
|
+
const fullTableName = getTableName({ indexName: table, schemaName: quotedSchemaName });
|
|
2055
|
+
const uniqueStr = unique ? "UNIQUE " : "";
|
|
2056
|
+
const methodStr = method !== "btree" ? `USING ${method} ` : "";
|
|
2057
|
+
const columnsStr = columns.map((col) => {
|
|
2058
|
+
if (col.includes(" DESC") || col.includes(" ASC")) {
|
|
2059
|
+
const [colName, ...modifiers] = col.split(" ");
|
|
2060
|
+
if (!colName) {
|
|
2061
|
+
throw new Error(`Invalid column specification: ${col}`);
|
|
2062
|
+
}
|
|
2063
|
+
return `"${parseSqlIdentifier(colName, "column name")}" ${modifiers.join(" ")}`;
|
|
2064
|
+
}
|
|
2065
|
+
return `"${parseSqlIdentifier(col, "column name")}"`;
|
|
2066
|
+
}).join(", ");
|
|
2067
|
+
const whereStr = where ? ` WHERE ${where}` : "";
|
|
2068
|
+
const quotedIndexName = `"${parseSqlIdentifier(name, "index name")}"`;
|
|
2069
|
+
return `CREATE ${uniqueStr}INDEX IF NOT EXISTS ${quotedIndexName} ON ${fullTableName} ${methodStr}(${columnsStr})${whereStr};`;
|
|
2070
|
+
}
|
|
2071
|
+
function generateTimestampTriggerSQL(tableName, schemaName) {
|
|
2072
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
2073
|
+
const fullTableName = getTableName({ indexName: tableName, schemaName: quotedSchemaName });
|
|
2074
|
+
const functionName = `${quotedSchemaName}.trigger_set_timestamps`;
|
|
2075
|
+
const triggerName = `"${parseSqlIdentifier(`${tableName}_timestamps`, "trigger name")}"`;
|
|
2076
|
+
return `CREATE OR REPLACE FUNCTION ${functionName}()
|
|
2077
|
+
RETURNS TRIGGER AS $$
|
|
2078
|
+
BEGIN
|
|
2079
|
+
IF TG_OP = 'INSERT' THEN
|
|
2080
|
+
NEW."createdAt" = NOW();
|
|
2081
|
+
NEW."updatedAt" = NOW();
|
|
2082
|
+
NEW."createdAtZ" = NOW();
|
|
2083
|
+
NEW."updatedAtZ" = NOW();
|
|
2084
|
+
ELSIF TG_OP = 'UPDATE' THEN
|
|
2085
|
+
NEW."updatedAt" = NOW();
|
|
2086
|
+
NEW."updatedAtZ" = NOW();
|
|
2087
|
+
NEW."createdAt" = OLD."createdAt";
|
|
2088
|
+
NEW."createdAtZ" = OLD."createdAtZ";
|
|
2089
|
+
END IF;
|
|
2090
|
+
RETURN NEW;
|
|
2091
|
+
END;
|
|
2092
|
+
$$ LANGUAGE plpgsql;
|
|
2093
|
+
|
|
2094
|
+
DROP TRIGGER IF EXISTS ${triggerName} ON ${fullTableName};
|
|
2095
|
+
|
|
2096
|
+
CREATE TRIGGER ${triggerName}
|
|
2097
|
+
BEFORE INSERT OR UPDATE ON ${fullTableName}
|
|
2098
|
+
FOR EACH ROW
|
|
2099
|
+
EXECUTE FUNCTION ${functionName}();`;
|
|
2053
2100
|
}
|
|
2054
2101
|
var schemaSetupRegistry = /* @__PURE__ */ new Map();
|
|
2055
2102
|
var PgDB = class extends MastraBase {
|
|
@@ -2250,14 +2297,15 @@ var PgDB = class extends MastraBase {
|
|
|
2250
2297
|
}
|
|
2251
2298
|
async createTable({
|
|
2252
2299
|
tableName,
|
|
2253
|
-
schema
|
|
2300
|
+
schema,
|
|
2301
|
+
compositePrimaryKey
|
|
2254
2302
|
}) {
|
|
2255
2303
|
try {
|
|
2256
2304
|
const timeZColumnNames = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => name);
|
|
2257
2305
|
if (this.schemaName) {
|
|
2258
2306
|
await this.setupSchema();
|
|
2259
2307
|
}
|
|
2260
|
-
const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName });
|
|
2308
|
+
const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName, compositePrimaryKey });
|
|
2261
2309
|
await this.client.none(sql);
|
|
2262
2310
|
await this.alterTable({
|
|
2263
2311
|
tableName,
|
|
@@ -2321,36 +2369,9 @@ Note: This migration may take some time for large tables.
|
|
|
2321
2369
|
}
|
|
2322
2370
|
}
|
|
2323
2371
|
async setupTimestampTriggers(tableName) {
|
|
2324
|
-
const
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
try {
|
|
2328
|
-
const triggerSQL = `
|
|
2329
|
-
CREATE OR REPLACE FUNCTION ${functionName}()
|
|
2330
|
-
RETURNS TRIGGER AS $$
|
|
2331
|
-
BEGIN
|
|
2332
|
-
IF TG_OP = 'INSERT' THEN
|
|
2333
|
-
NEW."createdAt" = NOW();
|
|
2334
|
-
NEW."updatedAt" = NOW();
|
|
2335
|
-
NEW."createdAtZ" = NOW();
|
|
2336
|
-
NEW."updatedAtZ" = NOW();
|
|
2337
|
-
ELSIF TG_OP = 'UPDATE' THEN
|
|
2338
|
-
NEW."updatedAt" = NOW();
|
|
2339
|
-
NEW."updatedAtZ" = NOW();
|
|
2340
|
-
NEW."createdAt" = OLD."createdAt";
|
|
2341
|
-
NEW."createdAtZ" = OLD."createdAtZ";
|
|
2342
|
-
END IF;
|
|
2343
|
-
RETURN NEW;
|
|
2344
|
-
END;
|
|
2345
|
-
$$ LANGUAGE plpgsql;
|
|
2346
|
-
|
|
2347
|
-
DROP TRIGGER IF EXISTS ${tableName}_timestamps ON ${fullTableName};
|
|
2348
|
-
|
|
2349
|
-
CREATE TRIGGER ${tableName}_timestamps
|
|
2350
|
-
BEFORE INSERT OR UPDATE ON ${fullTableName}
|
|
2351
|
-
FOR EACH ROW
|
|
2352
|
-
EXECUTE FUNCTION ${functionName}();
|
|
2353
|
-
`;
|
|
2372
|
+
const fullTableName = getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) });
|
|
2373
|
+
try {
|
|
2374
|
+
const triggerSQL = generateTimestampTriggerSQL(tableName, this.schemaName);
|
|
2354
2375
|
await this.client.none(triggerSQL);
|
|
2355
2376
|
this.logger?.debug?.(`Set up timestamp triggers for table ${fullTableName}`);
|
|
2356
2377
|
} catch (error) {
|
|
@@ -3143,6 +3164,24 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3143
3164
|
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
3144
3165
|
this.#indexes = indexes?.filter((idx) => _AgentsPG.MANAGED_TABLES.includes(idx.table));
|
|
3145
3166
|
}
|
|
3167
|
+
/**
|
|
3168
|
+
* Returns all DDL statements for this domain: tables.
|
|
3169
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
3170
|
+
*/
|
|
3171
|
+
static getExportDDL(schemaName) {
|
|
3172
|
+
const statements = [];
|
|
3173
|
+
for (const tableName of _AgentsPG.MANAGED_TABLES) {
|
|
3174
|
+
statements.push(
|
|
3175
|
+
generateTableSQL({
|
|
3176
|
+
tableName,
|
|
3177
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
3178
|
+
schemaName,
|
|
3179
|
+
includeAllConstraints: true
|
|
3180
|
+
})
|
|
3181
|
+
);
|
|
3182
|
+
}
|
|
3183
|
+
return statements;
|
|
3184
|
+
}
|
|
3146
3185
|
/**
|
|
3147
3186
|
* Returns default index definitions for the agents domain tables.
|
|
3148
3187
|
* Currently no default indexes are defined for agents.
|
|
@@ -3488,7 +3527,9 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3488
3527
|
"inputProcessors",
|
|
3489
3528
|
"outputProcessors",
|
|
3490
3529
|
"memory",
|
|
3491
|
-
"scorers"
|
|
3530
|
+
"scorers",
|
|
3531
|
+
"mcpClients",
|
|
3532
|
+
"requestContextSchema"
|
|
3492
3533
|
];
|
|
3493
3534
|
const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
|
|
3494
3535
|
if (hasConfigUpdate) {
|
|
@@ -3618,16 +3659,1975 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3618
3659
|
},
|
|
3619
3660
|
new Error("page must be >= 0")
|
|
3620
3661
|
);
|
|
3621
|
-
}
|
|
3622
|
-
const perPage = normalizePerPage(perPageInput, 100);
|
|
3623
|
-
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
3624
|
-
try {
|
|
3625
|
-
const tableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
|
|
3626
|
-
const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
3662
|
+
}
|
|
3663
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
3664
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
3665
|
+
try {
|
|
3666
|
+
const tableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
|
|
3667
|
+
const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
3668
|
+
const total = parseInt(countResult.count, 10);
|
|
3669
|
+
if (total === 0) {
|
|
3670
|
+
return {
|
|
3671
|
+
agents: [],
|
|
3672
|
+
total: 0,
|
|
3673
|
+
page,
|
|
3674
|
+
perPage: perPageForResponse,
|
|
3675
|
+
hasMore: false
|
|
3676
|
+
};
|
|
3677
|
+
}
|
|
3678
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
3679
|
+
const dataResult = await this.#db.client.manyOrNone(
|
|
3680
|
+
`SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
|
|
3681
|
+
[limitValue, offset]
|
|
3682
|
+
);
|
|
3683
|
+
const agents = (dataResult || []).map((row) => this.parseRow(row));
|
|
3684
|
+
return {
|
|
3685
|
+
agents,
|
|
3686
|
+
total,
|
|
3687
|
+
page,
|
|
3688
|
+
perPage: perPageForResponse,
|
|
3689
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
3690
|
+
};
|
|
3691
|
+
} catch (error) {
|
|
3692
|
+
if (error instanceof MastraError) throw error;
|
|
3693
|
+
throw new MastraError(
|
|
3694
|
+
{
|
|
3695
|
+
id: createStorageErrorId("PG", "LIST_AGENTS", "FAILED"),
|
|
3696
|
+
domain: ErrorDomain.STORAGE,
|
|
3697
|
+
category: ErrorCategory.THIRD_PARTY
|
|
3698
|
+
},
|
|
3699
|
+
error
|
|
3700
|
+
);
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
// ==========================================================================
|
|
3704
|
+
// Agent Version Methods
|
|
3705
|
+
// ==========================================================================
|
|
3706
|
+
async createVersion(input) {
|
|
3707
|
+
try {
|
|
3708
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3709
|
+
const now = /* @__PURE__ */ new Date();
|
|
3710
|
+
const nowIso = now.toISOString();
|
|
3711
|
+
await this.#db.client.none(
|
|
3712
|
+
`INSERT INTO ${tableName} (
|
|
3713
|
+
id, "agentId", "versionNumber",
|
|
3714
|
+
name, description, instructions, model, tools,
|
|
3715
|
+
"defaultOptions", workflows, agents, "integrationTools",
|
|
3716
|
+
"inputProcessors", "outputProcessors", memory, scorers,
|
|
3717
|
+
"mcpClients", "requestContextSchema", "changedFields", "changeMessage",
|
|
3718
|
+
"createdAt", "createdAtZ"
|
|
3719
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`,
|
|
3720
|
+
[
|
|
3721
|
+
input.id,
|
|
3722
|
+
input.agentId,
|
|
3723
|
+
input.versionNumber,
|
|
3724
|
+
input.name,
|
|
3725
|
+
input.description ?? null,
|
|
3726
|
+
this.serializeInstructions(input.instructions),
|
|
3727
|
+
JSON.stringify(input.model),
|
|
3728
|
+
input.tools ? JSON.stringify(input.tools) : null,
|
|
3729
|
+
input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
|
|
3730
|
+
input.workflows ? JSON.stringify(input.workflows) : null,
|
|
3731
|
+
input.agents ? JSON.stringify(input.agents) : null,
|
|
3732
|
+
input.integrationTools ? JSON.stringify(input.integrationTools) : null,
|
|
3733
|
+
input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
|
|
3734
|
+
input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
|
|
3735
|
+
input.memory ? JSON.stringify(input.memory) : null,
|
|
3736
|
+
input.scorers ? JSON.stringify(input.scorers) : null,
|
|
3737
|
+
input.mcpClients ? JSON.stringify(input.mcpClients) : null,
|
|
3738
|
+
input.requestContextSchema ? JSON.stringify(input.requestContextSchema) : null,
|
|
3739
|
+
input.changedFields ? JSON.stringify(input.changedFields) : null,
|
|
3740
|
+
input.changeMessage ?? null,
|
|
3741
|
+
nowIso,
|
|
3742
|
+
nowIso
|
|
3743
|
+
]
|
|
3744
|
+
);
|
|
3745
|
+
return {
|
|
3746
|
+
...input,
|
|
3747
|
+
createdAt: now
|
|
3748
|
+
};
|
|
3749
|
+
} catch (error) {
|
|
3750
|
+
if (error instanceof MastraError) throw error;
|
|
3751
|
+
throw new MastraError(
|
|
3752
|
+
{
|
|
3753
|
+
id: createStorageErrorId("PG", "CREATE_VERSION", "FAILED"),
|
|
3754
|
+
domain: ErrorDomain.STORAGE,
|
|
3755
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3756
|
+
details: { versionId: input.id, agentId: input.agentId }
|
|
3757
|
+
},
|
|
3758
|
+
error
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
async getVersion(id) {
|
|
3763
|
+
try {
|
|
3764
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3765
|
+
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
|
|
3766
|
+
if (!result) {
|
|
3767
|
+
return null;
|
|
3768
|
+
}
|
|
3769
|
+
return this.parseVersionRow(result);
|
|
3770
|
+
} catch (error) {
|
|
3771
|
+
if (error instanceof MastraError) throw error;
|
|
3772
|
+
throw new MastraError(
|
|
3773
|
+
{
|
|
3774
|
+
id: createStorageErrorId("PG", "GET_VERSION", "FAILED"),
|
|
3775
|
+
domain: ErrorDomain.STORAGE,
|
|
3776
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3777
|
+
details: { versionId: id }
|
|
3778
|
+
},
|
|
3779
|
+
error
|
|
3780
|
+
);
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
async getVersionByNumber(agentId, versionNumber) {
|
|
3784
|
+
try {
|
|
3785
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3786
|
+
const result = await this.#db.client.oneOrNone(
|
|
3787
|
+
`SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`,
|
|
3788
|
+
[agentId, versionNumber]
|
|
3789
|
+
);
|
|
3790
|
+
if (!result) {
|
|
3791
|
+
return null;
|
|
3792
|
+
}
|
|
3793
|
+
return this.parseVersionRow(result);
|
|
3794
|
+
} catch (error) {
|
|
3795
|
+
if (error instanceof MastraError) throw error;
|
|
3796
|
+
throw new MastraError(
|
|
3797
|
+
{
|
|
3798
|
+
id: createStorageErrorId("PG", "GET_VERSION_BY_NUMBER", "FAILED"),
|
|
3799
|
+
domain: ErrorDomain.STORAGE,
|
|
3800
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3801
|
+
details: { agentId, versionNumber }
|
|
3802
|
+
},
|
|
3803
|
+
error
|
|
3804
|
+
);
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
async getLatestVersion(agentId) {
|
|
3808
|
+
try {
|
|
3809
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3810
|
+
const result = await this.#db.client.oneOrNone(
|
|
3811
|
+
`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
|
|
3812
|
+
[agentId]
|
|
3813
|
+
);
|
|
3814
|
+
if (!result) {
|
|
3815
|
+
return null;
|
|
3816
|
+
}
|
|
3817
|
+
return this.parseVersionRow(result);
|
|
3818
|
+
} catch (error) {
|
|
3819
|
+
if (error instanceof MastraError) throw error;
|
|
3820
|
+
throw new MastraError(
|
|
3821
|
+
{
|
|
3822
|
+
id: createStorageErrorId("PG", "GET_LATEST_VERSION", "FAILED"),
|
|
3823
|
+
domain: ErrorDomain.STORAGE,
|
|
3824
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3825
|
+
details: { agentId }
|
|
3826
|
+
},
|
|
3827
|
+
error
|
|
3828
|
+
);
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
3831
|
+
async listVersions(input) {
|
|
3832
|
+
const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
|
|
3833
|
+
if (page < 0) {
|
|
3834
|
+
throw new MastraError(
|
|
3835
|
+
{
|
|
3836
|
+
id: createStorageErrorId("PG", "LIST_VERSIONS", "INVALID_PAGE"),
|
|
3837
|
+
domain: ErrorDomain.STORAGE,
|
|
3838
|
+
category: ErrorCategory.USER,
|
|
3839
|
+
details: { page }
|
|
3840
|
+
},
|
|
3841
|
+
new Error("page must be >= 0")
|
|
3842
|
+
);
|
|
3843
|
+
}
|
|
3844
|
+
const perPage = normalizePerPage(perPageInput, 20);
|
|
3845
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
3846
|
+
try {
|
|
3847
|
+
const { field, direction } = this.parseVersionOrderBy(orderBy);
|
|
3848
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3849
|
+
const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
|
|
3850
|
+
agentId
|
|
3851
|
+
]);
|
|
3852
|
+
const total = parseInt(countResult.count, 10);
|
|
3853
|
+
if (total === 0) {
|
|
3854
|
+
return {
|
|
3855
|
+
versions: [],
|
|
3856
|
+
total: 0,
|
|
3857
|
+
page,
|
|
3858
|
+
perPage: perPageForResponse,
|
|
3859
|
+
hasMore: false
|
|
3860
|
+
};
|
|
3861
|
+
}
|
|
3862
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
3863
|
+
const dataResult = await this.#db.client.manyOrNone(
|
|
3864
|
+
`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
|
|
3865
|
+
[agentId, limitValue, offset]
|
|
3866
|
+
);
|
|
3867
|
+
const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
|
|
3868
|
+
return {
|
|
3869
|
+
versions,
|
|
3870
|
+
total,
|
|
3871
|
+
page,
|
|
3872
|
+
perPage: perPageForResponse,
|
|
3873
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
3874
|
+
};
|
|
3875
|
+
} catch (error) {
|
|
3876
|
+
if (error instanceof MastraError) throw error;
|
|
3877
|
+
throw new MastraError(
|
|
3878
|
+
{
|
|
3879
|
+
id: createStorageErrorId("PG", "LIST_VERSIONS", "FAILED"),
|
|
3880
|
+
domain: ErrorDomain.STORAGE,
|
|
3881
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3882
|
+
details: { agentId }
|
|
3883
|
+
},
|
|
3884
|
+
error
|
|
3885
|
+
);
|
|
3886
|
+
}
|
|
3887
|
+
}
|
|
3888
|
+
async deleteVersion(id) {
|
|
3889
|
+
try {
|
|
3890
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3891
|
+
await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
|
|
3892
|
+
} catch (error) {
|
|
3893
|
+
if (error instanceof MastraError) throw error;
|
|
3894
|
+
throw new MastraError(
|
|
3895
|
+
{
|
|
3896
|
+
id: createStorageErrorId("PG", "DELETE_VERSION", "FAILED"),
|
|
3897
|
+
domain: ErrorDomain.STORAGE,
|
|
3898
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3899
|
+
details: { versionId: id }
|
|
3900
|
+
},
|
|
3901
|
+
error
|
|
3902
|
+
);
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
async deleteVersionsByParentId(entityId) {
|
|
3906
|
+
try {
|
|
3907
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3908
|
+
await this.#db.client.none(`DELETE FROM ${tableName} WHERE "agentId" = $1`, [entityId]);
|
|
3909
|
+
} catch (error) {
|
|
3910
|
+
if (error instanceof MastraError) throw error;
|
|
3911
|
+
throw new MastraError(
|
|
3912
|
+
{
|
|
3913
|
+
id: createStorageErrorId("PG", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
|
|
3914
|
+
domain: ErrorDomain.STORAGE,
|
|
3915
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3916
|
+
details: { agentId: entityId }
|
|
3917
|
+
},
|
|
3918
|
+
error
|
|
3919
|
+
);
|
|
3920
|
+
}
|
|
3921
|
+
}
|
|
3922
|
+
async countVersions(agentId) {
|
|
3923
|
+
try {
|
|
3924
|
+
const tableName = getTableName2({ indexName: TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
3925
|
+
const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
|
|
3926
|
+
agentId
|
|
3927
|
+
]);
|
|
3928
|
+
return parseInt(result.count, 10);
|
|
3929
|
+
} catch (error) {
|
|
3930
|
+
if (error instanceof MastraError) throw error;
|
|
3931
|
+
throw new MastraError(
|
|
3932
|
+
{
|
|
3933
|
+
id: createStorageErrorId("PG", "COUNT_VERSIONS", "FAILED"),
|
|
3934
|
+
domain: ErrorDomain.STORAGE,
|
|
3935
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3936
|
+
details: { agentId }
|
|
3937
|
+
},
|
|
3938
|
+
error
|
|
3939
|
+
);
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
// ==========================================================================
|
|
3943
|
+
// Private Helper Methods
|
|
3944
|
+
// ==========================================================================
|
|
3945
|
+
serializeInstructions(instructions) {
|
|
3946
|
+
if (instructions == null) return void 0;
|
|
3947
|
+
return Array.isArray(instructions) ? JSON.stringify(instructions) : instructions;
|
|
3948
|
+
}
|
|
3949
|
+
deserializeInstructions(raw) {
|
|
3950
|
+
if (!raw) return "";
|
|
3951
|
+
try {
|
|
3952
|
+
const parsed = JSON.parse(raw);
|
|
3953
|
+
if (Array.isArray(parsed)) return parsed;
|
|
3954
|
+
} catch {
|
|
3955
|
+
}
|
|
3956
|
+
return raw;
|
|
3957
|
+
}
|
|
3958
|
+
parseVersionRow(row) {
|
|
3959
|
+
return {
|
|
3960
|
+
id: row.id,
|
|
3961
|
+
agentId: row.agentId,
|
|
3962
|
+
versionNumber: row.versionNumber,
|
|
3963
|
+
name: row.name,
|
|
3964
|
+
description: row.description,
|
|
3965
|
+
instructions: this.deserializeInstructions(row.instructions),
|
|
3966
|
+
model: this.parseJson(row.model, "model"),
|
|
3967
|
+
tools: this.parseJson(row.tools, "tools"),
|
|
3968
|
+
defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
|
|
3969
|
+
workflows: this.parseJson(row.workflows, "workflows"),
|
|
3970
|
+
agents: this.parseJson(row.agents, "agents"),
|
|
3971
|
+
integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
|
|
3972
|
+
inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
|
|
3973
|
+
outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
|
|
3974
|
+
memory: this.parseJson(row.memory, "memory"),
|
|
3975
|
+
scorers: this.parseJson(row.scorers, "scorers"),
|
|
3976
|
+
mcpClients: this.parseJson(row.mcpClients, "mcpClients"),
|
|
3977
|
+
requestContextSchema: this.parseJson(row.requestContextSchema, "requestContextSchema"),
|
|
3978
|
+
changedFields: this.parseJson(row.changedFields, "changedFields"),
|
|
3979
|
+
changeMessage: row.changeMessage,
|
|
3980
|
+
createdAt: row.createdAtZ || row.createdAt
|
|
3981
|
+
};
|
|
3982
|
+
}
|
|
3983
|
+
};
|
|
3984
|
+
function jsonbArg(value) {
|
|
3985
|
+
return value === void 0 || value === null ? null : JSON.stringify(value);
|
|
3986
|
+
}
|
|
3987
|
+
var DatasetsPG = class _DatasetsPG extends DatasetsStorage {
|
|
3988
|
+
#db;
|
|
3989
|
+
#schema;
|
|
3990
|
+
#skipDefaultIndexes;
|
|
3991
|
+
#indexes;
|
|
3992
|
+
static MANAGED_TABLES = [TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS];
|
|
3993
|
+
constructor(config) {
|
|
3994
|
+
super();
|
|
3995
|
+
const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
|
|
3996
|
+
this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
|
|
3997
|
+
this.#schema = schemaName || "public";
|
|
3998
|
+
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
3999
|
+
this.#indexes = indexes?.filter((idx) => _DatasetsPG.MANAGED_TABLES.includes(idx.table));
|
|
4000
|
+
}
|
|
4001
|
+
static getExportDDL(schemaName) {
|
|
4002
|
+
const statements = [];
|
|
4003
|
+
for (const tableName of _DatasetsPG.MANAGED_TABLES) {
|
|
4004
|
+
statements.push(
|
|
4005
|
+
generateTableSQL({
|
|
4006
|
+
tableName,
|
|
4007
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
4008
|
+
schemaName,
|
|
4009
|
+
compositePrimaryKey: TABLE_CONFIGS[tableName]?.compositePrimaryKey,
|
|
4010
|
+
includeAllConstraints: true
|
|
4011
|
+
})
|
|
4012
|
+
);
|
|
4013
|
+
}
|
|
4014
|
+
return statements;
|
|
4015
|
+
}
|
|
4016
|
+
async init() {
|
|
4017
|
+
await this.#db.createTable({ tableName: TABLE_DATASETS, schema: DATASETS_SCHEMA });
|
|
4018
|
+
await this.#db.createTable({
|
|
4019
|
+
tableName: TABLE_DATASET_ITEMS,
|
|
4020
|
+
schema: DATASET_ITEMS_SCHEMA,
|
|
4021
|
+
compositePrimaryKey: TABLE_CONFIGS[TABLE_DATASET_ITEMS]?.compositePrimaryKey
|
|
4022
|
+
});
|
|
4023
|
+
await this.#db.createTable({ tableName: TABLE_DATASET_VERSIONS, schema: DATASET_VERSIONS_SCHEMA });
|
|
4024
|
+
await this.createDefaultIndexes();
|
|
4025
|
+
await this.createCustomIndexes();
|
|
4026
|
+
}
|
|
4027
|
+
getDefaultIndexDefinitions() {
|
|
4028
|
+
return [
|
|
4029
|
+
{ name: "idx_dataset_items_dataset_validto", table: TABLE_DATASET_ITEMS, columns: ["datasetId", "validTo"] },
|
|
4030
|
+
{
|
|
4031
|
+
name: "idx_dataset_items_dataset_version",
|
|
4032
|
+
table: TABLE_DATASET_ITEMS,
|
|
4033
|
+
columns: ["datasetId", "datasetVersion"]
|
|
4034
|
+
},
|
|
4035
|
+
{
|
|
4036
|
+
name: "idx_dataset_items_dataset_validto_deleted",
|
|
4037
|
+
table: TABLE_DATASET_ITEMS,
|
|
4038
|
+
columns: ["datasetId", "validTo", "isDeleted"]
|
|
4039
|
+
},
|
|
4040
|
+
{
|
|
4041
|
+
name: "idx_dataset_versions_dataset_version",
|
|
4042
|
+
table: TABLE_DATASET_VERSIONS,
|
|
4043
|
+
columns: ["datasetId", "version"]
|
|
4044
|
+
},
|
|
4045
|
+
{
|
|
4046
|
+
name: "idx_dataset_versions_dataset_version_unique",
|
|
4047
|
+
table: TABLE_DATASET_VERSIONS,
|
|
4048
|
+
columns: ["datasetId", "version"],
|
|
4049
|
+
unique: true
|
|
4050
|
+
}
|
|
4051
|
+
];
|
|
4052
|
+
}
|
|
4053
|
+
async createDefaultIndexes() {
|
|
4054
|
+
if (this.#skipDefaultIndexes) return;
|
|
4055
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) {
|
|
4056
|
+
try {
|
|
4057
|
+
await this.#db.createIndex(indexDef);
|
|
4058
|
+
} catch (error) {
|
|
4059
|
+
this.logger?.warn?.(`Failed to create default index ${indexDef.name}:`, error);
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
async createCustomIndexes() {
|
|
4064
|
+
if (!this.#indexes || this.#indexes.length === 0) return;
|
|
4065
|
+
for (const indexDef of this.#indexes) {
|
|
4066
|
+
try {
|
|
4067
|
+
await this.#db.createIndex(indexDef);
|
|
4068
|
+
} catch (error) {
|
|
4069
|
+
this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4073
|
+
// --- Row transformers ---
|
|
4074
|
+
transformDatasetRow(row) {
|
|
4075
|
+
return {
|
|
4076
|
+
id: row.id,
|
|
4077
|
+
name: row.name,
|
|
4078
|
+
description: row.description ?? void 0,
|
|
4079
|
+
metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
|
|
4080
|
+
inputSchema: row.inputSchema ? safelyParseJSON(row.inputSchema) : void 0,
|
|
4081
|
+
groundTruthSchema: row.groundTruthSchema ? safelyParseJSON(row.groundTruthSchema) : void 0,
|
|
4082
|
+
version: row.version,
|
|
4083
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
4084
|
+
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
4085
|
+
};
|
|
4086
|
+
}
|
|
4087
|
+
transformItemRow(row) {
|
|
4088
|
+
return {
|
|
4089
|
+
id: row.id,
|
|
4090
|
+
datasetId: row.datasetId,
|
|
4091
|
+
datasetVersion: row.datasetVersion,
|
|
4092
|
+
input: safelyParseJSON(row.input),
|
|
4093
|
+
groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : void 0,
|
|
4094
|
+
metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
|
|
4095
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
4096
|
+
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
4097
|
+
};
|
|
4098
|
+
}
|
|
4099
|
+
transformItemRowFull(row) {
|
|
4100
|
+
return {
|
|
4101
|
+
id: row.id,
|
|
4102
|
+
datasetId: row.datasetId,
|
|
4103
|
+
datasetVersion: row.datasetVersion,
|
|
4104
|
+
validTo: row.validTo,
|
|
4105
|
+
isDeleted: Boolean(row.isDeleted),
|
|
4106
|
+
input: safelyParseJSON(row.input),
|
|
4107
|
+
groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : void 0,
|
|
4108
|
+
metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
|
|
4109
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
4110
|
+
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
4111
|
+
};
|
|
4112
|
+
}
|
|
4113
|
+
transformDatasetVersionRow(row) {
|
|
4114
|
+
return {
|
|
4115
|
+
id: row.id,
|
|
4116
|
+
datasetId: row.datasetId,
|
|
4117
|
+
version: row.version,
|
|
4118
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt)
|
|
4119
|
+
};
|
|
4120
|
+
}
|
|
4121
|
+
// --- Dataset CRUD ---
|
|
4122
|
+
async createDataset(input) {
|
|
4123
|
+
try {
|
|
4124
|
+
const id = crypto.randomUUID();
|
|
4125
|
+
const now = /* @__PURE__ */ new Date();
|
|
4126
|
+
const nowIso = now.toISOString();
|
|
4127
|
+
await this.#db.insert({
|
|
4128
|
+
tableName: TABLE_DATASETS,
|
|
4129
|
+
record: {
|
|
4130
|
+
id,
|
|
4131
|
+
name: input.name,
|
|
4132
|
+
description: input.description ?? null,
|
|
4133
|
+
metadata: input.metadata ?? null,
|
|
4134
|
+
inputSchema: input.inputSchema ?? null,
|
|
4135
|
+
groundTruthSchema: input.groundTruthSchema ?? null,
|
|
4136
|
+
version: 0,
|
|
4137
|
+
createdAt: nowIso,
|
|
4138
|
+
updatedAt: nowIso
|
|
4139
|
+
}
|
|
4140
|
+
});
|
|
4141
|
+
return {
|
|
4142
|
+
id,
|
|
4143
|
+
name: input.name,
|
|
4144
|
+
description: input.description,
|
|
4145
|
+
metadata: input.metadata,
|
|
4146
|
+
inputSchema: input.inputSchema,
|
|
4147
|
+
groundTruthSchema: input.groundTruthSchema,
|
|
4148
|
+
version: 0,
|
|
4149
|
+
createdAt: now,
|
|
4150
|
+
updatedAt: now
|
|
4151
|
+
};
|
|
4152
|
+
} catch (error) {
|
|
4153
|
+
throw new MastraError(
|
|
4154
|
+
{
|
|
4155
|
+
id: createStorageErrorId("PG", "CREATE_DATASET", "FAILED"),
|
|
4156
|
+
domain: ErrorDomain.STORAGE,
|
|
4157
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4158
|
+
},
|
|
4159
|
+
error
|
|
4160
|
+
);
|
|
4161
|
+
}
|
|
4162
|
+
}
|
|
4163
|
+
async getDatasetById({ id }) {
|
|
4164
|
+
try {
|
|
4165
|
+
const tableName = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4166
|
+
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
|
|
4167
|
+
return result ? this.transformDatasetRow(result) : null;
|
|
4168
|
+
} catch (error) {
|
|
4169
|
+
throw new MastraError(
|
|
4170
|
+
{
|
|
4171
|
+
id: createStorageErrorId("PG", "GET_DATASET", "FAILED"),
|
|
4172
|
+
domain: ErrorDomain.STORAGE,
|
|
4173
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4174
|
+
},
|
|
4175
|
+
error
|
|
4176
|
+
);
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
async _doUpdateDataset(args) {
|
|
4180
|
+
try {
|
|
4181
|
+
const existing = await this.getDatasetById({ id: args.id });
|
|
4182
|
+
if (!existing) {
|
|
4183
|
+
throw new MastraError({
|
|
4184
|
+
id: createStorageErrorId("PG", "UPDATE_DATASET", "NOT_FOUND"),
|
|
4185
|
+
domain: ErrorDomain.STORAGE,
|
|
4186
|
+
category: ErrorCategory.USER,
|
|
4187
|
+
details: { datasetId: args.id }
|
|
4188
|
+
});
|
|
4189
|
+
}
|
|
4190
|
+
const tableName = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4191
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4192
|
+
const setClauses = ['"updatedAt" = $1', '"updatedAtZ" = $2'];
|
|
4193
|
+
const values = [now, now];
|
|
4194
|
+
let paramIndex = 3;
|
|
4195
|
+
if (args.name !== void 0) {
|
|
4196
|
+
setClauses.push(`"name" = $${paramIndex++}`);
|
|
4197
|
+
values.push(args.name);
|
|
4198
|
+
}
|
|
4199
|
+
if (args.description !== void 0) {
|
|
4200
|
+
setClauses.push(`"description" = $${paramIndex++}`);
|
|
4201
|
+
values.push(args.description);
|
|
4202
|
+
}
|
|
4203
|
+
if (args.metadata !== void 0) {
|
|
4204
|
+
setClauses.push(`"metadata" = $${paramIndex++}`);
|
|
4205
|
+
values.push(JSON.stringify(args.metadata));
|
|
4206
|
+
}
|
|
4207
|
+
if (args.inputSchema !== void 0) {
|
|
4208
|
+
setClauses.push(`"inputSchema" = $${paramIndex++}`);
|
|
4209
|
+
values.push(args.inputSchema === null ? null : JSON.stringify(args.inputSchema));
|
|
4210
|
+
}
|
|
4211
|
+
if (args.groundTruthSchema !== void 0) {
|
|
4212
|
+
setClauses.push(`"groundTruthSchema" = $${paramIndex++}`);
|
|
4213
|
+
values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
|
|
4214
|
+
}
|
|
4215
|
+
values.push(args.id);
|
|
4216
|
+
await this.#db.client.none(
|
|
4217
|
+
`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`,
|
|
4218
|
+
values
|
|
4219
|
+
);
|
|
4220
|
+
return {
|
|
4221
|
+
...existing,
|
|
4222
|
+
name: args.name ?? existing.name,
|
|
4223
|
+
description: args.description ?? existing.description,
|
|
4224
|
+
metadata: args.metadata ?? existing.metadata,
|
|
4225
|
+
inputSchema: args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema,
|
|
4226
|
+
groundTruthSchema: args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema,
|
|
4227
|
+
updatedAt: new Date(now)
|
|
4228
|
+
};
|
|
4229
|
+
} catch (error) {
|
|
4230
|
+
if (error instanceof MastraError) throw error;
|
|
4231
|
+
throw new MastraError(
|
|
4232
|
+
{
|
|
4233
|
+
id: createStorageErrorId("PG", "UPDATE_DATASET", "FAILED"),
|
|
4234
|
+
domain: ErrorDomain.STORAGE,
|
|
4235
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4236
|
+
},
|
|
4237
|
+
error
|
|
4238
|
+
);
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
async deleteDataset({ id }) {
|
|
4242
|
+
try {
|
|
4243
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4244
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4245
|
+
const versionsTable = getTableName2({
|
|
4246
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4247
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4248
|
+
});
|
|
4249
|
+
const experimentsTable = getTableName2({ indexName: TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
|
|
4250
|
+
const experimentResultsTable = getTableName2({
|
|
4251
|
+
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
4252
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4253
|
+
});
|
|
4254
|
+
try {
|
|
4255
|
+
await this.#db.client.none(
|
|
4256
|
+
`DELETE FROM ${experimentResultsTable} WHERE "experimentId" IN (SELECT "id" FROM ${experimentsTable} WHERE "datasetId" = $1)`,
|
|
4257
|
+
[id]
|
|
4258
|
+
);
|
|
4259
|
+
} catch {
|
|
4260
|
+
}
|
|
4261
|
+
try {
|
|
4262
|
+
await this.#db.client.none(
|
|
4263
|
+
`UPDATE ${experimentsTable} SET "datasetId" = NULL, "datasetVersion" = NULL WHERE "datasetId" = $1`,
|
|
4264
|
+
[id]
|
|
4265
|
+
);
|
|
4266
|
+
} catch {
|
|
4267
|
+
}
|
|
4268
|
+
await this.#db.client.tx(async (t) => {
|
|
4269
|
+
await t.none(`DELETE FROM ${versionsTable} WHERE "datasetId" = $1`, [id]);
|
|
4270
|
+
await t.none(`DELETE FROM ${itemsTable} WHERE "datasetId" = $1`, [id]);
|
|
4271
|
+
await t.none(`DELETE FROM ${datasetsTable} WHERE "id" = $1`, [id]);
|
|
4272
|
+
});
|
|
4273
|
+
} catch (error) {
|
|
4274
|
+
if (error instanceof MastraError) throw error;
|
|
4275
|
+
throw new MastraError(
|
|
4276
|
+
{
|
|
4277
|
+
id: createStorageErrorId("PG", "DELETE_DATASET", "FAILED"),
|
|
4278
|
+
domain: ErrorDomain.STORAGE,
|
|
4279
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4280
|
+
},
|
|
4281
|
+
error
|
|
4282
|
+
);
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
async listDatasets(args) {
|
|
4286
|
+
try {
|
|
4287
|
+
const { page, perPage: perPageInput } = args.pagination;
|
|
4288
|
+
const tableName = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4289
|
+
const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
|
|
4290
|
+
const total = parseInt(countResult.count, 10);
|
|
4291
|
+
if (total === 0) {
|
|
4292
|
+
return { datasets: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
4293
|
+
}
|
|
4294
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
4295
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
4296
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
4297
|
+
const rows = await this.#db.client.manyOrNone(
|
|
4298
|
+
`SELECT * FROM ${tableName} ORDER BY "createdAt" DESC LIMIT $1 OFFSET $2`,
|
|
4299
|
+
[limitValue, offset]
|
|
4300
|
+
);
|
|
4301
|
+
return {
|
|
4302
|
+
datasets: (rows || []).map((row) => this.transformDatasetRow(row)),
|
|
4303
|
+
pagination: {
|
|
4304
|
+
total,
|
|
4305
|
+
page,
|
|
4306
|
+
perPage: perPageForResponse,
|
|
4307
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
4308
|
+
}
|
|
4309
|
+
};
|
|
4310
|
+
} catch (error) {
|
|
4311
|
+
throw new MastraError(
|
|
4312
|
+
{
|
|
4313
|
+
id: createStorageErrorId("PG", "LIST_DATASETS", "FAILED"),
|
|
4314
|
+
domain: ErrorDomain.STORAGE,
|
|
4315
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4316
|
+
},
|
|
4317
|
+
error
|
|
4318
|
+
);
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
// --- SCD-2 mutations ---
|
|
4322
|
+
async _doAddItem(args) {
|
|
4323
|
+
try {
|
|
4324
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4325
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4326
|
+
const versionsTable = getTableName2({
|
|
4327
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4328
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4329
|
+
});
|
|
4330
|
+
const id = crypto.randomUUID();
|
|
4331
|
+
const versionId = crypto.randomUUID();
|
|
4332
|
+
const now = /* @__PURE__ */ new Date();
|
|
4333
|
+
const nowIso = now.toISOString();
|
|
4334
|
+
let newVersion;
|
|
4335
|
+
await this.#db.client.tx(async (t) => {
|
|
4336
|
+
const row = await t.one(
|
|
4337
|
+
`UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
|
|
4338
|
+
[args.datasetId]
|
|
4339
|
+
);
|
|
4340
|
+
newVersion = row.version;
|
|
4341
|
+
await t.none(
|
|
4342
|
+
`INSERT INTO ${itemsTable} ("id","datasetId","datasetVersion","validTo","isDeleted","input","groundTruth","metadata","createdAt","createdAtZ","updatedAt","updatedAtZ") VALUES ($1,$2,$3,NULL,false,$4,$5,$6,$7,$8,$9,$10)`,
|
|
4343
|
+
[
|
|
4344
|
+
id,
|
|
4345
|
+
args.datasetId,
|
|
4346
|
+
newVersion,
|
|
4347
|
+
JSON.stringify(args.input),
|
|
4348
|
+
jsonbArg(args.groundTruth),
|
|
4349
|
+
jsonbArg(args.metadata),
|
|
4350
|
+
nowIso,
|
|
4351
|
+
nowIso,
|
|
4352
|
+
nowIso,
|
|
4353
|
+
nowIso
|
|
4354
|
+
]
|
|
4355
|
+
);
|
|
4356
|
+
await t.none(
|
|
4357
|
+
`INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
|
|
4358
|
+
[versionId, args.datasetId, newVersion, nowIso, nowIso]
|
|
4359
|
+
);
|
|
4360
|
+
});
|
|
4361
|
+
return {
|
|
4362
|
+
id,
|
|
4363
|
+
datasetId: args.datasetId,
|
|
4364
|
+
datasetVersion: newVersion,
|
|
4365
|
+
input: args.input,
|
|
4366
|
+
groundTruth: args.groundTruth,
|
|
4367
|
+
metadata: args.metadata,
|
|
4368
|
+
createdAt: now,
|
|
4369
|
+
updatedAt: now
|
|
4370
|
+
};
|
|
4371
|
+
} catch (error) {
|
|
4372
|
+
if (error instanceof MastraError) throw error;
|
|
4373
|
+
throw new MastraError(
|
|
4374
|
+
{
|
|
4375
|
+
id: createStorageErrorId("PG", "ADD_ITEM", "FAILED"),
|
|
4376
|
+
domain: ErrorDomain.STORAGE,
|
|
4377
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4378
|
+
},
|
|
4379
|
+
error
|
|
4380
|
+
);
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
async _doUpdateItem(args) {
|
|
4384
|
+
try {
|
|
4385
|
+
const existing = await this.getItemById({ id: args.id });
|
|
4386
|
+
if (!existing) {
|
|
4387
|
+
throw new MastraError({
|
|
4388
|
+
id: createStorageErrorId("PG", "UPDATE_ITEM", "NOT_FOUND"),
|
|
4389
|
+
domain: ErrorDomain.STORAGE,
|
|
4390
|
+
category: ErrorCategory.USER,
|
|
4391
|
+
details: { itemId: args.id }
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
if (existing.datasetId !== args.datasetId) {
|
|
4395
|
+
throw new MastraError({
|
|
4396
|
+
id: createStorageErrorId("PG", "UPDATE_ITEM", "DATASET_MISMATCH"),
|
|
4397
|
+
domain: ErrorDomain.STORAGE,
|
|
4398
|
+
category: ErrorCategory.USER,
|
|
4399
|
+
details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
|
|
4400
|
+
});
|
|
4401
|
+
}
|
|
4402
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4403
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4404
|
+
const versionsTable = getTableName2({
|
|
4405
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4406
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4407
|
+
});
|
|
4408
|
+
const versionId = crypto.randomUUID();
|
|
4409
|
+
const now = /* @__PURE__ */ new Date();
|
|
4410
|
+
const nowIso = now.toISOString();
|
|
4411
|
+
const mergedInput = args.input ?? existing.input;
|
|
4412
|
+
const mergedGroundTruth = args.groundTruth ?? existing.groundTruth;
|
|
4413
|
+
const mergedMetadata = args.metadata ?? existing.metadata;
|
|
4414
|
+
let newVersion;
|
|
4415
|
+
await this.#db.client.tx(async (t) => {
|
|
4416
|
+
const row = await t.one(
|
|
4417
|
+
`UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
|
|
4418
|
+
[args.datasetId]
|
|
4419
|
+
);
|
|
4420
|
+
newVersion = row.version;
|
|
4421
|
+
await t.none(
|
|
4422
|
+
`UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
|
|
4423
|
+
[newVersion, args.id]
|
|
4424
|
+
);
|
|
4425
|
+
await t.none(
|
|
4426
|
+
`INSERT INTO ${itemsTable} ("id","datasetId","datasetVersion","validTo","isDeleted","input","groundTruth","metadata","createdAt","createdAtZ","updatedAt","updatedAtZ") VALUES ($1,$2,$3,NULL,false,$4,$5,$6,$7,$8,$9,$10)`,
|
|
4427
|
+
[
|
|
4428
|
+
args.id,
|
|
4429
|
+
args.datasetId,
|
|
4430
|
+
newVersion,
|
|
4431
|
+
JSON.stringify(mergedInput),
|
|
4432
|
+
jsonbArg(mergedGroundTruth),
|
|
4433
|
+
jsonbArg(mergedMetadata),
|
|
4434
|
+
existing.createdAt.toISOString(),
|
|
4435
|
+
existing.createdAt.toISOString(),
|
|
4436
|
+
nowIso,
|
|
4437
|
+
nowIso
|
|
4438
|
+
]
|
|
4439
|
+
);
|
|
4440
|
+
await t.none(
|
|
4441
|
+
`INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
|
|
4442
|
+
[versionId, args.datasetId, newVersion, nowIso, nowIso]
|
|
4443
|
+
);
|
|
4444
|
+
});
|
|
4445
|
+
return {
|
|
4446
|
+
...existing,
|
|
4447
|
+
datasetVersion: newVersion,
|
|
4448
|
+
input: mergedInput,
|
|
4449
|
+
groundTruth: mergedGroundTruth,
|
|
4450
|
+
metadata: mergedMetadata,
|
|
4451
|
+
updatedAt: now
|
|
4452
|
+
};
|
|
4453
|
+
} catch (error) {
|
|
4454
|
+
if (error instanceof MastraError) throw error;
|
|
4455
|
+
throw new MastraError(
|
|
4456
|
+
{
|
|
4457
|
+
id: createStorageErrorId("PG", "UPDATE_ITEM", "FAILED"),
|
|
4458
|
+
domain: ErrorDomain.STORAGE,
|
|
4459
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4460
|
+
},
|
|
4461
|
+
error
|
|
4462
|
+
);
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
async _doDeleteItem({ id, datasetId }) {
|
|
4466
|
+
try {
|
|
4467
|
+
const existing = await this.getItemById({ id });
|
|
4468
|
+
if (!existing) return;
|
|
4469
|
+
if (existing.datasetId !== datasetId) {
|
|
4470
|
+
throw new MastraError({
|
|
4471
|
+
id: createStorageErrorId("PG", "DELETE_ITEM", "DATASET_MISMATCH"),
|
|
4472
|
+
domain: ErrorDomain.STORAGE,
|
|
4473
|
+
category: ErrorCategory.USER,
|
|
4474
|
+
details: { itemId: id, expectedDatasetId: datasetId, actualDatasetId: existing.datasetId }
|
|
4475
|
+
});
|
|
4476
|
+
}
|
|
4477
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4478
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4479
|
+
const versionsTable = getTableName2({
|
|
4480
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4481
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4482
|
+
});
|
|
4483
|
+
const versionId = crypto.randomUUID();
|
|
4484
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
4485
|
+
await this.#db.client.tx(async (t) => {
|
|
4486
|
+
const row = await t.one(
|
|
4487
|
+
`UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
|
|
4488
|
+
[datasetId]
|
|
4489
|
+
);
|
|
4490
|
+
const newVersion = row.version;
|
|
4491
|
+
await t.none(
|
|
4492
|
+
`UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
|
|
4493
|
+
[newVersion, id]
|
|
4494
|
+
);
|
|
4495
|
+
await t.none(
|
|
4496
|
+
`INSERT INTO ${itemsTable} ("id","datasetId","datasetVersion","validTo","isDeleted","input","groundTruth","metadata","createdAt","createdAtZ","updatedAt","updatedAtZ") VALUES ($1,$2,$3,NULL,true,$4,$5,$6,$7,$8,$9,$10)`,
|
|
4497
|
+
[
|
|
4498
|
+
id,
|
|
4499
|
+
datasetId,
|
|
4500
|
+
newVersion,
|
|
4501
|
+
JSON.stringify(existing.input),
|
|
4502
|
+
jsonbArg(existing.groundTruth),
|
|
4503
|
+
jsonbArg(existing.metadata),
|
|
4504
|
+
existing.createdAt.toISOString(),
|
|
4505
|
+
existing.createdAt.toISOString(),
|
|
4506
|
+
nowIso,
|
|
4507
|
+
nowIso
|
|
4508
|
+
]
|
|
4509
|
+
);
|
|
4510
|
+
await t.none(
|
|
4511
|
+
`INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
|
|
4512
|
+
[versionId, datasetId, newVersion, nowIso, nowIso]
|
|
4513
|
+
);
|
|
4514
|
+
});
|
|
4515
|
+
} catch (error) {
|
|
4516
|
+
if (error instanceof MastraError) throw error;
|
|
4517
|
+
throw new MastraError(
|
|
4518
|
+
{
|
|
4519
|
+
id: createStorageErrorId("PG", "DELETE_ITEM", "FAILED"),
|
|
4520
|
+
domain: ErrorDomain.STORAGE,
|
|
4521
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4522
|
+
},
|
|
4523
|
+
error
|
|
4524
|
+
);
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
async _doBatchInsertItems(input) {
|
|
4528
|
+
try {
|
|
4529
|
+
const dataset = await this.getDatasetById({ id: input.datasetId });
|
|
4530
|
+
if (!dataset) {
|
|
4531
|
+
throw new MastraError({
|
|
4532
|
+
id: createStorageErrorId("PG", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
|
|
4533
|
+
domain: ErrorDomain.STORAGE,
|
|
4534
|
+
category: ErrorCategory.USER,
|
|
4535
|
+
details: { datasetId: input.datasetId }
|
|
4536
|
+
});
|
|
4537
|
+
}
|
|
4538
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4539
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4540
|
+
const versionsTable = getTableName2({
|
|
4541
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4542
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4543
|
+
});
|
|
4544
|
+
const now = /* @__PURE__ */ new Date();
|
|
4545
|
+
const nowIso = now.toISOString();
|
|
4546
|
+
const versionId = crypto.randomUUID();
|
|
4547
|
+
const itemsWithIds = input.items.map((itemInput) => ({ id: crypto.randomUUID(), input: itemInput }));
|
|
4548
|
+
let newVersion;
|
|
4549
|
+
await this.#db.client.tx(async (t) => {
|
|
4550
|
+
const row = await t.one(
|
|
4551
|
+
`UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
|
|
4552
|
+
[input.datasetId]
|
|
4553
|
+
);
|
|
4554
|
+
newVersion = row.version;
|
|
4555
|
+
for (const { id, input: itemInput } of itemsWithIds) {
|
|
4556
|
+
await t.none(
|
|
4557
|
+
`INSERT INTO ${itemsTable} ("id","datasetId","datasetVersion","validTo","isDeleted","input","groundTruth","metadata","createdAt","createdAtZ","updatedAt","updatedAtZ") VALUES ($1,$2,$3,NULL,false,$4,$5,$6,$7,$8,$9,$10)`,
|
|
4558
|
+
[
|
|
4559
|
+
id,
|
|
4560
|
+
input.datasetId,
|
|
4561
|
+
newVersion,
|
|
4562
|
+
JSON.stringify(itemInput.input),
|
|
4563
|
+
jsonbArg(itemInput.groundTruth),
|
|
4564
|
+
jsonbArg(itemInput.metadata),
|
|
4565
|
+
nowIso,
|
|
4566
|
+
nowIso,
|
|
4567
|
+
nowIso,
|
|
4568
|
+
nowIso
|
|
4569
|
+
]
|
|
4570
|
+
);
|
|
4571
|
+
}
|
|
4572
|
+
await t.none(
|
|
4573
|
+
`INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
|
|
4574
|
+
[versionId, input.datasetId, newVersion, nowIso, nowIso]
|
|
4575
|
+
);
|
|
4576
|
+
});
|
|
4577
|
+
return itemsWithIds.map(({ id, input: itemInput }) => ({
|
|
4578
|
+
id,
|
|
4579
|
+
datasetId: input.datasetId,
|
|
4580
|
+
datasetVersion: newVersion,
|
|
4581
|
+
input: itemInput.input,
|
|
4582
|
+
groundTruth: itemInput.groundTruth,
|
|
4583
|
+
metadata: itemInput.metadata,
|
|
4584
|
+
createdAt: now,
|
|
4585
|
+
updatedAt: now
|
|
4586
|
+
}));
|
|
4587
|
+
} catch (error) {
|
|
4588
|
+
if (error instanceof MastraError) throw error;
|
|
4589
|
+
throw new MastraError(
|
|
4590
|
+
{
|
|
4591
|
+
id: createStorageErrorId("PG", "BULK_ADD_ITEMS", "FAILED"),
|
|
4592
|
+
domain: ErrorDomain.STORAGE,
|
|
4593
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4594
|
+
},
|
|
4595
|
+
error
|
|
4596
|
+
);
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
async _doBatchDeleteItems(input) {
|
|
4600
|
+
try {
|
|
4601
|
+
const dataset = await this.getDatasetById({ id: input.datasetId });
|
|
4602
|
+
if (!dataset) {
|
|
4603
|
+
throw new MastraError({
|
|
4604
|
+
id: createStorageErrorId("PG", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
|
|
4605
|
+
domain: ErrorDomain.STORAGE,
|
|
4606
|
+
category: ErrorCategory.USER,
|
|
4607
|
+
details: { datasetId: input.datasetId }
|
|
4608
|
+
});
|
|
4609
|
+
}
|
|
4610
|
+
const currentItems = [];
|
|
4611
|
+
for (const itemId of input.itemIds) {
|
|
4612
|
+
const item = await this.getItemById({ id: itemId });
|
|
4613
|
+
if (item && item.datasetId === input.datasetId) {
|
|
4614
|
+
currentItems.push(item);
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
if (currentItems.length === 0) return;
|
|
4618
|
+
const datasetsTable = getTableName2({ indexName: TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
|
|
4619
|
+
const itemsTable = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4620
|
+
const versionsTable = getTableName2({
|
|
4621
|
+
indexName: TABLE_DATASET_VERSIONS,
|
|
4622
|
+
schemaName: getSchemaName2(this.#schema)
|
|
4623
|
+
});
|
|
4624
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
4625
|
+
const versionId = crypto.randomUUID();
|
|
4626
|
+
await this.#db.client.tx(async (t) => {
|
|
4627
|
+
const row = await t.one(
|
|
4628
|
+
`UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
|
|
4629
|
+
[input.datasetId]
|
|
4630
|
+
);
|
|
4631
|
+
const newVersion = row.version;
|
|
4632
|
+
for (const item of currentItems) {
|
|
4633
|
+
await t.none(
|
|
4634
|
+
`UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
|
|
4635
|
+
[newVersion, item.id]
|
|
4636
|
+
);
|
|
4637
|
+
await t.none(
|
|
4638
|
+
`INSERT INTO ${itemsTable} ("id","datasetId","datasetVersion","validTo","isDeleted","input","groundTruth","metadata","createdAt","createdAtZ","updatedAt","updatedAtZ") VALUES ($1,$2,$3,NULL,true,$4,$5,$6,$7,$8,$9,$10)`,
|
|
4639
|
+
[
|
|
4640
|
+
item.id,
|
|
4641
|
+
input.datasetId,
|
|
4642
|
+
newVersion,
|
|
4643
|
+
JSON.stringify(item.input),
|
|
4644
|
+
jsonbArg(item.groundTruth),
|
|
4645
|
+
jsonbArg(item.metadata),
|
|
4646
|
+
item.createdAt.toISOString(),
|
|
4647
|
+
item.createdAt.toISOString(),
|
|
4648
|
+
nowIso,
|
|
4649
|
+
nowIso
|
|
4650
|
+
]
|
|
4651
|
+
);
|
|
4652
|
+
}
|
|
4653
|
+
await t.none(
|
|
4654
|
+
`INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
|
|
4655
|
+
[versionId, input.datasetId, newVersion, nowIso, nowIso]
|
|
4656
|
+
);
|
|
4657
|
+
});
|
|
4658
|
+
} catch (error) {
|
|
4659
|
+
if (error instanceof MastraError) throw error;
|
|
4660
|
+
throw new MastraError(
|
|
4661
|
+
{
|
|
4662
|
+
id: createStorageErrorId("PG", "BULK_DELETE_ITEMS", "FAILED"),
|
|
4663
|
+
domain: ErrorDomain.STORAGE,
|
|
4664
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4665
|
+
},
|
|
4666
|
+
error
|
|
4667
|
+
);
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
// --- SCD-2 queries ---
|
|
4671
|
+
async getItemById(args) {
|
|
4672
|
+
try {
|
|
4673
|
+
const tableName = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4674
|
+
let result;
|
|
4675
|
+
if (args.datasetVersion !== void 0) {
|
|
4676
|
+
result = await this.#db.client.oneOrNone(
|
|
4677
|
+
`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" = $2 AND "isDeleted" = false`,
|
|
4678
|
+
[args.id, args.datasetVersion]
|
|
4679
|
+
);
|
|
4680
|
+
} else {
|
|
4681
|
+
result = await this.#db.client.oneOrNone(
|
|
4682
|
+
`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`,
|
|
4683
|
+
[args.id]
|
|
4684
|
+
);
|
|
4685
|
+
}
|
|
4686
|
+
return result ? this.transformItemRow(result) : null;
|
|
4687
|
+
} catch (error) {
|
|
4688
|
+
throw new MastraError(
|
|
4689
|
+
{
|
|
4690
|
+
id: createStorageErrorId("PG", "GET_ITEM", "FAILED"),
|
|
4691
|
+
domain: ErrorDomain.STORAGE,
|
|
4692
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4693
|
+
},
|
|
4694
|
+
error
|
|
4695
|
+
);
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
async getItemsByVersion({ datasetId, version }) {
|
|
4699
|
+
try {
|
|
4700
|
+
const tableName = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4701
|
+
const rows = await this.#db.client.manyOrNone(
|
|
4702
|
+
`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC`,
|
|
4703
|
+
[datasetId, version, version]
|
|
4704
|
+
);
|
|
4705
|
+
return (rows || []).map((row) => this.transformItemRow(row));
|
|
4706
|
+
} catch (error) {
|
|
4707
|
+
throw new MastraError(
|
|
4708
|
+
{
|
|
4709
|
+
id: createStorageErrorId("PG", "GET_ITEMS_BY_VERSION", "FAILED"),
|
|
4710
|
+
domain: ErrorDomain.STORAGE,
|
|
4711
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4712
|
+
},
|
|
4713
|
+
error
|
|
4714
|
+
);
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
async getItemHistory(itemId) {
|
|
4718
|
+
try {
|
|
4719
|
+
const tableName = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4720
|
+
const rows = await this.#db.client.manyOrNone(
|
|
4721
|
+
`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`,
|
|
4722
|
+
[itemId]
|
|
4723
|
+
);
|
|
4724
|
+
return (rows || []).map((row) => this.transformItemRowFull(row));
|
|
4725
|
+
} catch (error) {
|
|
4726
|
+
throw new MastraError(
|
|
4727
|
+
{
|
|
4728
|
+
id: createStorageErrorId("PG", "GET_ITEM_HISTORY", "FAILED"),
|
|
4729
|
+
domain: ErrorDomain.STORAGE,
|
|
4730
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4731
|
+
},
|
|
4732
|
+
error
|
|
4733
|
+
);
|
|
4734
|
+
}
|
|
4735
|
+
}
|
|
4736
|
+
async listItems(args) {
|
|
4737
|
+
try {
|
|
4738
|
+
const { page, perPage: perPageInput } = args.pagination;
|
|
4739
|
+
const tableName = getTableName2({ indexName: TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
|
|
4740
|
+
const conditions = ['"datasetId" = $1'];
|
|
4741
|
+
const queryParams = [args.datasetId];
|
|
4742
|
+
let paramIndex = 2;
|
|
4743
|
+
if (args.version !== void 0) {
|
|
4744
|
+
conditions.push(`"datasetVersion" <= $${paramIndex++}`);
|
|
4745
|
+
queryParams.push(args.version);
|
|
4746
|
+
conditions.push(`("validTo" IS NULL OR "validTo" > $${paramIndex++})`);
|
|
4747
|
+
queryParams.push(args.version);
|
|
4748
|
+
conditions.push(`"isDeleted" = false`);
|
|
4749
|
+
} else {
|
|
4750
|
+
conditions.push(`"validTo" IS NULL`);
|
|
4751
|
+
conditions.push(`"isDeleted" = false`);
|
|
4752
|
+
}
|
|
4753
|
+
if (args.search) {
|
|
4754
|
+
conditions.push(
|
|
4755
|
+
`("input"::text ILIKE $${paramIndex} OR COALESCE("groundTruth"::text, '') ILIKE $${paramIndex})`
|
|
4756
|
+
);
|
|
4757
|
+
queryParams.push(`%${args.search}%`);
|
|
4758
|
+
paramIndex++;
|
|
4759
|
+
}
|
|
4760
|
+
const whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
4761
|
+
const countResult = await this.#db.client.one(
|
|
4762
|
+
`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
|
|
4763
|
+
queryParams
|
|
4764
|
+
);
|
|
4765
|
+
const total = parseInt(countResult.count, 10);
|
|
4766
|
+
if (total === 0) {
|
|
4767
|
+
return { items: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
4768
|
+
}
|
|
4769
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
4770
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
4771
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
4772
|
+
const rows = await this.#db.client.manyOrNone(
|
|
4773
|
+
`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
|
|
4774
|
+
[...queryParams, limitValue, offset]
|
|
4775
|
+
);
|
|
4776
|
+
return {
|
|
4777
|
+
items: (rows || []).map((row) => this.transformItemRow(row)),
|
|
4778
|
+
pagination: {
|
|
4779
|
+
total,
|
|
4780
|
+
page,
|
|
4781
|
+
perPage: perPageForResponse,
|
|
4782
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
4783
|
+
}
|
|
4784
|
+
};
|
|
4785
|
+
} catch (error) {
|
|
4786
|
+
throw new MastraError(
|
|
4787
|
+
{
|
|
4788
|
+
id: createStorageErrorId("PG", "LIST_ITEMS", "FAILED"),
|
|
4789
|
+
domain: ErrorDomain.STORAGE,
|
|
4790
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4791
|
+
},
|
|
4792
|
+
error
|
|
4793
|
+
);
|
|
4794
|
+
}
|
|
4795
|
+
}
|
|
4796
|
+
// --- Dataset versions ---
|
|
4797
|
+
async createDatasetVersion(datasetId, version) {
|
|
4798
|
+
try {
|
|
4799
|
+
const id = crypto.randomUUID();
|
|
4800
|
+
const now = /* @__PURE__ */ new Date();
|
|
4801
|
+
const nowIso = now.toISOString();
|
|
4802
|
+
await this.#db.insert({
|
|
4803
|
+
tableName: TABLE_DATASET_VERSIONS,
|
|
4804
|
+
record: { id, datasetId, version, createdAt: nowIso }
|
|
4805
|
+
});
|
|
4806
|
+
return { id, datasetId, version, createdAt: now };
|
|
4807
|
+
} catch (error) {
|
|
4808
|
+
throw new MastraError(
|
|
4809
|
+
{
|
|
4810
|
+
id: createStorageErrorId("PG", "CREATE_DATASET_VERSION", "FAILED"),
|
|
4811
|
+
domain: ErrorDomain.STORAGE,
|
|
4812
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4813
|
+
},
|
|
4814
|
+
error
|
|
4815
|
+
);
|
|
4816
|
+
}
|
|
4817
|
+
}
|
|
4818
|
+
async listDatasetVersions(input) {
|
|
4819
|
+
try {
|
|
4820
|
+
const { page, perPage: perPageInput } = input.pagination;
|
|
4821
|
+
const tableName = getTableName2({ indexName: TABLE_DATASET_VERSIONS, schemaName: getSchemaName2(this.#schema) });
|
|
4822
|
+
const countResult = await this.#db.client.one(
|
|
4823
|
+
`SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`,
|
|
4824
|
+
[input.datasetId]
|
|
4825
|
+
);
|
|
4826
|
+
const total = parseInt(countResult.count, 10);
|
|
4827
|
+
if (total === 0) {
|
|
4828
|
+
return { versions: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
4829
|
+
}
|
|
4830
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
4831
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
4832
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
4833
|
+
const rows = await this.#db.client.manyOrNone(
|
|
4834
|
+
`SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`,
|
|
4835
|
+
[input.datasetId, limitValue, offset]
|
|
4836
|
+
);
|
|
4837
|
+
return {
|
|
4838
|
+
versions: (rows || []).map((row) => this.transformDatasetVersionRow(row)),
|
|
4839
|
+
pagination: {
|
|
4840
|
+
total,
|
|
4841
|
+
page,
|
|
4842
|
+
perPage: perPageForResponse,
|
|
4843
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
4844
|
+
}
|
|
4845
|
+
};
|
|
4846
|
+
} catch (error) {
|
|
4847
|
+
throw new MastraError(
|
|
4848
|
+
{
|
|
4849
|
+
id: createStorageErrorId("PG", "LIST_DATASET_VERSIONS", "FAILED"),
|
|
4850
|
+
domain: ErrorDomain.STORAGE,
|
|
4851
|
+
category: ErrorCategory.THIRD_PARTY
|
|
4852
|
+
},
|
|
4853
|
+
error
|
|
4854
|
+
);
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
// --- Clear ---
|
|
4858
|
+
async dangerouslyClearAll() {
|
|
4859
|
+
await this.#db.clearTable({ tableName: TABLE_DATASET_VERSIONS });
|
|
4860
|
+
await this.#db.clearTable({ tableName: TABLE_DATASET_ITEMS });
|
|
4861
|
+
await this.#db.clearTable({ tableName: TABLE_DATASETS });
|
|
4862
|
+
}
|
|
4863
|
+
};
|
|
4864
|
+
var ExperimentsPG = class _ExperimentsPG extends ExperimentsStorage {
|
|
4865
|
+
#db;
|
|
4866
|
+
#schema;
|
|
4867
|
+
#skipDefaultIndexes;
|
|
4868
|
+
#indexes;
|
|
4869
|
+
static MANAGED_TABLES = [TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS];
|
|
4870
|
+
constructor(config) {
|
|
4871
|
+
super();
|
|
4872
|
+
const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
|
|
4873
|
+
this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
|
|
4874
|
+
this.#schema = schemaName || "public";
|
|
4875
|
+
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
4876
|
+
this.#indexes = indexes?.filter((idx) => _ExperimentsPG.MANAGED_TABLES.includes(idx.table));
|
|
4877
|
+
}
|
|
4878
|
+
static getExportDDL(schemaName) {
|
|
4879
|
+
const statements = [];
|
|
4880
|
+
for (const tableName of _ExperimentsPG.MANAGED_TABLES) {
|
|
4881
|
+
statements.push(
|
|
4882
|
+
generateTableSQL({
|
|
4883
|
+
tableName,
|
|
4884
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
4885
|
+
schemaName,
|
|
4886
|
+
includeAllConstraints: true
|
|
4887
|
+
})
|
|
4888
|
+
);
|
|
4889
|
+
}
|
|
4890
|
+
return statements;
|
|
4891
|
+
}
|
|
4892
|
+
async init() {
|
|
4893
|
+
await this.#db.createTable({ tableName: TABLE_EXPERIMENTS, schema: EXPERIMENTS_SCHEMA });
|
|
4894
|
+
await this.#db.createTable({ tableName: TABLE_EXPERIMENT_RESULTS, schema: EXPERIMENT_RESULTS_SCHEMA });
|
|
4895
|
+
await this.createDefaultIndexes();
|
|
4896
|
+
await this.createCustomIndexes();
|
|
4897
|
+
}
|
|
4898
|
+
getDefaultIndexDefinitions() {
|
|
4899
|
+
return [
|
|
4900
|
+
{ name: "idx_experiments_datasetid", table: TABLE_EXPERIMENTS, columns: ["datasetId"] },
|
|
4901
|
+
{ name: "idx_experiment_results_experimentid", table: TABLE_EXPERIMENT_RESULTS, columns: ["experimentId"] },
|
|
4902
|
+
{
|
|
4903
|
+
name: "idx_experiment_results_exp_item",
|
|
4904
|
+
table: TABLE_EXPERIMENT_RESULTS,
|
|
4905
|
+
columns: ["experimentId", "itemId"],
|
|
4906
|
+
unique: true
|
|
4907
|
+
}
|
|
4908
|
+
];
|
|
4909
|
+
}
|
|
4910
|
+
async createDefaultIndexes() {
|
|
4911
|
+
if (this.#skipDefaultIndexes) return;
|
|
4912
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) {
|
|
4913
|
+
try {
|
|
4914
|
+
await this.#db.createIndex(indexDef);
|
|
4915
|
+
} catch (error) {
|
|
4916
|
+
this.logger?.warn?.(`Failed to create default index ${indexDef.name}:`, error);
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4919
|
+
}
|
|
4920
|
+
async createCustomIndexes() {
|
|
4921
|
+
if (!this.#indexes || this.#indexes.length === 0) return;
|
|
4922
|
+
for (const indexDef of this.#indexes) {
|
|
4923
|
+
try {
|
|
4924
|
+
await this.#db.createIndex(indexDef);
|
|
4925
|
+
} catch (error) {
|
|
4926
|
+
this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
|
|
4927
|
+
}
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
// --- Row transformers ---
|
|
4931
|
+
transformExperimentRow(row) {
|
|
4932
|
+
return {
|
|
4933
|
+
id: row.id,
|
|
4934
|
+
name: row.name ?? void 0,
|
|
4935
|
+
description: row.description ?? void 0,
|
|
4936
|
+
metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
|
|
4937
|
+
datasetId: row.datasetId ?? null,
|
|
4938
|
+
datasetVersion: row.datasetVersion != null ? row.datasetVersion : null,
|
|
4939
|
+
targetType: row.targetType,
|
|
4940
|
+
targetId: row.targetId,
|
|
4941
|
+
status: row.status,
|
|
4942
|
+
totalItems: row.totalItems,
|
|
4943
|
+
succeededCount: row.succeededCount,
|
|
4944
|
+
failedCount: row.failedCount,
|
|
4945
|
+
skippedCount: row.skippedCount ?? 0,
|
|
4946
|
+
startedAt: row.startedAt ? ensureDate(row.startedAtZ || row.startedAt) : null,
|
|
4947
|
+
completedAt: row.completedAt ? ensureDate(row.completedAtZ || row.completedAt) : null,
|
|
4948
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt),
|
|
4949
|
+
updatedAt: ensureDate(row.updatedAtZ || row.updatedAt)
|
|
4950
|
+
};
|
|
4951
|
+
}
|
|
4952
|
+
transformExperimentResultRow(row) {
|
|
4953
|
+
return {
|
|
4954
|
+
id: row.id,
|
|
4955
|
+
experimentId: row.experimentId,
|
|
4956
|
+
itemId: row.itemId,
|
|
4957
|
+
itemDatasetVersion: row.itemDatasetVersion != null ? row.itemDatasetVersion : null,
|
|
4958
|
+
input: safelyParseJSON(row.input),
|
|
4959
|
+
output: row.output ? safelyParseJSON(row.output) : null,
|
|
4960
|
+
groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : null,
|
|
4961
|
+
error: row.error ? safelyParseJSON(row.error) : null,
|
|
4962
|
+
startedAt: ensureDate(row.startedAtZ || row.startedAt),
|
|
4963
|
+
completedAt: ensureDate(row.completedAtZ || row.completedAt),
|
|
4964
|
+
retryCount: row.retryCount,
|
|
4965
|
+
traceId: row.traceId ?? null,
|
|
4966
|
+
createdAt: ensureDate(row.createdAtZ || row.createdAt)
|
|
4967
|
+
};
|
|
4968
|
+
}
|
|
4969
|
+
// --- Experiment CRUD ---
|
|
4970
|
+
async createExperiment(input) {
|
|
4971
|
+
try {
|
|
4972
|
+
const id = input.id ?? crypto.randomUUID();
|
|
4973
|
+
const now = /* @__PURE__ */ new Date();
|
|
4974
|
+
const nowIso = now.toISOString();
|
|
4975
|
+
await this.#db.insert({
|
|
4976
|
+
tableName: TABLE_EXPERIMENTS,
|
|
4977
|
+
record: {
|
|
4978
|
+
id,
|
|
4979
|
+
name: input.name ?? null,
|
|
4980
|
+
description: input.description ?? null,
|
|
4981
|
+
metadata: input.metadata ?? null,
|
|
4982
|
+
datasetId: input.datasetId ?? null,
|
|
4983
|
+
datasetVersion: input.datasetVersion ?? null,
|
|
4984
|
+
targetType: input.targetType,
|
|
4985
|
+
targetId: input.targetId,
|
|
4986
|
+
status: "pending",
|
|
4987
|
+
totalItems: input.totalItems,
|
|
4988
|
+
succeededCount: 0,
|
|
4989
|
+
failedCount: 0,
|
|
4990
|
+
skippedCount: 0,
|
|
4991
|
+
startedAt: null,
|
|
4992
|
+
completedAt: null,
|
|
4993
|
+
createdAt: nowIso,
|
|
4994
|
+
updatedAt: nowIso
|
|
4995
|
+
}
|
|
4996
|
+
});
|
|
4997
|
+
return {
|
|
4998
|
+
id,
|
|
4999
|
+
name: input.name,
|
|
5000
|
+
description: input.description,
|
|
5001
|
+
metadata: input.metadata,
|
|
5002
|
+
datasetId: input.datasetId ?? null,
|
|
5003
|
+
datasetVersion: input.datasetVersion ?? null,
|
|
5004
|
+
targetType: input.targetType,
|
|
5005
|
+
targetId: input.targetId,
|
|
5006
|
+
status: "pending",
|
|
5007
|
+
totalItems: input.totalItems,
|
|
5008
|
+
succeededCount: 0,
|
|
5009
|
+
failedCount: 0,
|
|
5010
|
+
skippedCount: 0,
|
|
5011
|
+
startedAt: null,
|
|
5012
|
+
completedAt: null,
|
|
5013
|
+
createdAt: now,
|
|
5014
|
+
updatedAt: now
|
|
5015
|
+
};
|
|
5016
|
+
} catch (error) {
|
|
5017
|
+
throw new MastraError(
|
|
5018
|
+
{
|
|
5019
|
+
id: createStorageErrorId("PG", "CREATE_EXPERIMENT", "FAILED"),
|
|
5020
|
+
domain: ErrorDomain.STORAGE,
|
|
5021
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5022
|
+
},
|
|
5023
|
+
error
|
|
5024
|
+
);
|
|
5025
|
+
}
|
|
5026
|
+
}
|
|
5027
|
+
async updateExperiment(input) {
|
|
5028
|
+
try {
|
|
5029
|
+
const existing = await this.getExperimentById({ id: input.id });
|
|
5030
|
+
if (!existing) {
|
|
5031
|
+
throw new MastraError({
|
|
5032
|
+
id: createStorageErrorId("PG", "UPDATE_EXPERIMENT", "NOT_FOUND"),
|
|
5033
|
+
domain: ErrorDomain.STORAGE,
|
|
5034
|
+
category: ErrorCategory.USER,
|
|
5035
|
+
details: { experimentId: input.id }
|
|
5036
|
+
});
|
|
5037
|
+
}
|
|
5038
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5039
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5040
|
+
const setClauses = ['"updatedAt" = $1', '"updatedAtZ" = $2'];
|
|
5041
|
+
const values = [now, now];
|
|
5042
|
+
let paramIndex = 3;
|
|
5043
|
+
if (input.name !== void 0) {
|
|
5044
|
+
setClauses.push(`"name" = $${paramIndex++}`);
|
|
5045
|
+
values.push(input.name);
|
|
5046
|
+
}
|
|
5047
|
+
if (input.description !== void 0) {
|
|
5048
|
+
setClauses.push(`"description" = $${paramIndex++}`);
|
|
5049
|
+
values.push(input.description);
|
|
5050
|
+
}
|
|
5051
|
+
if (input.metadata !== void 0) {
|
|
5052
|
+
setClauses.push(`"metadata" = $${paramIndex++}`);
|
|
5053
|
+
values.push(JSON.stringify(input.metadata));
|
|
5054
|
+
}
|
|
5055
|
+
if (input.status !== void 0) {
|
|
5056
|
+
setClauses.push(`"status" = $${paramIndex++}`);
|
|
5057
|
+
values.push(input.status);
|
|
5058
|
+
}
|
|
5059
|
+
if (input.succeededCount !== void 0) {
|
|
5060
|
+
setClauses.push(`"succeededCount" = $${paramIndex++}`);
|
|
5061
|
+
values.push(input.succeededCount);
|
|
5062
|
+
}
|
|
5063
|
+
if (input.failedCount !== void 0) {
|
|
5064
|
+
setClauses.push(`"failedCount" = $${paramIndex++}`);
|
|
5065
|
+
values.push(input.failedCount);
|
|
5066
|
+
}
|
|
5067
|
+
if (input.skippedCount !== void 0) {
|
|
5068
|
+
setClauses.push(`"skippedCount" = $${paramIndex++}`);
|
|
5069
|
+
values.push(input.skippedCount);
|
|
5070
|
+
}
|
|
5071
|
+
if (input.startedAt !== void 0) {
|
|
5072
|
+
setClauses.push(`"startedAt" = $${paramIndex++}`);
|
|
5073
|
+
values.push(input.startedAt?.toISOString() ?? null);
|
|
5074
|
+
}
|
|
5075
|
+
if (input.completedAt !== void 0) {
|
|
5076
|
+
setClauses.push(`"completedAt" = $${paramIndex++}`);
|
|
5077
|
+
values.push(input.completedAt?.toISOString() ?? null);
|
|
5078
|
+
}
|
|
5079
|
+
values.push(input.id);
|
|
5080
|
+
await this.#db.client.none(
|
|
5081
|
+
`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`,
|
|
5082
|
+
values
|
|
5083
|
+
);
|
|
5084
|
+
const updated = await this.getExperimentById({ id: input.id });
|
|
5085
|
+
return updated;
|
|
5086
|
+
} catch (error) {
|
|
5087
|
+
if (error instanceof MastraError) throw error;
|
|
5088
|
+
throw new MastraError(
|
|
5089
|
+
{
|
|
5090
|
+
id: createStorageErrorId("PG", "UPDATE_EXPERIMENT", "FAILED"),
|
|
5091
|
+
domain: ErrorDomain.STORAGE,
|
|
5092
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5093
|
+
},
|
|
5094
|
+
error
|
|
5095
|
+
);
|
|
5096
|
+
}
|
|
5097
|
+
}
|
|
5098
|
+
async getExperimentById({ id }) {
|
|
5099
|
+
try {
|
|
5100
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5101
|
+
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
|
|
5102
|
+
return result ? this.transformExperimentRow(result) : null;
|
|
5103
|
+
} catch (error) {
|
|
5104
|
+
throw new MastraError(
|
|
5105
|
+
{
|
|
5106
|
+
id: createStorageErrorId("PG", "GET_EXPERIMENT", "FAILED"),
|
|
5107
|
+
domain: ErrorDomain.STORAGE,
|
|
5108
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5109
|
+
},
|
|
5110
|
+
error
|
|
5111
|
+
);
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
async listExperiments(args) {
|
|
5115
|
+
try {
|
|
5116
|
+
const { page, perPage: perPageInput } = args.pagination;
|
|
5117
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5118
|
+
const conditions = [];
|
|
5119
|
+
const queryParams = [];
|
|
5120
|
+
let paramIndex = 1;
|
|
5121
|
+
if (args.datasetId) {
|
|
5122
|
+
conditions.push(`"datasetId" = $${paramIndex++}`);
|
|
5123
|
+
queryParams.push(args.datasetId);
|
|
5124
|
+
}
|
|
5125
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
5126
|
+
const countResult = await this.#db.client.one(
|
|
5127
|
+
`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
|
|
5128
|
+
queryParams
|
|
5129
|
+
);
|
|
5130
|
+
const total = parseInt(countResult.count, 10);
|
|
5131
|
+
if (total === 0) {
|
|
5132
|
+
return { experiments: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
5133
|
+
}
|
|
5134
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
5135
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
5136
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
5137
|
+
const rows = await this.#db.client.manyOrNone(
|
|
5138
|
+
`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
|
|
5139
|
+
[...queryParams, limitValue, offset]
|
|
5140
|
+
);
|
|
5141
|
+
return {
|
|
5142
|
+
experiments: (rows || []).map((row) => this.transformExperimentRow(row)),
|
|
5143
|
+
pagination: {
|
|
5144
|
+
total,
|
|
5145
|
+
page,
|
|
5146
|
+
perPage: perPageForResponse,
|
|
5147
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
5148
|
+
}
|
|
5149
|
+
};
|
|
5150
|
+
} catch (error) {
|
|
5151
|
+
throw new MastraError(
|
|
5152
|
+
{
|
|
5153
|
+
id: createStorageErrorId("PG", "LIST_EXPERIMENTS", "FAILED"),
|
|
5154
|
+
domain: ErrorDomain.STORAGE,
|
|
5155
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5156
|
+
},
|
|
5157
|
+
error
|
|
5158
|
+
);
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5161
|
+
async deleteExperiment({ id }) {
|
|
5162
|
+
try {
|
|
5163
|
+
const resultsTable = getTableName2({
|
|
5164
|
+
indexName: TABLE_EXPERIMENT_RESULTS,
|
|
5165
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5166
|
+
});
|
|
5167
|
+
const experimentsTable = getTableName2({ indexName: TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5168
|
+
await this.#db.client.none(`DELETE FROM ${resultsTable} WHERE "experimentId" = $1`, [id]);
|
|
5169
|
+
await this.#db.client.none(`DELETE FROM ${experimentsTable} WHERE "id" = $1`, [id]);
|
|
5170
|
+
} catch (error) {
|
|
5171
|
+
throw new MastraError(
|
|
5172
|
+
{
|
|
5173
|
+
id: createStorageErrorId("PG", "DELETE_EXPERIMENT", "FAILED"),
|
|
5174
|
+
domain: ErrorDomain.STORAGE,
|
|
5175
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5176
|
+
},
|
|
5177
|
+
error
|
|
5178
|
+
);
|
|
5179
|
+
}
|
|
5180
|
+
}
|
|
5181
|
+
// --- Experiment results ---
|
|
5182
|
+
async addExperimentResult(input) {
|
|
5183
|
+
try {
|
|
5184
|
+
const id = input.id ?? crypto.randomUUID();
|
|
5185
|
+
const now = /* @__PURE__ */ new Date();
|
|
5186
|
+
const nowIso = now.toISOString();
|
|
5187
|
+
await this.#db.insert({
|
|
5188
|
+
tableName: TABLE_EXPERIMENT_RESULTS,
|
|
5189
|
+
record: {
|
|
5190
|
+
id,
|
|
5191
|
+
experimentId: input.experimentId,
|
|
5192
|
+
itemId: input.itemId,
|
|
5193
|
+
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
5194
|
+
input: input.input,
|
|
5195
|
+
output: input.output ?? null,
|
|
5196
|
+
groundTruth: input.groundTruth ?? null,
|
|
5197
|
+
error: input.error ?? null,
|
|
5198
|
+
startedAt: input.startedAt.toISOString(),
|
|
5199
|
+
completedAt: input.completedAt.toISOString(),
|
|
5200
|
+
retryCount: input.retryCount,
|
|
5201
|
+
traceId: input.traceId ?? null,
|
|
5202
|
+
createdAt: nowIso
|
|
5203
|
+
}
|
|
5204
|
+
});
|
|
5205
|
+
return {
|
|
5206
|
+
id,
|
|
5207
|
+
experimentId: input.experimentId,
|
|
5208
|
+
itemId: input.itemId,
|
|
5209
|
+
itemDatasetVersion: input.itemDatasetVersion ?? null,
|
|
5210
|
+
input: input.input,
|
|
5211
|
+
output: input.output ?? null,
|
|
5212
|
+
groundTruth: input.groundTruth ?? null,
|
|
5213
|
+
error: input.error ?? null,
|
|
5214
|
+
startedAt: input.startedAt,
|
|
5215
|
+
completedAt: input.completedAt,
|
|
5216
|
+
retryCount: input.retryCount,
|
|
5217
|
+
traceId: input.traceId ?? null,
|
|
5218
|
+
createdAt: now
|
|
5219
|
+
};
|
|
5220
|
+
} catch (error) {
|
|
5221
|
+
throw new MastraError(
|
|
5222
|
+
{
|
|
5223
|
+
id: createStorageErrorId("PG", "ADD_EXPERIMENT_RESULT", "FAILED"),
|
|
5224
|
+
domain: ErrorDomain.STORAGE,
|
|
5225
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5226
|
+
},
|
|
5227
|
+
error
|
|
5228
|
+
);
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
async getExperimentResultById({ id }) {
|
|
5232
|
+
try {
|
|
5233
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
|
|
5234
|
+
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
|
|
5235
|
+
return result ? this.transformExperimentResultRow(result) : null;
|
|
5236
|
+
} catch (error) {
|
|
5237
|
+
throw new MastraError(
|
|
5238
|
+
{
|
|
5239
|
+
id: createStorageErrorId("PG", "GET_EXPERIMENT_RESULT", "FAILED"),
|
|
5240
|
+
domain: ErrorDomain.STORAGE,
|
|
5241
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5242
|
+
},
|
|
5243
|
+
error
|
|
5244
|
+
);
|
|
5245
|
+
}
|
|
5246
|
+
}
|
|
5247
|
+
async listExperimentResults(args) {
|
|
5248
|
+
try {
|
|
5249
|
+
const { page, perPage: perPageInput } = args.pagination;
|
|
5250
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
|
|
5251
|
+
const countResult = await this.#db.client.one(
|
|
5252
|
+
`SELECT COUNT(*) as count FROM ${tableName} WHERE "experimentId" = $1`,
|
|
5253
|
+
[args.experimentId]
|
|
5254
|
+
);
|
|
5255
|
+
const total = parseInt(countResult.count, 10);
|
|
5256
|
+
if (total === 0) {
|
|
5257
|
+
return { results: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
|
|
5258
|
+
}
|
|
5259
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
5260
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
5261
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
5262
|
+
const rows = await this.#db.client.manyOrNone(
|
|
5263
|
+
`SELECT * FROM ${tableName} WHERE "experimentId" = $1 ORDER BY "startedAt" ASC LIMIT $2 OFFSET $3`,
|
|
5264
|
+
[args.experimentId, limitValue, offset]
|
|
5265
|
+
);
|
|
5266
|
+
return {
|
|
5267
|
+
results: (rows || []).map((row) => this.transformExperimentResultRow(row)),
|
|
5268
|
+
pagination: {
|
|
5269
|
+
total,
|
|
5270
|
+
page,
|
|
5271
|
+
perPage: perPageForResponse,
|
|
5272
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
5273
|
+
}
|
|
5274
|
+
};
|
|
5275
|
+
} catch (error) {
|
|
5276
|
+
throw new MastraError(
|
|
5277
|
+
{
|
|
5278
|
+
id: createStorageErrorId("PG", "LIST_EXPERIMENT_RESULTS", "FAILED"),
|
|
5279
|
+
domain: ErrorDomain.STORAGE,
|
|
5280
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5281
|
+
},
|
|
5282
|
+
error
|
|
5283
|
+
);
|
|
5284
|
+
}
|
|
5285
|
+
}
|
|
5286
|
+
async deleteExperimentResults({ experimentId }) {
|
|
5287
|
+
try {
|
|
5288
|
+
const tableName = getTableName2({ indexName: TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
|
|
5289
|
+
await this.#db.client.none(`DELETE FROM ${tableName} WHERE "experimentId" = $1`, [experimentId]);
|
|
5290
|
+
} catch (error) {
|
|
5291
|
+
throw new MastraError(
|
|
5292
|
+
{
|
|
5293
|
+
id: createStorageErrorId("PG", "DELETE_EXPERIMENT_RESULTS", "FAILED"),
|
|
5294
|
+
domain: ErrorDomain.STORAGE,
|
|
5295
|
+
category: ErrorCategory.THIRD_PARTY
|
|
5296
|
+
},
|
|
5297
|
+
error
|
|
5298
|
+
);
|
|
5299
|
+
}
|
|
5300
|
+
}
|
|
5301
|
+
// --- Clear ---
|
|
5302
|
+
async dangerouslyClearAll() {
|
|
5303
|
+
await this.#db.clearTable({ tableName: TABLE_EXPERIMENT_RESULTS });
|
|
5304
|
+
await this.#db.clearTable({ tableName: TABLE_EXPERIMENTS });
|
|
5305
|
+
}
|
|
5306
|
+
};
|
|
5307
|
+
var SNAPSHOT_FIELDS = ["name", "description", "servers"];
|
|
5308
|
+
var MCPClientsPG = class _MCPClientsPG extends MCPClientsStorage {
|
|
5309
|
+
#db;
|
|
5310
|
+
#schema;
|
|
5311
|
+
#skipDefaultIndexes;
|
|
5312
|
+
#indexes;
|
|
5313
|
+
static MANAGED_TABLES = [TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS];
|
|
5314
|
+
constructor(config) {
|
|
5315
|
+
super();
|
|
5316
|
+
const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
|
|
5317
|
+
this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
|
|
5318
|
+
this.#schema = schemaName || "public";
|
|
5319
|
+
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
5320
|
+
this.#indexes = indexes?.filter((idx) => _MCPClientsPG.MANAGED_TABLES.includes(idx.table));
|
|
5321
|
+
}
|
|
5322
|
+
getDefaultIndexDefinitions() {
|
|
5323
|
+
return [
|
|
5324
|
+
{
|
|
5325
|
+
name: "idx_mcp_client_versions_client_version",
|
|
5326
|
+
table: TABLE_MCP_CLIENT_VERSIONS,
|
|
5327
|
+
columns: ["mcpClientId", "versionNumber"],
|
|
5328
|
+
unique: true
|
|
5329
|
+
}
|
|
5330
|
+
];
|
|
5331
|
+
}
|
|
5332
|
+
async createDefaultIndexes() {
|
|
5333
|
+
if (this.#skipDefaultIndexes) {
|
|
5334
|
+
return;
|
|
5335
|
+
}
|
|
5336
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) {
|
|
5337
|
+
try {
|
|
5338
|
+
await this.#db.createIndex(indexDef);
|
|
5339
|
+
} catch {
|
|
5340
|
+
}
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
async init() {
|
|
5344
|
+
await this.#db.createTable({
|
|
5345
|
+
tableName: TABLE_MCP_CLIENTS,
|
|
5346
|
+
schema: TABLE_SCHEMAS[TABLE_MCP_CLIENTS]
|
|
5347
|
+
});
|
|
5348
|
+
await this.#db.createTable({
|
|
5349
|
+
tableName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5350
|
+
schema: TABLE_SCHEMAS[TABLE_MCP_CLIENT_VERSIONS]
|
|
5351
|
+
});
|
|
5352
|
+
await this.createDefaultIndexes();
|
|
5353
|
+
await this.createCustomIndexes();
|
|
5354
|
+
}
|
|
5355
|
+
async createCustomIndexes() {
|
|
5356
|
+
if (!this.#indexes || this.#indexes.length === 0) {
|
|
5357
|
+
return;
|
|
5358
|
+
}
|
|
5359
|
+
for (const indexDef of this.#indexes) {
|
|
5360
|
+
try {
|
|
5361
|
+
await this.#db.createIndex(indexDef);
|
|
5362
|
+
} catch (error) {
|
|
5363
|
+
this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
|
|
5364
|
+
}
|
|
5365
|
+
}
|
|
5366
|
+
}
|
|
5367
|
+
async dangerouslyClearAll() {
|
|
5368
|
+
await this.#db.clearTable({ tableName: TABLE_MCP_CLIENT_VERSIONS });
|
|
5369
|
+
await this.#db.clearTable({ tableName: TABLE_MCP_CLIENTS });
|
|
5370
|
+
}
|
|
5371
|
+
// ==========================================================================
|
|
5372
|
+
// MCP Client CRUD Methods
|
|
5373
|
+
// ==========================================================================
|
|
5374
|
+
async getById(id) {
|
|
5375
|
+
try {
|
|
5376
|
+
const tableName = getTableName2({ indexName: TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5377
|
+
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
|
|
5378
|
+
if (!result) {
|
|
5379
|
+
return null;
|
|
5380
|
+
}
|
|
5381
|
+
return this.parseMCPClientRow(result);
|
|
5382
|
+
} catch (error) {
|
|
5383
|
+
if (error instanceof MastraError) throw error;
|
|
5384
|
+
throw new MastraError(
|
|
5385
|
+
{
|
|
5386
|
+
id: createStorageErrorId("PG", "GET_MCP_CLIENT_BY_ID", "FAILED"),
|
|
5387
|
+
domain: ErrorDomain.STORAGE,
|
|
5388
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
5389
|
+
details: { mcpClientId: id }
|
|
5390
|
+
},
|
|
5391
|
+
error
|
|
5392
|
+
);
|
|
5393
|
+
}
|
|
5394
|
+
}
|
|
5395
|
+
async create(input) {
|
|
5396
|
+
const { mcpClient } = input;
|
|
5397
|
+
try {
|
|
5398
|
+
const tableName = getTableName2({ indexName: TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5399
|
+
const now = /* @__PURE__ */ new Date();
|
|
5400
|
+
const nowIso = now.toISOString();
|
|
5401
|
+
await this.#db.client.none(
|
|
5402
|
+
`INSERT INTO ${tableName} (
|
|
5403
|
+
id, status, "activeVersionId", "authorId", metadata,
|
|
5404
|
+
"createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
|
|
5405
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
|
5406
|
+
[
|
|
5407
|
+
mcpClient.id,
|
|
5408
|
+
"draft",
|
|
5409
|
+
null,
|
|
5410
|
+
mcpClient.authorId ?? null,
|
|
5411
|
+
mcpClient.metadata ? JSON.stringify(mcpClient.metadata) : null,
|
|
5412
|
+
nowIso,
|
|
5413
|
+
nowIso,
|
|
5414
|
+
nowIso,
|
|
5415
|
+
nowIso
|
|
5416
|
+
]
|
|
5417
|
+
);
|
|
5418
|
+
const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;
|
|
5419
|
+
const versionId = crypto.randomUUID();
|
|
5420
|
+
await this.createVersion({
|
|
5421
|
+
id: versionId,
|
|
5422
|
+
mcpClientId: mcpClient.id,
|
|
5423
|
+
versionNumber: 1,
|
|
5424
|
+
...snapshotConfig,
|
|
5425
|
+
changedFields: [...SNAPSHOT_FIELDS],
|
|
5426
|
+
changeMessage: "Initial version"
|
|
5427
|
+
});
|
|
5428
|
+
return {
|
|
5429
|
+
id: mcpClient.id,
|
|
5430
|
+
status: "draft",
|
|
5431
|
+
activeVersionId: void 0,
|
|
5432
|
+
authorId: mcpClient.authorId,
|
|
5433
|
+
metadata: mcpClient.metadata,
|
|
5434
|
+
createdAt: now,
|
|
5435
|
+
updatedAt: now
|
|
5436
|
+
};
|
|
5437
|
+
} catch (error) {
|
|
5438
|
+
try {
|
|
5439
|
+
const tableName = getTableName2({
|
|
5440
|
+
indexName: TABLE_MCP_CLIENTS,
|
|
5441
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5442
|
+
});
|
|
5443
|
+
await this.#db.client.none(
|
|
5444
|
+
`DELETE FROM ${tableName} WHERE id = $1 AND status = 'draft' AND "activeVersionId" IS NULL`,
|
|
5445
|
+
[mcpClient.id]
|
|
5446
|
+
);
|
|
5447
|
+
} catch {
|
|
5448
|
+
}
|
|
5449
|
+
if (error instanceof MastraError) throw error;
|
|
5450
|
+
throw new MastraError(
|
|
5451
|
+
{
|
|
5452
|
+
id: createStorageErrorId("PG", "CREATE_MCP_CLIENT", "FAILED"),
|
|
5453
|
+
domain: ErrorDomain.STORAGE,
|
|
5454
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
5455
|
+
details: { mcpClientId: mcpClient.id }
|
|
5456
|
+
},
|
|
5457
|
+
error
|
|
5458
|
+
);
|
|
5459
|
+
}
|
|
5460
|
+
}
|
|
5461
|
+
async update(input) {
|
|
5462
|
+
const { id, ...updates } = input;
|
|
5463
|
+
try {
|
|
5464
|
+
const tableName = getTableName2({ indexName: TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5465
|
+
const existingClient = await this.getById(id);
|
|
5466
|
+
if (!existingClient) {
|
|
5467
|
+
throw new MastraError({
|
|
5468
|
+
id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND"),
|
|
5469
|
+
domain: ErrorDomain.STORAGE,
|
|
5470
|
+
category: ErrorCategory.USER,
|
|
5471
|
+
text: `MCP client ${id} not found`,
|
|
5472
|
+
details: { mcpClientId: id }
|
|
5473
|
+
});
|
|
5474
|
+
}
|
|
5475
|
+
const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
|
|
5476
|
+
let versionCreated = false;
|
|
5477
|
+
const hasConfigUpdate = SNAPSHOT_FIELDS.some((field) => field in configFields);
|
|
5478
|
+
if (hasConfigUpdate) {
|
|
5479
|
+
const latestVersion = await this.getLatestVersion(id);
|
|
5480
|
+
if (!latestVersion) {
|
|
5481
|
+
throw new MastraError({
|
|
5482
|
+
id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NO_VERSIONS"),
|
|
5483
|
+
domain: ErrorDomain.STORAGE,
|
|
5484
|
+
category: ErrorCategory.SYSTEM,
|
|
5485
|
+
text: `No versions found for MCP client ${id}`,
|
|
5486
|
+
details: { mcpClientId: id }
|
|
5487
|
+
});
|
|
5488
|
+
}
|
|
5489
|
+
const {
|
|
5490
|
+
id: _versionId,
|
|
5491
|
+
mcpClientId: _mcpClientId,
|
|
5492
|
+
versionNumber: _versionNumber,
|
|
5493
|
+
changedFields: _changedFields,
|
|
5494
|
+
changeMessage: _changeMessage,
|
|
5495
|
+
createdAt: _createdAt,
|
|
5496
|
+
...latestConfig
|
|
5497
|
+
} = latestVersion;
|
|
5498
|
+
const newConfig = { ...latestConfig, ...configFields };
|
|
5499
|
+
const changedFields = SNAPSHOT_FIELDS.filter(
|
|
5500
|
+
(field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
|
|
5501
|
+
);
|
|
5502
|
+
if (changedFields.length > 0) {
|
|
5503
|
+
versionCreated = true;
|
|
5504
|
+
const newVersionId = crypto.randomUUID();
|
|
5505
|
+
await this.createVersion({
|
|
5506
|
+
id: newVersionId,
|
|
5507
|
+
mcpClientId: id,
|
|
5508
|
+
versionNumber: latestVersion.versionNumber + 1,
|
|
5509
|
+
...newConfig,
|
|
5510
|
+
changedFields: [...changedFields],
|
|
5511
|
+
changeMessage: `Updated ${changedFields.join(", ")}`
|
|
5512
|
+
});
|
|
5513
|
+
}
|
|
5514
|
+
}
|
|
5515
|
+
const setClauses = [];
|
|
5516
|
+
const values = [];
|
|
5517
|
+
let paramIndex = 1;
|
|
5518
|
+
if (authorId !== void 0) {
|
|
5519
|
+
setClauses.push(`"authorId" = $${paramIndex++}`);
|
|
5520
|
+
values.push(authorId);
|
|
5521
|
+
}
|
|
5522
|
+
if (activeVersionId !== void 0) {
|
|
5523
|
+
setClauses.push(`"activeVersionId" = $${paramIndex++}`);
|
|
5524
|
+
values.push(activeVersionId);
|
|
5525
|
+
if (status === void 0) {
|
|
5526
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
5527
|
+
values.push("published");
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5530
|
+
if (status !== void 0) {
|
|
5531
|
+
setClauses.push(`status = $${paramIndex++}`);
|
|
5532
|
+
values.push(status);
|
|
5533
|
+
}
|
|
5534
|
+
if (metadata !== void 0) {
|
|
5535
|
+
const mergedMetadata = { ...existingClient.metadata || {}, ...metadata };
|
|
5536
|
+
setClauses.push(`metadata = $${paramIndex++}`);
|
|
5537
|
+
values.push(JSON.stringify(mergedMetadata));
|
|
5538
|
+
}
|
|
5539
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
5540
|
+
setClauses.push(`"updatedAt" = $${paramIndex++}`);
|
|
5541
|
+
values.push(now);
|
|
5542
|
+
setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
|
|
5543
|
+
values.push(now);
|
|
5544
|
+
values.push(id);
|
|
5545
|
+
if (setClauses.length > 2 || versionCreated) {
|
|
5546
|
+
await this.#db.client.none(
|
|
5547
|
+
`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
|
|
5548
|
+
values
|
|
5549
|
+
);
|
|
5550
|
+
}
|
|
5551
|
+
const updatedClient = await this.getById(id);
|
|
5552
|
+
if (!updatedClient) {
|
|
5553
|
+
throw new MastraError({
|
|
5554
|
+
id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND_AFTER_UPDATE"),
|
|
5555
|
+
domain: ErrorDomain.STORAGE,
|
|
5556
|
+
category: ErrorCategory.SYSTEM,
|
|
5557
|
+
text: `MCP client ${id} not found after update`,
|
|
5558
|
+
details: { mcpClientId: id }
|
|
5559
|
+
});
|
|
5560
|
+
}
|
|
5561
|
+
return updatedClient;
|
|
5562
|
+
} catch (error) {
|
|
5563
|
+
if (error instanceof MastraError) throw error;
|
|
5564
|
+
throw new MastraError(
|
|
5565
|
+
{
|
|
5566
|
+
id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "FAILED"),
|
|
5567
|
+
domain: ErrorDomain.STORAGE,
|
|
5568
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
5569
|
+
details: { mcpClientId: id }
|
|
5570
|
+
},
|
|
5571
|
+
error
|
|
5572
|
+
);
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
async delete(id) {
|
|
5576
|
+
try {
|
|
5577
|
+
const tableName = getTableName2({ indexName: TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5578
|
+
await this.deleteVersionsByParentId(id);
|
|
5579
|
+
await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
|
|
5580
|
+
} catch (error) {
|
|
5581
|
+
if (error instanceof MastraError) throw error;
|
|
5582
|
+
throw new MastraError(
|
|
5583
|
+
{
|
|
5584
|
+
id: createStorageErrorId("PG", "DELETE_MCP_CLIENT", "FAILED"),
|
|
5585
|
+
domain: ErrorDomain.STORAGE,
|
|
5586
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
5587
|
+
details: { mcpClientId: id }
|
|
5588
|
+
},
|
|
5589
|
+
error
|
|
5590
|
+
);
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5593
|
+
async list(args) {
|
|
5594
|
+
const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
|
|
5595
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
5596
|
+
if (page < 0) {
|
|
5597
|
+
throw new MastraError(
|
|
5598
|
+
{
|
|
5599
|
+
id: createStorageErrorId("PG", "LIST_MCP_CLIENTS", "INVALID_PAGE"),
|
|
5600
|
+
domain: ErrorDomain.STORAGE,
|
|
5601
|
+
category: ErrorCategory.USER,
|
|
5602
|
+
details: { page }
|
|
5603
|
+
},
|
|
5604
|
+
new Error("page must be >= 0")
|
|
5605
|
+
);
|
|
5606
|
+
}
|
|
5607
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
5608
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
5609
|
+
try {
|
|
5610
|
+
const tableName = getTableName2({ indexName: TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
|
|
5611
|
+
const conditions = [];
|
|
5612
|
+
const queryParams = [];
|
|
5613
|
+
let paramIdx = 1;
|
|
5614
|
+
if (authorId !== void 0) {
|
|
5615
|
+
conditions.push(`"authorId" = $${paramIdx++}`);
|
|
5616
|
+
queryParams.push(authorId);
|
|
5617
|
+
}
|
|
5618
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
5619
|
+
conditions.push(`metadata @> $${paramIdx++}::jsonb`);
|
|
5620
|
+
queryParams.push(JSON.stringify(metadata));
|
|
5621
|
+
}
|
|
5622
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
5623
|
+
const countResult = await this.#db.client.one(
|
|
5624
|
+
`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
|
|
5625
|
+
queryParams
|
|
5626
|
+
);
|
|
3627
5627
|
const total = parseInt(countResult.count, 10);
|
|
3628
5628
|
if (total === 0) {
|
|
3629
5629
|
return {
|
|
3630
|
-
|
|
5630
|
+
mcpClients: [],
|
|
3631
5631
|
total: 0,
|
|
3632
5632
|
page,
|
|
3633
5633
|
perPage: perPageForResponse,
|
|
@@ -3636,12 +5636,12 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3636
5636
|
}
|
|
3637
5637
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3638
5638
|
const dataResult = await this.#db.client.manyOrNone(
|
|
3639
|
-
`SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT
|
|
3640
|
-
[limitValue, offset]
|
|
5639
|
+
`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`,
|
|
5640
|
+
[...queryParams, limitValue, offset]
|
|
3641
5641
|
);
|
|
3642
|
-
const
|
|
5642
|
+
const mcpClients = (dataResult || []).map((row) => this.parseMCPClientRow(row));
|
|
3643
5643
|
return {
|
|
3644
|
-
|
|
5644
|
+
mcpClients,
|
|
3645
5645
|
total,
|
|
3646
5646
|
page,
|
|
3647
5647
|
perPage: perPageForResponse,
|
|
@@ -3651,7 +5651,7 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3651
5651
|
if (error instanceof MastraError) throw error;
|
|
3652
5652
|
throw new MastraError(
|
|
3653
5653
|
{
|
|
3654
|
-
id: createStorageErrorId("PG", "
|
|
5654
|
+
id: createStorageErrorId("PG", "LIST_MCP_CLIENTS", "FAILED"),
|
|
3655
5655
|
domain: ErrorDomain.STORAGE,
|
|
3656
5656
|
category: ErrorCategory.THIRD_PARTY
|
|
3657
5657
|
},
|
|
@@ -3660,39 +5660,30 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3660
5660
|
}
|
|
3661
5661
|
}
|
|
3662
5662
|
// ==========================================================================
|
|
3663
|
-
//
|
|
5663
|
+
// MCP Client Version Methods
|
|
3664
5664
|
// ==========================================================================
|
|
3665
5665
|
async createVersion(input) {
|
|
3666
5666
|
try {
|
|
3667
|
-
const tableName = getTableName2({
|
|
5667
|
+
const tableName = getTableName2({
|
|
5668
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5669
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5670
|
+
});
|
|
3668
5671
|
const now = /* @__PURE__ */ new Date();
|
|
3669
5672
|
const nowIso = now.toISOString();
|
|
3670
5673
|
await this.#db.client.none(
|
|
3671
5674
|
`INSERT INTO ${tableName} (
|
|
3672
|
-
id, "
|
|
3673
|
-
name, description,
|
|
3674
|
-
"defaultOptions", workflows, agents, "integrationTools",
|
|
3675
|
-
"inputProcessors", "outputProcessors", memory, scorers,
|
|
5675
|
+
id, "mcpClientId", "versionNumber",
|
|
5676
|
+
name, description, servers,
|
|
3676
5677
|
"changedFields", "changeMessage",
|
|
3677
5678
|
"createdAt", "createdAtZ"
|
|
3678
|
-
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10
|
|
5679
|
+
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
|
|
3679
5680
|
[
|
|
3680
5681
|
input.id,
|
|
3681
|
-
input.
|
|
5682
|
+
input.mcpClientId,
|
|
3682
5683
|
input.versionNumber,
|
|
3683
5684
|
input.name,
|
|
3684
5685
|
input.description ?? null,
|
|
3685
|
-
|
|
3686
|
-
JSON.stringify(input.model),
|
|
3687
|
-
input.tools ? JSON.stringify(input.tools) : null,
|
|
3688
|
-
input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
|
|
3689
|
-
input.workflows ? JSON.stringify(input.workflows) : null,
|
|
3690
|
-
input.agents ? JSON.stringify(input.agents) : null,
|
|
3691
|
-
input.integrationTools ? JSON.stringify(input.integrationTools) : null,
|
|
3692
|
-
input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
|
|
3693
|
-
input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
|
|
3694
|
-
input.memory ? JSON.stringify(input.memory) : null,
|
|
3695
|
-
input.scorers ? JSON.stringify(input.scorers) : null,
|
|
5686
|
+
JSON.stringify(input.servers),
|
|
3696
5687
|
input.changedFields ? JSON.stringify(input.changedFields) : null,
|
|
3697
5688
|
input.changeMessage ?? null,
|
|
3698
5689
|
nowIso,
|
|
@@ -3707,10 +5698,10 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3707
5698
|
if (error instanceof MastraError) throw error;
|
|
3708
5699
|
throw new MastraError(
|
|
3709
5700
|
{
|
|
3710
|
-
id: createStorageErrorId("PG", "
|
|
5701
|
+
id: createStorageErrorId("PG", "CREATE_MCP_CLIENT_VERSION", "FAILED"),
|
|
3711
5702
|
domain: ErrorDomain.STORAGE,
|
|
3712
5703
|
category: ErrorCategory.THIRD_PARTY,
|
|
3713
|
-
details: { versionId: input.id,
|
|
5704
|
+
details: { versionId: input.id, mcpClientId: input.mcpClientId }
|
|
3714
5705
|
},
|
|
3715
5706
|
error
|
|
3716
5707
|
);
|
|
@@ -3718,7 +5709,10 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3718
5709
|
}
|
|
3719
5710
|
async getVersion(id) {
|
|
3720
5711
|
try {
|
|
3721
|
-
const tableName = getTableName2({
|
|
5712
|
+
const tableName = getTableName2({
|
|
5713
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5714
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5715
|
+
});
|
|
3722
5716
|
const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
|
|
3723
5717
|
if (!result) {
|
|
3724
5718
|
return null;
|
|
@@ -3728,7 +5722,7 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3728
5722
|
if (error instanceof MastraError) throw error;
|
|
3729
5723
|
throw new MastraError(
|
|
3730
5724
|
{
|
|
3731
|
-
id: createStorageErrorId("PG", "
|
|
5725
|
+
id: createStorageErrorId("PG", "GET_MCP_CLIENT_VERSION", "FAILED"),
|
|
3732
5726
|
domain: ErrorDomain.STORAGE,
|
|
3733
5727
|
category: ErrorCategory.THIRD_PARTY,
|
|
3734
5728
|
details: { versionId: id }
|
|
@@ -3737,12 +5731,15 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3737
5731
|
);
|
|
3738
5732
|
}
|
|
3739
5733
|
}
|
|
3740
|
-
async getVersionByNumber(
|
|
5734
|
+
async getVersionByNumber(mcpClientId, versionNumber) {
|
|
3741
5735
|
try {
|
|
3742
|
-
const tableName = getTableName2({
|
|
5736
|
+
const tableName = getTableName2({
|
|
5737
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5738
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5739
|
+
});
|
|
3743
5740
|
const result = await this.#db.client.oneOrNone(
|
|
3744
|
-
`SELECT * FROM ${tableName} WHERE "
|
|
3745
|
-
[
|
|
5741
|
+
`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`,
|
|
5742
|
+
[mcpClientId, versionNumber]
|
|
3746
5743
|
);
|
|
3747
5744
|
if (!result) {
|
|
3748
5745
|
return null;
|
|
@@ -3752,21 +5749,24 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3752
5749
|
if (error instanceof MastraError) throw error;
|
|
3753
5750
|
throw new MastraError(
|
|
3754
5751
|
{
|
|
3755
|
-
id: createStorageErrorId("PG", "
|
|
5752
|
+
id: createStorageErrorId("PG", "GET_MCP_CLIENT_VERSION_BY_NUMBER", "FAILED"),
|
|
3756
5753
|
domain: ErrorDomain.STORAGE,
|
|
3757
5754
|
category: ErrorCategory.THIRD_PARTY,
|
|
3758
|
-
details: {
|
|
5755
|
+
details: { mcpClientId, versionNumber }
|
|
3759
5756
|
},
|
|
3760
5757
|
error
|
|
3761
5758
|
);
|
|
3762
5759
|
}
|
|
3763
5760
|
}
|
|
3764
|
-
async getLatestVersion(
|
|
5761
|
+
async getLatestVersion(mcpClientId) {
|
|
3765
5762
|
try {
|
|
3766
|
-
const tableName = getTableName2({
|
|
5763
|
+
const tableName = getTableName2({
|
|
5764
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5765
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5766
|
+
});
|
|
3767
5767
|
const result = await this.#db.client.oneOrNone(
|
|
3768
|
-
`SELECT * FROM ${tableName} WHERE "
|
|
3769
|
-
[
|
|
5768
|
+
`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
|
|
5769
|
+
[mcpClientId]
|
|
3770
5770
|
);
|
|
3771
5771
|
if (!result) {
|
|
3772
5772
|
return null;
|
|
@@ -3776,21 +5776,21 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3776
5776
|
if (error instanceof MastraError) throw error;
|
|
3777
5777
|
throw new MastraError(
|
|
3778
5778
|
{
|
|
3779
|
-
id: createStorageErrorId("PG", "
|
|
5779
|
+
id: createStorageErrorId("PG", "GET_LATEST_MCP_CLIENT_VERSION", "FAILED"),
|
|
3780
5780
|
domain: ErrorDomain.STORAGE,
|
|
3781
5781
|
category: ErrorCategory.THIRD_PARTY,
|
|
3782
|
-
details: {
|
|
5782
|
+
details: { mcpClientId }
|
|
3783
5783
|
},
|
|
3784
5784
|
error
|
|
3785
5785
|
);
|
|
3786
5786
|
}
|
|
3787
5787
|
}
|
|
3788
5788
|
async listVersions(input) {
|
|
3789
|
-
const {
|
|
5789
|
+
const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;
|
|
3790
5790
|
if (page < 0) {
|
|
3791
5791
|
throw new MastraError(
|
|
3792
5792
|
{
|
|
3793
|
-
id: createStorageErrorId("PG", "
|
|
5793
|
+
id: createStorageErrorId("PG", "LIST_MCP_CLIENT_VERSIONS", "INVALID_PAGE"),
|
|
3794
5794
|
domain: ErrorDomain.STORAGE,
|
|
3795
5795
|
category: ErrorCategory.USER,
|
|
3796
5796
|
details: { page }
|
|
@@ -3802,10 +5802,14 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3802
5802
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
3803
5803
|
try {
|
|
3804
5804
|
const { field, direction } = this.parseVersionOrderBy(orderBy);
|
|
3805
|
-
const tableName = getTableName2({
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
5805
|
+
const tableName = getTableName2({
|
|
5806
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5807
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5808
|
+
});
|
|
5809
|
+
const countResult = await this.#db.client.one(
|
|
5810
|
+
`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`,
|
|
5811
|
+
[mcpClientId]
|
|
5812
|
+
);
|
|
3809
5813
|
const total = parseInt(countResult.count, 10);
|
|
3810
5814
|
if (total === 0) {
|
|
3811
5815
|
return {
|
|
@@ -3818,8 +5822,8 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3818
5822
|
}
|
|
3819
5823
|
const limitValue = perPageInput === false ? total : perPage;
|
|
3820
5824
|
const dataResult = await this.#db.client.manyOrNone(
|
|
3821
|
-
`SELECT * FROM ${tableName} WHERE "
|
|
3822
|
-
[
|
|
5825
|
+
`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
|
|
5826
|
+
[mcpClientId, limitValue, offset]
|
|
3823
5827
|
);
|
|
3824
5828
|
const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
|
|
3825
5829
|
return {
|
|
@@ -3833,10 +5837,10 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3833
5837
|
if (error instanceof MastraError) throw error;
|
|
3834
5838
|
throw new MastraError(
|
|
3835
5839
|
{
|
|
3836
|
-
id: createStorageErrorId("PG", "
|
|
5840
|
+
id: createStorageErrorId("PG", "LIST_MCP_CLIENT_VERSIONS", "FAILED"),
|
|
3837
5841
|
domain: ErrorDomain.STORAGE,
|
|
3838
5842
|
category: ErrorCategory.THIRD_PARTY,
|
|
3839
|
-
details: {
|
|
5843
|
+
details: { mcpClientId }
|
|
3840
5844
|
},
|
|
3841
5845
|
error
|
|
3842
5846
|
);
|
|
@@ -3844,13 +5848,16 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3844
5848
|
}
|
|
3845
5849
|
async deleteVersion(id) {
|
|
3846
5850
|
try {
|
|
3847
|
-
const tableName = getTableName2({
|
|
5851
|
+
const tableName = getTableName2({
|
|
5852
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5853
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5854
|
+
});
|
|
3848
5855
|
await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
|
|
3849
5856
|
} catch (error) {
|
|
3850
5857
|
if (error instanceof MastraError) throw error;
|
|
3851
5858
|
throw new MastraError(
|
|
3852
5859
|
{
|
|
3853
|
-
id: createStorageErrorId("PG", "
|
|
5860
|
+
id: createStorageErrorId("PG", "DELETE_MCP_CLIENT_VERSION", "FAILED"),
|
|
3854
5861
|
domain: ErrorDomain.STORAGE,
|
|
3855
5862
|
category: ErrorCategory.THIRD_PARTY,
|
|
3856
5863
|
details: { versionId: id }
|
|
@@ -3861,36 +5868,42 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3861
5868
|
}
|
|
3862
5869
|
async deleteVersionsByParentId(entityId) {
|
|
3863
5870
|
try {
|
|
3864
|
-
const tableName = getTableName2({
|
|
3865
|
-
|
|
5871
|
+
const tableName = getTableName2({
|
|
5872
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5873
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5874
|
+
});
|
|
5875
|
+
await this.#db.client.none(`DELETE FROM ${tableName} WHERE "mcpClientId" = $1`, [entityId]);
|
|
3866
5876
|
} catch (error) {
|
|
3867
5877
|
if (error instanceof MastraError) throw error;
|
|
3868
5878
|
throw new MastraError(
|
|
3869
5879
|
{
|
|
3870
|
-
id: createStorageErrorId("PG", "
|
|
5880
|
+
id: createStorageErrorId("PG", "DELETE_MCP_CLIENT_VERSIONS_BY_MCP_CLIENT_ID", "FAILED"),
|
|
3871
5881
|
domain: ErrorDomain.STORAGE,
|
|
3872
5882
|
category: ErrorCategory.THIRD_PARTY,
|
|
3873
|
-
details: {
|
|
5883
|
+
details: { mcpClientId: entityId }
|
|
3874
5884
|
},
|
|
3875
5885
|
error
|
|
3876
5886
|
);
|
|
3877
5887
|
}
|
|
3878
5888
|
}
|
|
3879
|
-
async countVersions(
|
|
5889
|
+
async countVersions(mcpClientId) {
|
|
3880
5890
|
try {
|
|
3881
|
-
const tableName = getTableName2({
|
|
3882
|
-
|
|
3883
|
-
|
|
5891
|
+
const tableName = getTableName2({
|
|
5892
|
+
indexName: TABLE_MCP_CLIENT_VERSIONS,
|
|
5893
|
+
schemaName: getSchemaName2(this.#schema)
|
|
5894
|
+
});
|
|
5895
|
+
const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [
|
|
5896
|
+
mcpClientId
|
|
3884
5897
|
]);
|
|
3885
5898
|
return parseInt(result.count, 10);
|
|
3886
5899
|
} catch (error) {
|
|
3887
5900
|
if (error instanceof MastraError) throw error;
|
|
3888
5901
|
throw new MastraError(
|
|
3889
5902
|
{
|
|
3890
|
-
id: createStorageErrorId("PG", "
|
|
5903
|
+
id: createStorageErrorId("PG", "COUNT_MCP_CLIENT_VERSIONS", "FAILED"),
|
|
3891
5904
|
domain: ErrorDomain.STORAGE,
|
|
3892
5905
|
category: ErrorCategory.THIRD_PARTY,
|
|
3893
|
-
details: {
|
|
5906
|
+
details: { mcpClientId }
|
|
3894
5907
|
},
|
|
3895
5908
|
error
|
|
3896
5909
|
);
|
|
@@ -3899,44 +5912,63 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
|
|
|
3899
5912
|
// ==========================================================================
|
|
3900
5913
|
// Private Helper Methods
|
|
3901
5914
|
// ==========================================================================
|
|
3902
|
-
|
|
3903
|
-
if (
|
|
3904
|
-
|
|
3905
|
-
}
|
|
3906
|
-
deserializeInstructions(raw) {
|
|
3907
|
-
if (!raw) return "";
|
|
5915
|
+
parseJson(value, fieldName) {
|
|
5916
|
+
if (!value) return void 0;
|
|
5917
|
+
if (typeof value !== "string") return value;
|
|
3908
5918
|
try {
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
5919
|
+
return JSON.parse(value);
|
|
5920
|
+
} catch (error) {
|
|
5921
|
+
if (error instanceof MastraError) throw error;
|
|
5922
|
+
const details = {
|
|
5923
|
+
value: value.length > 100 ? value.substring(0, 100) + "..." : value
|
|
5924
|
+
};
|
|
5925
|
+
if (fieldName) {
|
|
5926
|
+
details.field = fieldName;
|
|
5927
|
+
}
|
|
5928
|
+
throw new MastraError(
|
|
5929
|
+
{
|
|
5930
|
+
id: createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
|
|
5931
|
+
domain: ErrorDomain.STORAGE,
|
|
5932
|
+
category: ErrorCategory.SYSTEM,
|
|
5933
|
+
text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
5934
|
+
details
|
|
5935
|
+
},
|
|
5936
|
+
error
|
|
5937
|
+
);
|
|
3912
5938
|
}
|
|
3913
|
-
|
|
5939
|
+
}
|
|
5940
|
+
parseMCPClientRow(row) {
|
|
5941
|
+
return {
|
|
5942
|
+
id: row.id,
|
|
5943
|
+
status: row.status,
|
|
5944
|
+
activeVersionId: row.activeVersionId,
|
|
5945
|
+
authorId: row.authorId,
|
|
5946
|
+
metadata: this.parseJson(row.metadata, "metadata"),
|
|
5947
|
+
createdAt: new Date(row.createdAtZ || row.createdAt),
|
|
5948
|
+
updatedAt: new Date(row.updatedAtZ || row.updatedAt)
|
|
5949
|
+
};
|
|
3914
5950
|
}
|
|
3915
5951
|
parseVersionRow(row) {
|
|
3916
5952
|
return {
|
|
3917
5953
|
id: row.id,
|
|
3918
|
-
|
|
5954
|
+
mcpClientId: row.mcpClientId,
|
|
3919
5955
|
versionNumber: row.versionNumber,
|
|
3920
5956
|
name: row.name,
|
|
3921
5957
|
description: row.description,
|
|
3922
|
-
|
|
3923
|
-
model: this.parseJson(row.model, "model"),
|
|
3924
|
-
tools: this.parseJson(row.tools, "tools"),
|
|
3925
|
-
defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
|
|
3926
|
-
workflows: this.parseJson(row.workflows, "workflows"),
|
|
3927
|
-
agents: this.parseJson(row.agents, "agents"),
|
|
3928
|
-
integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
|
|
3929
|
-
inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
|
|
3930
|
-
outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
|
|
3931
|
-
memory: this.parseJson(row.memory, "memory"),
|
|
3932
|
-
scorers: this.parseJson(row.scorers, "scorers"),
|
|
5958
|
+
servers: this.parseJson(row.servers, "servers"),
|
|
3933
5959
|
changedFields: this.parseJson(row.changedFields, "changedFields"),
|
|
3934
5960
|
changeMessage: row.changeMessage,
|
|
3935
|
-
createdAt: row.createdAtZ || row.createdAt
|
|
5961
|
+
createdAt: new Date(row.createdAtZ || row.createdAt)
|
|
3936
5962
|
};
|
|
3937
5963
|
}
|
|
3938
5964
|
};
|
|
3939
5965
|
var OM_TABLE = "mastra_observational_memory";
|
|
5966
|
+
var _omTableSchema;
|
|
5967
|
+
try {
|
|
5968
|
+
const storage = __require("@mastra/core/storage");
|
|
5969
|
+
_omTableSchema = storage.OBSERVATIONAL_MEMORY_TABLE_SCHEMA;
|
|
5970
|
+
} catch {
|
|
5971
|
+
}
|
|
3940
5972
|
function getSchemaName3(schema) {
|
|
3941
5973
|
return schema ? `"${schema}"` : '"public"';
|
|
3942
5974
|
}
|
|
@@ -4015,9 +6047,9 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
4015
6047
|
}
|
|
4016
6048
|
/**
|
|
4017
6049
|
* Returns default index definitions for the memory domain tables.
|
|
6050
|
+
* @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
|
|
4018
6051
|
*/
|
|
4019
|
-
|
|
4020
|
-
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
6052
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
4021
6053
|
return [
|
|
4022
6054
|
{
|
|
4023
6055
|
name: `${schemaPrefix}mastra_threads_resourceid_createdat_idx`,
|
|
@@ -4031,6 +6063,53 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
4031
6063
|
}
|
|
4032
6064
|
];
|
|
4033
6065
|
}
|
|
6066
|
+
/**
|
|
6067
|
+
* Returns all DDL statements for this domain: tables (threads, messages, resources, OM), indexes.
|
|
6068
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
6069
|
+
*/
|
|
6070
|
+
static getExportDDL(schemaName) {
|
|
6071
|
+
const statements = [];
|
|
6072
|
+
const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
6073
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
6074
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
6075
|
+
for (const tableName of [TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES]) {
|
|
6076
|
+
statements.push(
|
|
6077
|
+
generateTableSQL({
|
|
6078
|
+
tableName,
|
|
6079
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
6080
|
+
schemaName,
|
|
6081
|
+
includeAllConstraints: true
|
|
6082
|
+
})
|
|
6083
|
+
);
|
|
6084
|
+
}
|
|
6085
|
+
const omSchema = _omTableSchema?.[OM_TABLE];
|
|
6086
|
+
if (omSchema) {
|
|
6087
|
+
statements.push(
|
|
6088
|
+
generateTableSQL({
|
|
6089
|
+
tableName: OM_TABLE,
|
|
6090
|
+
schema: omSchema,
|
|
6091
|
+
schemaName,
|
|
6092
|
+
includeAllConstraints: true
|
|
6093
|
+
})
|
|
6094
|
+
);
|
|
6095
|
+
const fullOmTableName = getTableName({ indexName: OM_TABLE, schemaName: quotedSchemaName });
|
|
6096
|
+
const idxPrefix = schemaPrefix ? `${schemaPrefix}` : "";
|
|
6097
|
+
statements.push(
|
|
6098
|
+
`CREATE INDEX IF NOT EXISTS "${idxPrefix}idx_om_lookup_key" ON ${fullOmTableName} ("lookupKey");`
|
|
6099
|
+
);
|
|
6100
|
+
}
|
|
6101
|
+
for (const idx of _MemoryPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
6102
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
6103
|
+
}
|
|
6104
|
+
return statements;
|
|
6105
|
+
}
|
|
6106
|
+
/**
|
|
6107
|
+
* Returns default index definitions for this instance's schema.
|
|
6108
|
+
*/
|
|
6109
|
+
getDefaultIndexDefinitions() {
|
|
6110
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
6111
|
+
return _MemoryPG.getDefaultIndexDefs(schemaPrefix);
|
|
6112
|
+
}
|
|
4034
6113
|
/**
|
|
4035
6114
|
* Creates default indexes for optimal query performance.
|
|
4036
6115
|
*/
|
|
@@ -5392,8 +7471,8 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5392
7471
|
input.observations,
|
|
5393
7472
|
lastObservedAtStr,
|
|
5394
7473
|
lastObservedAtStr,
|
|
5395
|
-
input.tokenCount,
|
|
5396
|
-
input.tokenCount,
|
|
7474
|
+
Math.round(input.tokenCount),
|
|
7475
|
+
Math.round(input.tokenCount),
|
|
5397
7476
|
observedMessageIdsJson,
|
|
5398
7477
|
nowStr,
|
|
5399
7478
|
nowStr,
|
|
@@ -5488,8 +7567,8 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5488
7567
|
nowStr,
|
|
5489
7568
|
// lastReflectionAtZ
|
|
5490
7569
|
record.pendingMessageTokens,
|
|
5491
|
-
record.totalTokensObserved,
|
|
5492
|
-
record.observationTokenCount,
|
|
7570
|
+
Math.round(record.totalTokensObserved),
|
|
7571
|
+
Math.round(record.observationTokenCount),
|
|
5493
7572
|
false,
|
|
5494
7573
|
// isObserving
|
|
5495
7574
|
false,
|
|
@@ -5607,7 +7686,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5607
7686
|
let values;
|
|
5608
7687
|
if (lastBufferedAtTokens !== void 0) {
|
|
5609
7688
|
query = `UPDATE ${tableName} SET "isBufferingObservation" = $1, "lastBufferedAtTokens" = $2, "updatedAt" = $3, "updatedAtZ" = $4 WHERE id = $5`;
|
|
5610
|
-
values = [isBuffering, lastBufferedAtTokens, nowStr, nowStr, id];
|
|
7689
|
+
values = [isBuffering, Math.round(lastBufferedAtTokens), nowStr, nowStr, id];
|
|
5611
7690
|
} else {
|
|
5612
7691
|
query = `UPDATE ${tableName} SET "isBufferingObservation" = $1, "updatedAt" = $2, "updatedAtZ" = $3 WHERE id = $4`;
|
|
5613
7692
|
values = [isBuffering, nowStr, nowStr, id];
|
|
@@ -5705,7 +7784,7 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5705
7784
|
"updatedAt" = $2,
|
|
5706
7785
|
"updatedAtZ" = $3
|
|
5707
7786
|
WHERE id = $4`,
|
|
5708
|
-
[tokenCount, nowStr, nowStr, id]
|
|
7787
|
+
[Math.round(tokenCount), nowStr, nowStr, id]
|
|
5709
7788
|
);
|
|
5710
7789
|
if (result.rowCount === 0) {
|
|
5711
7790
|
throw new MastraError({
|
|
@@ -5745,9 +7824,9 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5745
7824
|
id: `ombuf-${randomUUID()}`,
|
|
5746
7825
|
cycleId: input.chunk.cycleId,
|
|
5747
7826
|
observations: input.chunk.observations,
|
|
5748
|
-
tokenCount: input.chunk.tokenCount,
|
|
7827
|
+
tokenCount: Math.round(input.chunk.tokenCount),
|
|
5749
7828
|
messageIds: input.chunk.messageIds,
|
|
5750
|
-
messageTokens: input.chunk.messageTokens,
|
|
7829
|
+
messageTokens: Math.round(input.chunk.messageTokens ?? 0),
|
|
5751
7830
|
lastObservedAt: input.chunk.lastObservedAt,
|
|
5752
7831
|
createdAt: /* @__PURE__ */ new Date(),
|
|
5753
7832
|
suggestedContinuation: input.chunk.suggestedContinuation,
|
|
@@ -5856,8 +7935,8 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5856
7935
|
const activatedChunks = chunks.slice(0, chunksToActivate);
|
|
5857
7936
|
const remainingChunks = chunks.slice(chunksToActivate);
|
|
5858
7937
|
const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
|
|
5859
|
-
const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
|
|
5860
|
-
const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
|
|
7938
|
+
const activatedTokens = Math.round(activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0));
|
|
7939
|
+
const activatedMessageTokens = Math.round(activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0));
|
|
5861
7940
|
const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
|
|
5862
7941
|
const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
|
|
5863
7942
|
const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
|
|
@@ -5944,8 +8023,8 @@ var MemoryPG = class _MemoryPG extends MemoryStorage {
|
|
|
5944
8023
|
WHERE id = $7`,
|
|
5945
8024
|
[
|
|
5946
8025
|
input.reflection,
|
|
5947
|
-
input.tokenCount,
|
|
5948
|
-
input.inputTokenCount,
|
|
8026
|
+
Math.round(input.tokenCount),
|
|
8027
|
+
Math.round(input.inputTokenCount),
|
|
5949
8028
|
input.reflectedObservationLineCount,
|
|
5950
8029
|
nowStr,
|
|
5951
8030
|
nowStr,
|
|
@@ -6068,9 +8147,9 @@ var ObservabilityPG = class _ObservabilityPG extends ObservabilityStorage {
|
|
|
6068
8147
|
}
|
|
6069
8148
|
/**
|
|
6070
8149
|
* Returns default index definitions for the observability domain tables.
|
|
8150
|
+
* @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
|
|
6071
8151
|
*/
|
|
6072
|
-
|
|
6073
|
-
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
8152
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
6074
8153
|
return [
|
|
6075
8154
|
{
|
|
6076
8155
|
name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
|
|
@@ -6132,6 +8211,35 @@ var ObservabilityPG = class _ObservabilityPG extends ObservabilityStorage {
|
|
|
6132
8211
|
}
|
|
6133
8212
|
];
|
|
6134
8213
|
}
|
|
8214
|
+
/**
|
|
8215
|
+
* Returns all DDL statements for this domain: table, constraints, timestamp trigger, and indexes.
|
|
8216
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
8217
|
+
*/
|
|
8218
|
+
static getExportDDL(schemaName) {
|
|
8219
|
+
const statements = [];
|
|
8220
|
+
const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
8221
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
8222
|
+
statements.push(
|
|
8223
|
+
generateTableSQL({
|
|
8224
|
+
tableName: TABLE_SPANS,
|
|
8225
|
+
schema: TABLE_SCHEMAS[TABLE_SPANS],
|
|
8226
|
+
schemaName,
|
|
8227
|
+
includeAllConstraints: true
|
|
8228
|
+
})
|
|
8229
|
+
);
|
|
8230
|
+
statements.push(generateTimestampTriggerSQL(TABLE_SPANS, schemaName));
|
|
8231
|
+
for (const idx of _ObservabilityPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
8232
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
8233
|
+
}
|
|
8234
|
+
return statements;
|
|
8235
|
+
}
|
|
8236
|
+
/**
|
|
8237
|
+
* Returns default index definitions for this instance's schema.
|
|
8238
|
+
*/
|
|
8239
|
+
getDefaultIndexDefinitions() {
|
|
8240
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
8241
|
+
return _ObservabilityPG.getDefaultIndexDefs(schemaPrefix);
|
|
8242
|
+
}
|
|
6135
8243
|
/**
|
|
6136
8244
|
* Creates default indexes for optimal query performance.
|
|
6137
8245
|
*/
|
|
@@ -6660,7 +8768,7 @@ var ObservabilityPG = class _ObservabilityPG extends ObservabilityStorage {
|
|
|
6660
8768
|
}
|
|
6661
8769
|
}
|
|
6662
8770
|
};
|
|
6663
|
-
var
|
|
8771
|
+
var SNAPSHOT_FIELDS2 = ["name", "description", "content", "rules"];
|
|
6664
8772
|
var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
6665
8773
|
#db;
|
|
6666
8774
|
#schema;
|
|
@@ -6675,16 +8783,47 @@ var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
|
6675
8783
|
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
6676
8784
|
this.#indexes = indexes?.filter((idx) => _PromptBlocksPG.MANAGED_TABLES.includes(idx.table));
|
|
6677
8785
|
}
|
|
6678
|
-
|
|
8786
|
+
/**
|
|
8787
|
+
* Returns default index definitions for the prompt blocks domain tables.
|
|
8788
|
+
* @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
|
|
8789
|
+
*/
|
|
8790
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
6679
8791
|
return [
|
|
6680
8792
|
{
|
|
6681
|
-
name:
|
|
8793
|
+
name: `${schemaPrefix}idx_prompt_block_versions_block_version`,
|
|
6682
8794
|
table: TABLE_PROMPT_BLOCK_VERSIONS,
|
|
6683
8795
|
columns: ["blockId", "versionNumber"],
|
|
6684
8796
|
unique: true
|
|
6685
8797
|
}
|
|
6686
8798
|
];
|
|
6687
8799
|
}
|
|
8800
|
+
/**
|
|
8801
|
+
* Returns all DDL statements for this domain: tables and indexes.
|
|
8802
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
8803
|
+
*/
|
|
8804
|
+
static getExportDDL(schemaName) {
|
|
8805
|
+
const statements = [];
|
|
8806
|
+
const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
8807
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
8808
|
+
for (const tableName of _PromptBlocksPG.MANAGED_TABLES) {
|
|
8809
|
+
statements.push(
|
|
8810
|
+
generateTableSQL({
|
|
8811
|
+
tableName,
|
|
8812
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
8813
|
+
schemaName,
|
|
8814
|
+
includeAllConstraints: true
|
|
8815
|
+
})
|
|
8816
|
+
);
|
|
8817
|
+
}
|
|
8818
|
+
for (const idx of _PromptBlocksPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
8819
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
8820
|
+
}
|
|
8821
|
+
return statements;
|
|
8822
|
+
}
|
|
8823
|
+
getDefaultIndexDefinitions() {
|
|
8824
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
8825
|
+
return _PromptBlocksPG.getDefaultIndexDefs(schemaPrefix);
|
|
8826
|
+
}
|
|
6688
8827
|
async createDefaultIndexes() {
|
|
6689
8828
|
if (this.#skipDefaultIndexes) {
|
|
6690
8829
|
return;
|
|
@@ -6775,7 +8914,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
|
6775
8914
|
blockId: promptBlock.id,
|
|
6776
8915
|
versionNumber: 1,
|
|
6777
8916
|
...snapshotConfig,
|
|
6778
|
-
changedFields: [...
|
|
8917
|
+
changedFields: [...SNAPSHOT_FIELDS2],
|
|
6779
8918
|
changeMessage: "Initial version"
|
|
6780
8919
|
});
|
|
6781
8920
|
return {
|
|
@@ -6824,7 +8963,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
|
6824
8963
|
}
|
|
6825
8964
|
const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
|
|
6826
8965
|
let versionCreated = false;
|
|
6827
|
-
const hasConfigUpdate =
|
|
8966
|
+
const hasConfigUpdate = SNAPSHOT_FIELDS2.some((field) => field in configFields);
|
|
6828
8967
|
if (hasConfigUpdate) {
|
|
6829
8968
|
const latestVersion = await this.getLatestVersion(id);
|
|
6830
8969
|
if (!latestVersion) {
|
|
@@ -6846,7 +8985,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
|
6846
8985
|
...latestConfig
|
|
6847
8986
|
} = latestVersion;
|
|
6848
8987
|
const newConfig = { ...latestConfig, ...configFields };
|
|
6849
|
-
const changedFields =
|
|
8988
|
+
const changedFields = SNAPSHOT_FIELDS2.filter(
|
|
6850
8989
|
(field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
|
|
6851
8990
|
);
|
|
6852
8991
|
if (changedFields.length > 0) {
|
|
@@ -7312,7 +9451,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends PromptBlocksStorage {
|
|
|
7312
9451
|
};
|
|
7313
9452
|
}
|
|
7314
9453
|
};
|
|
7315
|
-
var
|
|
9454
|
+
var SNAPSHOT_FIELDS3 = [
|
|
7316
9455
|
"name",
|
|
7317
9456
|
"description",
|
|
7318
9457
|
"type",
|
|
@@ -7338,16 +9477,47 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends ScorerDefinitionsSt
|
|
|
7338
9477
|
(idx) => _ScorerDefinitionsPG.MANAGED_TABLES.includes(idx.table)
|
|
7339
9478
|
);
|
|
7340
9479
|
}
|
|
7341
|
-
|
|
9480
|
+
/**
|
|
9481
|
+
* Returns default index definitions for the scorer definitions domain tables.
|
|
9482
|
+
* @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
|
|
9483
|
+
*/
|
|
9484
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
7342
9485
|
return [
|
|
7343
9486
|
{
|
|
7344
|
-
name:
|
|
9487
|
+
name: `${schemaPrefix}idx_scorer_definition_versions_def_version`,
|
|
7345
9488
|
table: TABLE_SCORER_DEFINITION_VERSIONS,
|
|
7346
9489
|
columns: ["scorerDefinitionId", "versionNumber"],
|
|
7347
9490
|
unique: true
|
|
7348
9491
|
}
|
|
7349
9492
|
];
|
|
7350
9493
|
}
|
|
9494
|
+
/**
|
|
9495
|
+
* Returns all DDL statements for this domain: tables and indexes.
|
|
9496
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
9497
|
+
*/
|
|
9498
|
+
static getExportDDL(schemaName) {
|
|
9499
|
+
const statements = [];
|
|
9500
|
+
const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
9501
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
9502
|
+
for (const tableName of _ScorerDefinitionsPG.MANAGED_TABLES) {
|
|
9503
|
+
statements.push(
|
|
9504
|
+
generateTableSQL({
|
|
9505
|
+
tableName,
|
|
9506
|
+
schema: TABLE_SCHEMAS[tableName],
|
|
9507
|
+
schemaName,
|
|
9508
|
+
includeAllConstraints: true
|
|
9509
|
+
})
|
|
9510
|
+
);
|
|
9511
|
+
}
|
|
9512
|
+
for (const idx of _ScorerDefinitionsPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
9513
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
9514
|
+
}
|
|
9515
|
+
return statements;
|
|
9516
|
+
}
|
|
9517
|
+
getDefaultIndexDefinitions() {
|
|
9518
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
9519
|
+
return _ScorerDefinitionsPG.getDefaultIndexDefs(schemaPrefix);
|
|
9520
|
+
}
|
|
7351
9521
|
async createDefaultIndexes() {
|
|
7352
9522
|
if (this.#skipDefaultIndexes) {
|
|
7353
9523
|
return;
|
|
@@ -7441,7 +9611,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends ScorerDefinitionsSt
|
|
|
7441
9611
|
scorerDefinitionId: scorerDefinition.id,
|
|
7442
9612
|
versionNumber: 1,
|
|
7443
9613
|
...snapshotConfig,
|
|
7444
|
-
changedFields: [...
|
|
9614
|
+
changedFields: [...SNAPSHOT_FIELDS3],
|
|
7445
9615
|
changeMessage: "Initial version"
|
|
7446
9616
|
});
|
|
7447
9617
|
return {
|
|
@@ -7493,7 +9663,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends ScorerDefinitionsSt
|
|
|
7493
9663
|
}
|
|
7494
9664
|
const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
|
|
7495
9665
|
let versionCreated = false;
|
|
7496
|
-
const hasConfigUpdate =
|
|
9666
|
+
const hasConfigUpdate = SNAPSHOT_FIELDS3.some((field) => field in configFields);
|
|
7497
9667
|
if (hasConfigUpdate) {
|
|
7498
9668
|
const latestVersion = await this.getLatestVersion(id);
|
|
7499
9669
|
if (!latestVersion) {
|
|
@@ -7515,7 +9685,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends ScorerDefinitionsSt
|
|
|
7515
9685
|
...latestConfig
|
|
7516
9686
|
} = latestVersion;
|
|
7517
9687
|
const newConfig = { ...latestConfig, ...configFields };
|
|
7518
|
-
const changedFields =
|
|
9688
|
+
const changedFields = SNAPSHOT_FIELDS3.filter(
|
|
7519
9689
|
(field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
|
|
7520
9690
|
);
|
|
7521
9691
|
if (changedFields.length > 0) {
|
|
@@ -8034,9 +10204,9 @@ var ScoresPG = class _ScoresPG extends ScoresStorage {
|
|
|
8034
10204
|
}
|
|
8035
10205
|
/**
|
|
8036
10206
|
* Returns default index definitions for the scores domain tables.
|
|
10207
|
+
* @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
|
|
8037
10208
|
*/
|
|
8038
|
-
|
|
8039
|
-
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
10209
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
8040
10210
|
return [
|
|
8041
10211
|
{
|
|
8042
10212
|
name: `${schemaPrefix}mastra_scores_trace_id_span_id_created_at_idx`,
|
|
@@ -8045,6 +10215,34 @@ var ScoresPG = class _ScoresPG extends ScoresStorage {
|
|
|
8045
10215
|
}
|
|
8046
10216
|
];
|
|
8047
10217
|
}
|
|
10218
|
+
/**
|
|
10219
|
+
* Returns all DDL statements for this domain: table and indexes.
|
|
10220
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
10221
|
+
*/
|
|
10222
|
+
static getExportDDL(schemaName) {
|
|
10223
|
+
const statements = [];
|
|
10224
|
+
const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
|
|
10225
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
10226
|
+
statements.push(
|
|
10227
|
+
generateTableSQL({
|
|
10228
|
+
tableName: TABLE_SCORERS,
|
|
10229
|
+
schema: TABLE_SCHEMAS[TABLE_SCORERS],
|
|
10230
|
+
schemaName,
|
|
10231
|
+
includeAllConstraints: true
|
|
10232
|
+
})
|
|
10233
|
+
);
|
|
10234
|
+
for (const idx of _ScoresPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
10235
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
10236
|
+
}
|
|
10237
|
+
return statements;
|
|
10238
|
+
}
|
|
10239
|
+
/**
|
|
10240
|
+
* Returns default index definitions for this instance's schema.
|
|
10241
|
+
*/
|
|
10242
|
+
getDefaultIndexDefinitions() {
|
|
10243
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
10244
|
+
return _ScoresPG.getDefaultIndexDefs(schemaPrefix);
|
|
10245
|
+
}
|
|
8048
10246
|
/**
|
|
8049
10247
|
* Creates default indexes for optimal query performance.
|
|
8050
10248
|
*/
|
|
@@ -8416,6 +10614,22 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
|
|
|
8416
10614
|
updatedAt: new Date(row.updatedAtZ || row.updatedAt)
|
|
8417
10615
|
};
|
|
8418
10616
|
}
|
|
10617
|
+
/**
|
|
10618
|
+
* Returns all DDL statements for this domain: table with unique constraint.
|
|
10619
|
+
* Used by exportSchemas to produce a complete, reproducible schema export.
|
|
10620
|
+
*/
|
|
10621
|
+
static getExportDDL(schemaName) {
|
|
10622
|
+
const statements = [];
|
|
10623
|
+
statements.push(
|
|
10624
|
+
generateTableSQL({
|
|
10625
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
10626
|
+
schema: TABLE_SCHEMAS[TABLE_WORKFLOW_SNAPSHOT],
|
|
10627
|
+
schemaName,
|
|
10628
|
+
includeAllConstraints: true
|
|
10629
|
+
})
|
|
10630
|
+
);
|
|
10631
|
+
return statements;
|
|
10632
|
+
}
|
|
8419
10633
|
/**
|
|
8420
10634
|
* Returns default index definitions for the workflows domain tables.
|
|
8421
10635
|
* Currently no default indexes are defined for workflows.
|
|
@@ -8682,6 +10896,29 @@ var WorkflowsPG = class _WorkflowsPG extends WorkflowsStorage {
|
|
|
8682
10896
|
// src/storage/index.ts
|
|
8683
10897
|
var DEFAULT_MAX_CONNECTIONS = 20;
|
|
8684
10898
|
var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
|
|
10899
|
+
var ALL_DOMAINS = [
|
|
10900
|
+
MemoryPG,
|
|
10901
|
+
ObservabilityPG,
|
|
10902
|
+
ScoresPG,
|
|
10903
|
+
ScorerDefinitionsPG,
|
|
10904
|
+
PromptBlocksPG,
|
|
10905
|
+
AgentsPG,
|
|
10906
|
+
WorkflowsPG,
|
|
10907
|
+
DatasetsPG,
|
|
10908
|
+
ExperimentsPG
|
|
10909
|
+
];
|
|
10910
|
+
function exportSchemas(schemaName) {
|
|
10911
|
+
const statements = [];
|
|
10912
|
+
if (schemaName) {
|
|
10913
|
+
const quotedSchemaName = getSchemaName(schemaName);
|
|
10914
|
+
statements.push(`CREATE SCHEMA IF NOT EXISTS ${quotedSchemaName};`);
|
|
10915
|
+
statements.push("");
|
|
10916
|
+
}
|
|
10917
|
+
for (const Domain of ALL_DOMAINS) {
|
|
10918
|
+
statements.push(...Domain.getExportDDL(schemaName));
|
|
10919
|
+
}
|
|
10920
|
+
return statements.join("\n");
|
|
10921
|
+
}
|
|
8685
10922
|
var PostgresStore = class extends MastraCompositeStore {
|
|
8686
10923
|
#pool;
|
|
8687
10924
|
#db;
|
|
@@ -8715,7 +10952,10 @@ var PostgresStore = class extends MastraCompositeStore {
|
|
|
8715
10952
|
observability: new ObservabilityPG(domainConfig),
|
|
8716
10953
|
agents: new AgentsPG(domainConfig),
|
|
8717
10954
|
promptBlocks: new PromptBlocksPG(domainConfig),
|
|
8718
|
-
scorerDefinitions: new ScorerDefinitionsPG(domainConfig)
|
|
10955
|
+
scorerDefinitions: new ScorerDefinitionsPG(domainConfig),
|
|
10956
|
+
mcpClients: new MCPClientsPG(domainConfig),
|
|
10957
|
+
datasets: new DatasetsPG(domainConfig),
|
|
10958
|
+
experiments: new ExperimentsPG(domainConfig)
|
|
8719
10959
|
};
|
|
8720
10960
|
} catch (e) {
|
|
8721
10961
|
throw new MastraError(
|
|
@@ -8904,6 +11144,6 @@ Example Complex Query:
|
|
|
8904
11144
|
]
|
|
8905
11145
|
}`;
|
|
8906
11146
|
|
|
8907
|
-
export { AgentsPG, MemoryPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PoolAdapter, PostgresStore, PromptBlocksPG, ScorerDefinitionsPG, ScoresPG, WorkflowsPG, exportSchemas };
|
|
11147
|
+
export { AgentsPG, DatasetsPG, ExperimentsPG, MCPClientsPG, MemoryPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PoolAdapter, PostgresStore, PromptBlocksPG, ScorerDefinitionsPG, ScoresPG, WorkflowsPG, exportSchemas };
|
|
8908
11148
|
//# sourceMappingURL=index.js.map
|
|
8909
11149
|
//# sourceMappingURL=index.js.map
|