@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.
Files changed (33) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/dist/docs/SKILL.md +1 -1
  3. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  4. package/dist/index.cjs +2423 -180
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.js +2422 -182
  7. package/dist/index.js.map +1 -1
  8. package/dist/storage/db/index.d.ts +23 -4
  9. package/dist/storage/db/index.d.ts.map +1 -1
  10. package/dist/storage/domains/agents/index.d.ts +5 -0
  11. package/dist/storage/domains/agents/index.d.ts.map +1 -1
  12. package/dist/storage/domains/datasets/index.d.ts +48 -0
  13. package/dist/storage/domains/datasets/index.d.ts.map +1 -0
  14. package/dist/storage/domains/experiments/index.d.ts +34 -0
  15. package/dist/storage/domains/experiments/index.d.ts.map +1 -0
  16. package/dist/storage/domains/mcp-clients/index.d.ts +33 -0
  17. package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -0
  18. package/dist/storage/domains/memory/index.d.ts +10 -0
  19. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  20. package/dist/storage/domains/observability/index.d.ts +10 -0
  21. package/dist/storage/domains/observability/index.d.ts.map +1 -1
  22. package/dist/storage/domains/prompt-blocks/index.d.ts +10 -0
  23. package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
  24. package/dist/storage/domains/scorer-definitions/index.d.ts +10 -0
  25. package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
  26. package/dist/storage/domains/scores/index.d.ts +10 -0
  27. package/dist/storage/domains/scores/index.d.ts.map +1 -1
  28. package/dist/storage/domains/workflows/index.d.ts +5 -0
  29. package/dist/storage/domains/workflows/index.d.ts.map +1 -1
  30. package/dist/storage/index.d.ts +10 -2
  31. package/dist/storage/index.d.ts.map +1 -1
  32. package/dist/storage/test-utils.d.ts.map +1 -1
  33. package/package.json +6 -6
package/dist/index.cjs CHANGED
@@ -36,7 +36,12 @@ function _interopNamespace(e) {
36
36
  var pg__namespace = /*#__PURE__*/_interopNamespace(pg);
37
37
  var xxhash__default = /*#__PURE__*/_interopDefault(xxhash);
38
38
 
39
- // src/vector/index.ts
39
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
40
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
41
+ }) : x)(function(x) {
42
+ if (typeof require !== "undefined") return require.apply(this, arguments);
43
+ throw Error('Dynamic require of "' + x + '" is not supported');
44
+ });
40
45
 
41
46
  // src/shared/config.ts
42
47
  var isPoolConfig = (cfg) => {
@@ -1996,8 +2001,17 @@ function generateTableSQL({
1996
2001
  tableName,
1997
2002
  schema,
1998
2003
  schemaName,
2004
+ compositePrimaryKey,
1999
2005
  includeAllConstraints = false
2000
2006
  }) {
2007
+ if (compositePrimaryKey) {
2008
+ for (const col of compositePrimaryKey) {
2009
+ if (!(col in schema)) {
2010
+ throw new Error(`compositePrimaryKey column "${col}" does not exist in schema for table "${tableName}"`);
2011
+ }
2012
+ }
2013
+ }
2014
+ const compositePKSet = compositePrimaryKey ? new Set(compositePrimaryKey) : null;
2001
2015
  const timeZColumns = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => {
2002
2016
  const parsedName = utils.parseSqlIdentifier(name, "column name");
2003
2017
  return `"${parsedName}Z" TIMESTAMPTZ DEFAULT NOW()`;
@@ -2005,11 +2019,16 @@ function generateTableSQL({
2005
2019
  const columns = Object.entries(schema).map(([name, def]) => {
2006
2020
  const parsedName = utils.parseSqlIdentifier(name, "column name");
2007
2021
  const constraints = [];
2008
- if (def.primaryKey) constraints.push("PRIMARY KEY");
2022
+ if (def.primaryKey && !compositePKSet?.has(name)) constraints.push("PRIMARY KEY");
2009
2023
  if (!def.nullable) constraints.push("NOT NULL");
2010
2024
  return `"${parsedName}" ${mapToSqlType(def.type)} ${constraints.join(" ")}`;
2011
2025
  });
2012
- const finalColumns = [...columns, ...timeZColumns].join(",\n");
2026
+ const tableConstraints = [];
2027
+ if (compositePrimaryKey) {
2028
+ const pkCols = compositePrimaryKey.map((c) => `"${utils.parseSqlIdentifier(c, "column name")}"`).join(", ");
2029
+ tableConstraints.push(`PRIMARY KEY (${pkCols})`);
2030
+ }
2031
+ const finalColumns = [...columns, ...timeZColumns, ...tableConstraints].join(",\n");
2013
2032
  const parsedSchemaName = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
2014
2033
  const workflowSnapshotConstraint = buildConstraintName({
2015
2034
  baseName: "mastra_workflow_snapshot_workflow_name_run_id_key",
@@ -2053,27 +2072,55 @@ function generateTableSQL({
2053
2072
  `;
2054
2073
  return sql;
2055
2074
  }
2056
- function exportSchemas(schemaName) {
2057
- const statements = [];
2058
- if (schemaName) {
2059
- const quotedSchemaName = getSchemaName(schemaName);
2060
- statements.push(`-- Create schema if it doesn't exist`);
2061
- statements.push(`CREATE SCHEMA IF NOT EXISTS ${quotedSchemaName};`);
2062
- statements.push("");
2063
- }
2064
- for (const [tableName, schema] of Object.entries(storage.TABLE_SCHEMAS)) {
2065
- statements.push(`-- Table: ${tableName}`);
2066
- const sql = generateTableSQL({
2067
- tableName,
2068
- schema,
2069
- schemaName,
2070
- includeAllConstraints: true
2071
- // Include all constraints for exports/documentation
2072
- });
2073
- statements.push(sql.trim());
2074
- statements.push("");
2075
- }
2076
- return statements.join("\n");
2075
+ function generateIndexSQL(options, schemaName) {
2076
+ const { name, table, columns, unique = false, where, method = "btree" } = options;
2077
+ const quotedSchemaName = getSchemaName(schemaName);
2078
+ const fullTableName = getTableName({ indexName: table, schemaName: quotedSchemaName });
2079
+ const uniqueStr = unique ? "UNIQUE " : "";
2080
+ const methodStr = method !== "btree" ? `USING ${method} ` : "";
2081
+ const columnsStr = columns.map((col) => {
2082
+ if (col.includes(" DESC") || col.includes(" ASC")) {
2083
+ const [colName, ...modifiers] = col.split(" ");
2084
+ if (!colName) {
2085
+ throw new Error(`Invalid column specification: ${col}`);
2086
+ }
2087
+ return `"${utils.parseSqlIdentifier(colName, "column name")}" ${modifiers.join(" ")}`;
2088
+ }
2089
+ return `"${utils.parseSqlIdentifier(col, "column name")}"`;
2090
+ }).join(", ");
2091
+ const whereStr = where ? ` WHERE ${where}` : "";
2092
+ const quotedIndexName = `"${utils.parseSqlIdentifier(name, "index name")}"`;
2093
+ return `CREATE ${uniqueStr}INDEX IF NOT EXISTS ${quotedIndexName} ON ${fullTableName} ${methodStr}(${columnsStr})${whereStr};`;
2094
+ }
2095
+ function generateTimestampTriggerSQL(tableName, schemaName) {
2096
+ const quotedSchemaName = getSchemaName(schemaName);
2097
+ const fullTableName = getTableName({ indexName: tableName, schemaName: quotedSchemaName });
2098
+ const functionName = `${quotedSchemaName}.trigger_set_timestamps`;
2099
+ const triggerName = `"${utils.parseSqlIdentifier(`${tableName}_timestamps`, "trigger name")}"`;
2100
+ return `CREATE OR REPLACE FUNCTION ${functionName}()
2101
+ RETURNS TRIGGER AS $$
2102
+ BEGIN
2103
+ IF TG_OP = 'INSERT' THEN
2104
+ NEW."createdAt" = NOW();
2105
+ NEW."updatedAt" = NOW();
2106
+ NEW."createdAtZ" = NOW();
2107
+ NEW."updatedAtZ" = NOW();
2108
+ ELSIF TG_OP = 'UPDATE' THEN
2109
+ NEW."updatedAt" = NOW();
2110
+ NEW."updatedAtZ" = NOW();
2111
+ NEW."createdAt" = OLD."createdAt";
2112
+ NEW."createdAtZ" = OLD."createdAtZ";
2113
+ END IF;
2114
+ RETURN NEW;
2115
+ END;
2116
+ $$ LANGUAGE plpgsql;
2117
+
2118
+ DROP TRIGGER IF EXISTS ${triggerName} ON ${fullTableName};
2119
+
2120
+ CREATE TRIGGER ${triggerName}
2121
+ BEFORE INSERT OR UPDATE ON ${fullTableName}
2122
+ FOR EACH ROW
2123
+ EXECUTE FUNCTION ${functionName}();`;
2077
2124
  }
2078
2125
  var schemaSetupRegistry = /* @__PURE__ */ new Map();
2079
2126
  var PgDB = class extends base.MastraBase {
@@ -2274,14 +2321,15 @@ var PgDB = class extends base.MastraBase {
2274
2321
  }
2275
2322
  async createTable({
2276
2323
  tableName,
2277
- schema
2324
+ schema,
2325
+ compositePrimaryKey
2278
2326
  }) {
2279
2327
  try {
2280
2328
  const timeZColumnNames = Object.entries(schema).filter(([_, def]) => def.type === "timestamp").map(([name]) => name);
2281
2329
  if (this.schemaName) {
2282
2330
  await this.setupSchema();
2283
2331
  }
2284
- const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName });
2332
+ const sql = generateTableSQL({ tableName, schema, schemaName: this.schemaName, compositePrimaryKey });
2285
2333
  await this.client.none(sql);
2286
2334
  await this.alterTable({
2287
2335
  tableName,
@@ -2345,36 +2393,9 @@ Note: This migration may take some time for large tables.
2345
2393
  }
2346
2394
  }
2347
2395
  async setupTimestampTriggers(tableName) {
2348
- const schemaName = getSchemaName(this.schemaName);
2349
- const fullTableName = getTableName({ indexName: tableName, schemaName });
2350
- const functionName = `${schemaName}.trigger_set_timestamps`;
2351
- try {
2352
- const triggerSQL = `
2353
- CREATE OR REPLACE FUNCTION ${functionName}()
2354
- RETURNS TRIGGER AS $$
2355
- BEGIN
2356
- IF TG_OP = 'INSERT' THEN
2357
- NEW."createdAt" = NOW();
2358
- NEW."updatedAt" = NOW();
2359
- NEW."createdAtZ" = NOW();
2360
- NEW."updatedAtZ" = NOW();
2361
- ELSIF TG_OP = 'UPDATE' THEN
2362
- NEW."updatedAt" = NOW();
2363
- NEW."updatedAtZ" = NOW();
2364
- NEW."createdAt" = OLD."createdAt";
2365
- NEW."createdAtZ" = OLD."createdAtZ";
2366
- END IF;
2367
- RETURN NEW;
2368
- END;
2369
- $$ LANGUAGE plpgsql;
2370
-
2371
- DROP TRIGGER IF EXISTS ${tableName}_timestamps ON ${fullTableName};
2372
-
2373
- CREATE TRIGGER ${tableName}_timestamps
2374
- BEFORE INSERT OR UPDATE ON ${fullTableName}
2375
- FOR EACH ROW
2376
- EXECUTE FUNCTION ${functionName}();
2377
- `;
2396
+ const fullTableName = getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) });
2397
+ try {
2398
+ const triggerSQL = generateTimestampTriggerSQL(tableName, this.schemaName);
2378
2399
  await this.client.none(triggerSQL);
2379
2400
  this.logger?.debug?.(`Set up timestamp triggers for table ${fullTableName}`);
2380
2401
  } catch (error) {
@@ -3167,6 +3188,24 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3167
3188
  this.#skipDefaultIndexes = skipDefaultIndexes;
3168
3189
  this.#indexes = indexes?.filter((idx) => _AgentsPG.MANAGED_TABLES.includes(idx.table));
3169
3190
  }
3191
+ /**
3192
+ * Returns all DDL statements for this domain: tables.
3193
+ * Used by exportSchemas to produce a complete, reproducible schema export.
3194
+ */
3195
+ static getExportDDL(schemaName) {
3196
+ const statements = [];
3197
+ for (const tableName of _AgentsPG.MANAGED_TABLES) {
3198
+ statements.push(
3199
+ generateTableSQL({
3200
+ tableName,
3201
+ schema: storage.TABLE_SCHEMAS[tableName],
3202
+ schemaName,
3203
+ includeAllConstraints: true
3204
+ })
3205
+ );
3206
+ }
3207
+ return statements;
3208
+ }
3170
3209
  /**
3171
3210
  * Returns default index definitions for the agents domain tables.
3172
3211
  * Currently no default indexes are defined for agents.
@@ -3512,7 +3551,9 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3512
3551
  "inputProcessors",
3513
3552
  "outputProcessors",
3514
3553
  "memory",
3515
- "scorers"
3554
+ "scorers",
3555
+ "mcpClients",
3556
+ "requestContextSchema"
3516
3557
  ];
3517
3558
  const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
3518
3559
  if (hasConfigUpdate) {
@@ -3642,16 +3683,1975 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3642
3683
  },
3643
3684
  new Error("page must be >= 0")
3644
3685
  );
3645
- }
3646
- const perPage = storage.normalizePerPage(perPageInput, 100);
3647
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3648
- try {
3649
- const tableName = getTableName2({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3650
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
3686
+ }
3687
+ const perPage = storage.normalizePerPage(perPageInput, 100);
3688
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3689
+ try {
3690
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3691
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
3692
+ const total = parseInt(countResult.count, 10);
3693
+ if (total === 0) {
3694
+ return {
3695
+ agents: [],
3696
+ total: 0,
3697
+ page,
3698
+ perPage: perPageForResponse,
3699
+ hasMore: false
3700
+ };
3701
+ }
3702
+ const limitValue = perPageInput === false ? total : perPage;
3703
+ const dataResult = await this.#db.client.manyOrNone(
3704
+ `SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
3705
+ [limitValue, offset]
3706
+ );
3707
+ const agents = (dataResult || []).map((row) => this.parseRow(row));
3708
+ return {
3709
+ agents,
3710
+ total,
3711
+ page,
3712
+ perPage: perPageForResponse,
3713
+ hasMore: perPageInput === false ? false : offset + perPage < total
3714
+ };
3715
+ } catch (error$1) {
3716
+ if (error$1 instanceof error.MastraError) throw error$1;
3717
+ throw new error.MastraError(
3718
+ {
3719
+ id: storage.createStorageErrorId("PG", "LIST_AGENTS", "FAILED"),
3720
+ domain: error.ErrorDomain.STORAGE,
3721
+ category: error.ErrorCategory.THIRD_PARTY
3722
+ },
3723
+ error$1
3724
+ );
3725
+ }
3726
+ }
3727
+ // ==========================================================================
3728
+ // Agent Version Methods
3729
+ // ==========================================================================
3730
+ async createVersion(input) {
3731
+ try {
3732
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3733
+ const now = /* @__PURE__ */ new Date();
3734
+ const nowIso = now.toISOString();
3735
+ await this.#db.client.none(
3736
+ `INSERT INTO ${tableName} (
3737
+ id, "agentId", "versionNumber",
3738
+ name, description, instructions, model, tools,
3739
+ "defaultOptions", workflows, agents, "integrationTools",
3740
+ "inputProcessors", "outputProcessors", memory, scorers,
3741
+ "mcpClients", "requestContextSchema", "changedFields", "changeMessage",
3742
+ "createdAt", "createdAtZ"
3743
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`,
3744
+ [
3745
+ input.id,
3746
+ input.agentId,
3747
+ input.versionNumber,
3748
+ input.name,
3749
+ input.description ?? null,
3750
+ this.serializeInstructions(input.instructions),
3751
+ JSON.stringify(input.model),
3752
+ input.tools ? JSON.stringify(input.tools) : null,
3753
+ input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
3754
+ input.workflows ? JSON.stringify(input.workflows) : null,
3755
+ input.agents ? JSON.stringify(input.agents) : null,
3756
+ input.integrationTools ? JSON.stringify(input.integrationTools) : null,
3757
+ input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
3758
+ input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
3759
+ input.memory ? JSON.stringify(input.memory) : null,
3760
+ input.scorers ? JSON.stringify(input.scorers) : null,
3761
+ input.mcpClients ? JSON.stringify(input.mcpClients) : null,
3762
+ input.requestContextSchema ? JSON.stringify(input.requestContextSchema) : null,
3763
+ input.changedFields ? JSON.stringify(input.changedFields) : null,
3764
+ input.changeMessage ?? null,
3765
+ nowIso,
3766
+ nowIso
3767
+ ]
3768
+ );
3769
+ return {
3770
+ ...input,
3771
+ createdAt: now
3772
+ };
3773
+ } catch (error$1) {
3774
+ if (error$1 instanceof error.MastraError) throw error$1;
3775
+ throw new error.MastraError(
3776
+ {
3777
+ id: storage.createStorageErrorId("PG", "CREATE_VERSION", "FAILED"),
3778
+ domain: error.ErrorDomain.STORAGE,
3779
+ category: error.ErrorCategory.THIRD_PARTY,
3780
+ details: { versionId: input.id, agentId: input.agentId }
3781
+ },
3782
+ error$1
3783
+ );
3784
+ }
3785
+ }
3786
+ async getVersion(id) {
3787
+ try {
3788
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3789
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
3790
+ if (!result) {
3791
+ return null;
3792
+ }
3793
+ return this.parseVersionRow(result);
3794
+ } catch (error$1) {
3795
+ if (error$1 instanceof error.MastraError) throw error$1;
3796
+ throw new error.MastraError(
3797
+ {
3798
+ id: storage.createStorageErrorId("PG", "GET_VERSION", "FAILED"),
3799
+ domain: error.ErrorDomain.STORAGE,
3800
+ category: error.ErrorCategory.THIRD_PARTY,
3801
+ details: { versionId: id }
3802
+ },
3803
+ error$1
3804
+ );
3805
+ }
3806
+ }
3807
+ async getVersionByNumber(agentId, versionNumber) {
3808
+ try {
3809
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3810
+ const result = await this.#db.client.oneOrNone(
3811
+ `SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`,
3812
+ [agentId, versionNumber]
3813
+ );
3814
+ if (!result) {
3815
+ return null;
3816
+ }
3817
+ return this.parseVersionRow(result);
3818
+ } catch (error$1) {
3819
+ if (error$1 instanceof error.MastraError) throw error$1;
3820
+ throw new error.MastraError(
3821
+ {
3822
+ id: storage.createStorageErrorId("PG", "GET_VERSION_BY_NUMBER", "FAILED"),
3823
+ domain: error.ErrorDomain.STORAGE,
3824
+ category: error.ErrorCategory.THIRD_PARTY,
3825
+ details: { agentId, versionNumber }
3826
+ },
3827
+ error$1
3828
+ );
3829
+ }
3830
+ }
3831
+ async getLatestVersion(agentId) {
3832
+ try {
3833
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3834
+ const result = await this.#db.client.oneOrNone(
3835
+ `SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
3836
+ [agentId]
3837
+ );
3838
+ if (!result) {
3839
+ return null;
3840
+ }
3841
+ return this.parseVersionRow(result);
3842
+ } catch (error$1) {
3843
+ if (error$1 instanceof error.MastraError) throw error$1;
3844
+ throw new error.MastraError(
3845
+ {
3846
+ id: storage.createStorageErrorId("PG", "GET_LATEST_VERSION", "FAILED"),
3847
+ domain: error.ErrorDomain.STORAGE,
3848
+ category: error.ErrorCategory.THIRD_PARTY,
3849
+ details: { agentId }
3850
+ },
3851
+ error$1
3852
+ );
3853
+ }
3854
+ }
3855
+ async listVersions(input) {
3856
+ const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
3857
+ if (page < 0) {
3858
+ throw new error.MastraError(
3859
+ {
3860
+ id: storage.createStorageErrorId("PG", "LIST_VERSIONS", "INVALID_PAGE"),
3861
+ domain: error.ErrorDomain.STORAGE,
3862
+ category: error.ErrorCategory.USER,
3863
+ details: { page }
3864
+ },
3865
+ new Error("page must be >= 0")
3866
+ );
3867
+ }
3868
+ const perPage = storage.normalizePerPage(perPageInput, 20);
3869
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3870
+ try {
3871
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
3872
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3873
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
3874
+ agentId
3875
+ ]);
3876
+ const total = parseInt(countResult.count, 10);
3877
+ if (total === 0) {
3878
+ return {
3879
+ versions: [],
3880
+ total: 0,
3881
+ page,
3882
+ perPage: perPageForResponse,
3883
+ hasMore: false
3884
+ };
3885
+ }
3886
+ const limitValue = perPageInput === false ? total : perPage;
3887
+ const dataResult = await this.#db.client.manyOrNone(
3888
+ `SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
3889
+ [agentId, limitValue, offset]
3890
+ );
3891
+ const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
3892
+ return {
3893
+ versions,
3894
+ total,
3895
+ page,
3896
+ perPage: perPageForResponse,
3897
+ hasMore: perPageInput === false ? false : offset + perPage < total
3898
+ };
3899
+ } catch (error$1) {
3900
+ if (error$1 instanceof error.MastraError) throw error$1;
3901
+ throw new error.MastraError(
3902
+ {
3903
+ id: storage.createStorageErrorId("PG", "LIST_VERSIONS", "FAILED"),
3904
+ domain: error.ErrorDomain.STORAGE,
3905
+ category: error.ErrorCategory.THIRD_PARTY,
3906
+ details: { agentId }
3907
+ },
3908
+ error$1
3909
+ );
3910
+ }
3911
+ }
3912
+ async deleteVersion(id) {
3913
+ try {
3914
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3915
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
3916
+ } catch (error$1) {
3917
+ if (error$1 instanceof error.MastraError) throw error$1;
3918
+ throw new error.MastraError(
3919
+ {
3920
+ id: storage.createStorageErrorId("PG", "DELETE_VERSION", "FAILED"),
3921
+ domain: error.ErrorDomain.STORAGE,
3922
+ category: error.ErrorCategory.THIRD_PARTY,
3923
+ details: { versionId: id }
3924
+ },
3925
+ error$1
3926
+ );
3927
+ }
3928
+ }
3929
+ async deleteVersionsByParentId(entityId) {
3930
+ try {
3931
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3932
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "agentId" = $1`, [entityId]);
3933
+ } catch (error$1) {
3934
+ if (error$1 instanceof error.MastraError) throw error$1;
3935
+ throw new error.MastraError(
3936
+ {
3937
+ id: storage.createStorageErrorId("PG", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
3938
+ domain: error.ErrorDomain.STORAGE,
3939
+ category: error.ErrorCategory.THIRD_PARTY,
3940
+ details: { agentId: entityId }
3941
+ },
3942
+ error$1
3943
+ );
3944
+ }
3945
+ }
3946
+ async countVersions(agentId) {
3947
+ try {
3948
+ const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3949
+ const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
3950
+ agentId
3951
+ ]);
3952
+ return parseInt(result.count, 10);
3953
+ } catch (error$1) {
3954
+ if (error$1 instanceof error.MastraError) throw error$1;
3955
+ throw new error.MastraError(
3956
+ {
3957
+ id: storage.createStorageErrorId("PG", "COUNT_VERSIONS", "FAILED"),
3958
+ domain: error.ErrorDomain.STORAGE,
3959
+ category: error.ErrorCategory.THIRD_PARTY,
3960
+ details: { agentId }
3961
+ },
3962
+ error$1
3963
+ );
3964
+ }
3965
+ }
3966
+ // ==========================================================================
3967
+ // Private Helper Methods
3968
+ // ==========================================================================
3969
+ serializeInstructions(instructions) {
3970
+ if (instructions == null) return void 0;
3971
+ return Array.isArray(instructions) ? JSON.stringify(instructions) : instructions;
3972
+ }
3973
+ deserializeInstructions(raw) {
3974
+ if (!raw) return "";
3975
+ try {
3976
+ const parsed = JSON.parse(raw);
3977
+ if (Array.isArray(parsed)) return parsed;
3978
+ } catch {
3979
+ }
3980
+ return raw;
3981
+ }
3982
+ parseVersionRow(row) {
3983
+ return {
3984
+ id: row.id,
3985
+ agentId: row.agentId,
3986
+ versionNumber: row.versionNumber,
3987
+ name: row.name,
3988
+ description: row.description,
3989
+ instructions: this.deserializeInstructions(row.instructions),
3990
+ model: this.parseJson(row.model, "model"),
3991
+ tools: this.parseJson(row.tools, "tools"),
3992
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
3993
+ workflows: this.parseJson(row.workflows, "workflows"),
3994
+ agents: this.parseJson(row.agents, "agents"),
3995
+ integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
3996
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
3997
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
3998
+ memory: this.parseJson(row.memory, "memory"),
3999
+ scorers: this.parseJson(row.scorers, "scorers"),
4000
+ mcpClients: this.parseJson(row.mcpClients, "mcpClients"),
4001
+ requestContextSchema: this.parseJson(row.requestContextSchema, "requestContextSchema"),
4002
+ changedFields: this.parseJson(row.changedFields, "changedFields"),
4003
+ changeMessage: row.changeMessage,
4004
+ createdAt: row.createdAtZ || row.createdAt
4005
+ };
4006
+ }
4007
+ };
4008
+ function jsonbArg(value) {
4009
+ return value === void 0 || value === null ? null : JSON.stringify(value);
4010
+ }
4011
+ var DatasetsPG = class _DatasetsPG extends storage.DatasetsStorage {
4012
+ #db;
4013
+ #schema;
4014
+ #skipDefaultIndexes;
4015
+ #indexes;
4016
+ static MANAGED_TABLES = [storage.TABLE_DATASETS, storage.TABLE_DATASET_ITEMS, storage.TABLE_DATASET_VERSIONS];
4017
+ constructor(config) {
4018
+ super();
4019
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4020
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
4021
+ this.#schema = schemaName || "public";
4022
+ this.#skipDefaultIndexes = skipDefaultIndexes;
4023
+ this.#indexes = indexes?.filter((idx) => _DatasetsPG.MANAGED_TABLES.includes(idx.table));
4024
+ }
4025
+ static getExportDDL(schemaName) {
4026
+ const statements = [];
4027
+ for (const tableName of _DatasetsPG.MANAGED_TABLES) {
4028
+ statements.push(
4029
+ generateTableSQL({
4030
+ tableName,
4031
+ schema: storage.TABLE_SCHEMAS[tableName],
4032
+ schemaName,
4033
+ compositePrimaryKey: storage.TABLE_CONFIGS[tableName]?.compositePrimaryKey,
4034
+ includeAllConstraints: true
4035
+ })
4036
+ );
4037
+ }
4038
+ return statements;
4039
+ }
4040
+ async init() {
4041
+ await this.#db.createTable({ tableName: storage.TABLE_DATASETS, schema: storage.DATASETS_SCHEMA });
4042
+ await this.#db.createTable({
4043
+ tableName: storage.TABLE_DATASET_ITEMS,
4044
+ schema: storage.DATASET_ITEMS_SCHEMA,
4045
+ compositePrimaryKey: storage.TABLE_CONFIGS[storage.TABLE_DATASET_ITEMS]?.compositePrimaryKey
4046
+ });
4047
+ await this.#db.createTable({ tableName: storage.TABLE_DATASET_VERSIONS, schema: storage.DATASET_VERSIONS_SCHEMA });
4048
+ await this.createDefaultIndexes();
4049
+ await this.createCustomIndexes();
4050
+ }
4051
+ getDefaultIndexDefinitions() {
4052
+ return [
4053
+ { name: "idx_dataset_items_dataset_validto", table: storage.TABLE_DATASET_ITEMS, columns: ["datasetId", "validTo"] },
4054
+ {
4055
+ name: "idx_dataset_items_dataset_version",
4056
+ table: storage.TABLE_DATASET_ITEMS,
4057
+ columns: ["datasetId", "datasetVersion"]
4058
+ },
4059
+ {
4060
+ name: "idx_dataset_items_dataset_validto_deleted",
4061
+ table: storage.TABLE_DATASET_ITEMS,
4062
+ columns: ["datasetId", "validTo", "isDeleted"]
4063
+ },
4064
+ {
4065
+ name: "idx_dataset_versions_dataset_version",
4066
+ table: storage.TABLE_DATASET_VERSIONS,
4067
+ columns: ["datasetId", "version"]
4068
+ },
4069
+ {
4070
+ name: "idx_dataset_versions_dataset_version_unique",
4071
+ table: storage.TABLE_DATASET_VERSIONS,
4072
+ columns: ["datasetId", "version"],
4073
+ unique: true
4074
+ }
4075
+ ];
4076
+ }
4077
+ async createDefaultIndexes() {
4078
+ if (this.#skipDefaultIndexes) return;
4079
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
4080
+ try {
4081
+ await this.#db.createIndex(indexDef);
4082
+ } catch (error) {
4083
+ this.logger?.warn?.(`Failed to create default index ${indexDef.name}:`, error);
4084
+ }
4085
+ }
4086
+ }
4087
+ async createCustomIndexes() {
4088
+ if (!this.#indexes || this.#indexes.length === 0) return;
4089
+ for (const indexDef of this.#indexes) {
4090
+ try {
4091
+ await this.#db.createIndex(indexDef);
4092
+ } catch (error) {
4093
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
4094
+ }
4095
+ }
4096
+ }
4097
+ // --- Row transformers ---
4098
+ transformDatasetRow(row) {
4099
+ return {
4100
+ id: row.id,
4101
+ name: row.name,
4102
+ description: row.description ?? void 0,
4103
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
4104
+ inputSchema: row.inputSchema ? storage.safelyParseJSON(row.inputSchema) : void 0,
4105
+ groundTruthSchema: row.groundTruthSchema ? storage.safelyParseJSON(row.groundTruthSchema) : void 0,
4106
+ version: row.version,
4107
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt),
4108
+ updatedAt: storage.ensureDate(row.updatedAtZ || row.updatedAt)
4109
+ };
4110
+ }
4111
+ transformItemRow(row) {
4112
+ return {
4113
+ id: row.id,
4114
+ datasetId: row.datasetId,
4115
+ datasetVersion: row.datasetVersion,
4116
+ input: storage.safelyParseJSON(row.input),
4117
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
4118
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
4119
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt),
4120
+ updatedAt: storage.ensureDate(row.updatedAtZ || row.updatedAt)
4121
+ };
4122
+ }
4123
+ transformItemRowFull(row) {
4124
+ return {
4125
+ id: row.id,
4126
+ datasetId: row.datasetId,
4127
+ datasetVersion: row.datasetVersion,
4128
+ validTo: row.validTo,
4129
+ isDeleted: Boolean(row.isDeleted),
4130
+ input: storage.safelyParseJSON(row.input),
4131
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
4132
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
4133
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt),
4134
+ updatedAt: storage.ensureDate(row.updatedAtZ || row.updatedAt)
4135
+ };
4136
+ }
4137
+ transformDatasetVersionRow(row) {
4138
+ return {
4139
+ id: row.id,
4140
+ datasetId: row.datasetId,
4141
+ version: row.version,
4142
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt)
4143
+ };
4144
+ }
4145
+ // --- Dataset CRUD ---
4146
+ async createDataset(input) {
4147
+ try {
4148
+ const id = crypto.randomUUID();
4149
+ const now = /* @__PURE__ */ new Date();
4150
+ const nowIso = now.toISOString();
4151
+ await this.#db.insert({
4152
+ tableName: storage.TABLE_DATASETS,
4153
+ record: {
4154
+ id,
4155
+ name: input.name,
4156
+ description: input.description ?? null,
4157
+ metadata: input.metadata ?? null,
4158
+ inputSchema: input.inputSchema ?? null,
4159
+ groundTruthSchema: input.groundTruthSchema ?? null,
4160
+ version: 0,
4161
+ createdAt: nowIso,
4162
+ updatedAt: nowIso
4163
+ }
4164
+ });
4165
+ return {
4166
+ id,
4167
+ name: input.name,
4168
+ description: input.description,
4169
+ metadata: input.metadata,
4170
+ inputSchema: input.inputSchema,
4171
+ groundTruthSchema: input.groundTruthSchema,
4172
+ version: 0,
4173
+ createdAt: now,
4174
+ updatedAt: now
4175
+ };
4176
+ } catch (error$1) {
4177
+ throw new error.MastraError(
4178
+ {
4179
+ id: storage.createStorageErrorId("PG", "CREATE_DATASET", "FAILED"),
4180
+ domain: error.ErrorDomain.STORAGE,
4181
+ category: error.ErrorCategory.THIRD_PARTY
4182
+ },
4183
+ error$1
4184
+ );
4185
+ }
4186
+ }
4187
+ async getDatasetById({ id }) {
4188
+ try {
4189
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4190
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
4191
+ return result ? this.transformDatasetRow(result) : null;
4192
+ } catch (error$1) {
4193
+ throw new error.MastraError(
4194
+ {
4195
+ id: storage.createStorageErrorId("PG", "GET_DATASET", "FAILED"),
4196
+ domain: error.ErrorDomain.STORAGE,
4197
+ category: error.ErrorCategory.THIRD_PARTY
4198
+ },
4199
+ error$1
4200
+ );
4201
+ }
4202
+ }
4203
+ async _doUpdateDataset(args) {
4204
+ try {
4205
+ const existing = await this.getDatasetById({ id: args.id });
4206
+ if (!existing) {
4207
+ throw new error.MastraError({
4208
+ id: storage.createStorageErrorId("PG", "UPDATE_DATASET", "NOT_FOUND"),
4209
+ domain: error.ErrorDomain.STORAGE,
4210
+ category: error.ErrorCategory.USER,
4211
+ details: { datasetId: args.id }
4212
+ });
4213
+ }
4214
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4215
+ const now = (/* @__PURE__ */ new Date()).toISOString();
4216
+ const setClauses = ['"updatedAt" = $1', '"updatedAtZ" = $2'];
4217
+ const values = [now, now];
4218
+ let paramIndex = 3;
4219
+ if (args.name !== void 0) {
4220
+ setClauses.push(`"name" = $${paramIndex++}`);
4221
+ values.push(args.name);
4222
+ }
4223
+ if (args.description !== void 0) {
4224
+ setClauses.push(`"description" = $${paramIndex++}`);
4225
+ values.push(args.description);
4226
+ }
4227
+ if (args.metadata !== void 0) {
4228
+ setClauses.push(`"metadata" = $${paramIndex++}`);
4229
+ values.push(JSON.stringify(args.metadata));
4230
+ }
4231
+ if (args.inputSchema !== void 0) {
4232
+ setClauses.push(`"inputSchema" = $${paramIndex++}`);
4233
+ values.push(args.inputSchema === null ? null : JSON.stringify(args.inputSchema));
4234
+ }
4235
+ if (args.groundTruthSchema !== void 0) {
4236
+ setClauses.push(`"groundTruthSchema" = $${paramIndex++}`);
4237
+ values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
4238
+ }
4239
+ values.push(args.id);
4240
+ await this.#db.client.none(
4241
+ `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`,
4242
+ values
4243
+ );
4244
+ return {
4245
+ ...existing,
4246
+ name: args.name ?? existing.name,
4247
+ description: args.description ?? existing.description,
4248
+ metadata: args.metadata ?? existing.metadata,
4249
+ inputSchema: args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema,
4250
+ groundTruthSchema: args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema,
4251
+ updatedAt: new Date(now)
4252
+ };
4253
+ } catch (error$1) {
4254
+ if (error$1 instanceof error.MastraError) throw error$1;
4255
+ throw new error.MastraError(
4256
+ {
4257
+ id: storage.createStorageErrorId("PG", "UPDATE_DATASET", "FAILED"),
4258
+ domain: error.ErrorDomain.STORAGE,
4259
+ category: error.ErrorCategory.THIRD_PARTY
4260
+ },
4261
+ error$1
4262
+ );
4263
+ }
4264
+ }
4265
+ async deleteDataset({ id }) {
4266
+ try {
4267
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4268
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4269
+ const versionsTable = getTableName2({
4270
+ indexName: storage.TABLE_DATASET_VERSIONS,
4271
+ schemaName: getSchemaName2(this.#schema)
4272
+ });
4273
+ const experimentsTable = getTableName2({ indexName: storage.TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
4274
+ const experimentResultsTable = getTableName2({
4275
+ indexName: storage.TABLE_EXPERIMENT_RESULTS,
4276
+ schemaName: getSchemaName2(this.#schema)
4277
+ });
4278
+ try {
4279
+ await this.#db.client.none(
4280
+ `DELETE FROM ${experimentResultsTable} WHERE "experimentId" IN (SELECT "id" FROM ${experimentsTable} WHERE "datasetId" = $1)`,
4281
+ [id]
4282
+ );
4283
+ } catch {
4284
+ }
4285
+ try {
4286
+ await this.#db.client.none(
4287
+ `UPDATE ${experimentsTable} SET "datasetId" = NULL, "datasetVersion" = NULL WHERE "datasetId" = $1`,
4288
+ [id]
4289
+ );
4290
+ } catch {
4291
+ }
4292
+ await this.#db.client.tx(async (t) => {
4293
+ await t.none(`DELETE FROM ${versionsTable} WHERE "datasetId" = $1`, [id]);
4294
+ await t.none(`DELETE FROM ${itemsTable} WHERE "datasetId" = $1`, [id]);
4295
+ await t.none(`DELETE FROM ${datasetsTable} WHERE "id" = $1`, [id]);
4296
+ });
4297
+ } catch (error$1) {
4298
+ if (error$1 instanceof error.MastraError) throw error$1;
4299
+ throw new error.MastraError(
4300
+ {
4301
+ id: storage.createStorageErrorId("PG", "DELETE_DATASET", "FAILED"),
4302
+ domain: error.ErrorDomain.STORAGE,
4303
+ category: error.ErrorCategory.THIRD_PARTY
4304
+ },
4305
+ error$1
4306
+ );
4307
+ }
4308
+ }
4309
+ async listDatasets(args) {
4310
+ try {
4311
+ const { page, perPage: perPageInput } = args.pagination;
4312
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4313
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName}`);
4314
+ const total = parseInt(countResult.count, 10);
4315
+ if (total === 0) {
4316
+ return { datasets: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
4317
+ }
4318
+ const perPage = storage.normalizePerPage(perPageInput, 100);
4319
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
4320
+ const limitValue = perPageInput === false ? total : perPage;
4321
+ const rows = await this.#db.client.manyOrNone(
4322
+ `SELECT * FROM ${tableName} ORDER BY "createdAt" DESC LIMIT $1 OFFSET $2`,
4323
+ [limitValue, offset]
4324
+ );
4325
+ return {
4326
+ datasets: (rows || []).map((row) => this.transformDatasetRow(row)),
4327
+ pagination: {
4328
+ total,
4329
+ page,
4330
+ perPage: perPageForResponse,
4331
+ hasMore: perPageInput === false ? false : offset + perPage < total
4332
+ }
4333
+ };
4334
+ } catch (error$1) {
4335
+ throw new error.MastraError(
4336
+ {
4337
+ id: storage.createStorageErrorId("PG", "LIST_DATASETS", "FAILED"),
4338
+ domain: error.ErrorDomain.STORAGE,
4339
+ category: error.ErrorCategory.THIRD_PARTY
4340
+ },
4341
+ error$1
4342
+ );
4343
+ }
4344
+ }
4345
+ // --- SCD-2 mutations ---
4346
+ async _doAddItem(args) {
4347
+ try {
4348
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4349
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4350
+ const versionsTable = getTableName2({
4351
+ indexName: storage.TABLE_DATASET_VERSIONS,
4352
+ schemaName: getSchemaName2(this.#schema)
4353
+ });
4354
+ const id = crypto.randomUUID();
4355
+ const versionId = crypto.randomUUID();
4356
+ const now = /* @__PURE__ */ new Date();
4357
+ const nowIso = now.toISOString();
4358
+ let newVersion;
4359
+ await this.#db.client.tx(async (t) => {
4360
+ const row = await t.one(
4361
+ `UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
4362
+ [args.datasetId]
4363
+ );
4364
+ newVersion = row.version;
4365
+ await t.none(
4366
+ `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)`,
4367
+ [
4368
+ id,
4369
+ args.datasetId,
4370
+ newVersion,
4371
+ JSON.stringify(args.input),
4372
+ jsonbArg(args.groundTruth),
4373
+ jsonbArg(args.metadata),
4374
+ nowIso,
4375
+ nowIso,
4376
+ nowIso,
4377
+ nowIso
4378
+ ]
4379
+ );
4380
+ await t.none(
4381
+ `INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
4382
+ [versionId, args.datasetId, newVersion, nowIso, nowIso]
4383
+ );
4384
+ });
4385
+ return {
4386
+ id,
4387
+ datasetId: args.datasetId,
4388
+ datasetVersion: newVersion,
4389
+ input: args.input,
4390
+ groundTruth: args.groundTruth,
4391
+ metadata: args.metadata,
4392
+ createdAt: now,
4393
+ updatedAt: now
4394
+ };
4395
+ } catch (error$1) {
4396
+ if (error$1 instanceof error.MastraError) throw error$1;
4397
+ throw new error.MastraError(
4398
+ {
4399
+ id: storage.createStorageErrorId("PG", "ADD_ITEM", "FAILED"),
4400
+ domain: error.ErrorDomain.STORAGE,
4401
+ category: error.ErrorCategory.THIRD_PARTY
4402
+ },
4403
+ error$1
4404
+ );
4405
+ }
4406
+ }
4407
+ async _doUpdateItem(args) {
4408
+ try {
4409
+ const existing = await this.getItemById({ id: args.id });
4410
+ if (!existing) {
4411
+ throw new error.MastraError({
4412
+ id: storage.createStorageErrorId("PG", "UPDATE_ITEM", "NOT_FOUND"),
4413
+ domain: error.ErrorDomain.STORAGE,
4414
+ category: error.ErrorCategory.USER,
4415
+ details: { itemId: args.id }
4416
+ });
4417
+ }
4418
+ if (existing.datasetId !== args.datasetId) {
4419
+ throw new error.MastraError({
4420
+ id: storage.createStorageErrorId("PG", "UPDATE_ITEM", "DATASET_MISMATCH"),
4421
+ domain: error.ErrorDomain.STORAGE,
4422
+ category: error.ErrorCategory.USER,
4423
+ details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
4424
+ });
4425
+ }
4426
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4427
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4428
+ const versionsTable = getTableName2({
4429
+ indexName: storage.TABLE_DATASET_VERSIONS,
4430
+ schemaName: getSchemaName2(this.#schema)
4431
+ });
4432
+ const versionId = crypto.randomUUID();
4433
+ const now = /* @__PURE__ */ new Date();
4434
+ const nowIso = now.toISOString();
4435
+ const mergedInput = args.input ?? existing.input;
4436
+ const mergedGroundTruth = args.groundTruth ?? existing.groundTruth;
4437
+ const mergedMetadata = args.metadata ?? existing.metadata;
4438
+ let newVersion;
4439
+ await this.#db.client.tx(async (t) => {
4440
+ const row = await t.one(
4441
+ `UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
4442
+ [args.datasetId]
4443
+ );
4444
+ newVersion = row.version;
4445
+ await t.none(
4446
+ `UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
4447
+ [newVersion, args.id]
4448
+ );
4449
+ await t.none(
4450
+ `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)`,
4451
+ [
4452
+ args.id,
4453
+ args.datasetId,
4454
+ newVersion,
4455
+ JSON.stringify(mergedInput),
4456
+ jsonbArg(mergedGroundTruth),
4457
+ jsonbArg(mergedMetadata),
4458
+ existing.createdAt.toISOString(),
4459
+ existing.createdAt.toISOString(),
4460
+ nowIso,
4461
+ nowIso
4462
+ ]
4463
+ );
4464
+ await t.none(
4465
+ `INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
4466
+ [versionId, args.datasetId, newVersion, nowIso, nowIso]
4467
+ );
4468
+ });
4469
+ return {
4470
+ ...existing,
4471
+ datasetVersion: newVersion,
4472
+ input: mergedInput,
4473
+ groundTruth: mergedGroundTruth,
4474
+ metadata: mergedMetadata,
4475
+ updatedAt: now
4476
+ };
4477
+ } catch (error$1) {
4478
+ if (error$1 instanceof error.MastraError) throw error$1;
4479
+ throw new error.MastraError(
4480
+ {
4481
+ id: storage.createStorageErrorId("PG", "UPDATE_ITEM", "FAILED"),
4482
+ domain: error.ErrorDomain.STORAGE,
4483
+ category: error.ErrorCategory.THIRD_PARTY
4484
+ },
4485
+ error$1
4486
+ );
4487
+ }
4488
+ }
4489
+ async _doDeleteItem({ id, datasetId }) {
4490
+ try {
4491
+ const existing = await this.getItemById({ id });
4492
+ if (!existing) return;
4493
+ if (existing.datasetId !== datasetId) {
4494
+ throw new error.MastraError({
4495
+ id: storage.createStorageErrorId("PG", "DELETE_ITEM", "DATASET_MISMATCH"),
4496
+ domain: error.ErrorDomain.STORAGE,
4497
+ category: error.ErrorCategory.USER,
4498
+ details: { itemId: id, expectedDatasetId: datasetId, actualDatasetId: existing.datasetId }
4499
+ });
4500
+ }
4501
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4502
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4503
+ const versionsTable = getTableName2({
4504
+ indexName: storage.TABLE_DATASET_VERSIONS,
4505
+ schemaName: getSchemaName2(this.#schema)
4506
+ });
4507
+ const versionId = crypto.randomUUID();
4508
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4509
+ await this.#db.client.tx(async (t) => {
4510
+ const row = await t.one(
4511
+ `UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
4512
+ [datasetId]
4513
+ );
4514
+ const newVersion = row.version;
4515
+ await t.none(
4516
+ `UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
4517
+ [newVersion, id]
4518
+ );
4519
+ await t.none(
4520
+ `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)`,
4521
+ [
4522
+ id,
4523
+ datasetId,
4524
+ newVersion,
4525
+ JSON.stringify(existing.input),
4526
+ jsonbArg(existing.groundTruth),
4527
+ jsonbArg(existing.metadata),
4528
+ existing.createdAt.toISOString(),
4529
+ existing.createdAt.toISOString(),
4530
+ nowIso,
4531
+ nowIso
4532
+ ]
4533
+ );
4534
+ await t.none(
4535
+ `INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
4536
+ [versionId, datasetId, newVersion, nowIso, nowIso]
4537
+ );
4538
+ });
4539
+ } catch (error$1) {
4540
+ if (error$1 instanceof error.MastraError) throw error$1;
4541
+ throw new error.MastraError(
4542
+ {
4543
+ id: storage.createStorageErrorId("PG", "DELETE_ITEM", "FAILED"),
4544
+ domain: error.ErrorDomain.STORAGE,
4545
+ category: error.ErrorCategory.THIRD_PARTY
4546
+ },
4547
+ error$1
4548
+ );
4549
+ }
4550
+ }
4551
+ async _doBatchInsertItems(input) {
4552
+ try {
4553
+ const dataset = await this.getDatasetById({ id: input.datasetId });
4554
+ if (!dataset) {
4555
+ throw new error.MastraError({
4556
+ id: storage.createStorageErrorId("PG", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
4557
+ domain: error.ErrorDomain.STORAGE,
4558
+ category: error.ErrorCategory.USER,
4559
+ details: { datasetId: input.datasetId }
4560
+ });
4561
+ }
4562
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4563
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4564
+ const versionsTable = getTableName2({
4565
+ indexName: storage.TABLE_DATASET_VERSIONS,
4566
+ schemaName: getSchemaName2(this.#schema)
4567
+ });
4568
+ const now = /* @__PURE__ */ new Date();
4569
+ const nowIso = now.toISOString();
4570
+ const versionId = crypto.randomUUID();
4571
+ const itemsWithIds = input.items.map((itemInput) => ({ id: crypto.randomUUID(), input: itemInput }));
4572
+ let newVersion;
4573
+ await this.#db.client.tx(async (t) => {
4574
+ const row = await t.one(
4575
+ `UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
4576
+ [input.datasetId]
4577
+ );
4578
+ newVersion = row.version;
4579
+ for (const { id, input: itemInput } of itemsWithIds) {
4580
+ await t.none(
4581
+ `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)`,
4582
+ [
4583
+ id,
4584
+ input.datasetId,
4585
+ newVersion,
4586
+ JSON.stringify(itemInput.input),
4587
+ jsonbArg(itemInput.groundTruth),
4588
+ jsonbArg(itemInput.metadata),
4589
+ nowIso,
4590
+ nowIso,
4591
+ nowIso,
4592
+ nowIso
4593
+ ]
4594
+ );
4595
+ }
4596
+ await t.none(
4597
+ `INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
4598
+ [versionId, input.datasetId, newVersion, nowIso, nowIso]
4599
+ );
4600
+ });
4601
+ return itemsWithIds.map(({ id, input: itemInput }) => ({
4602
+ id,
4603
+ datasetId: input.datasetId,
4604
+ datasetVersion: newVersion,
4605
+ input: itemInput.input,
4606
+ groundTruth: itemInput.groundTruth,
4607
+ metadata: itemInput.metadata,
4608
+ createdAt: now,
4609
+ updatedAt: now
4610
+ }));
4611
+ } catch (error$1) {
4612
+ if (error$1 instanceof error.MastraError) throw error$1;
4613
+ throw new error.MastraError(
4614
+ {
4615
+ id: storage.createStorageErrorId("PG", "BULK_ADD_ITEMS", "FAILED"),
4616
+ domain: error.ErrorDomain.STORAGE,
4617
+ category: error.ErrorCategory.THIRD_PARTY
4618
+ },
4619
+ error$1
4620
+ );
4621
+ }
4622
+ }
4623
+ async _doBatchDeleteItems(input) {
4624
+ try {
4625
+ const dataset = await this.getDatasetById({ id: input.datasetId });
4626
+ if (!dataset) {
4627
+ throw new error.MastraError({
4628
+ id: storage.createStorageErrorId("PG", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
4629
+ domain: error.ErrorDomain.STORAGE,
4630
+ category: error.ErrorCategory.USER,
4631
+ details: { datasetId: input.datasetId }
4632
+ });
4633
+ }
4634
+ const currentItems = [];
4635
+ for (const itemId of input.itemIds) {
4636
+ const item = await this.getItemById({ id: itemId });
4637
+ if (item && item.datasetId === input.datasetId) {
4638
+ currentItems.push(item);
4639
+ }
4640
+ }
4641
+ if (currentItems.length === 0) return;
4642
+ const datasetsTable = getTableName2({ indexName: storage.TABLE_DATASETS, schemaName: getSchemaName2(this.#schema) });
4643
+ const itemsTable = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4644
+ const versionsTable = getTableName2({
4645
+ indexName: storage.TABLE_DATASET_VERSIONS,
4646
+ schemaName: getSchemaName2(this.#schema)
4647
+ });
4648
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4649
+ const versionId = crypto.randomUUID();
4650
+ await this.#db.client.tx(async (t) => {
4651
+ const row = await t.one(
4652
+ `UPDATE ${datasetsTable} SET "version" = "version" + 1 WHERE "id" = $1 RETURNING "version"`,
4653
+ [input.datasetId]
4654
+ );
4655
+ const newVersion = row.version;
4656
+ for (const item of currentItems) {
4657
+ await t.none(
4658
+ `UPDATE ${itemsTable} SET "validTo" = $1 WHERE "id" = $2 AND "validTo" IS NULL AND "isDeleted" = false`,
4659
+ [newVersion, item.id]
4660
+ );
4661
+ await t.none(
4662
+ `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)`,
4663
+ [
4664
+ item.id,
4665
+ input.datasetId,
4666
+ newVersion,
4667
+ JSON.stringify(item.input),
4668
+ jsonbArg(item.groundTruth),
4669
+ jsonbArg(item.metadata),
4670
+ item.createdAt.toISOString(),
4671
+ item.createdAt.toISOString(),
4672
+ nowIso,
4673
+ nowIso
4674
+ ]
4675
+ );
4676
+ }
4677
+ await t.none(
4678
+ `INSERT INTO ${versionsTable} ("id","datasetId","version","createdAt","createdAtZ") VALUES ($1,$2,$3,$4,$5)`,
4679
+ [versionId, input.datasetId, newVersion, nowIso, nowIso]
4680
+ );
4681
+ });
4682
+ } catch (error$1) {
4683
+ if (error$1 instanceof error.MastraError) throw error$1;
4684
+ throw new error.MastraError(
4685
+ {
4686
+ id: storage.createStorageErrorId("PG", "BULK_DELETE_ITEMS", "FAILED"),
4687
+ domain: error.ErrorDomain.STORAGE,
4688
+ category: error.ErrorCategory.THIRD_PARTY
4689
+ },
4690
+ error$1
4691
+ );
4692
+ }
4693
+ }
4694
+ // --- SCD-2 queries ---
4695
+ async getItemById(args) {
4696
+ try {
4697
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4698
+ let result;
4699
+ if (args.datasetVersion !== void 0) {
4700
+ result = await this.#db.client.oneOrNone(
4701
+ `SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" = $2 AND "isDeleted" = false`,
4702
+ [args.id, args.datasetVersion]
4703
+ );
4704
+ } else {
4705
+ result = await this.#db.client.oneOrNone(
4706
+ `SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`,
4707
+ [args.id]
4708
+ );
4709
+ }
4710
+ return result ? this.transformItemRow(result) : null;
4711
+ } catch (error$1) {
4712
+ throw new error.MastraError(
4713
+ {
4714
+ id: storage.createStorageErrorId("PG", "GET_ITEM", "FAILED"),
4715
+ domain: error.ErrorDomain.STORAGE,
4716
+ category: error.ErrorCategory.THIRD_PARTY
4717
+ },
4718
+ error$1
4719
+ );
4720
+ }
4721
+ }
4722
+ async getItemsByVersion({ datasetId, version }) {
4723
+ try {
4724
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4725
+ const rows = await this.#db.client.manyOrNone(
4726
+ `SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC`,
4727
+ [datasetId, version, version]
4728
+ );
4729
+ return (rows || []).map((row) => this.transformItemRow(row));
4730
+ } catch (error$1) {
4731
+ throw new error.MastraError(
4732
+ {
4733
+ id: storage.createStorageErrorId("PG", "GET_ITEMS_BY_VERSION", "FAILED"),
4734
+ domain: error.ErrorDomain.STORAGE,
4735
+ category: error.ErrorCategory.THIRD_PARTY
4736
+ },
4737
+ error$1
4738
+ );
4739
+ }
4740
+ }
4741
+ async getItemHistory(itemId) {
4742
+ try {
4743
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4744
+ const rows = await this.#db.client.manyOrNone(
4745
+ `SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`,
4746
+ [itemId]
4747
+ );
4748
+ return (rows || []).map((row) => this.transformItemRowFull(row));
4749
+ } catch (error$1) {
4750
+ throw new error.MastraError(
4751
+ {
4752
+ id: storage.createStorageErrorId("PG", "GET_ITEM_HISTORY", "FAILED"),
4753
+ domain: error.ErrorDomain.STORAGE,
4754
+ category: error.ErrorCategory.THIRD_PARTY
4755
+ },
4756
+ error$1
4757
+ );
4758
+ }
4759
+ }
4760
+ async listItems(args) {
4761
+ try {
4762
+ const { page, perPage: perPageInput } = args.pagination;
4763
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASET_ITEMS, schemaName: getSchemaName2(this.#schema) });
4764
+ const conditions = ['"datasetId" = $1'];
4765
+ const queryParams = [args.datasetId];
4766
+ let paramIndex = 2;
4767
+ if (args.version !== void 0) {
4768
+ conditions.push(`"datasetVersion" <= $${paramIndex++}`);
4769
+ queryParams.push(args.version);
4770
+ conditions.push(`("validTo" IS NULL OR "validTo" > $${paramIndex++})`);
4771
+ queryParams.push(args.version);
4772
+ conditions.push(`"isDeleted" = false`);
4773
+ } else {
4774
+ conditions.push(`"validTo" IS NULL`);
4775
+ conditions.push(`"isDeleted" = false`);
4776
+ }
4777
+ if (args.search) {
4778
+ conditions.push(
4779
+ `("input"::text ILIKE $${paramIndex} OR COALESCE("groundTruth"::text, '') ILIKE $${paramIndex})`
4780
+ );
4781
+ queryParams.push(`%${args.search}%`);
4782
+ paramIndex++;
4783
+ }
4784
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
4785
+ const countResult = await this.#db.client.one(
4786
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
4787
+ queryParams
4788
+ );
4789
+ const total = parseInt(countResult.count, 10);
4790
+ if (total === 0) {
4791
+ return { items: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
4792
+ }
4793
+ const perPage = storage.normalizePerPage(perPageInput, 100);
4794
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
4795
+ const limitValue = perPageInput === false ? total : perPage;
4796
+ const rows = await this.#db.client.manyOrNone(
4797
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
4798
+ [...queryParams, limitValue, offset]
4799
+ );
4800
+ return {
4801
+ items: (rows || []).map((row) => this.transformItemRow(row)),
4802
+ pagination: {
4803
+ total,
4804
+ page,
4805
+ perPage: perPageForResponse,
4806
+ hasMore: perPageInput === false ? false : offset + perPage < total
4807
+ }
4808
+ };
4809
+ } catch (error$1) {
4810
+ throw new error.MastraError(
4811
+ {
4812
+ id: storage.createStorageErrorId("PG", "LIST_ITEMS", "FAILED"),
4813
+ domain: error.ErrorDomain.STORAGE,
4814
+ category: error.ErrorCategory.THIRD_PARTY
4815
+ },
4816
+ error$1
4817
+ );
4818
+ }
4819
+ }
4820
+ // --- Dataset versions ---
4821
+ async createDatasetVersion(datasetId, version) {
4822
+ try {
4823
+ const id = crypto.randomUUID();
4824
+ const now = /* @__PURE__ */ new Date();
4825
+ const nowIso = now.toISOString();
4826
+ await this.#db.insert({
4827
+ tableName: storage.TABLE_DATASET_VERSIONS,
4828
+ record: { id, datasetId, version, createdAt: nowIso }
4829
+ });
4830
+ return { id, datasetId, version, createdAt: now };
4831
+ } catch (error$1) {
4832
+ throw new error.MastraError(
4833
+ {
4834
+ id: storage.createStorageErrorId("PG", "CREATE_DATASET_VERSION", "FAILED"),
4835
+ domain: error.ErrorDomain.STORAGE,
4836
+ category: error.ErrorCategory.THIRD_PARTY
4837
+ },
4838
+ error$1
4839
+ );
4840
+ }
4841
+ }
4842
+ async listDatasetVersions(input) {
4843
+ try {
4844
+ const { page, perPage: perPageInput } = input.pagination;
4845
+ const tableName = getTableName2({ indexName: storage.TABLE_DATASET_VERSIONS, schemaName: getSchemaName2(this.#schema) });
4846
+ const countResult = await this.#db.client.one(
4847
+ `SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`,
4848
+ [input.datasetId]
4849
+ );
4850
+ const total = parseInt(countResult.count, 10);
4851
+ if (total === 0) {
4852
+ return { versions: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
4853
+ }
4854
+ const perPage = storage.normalizePerPage(perPageInput, 100);
4855
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
4856
+ const limitValue = perPageInput === false ? total : perPage;
4857
+ const rows = await this.#db.client.manyOrNone(
4858
+ `SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`,
4859
+ [input.datasetId, limitValue, offset]
4860
+ );
4861
+ return {
4862
+ versions: (rows || []).map((row) => this.transformDatasetVersionRow(row)),
4863
+ pagination: {
4864
+ total,
4865
+ page,
4866
+ perPage: perPageForResponse,
4867
+ hasMore: perPageInput === false ? false : offset + perPage < total
4868
+ }
4869
+ };
4870
+ } catch (error$1) {
4871
+ throw new error.MastraError(
4872
+ {
4873
+ id: storage.createStorageErrorId("PG", "LIST_DATASET_VERSIONS", "FAILED"),
4874
+ domain: error.ErrorDomain.STORAGE,
4875
+ category: error.ErrorCategory.THIRD_PARTY
4876
+ },
4877
+ error$1
4878
+ );
4879
+ }
4880
+ }
4881
+ // --- Clear ---
4882
+ async dangerouslyClearAll() {
4883
+ await this.#db.clearTable({ tableName: storage.TABLE_DATASET_VERSIONS });
4884
+ await this.#db.clearTable({ tableName: storage.TABLE_DATASET_ITEMS });
4885
+ await this.#db.clearTable({ tableName: storage.TABLE_DATASETS });
4886
+ }
4887
+ };
4888
+ var ExperimentsPG = class _ExperimentsPG extends storage.ExperimentsStorage {
4889
+ #db;
4890
+ #schema;
4891
+ #skipDefaultIndexes;
4892
+ #indexes;
4893
+ static MANAGED_TABLES = [storage.TABLE_EXPERIMENTS, storage.TABLE_EXPERIMENT_RESULTS];
4894
+ constructor(config) {
4895
+ super();
4896
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4897
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
4898
+ this.#schema = schemaName || "public";
4899
+ this.#skipDefaultIndexes = skipDefaultIndexes;
4900
+ this.#indexes = indexes?.filter((idx) => _ExperimentsPG.MANAGED_TABLES.includes(idx.table));
4901
+ }
4902
+ static getExportDDL(schemaName) {
4903
+ const statements = [];
4904
+ for (const tableName of _ExperimentsPG.MANAGED_TABLES) {
4905
+ statements.push(
4906
+ generateTableSQL({
4907
+ tableName,
4908
+ schema: storage.TABLE_SCHEMAS[tableName],
4909
+ schemaName,
4910
+ includeAllConstraints: true
4911
+ })
4912
+ );
4913
+ }
4914
+ return statements;
4915
+ }
4916
+ async init() {
4917
+ await this.#db.createTable({ tableName: storage.TABLE_EXPERIMENTS, schema: storage.EXPERIMENTS_SCHEMA });
4918
+ await this.#db.createTable({ tableName: storage.TABLE_EXPERIMENT_RESULTS, schema: storage.EXPERIMENT_RESULTS_SCHEMA });
4919
+ await this.createDefaultIndexes();
4920
+ await this.createCustomIndexes();
4921
+ }
4922
+ getDefaultIndexDefinitions() {
4923
+ return [
4924
+ { name: "idx_experiments_datasetid", table: storage.TABLE_EXPERIMENTS, columns: ["datasetId"] },
4925
+ { name: "idx_experiment_results_experimentid", table: storage.TABLE_EXPERIMENT_RESULTS, columns: ["experimentId"] },
4926
+ {
4927
+ name: "idx_experiment_results_exp_item",
4928
+ table: storage.TABLE_EXPERIMENT_RESULTS,
4929
+ columns: ["experimentId", "itemId"],
4930
+ unique: true
4931
+ }
4932
+ ];
4933
+ }
4934
+ async createDefaultIndexes() {
4935
+ if (this.#skipDefaultIndexes) return;
4936
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
4937
+ try {
4938
+ await this.#db.createIndex(indexDef);
4939
+ } catch (error) {
4940
+ this.logger?.warn?.(`Failed to create default index ${indexDef.name}:`, error);
4941
+ }
4942
+ }
4943
+ }
4944
+ async createCustomIndexes() {
4945
+ if (!this.#indexes || this.#indexes.length === 0) return;
4946
+ for (const indexDef of this.#indexes) {
4947
+ try {
4948
+ await this.#db.createIndex(indexDef);
4949
+ } catch (error) {
4950
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
4951
+ }
4952
+ }
4953
+ }
4954
+ // --- Row transformers ---
4955
+ transformExperimentRow(row) {
4956
+ return {
4957
+ id: row.id,
4958
+ name: row.name ?? void 0,
4959
+ description: row.description ?? void 0,
4960
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
4961
+ datasetId: row.datasetId ?? null,
4962
+ datasetVersion: row.datasetVersion != null ? row.datasetVersion : null,
4963
+ targetType: row.targetType,
4964
+ targetId: row.targetId,
4965
+ status: row.status,
4966
+ totalItems: row.totalItems,
4967
+ succeededCount: row.succeededCount,
4968
+ failedCount: row.failedCount,
4969
+ skippedCount: row.skippedCount ?? 0,
4970
+ startedAt: row.startedAt ? storage.ensureDate(row.startedAtZ || row.startedAt) : null,
4971
+ completedAt: row.completedAt ? storage.ensureDate(row.completedAtZ || row.completedAt) : null,
4972
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt),
4973
+ updatedAt: storage.ensureDate(row.updatedAtZ || row.updatedAt)
4974
+ };
4975
+ }
4976
+ transformExperimentResultRow(row) {
4977
+ return {
4978
+ id: row.id,
4979
+ experimentId: row.experimentId,
4980
+ itemId: row.itemId,
4981
+ itemDatasetVersion: row.itemDatasetVersion != null ? row.itemDatasetVersion : null,
4982
+ input: storage.safelyParseJSON(row.input),
4983
+ output: row.output ? storage.safelyParseJSON(row.output) : null,
4984
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : null,
4985
+ error: row.error ? storage.safelyParseJSON(row.error) : null,
4986
+ startedAt: storage.ensureDate(row.startedAtZ || row.startedAt),
4987
+ completedAt: storage.ensureDate(row.completedAtZ || row.completedAt),
4988
+ retryCount: row.retryCount,
4989
+ traceId: row.traceId ?? null,
4990
+ createdAt: storage.ensureDate(row.createdAtZ || row.createdAt)
4991
+ };
4992
+ }
4993
+ // --- Experiment CRUD ---
4994
+ async createExperiment(input) {
4995
+ try {
4996
+ const id = input.id ?? crypto.randomUUID();
4997
+ const now = /* @__PURE__ */ new Date();
4998
+ const nowIso = now.toISOString();
4999
+ await this.#db.insert({
5000
+ tableName: storage.TABLE_EXPERIMENTS,
5001
+ record: {
5002
+ id,
5003
+ name: input.name ?? null,
5004
+ description: input.description ?? null,
5005
+ metadata: input.metadata ?? null,
5006
+ datasetId: input.datasetId ?? null,
5007
+ datasetVersion: input.datasetVersion ?? null,
5008
+ targetType: input.targetType,
5009
+ targetId: input.targetId,
5010
+ status: "pending",
5011
+ totalItems: input.totalItems,
5012
+ succeededCount: 0,
5013
+ failedCount: 0,
5014
+ skippedCount: 0,
5015
+ startedAt: null,
5016
+ completedAt: null,
5017
+ createdAt: nowIso,
5018
+ updatedAt: nowIso
5019
+ }
5020
+ });
5021
+ return {
5022
+ id,
5023
+ name: input.name,
5024
+ description: input.description,
5025
+ metadata: input.metadata,
5026
+ datasetId: input.datasetId ?? null,
5027
+ datasetVersion: input.datasetVersion ?? null,
5028
+ targetType: input.targetType,
5029
+ targetId: input.targetId,
5030
+ status: "pending",
5031
+ totalItems: input.totalItems,
5032
+ succeededCount: 0,
5033
+ failedCount: 0,
5034
+ skippedCount: 0,
5035
+ startedAt: null,
5036
+ completedAt: null,
5037
+ createdAt: now,
5038
+ updatedAt: now
5039
+ };
5040
+ } catch (error$1) {
5041
+ throw new error.MastraError(
5042
+ {
5043
+ id: storage.createStorageErrorId("PG", "CREATE_EXPERIMENT", "FAILED"),
5044
+ domain: error.ErrorDomain.STORAGE,
5045
+ category: error.ErrorCategory.THIRD_PARTY
5046
+ },
5047
+ error$1
5048
+ );
5049
+ }
5050
+ }
5051
+ async updateExperiment(input) {
5052
+ try {
5053
+ const existing = await this.getExperimentById({ id: input.id });
5054
+ if (!existing) {
5055
+ throw new error.MastraError({
5056
+ id: storage.createStorageErrorId("PG", "UPDATE_EXPERIMENT", "NOT_FOUND"),
5057
+ domain: error.ErrorDomain.STORAGE,
5058
+ category: error.ErrorCategory.USER,
5059
+ details: { experimentId: input.id }
5060
+ });
5061
+ }
5062
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
5063
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5064
+ const setClauses = ['"updatedAt" = $1', '"updatedAtZ" = $2'];
5065
+ const values = [now, now];
5066
+ let paramIndex = 3;
5067
+ if (input.name !== void 0) {
5068
+ setClauses.push(`"name" = $${paramIndex++}`);
5069
+ values.push(input.name);
5070
+ }
5071
+ if (input.description !== void 0) {
5072
+ setClauses.push(`"description" = $${paramIndex++}`);
5073
+ values.push(input.description);
5074
+ }
5075
+ if (input.metadata !== void 0) {
5076
+ setClauses.push(`"metadata" = $${paramIndex++}`);
5077
+ values.push(JSON.stringify(input.metadata));
5078
+ }
5079
+ if (input.status !== void 0) {
5080
+ setClauses.push(`"status" = $${paramIndex++}`);
5081
+ values.push(input.status);
5082
+ }
5083
+ if (input.succeededCount !== void 0) {
5084
+ setClauses.push(`"succeededCount" = $${paramIndex++}`);
5085
+ values.push(input.succeededCount);
5086
+ }
5087
+ if (input.failedCount !== void 0) {
5088
+ setClauses.push(`"failedCount" = $${paramIndex++}`);
5089
+ values.push(input.failedCount);
5090
+ }
5091
+ if (input.skippedCount !== void 0) {
5092
+ setClauses.push(`"skippedCount" = $${paramIndex++}`);
5093
+ values.push(input.skippedCount);
5094
+ }
5095
+ if (input.startedAt !== void 0) {
5096
+ setClauses.push(`"startedAt" = $${paramIndex++}`);
5097
+ values.push(input.startedAt?.toISOString() ?? null);
5098
+ }
5099
+ if (input.completedAt !== void 0) {
5100
+ setClauses.push(`"completedAt" = $${paramIndex++}`);
5101
+ values.push(input.completedAt?.toISOString() ?? null);
5102
+ }
5103
+ values.push(input.id);
5104
+ await this.#db.client.none(
5105
+ `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`,
5106
+ values
5107
+ );
5108
+ const updated = await this.getExperimentById({ id: input.id });
5109
+ return updated;
5110
+ } catch (error$1) {
5111
+ if (error$1 instanceof error.MastraError) throw error$1;
5112
+ throw new error.MastraError(
5113
+ {
5114
+ id: storage.createStorageErrorId("PG", "UPDATE_EXPERIMENT", "FAILED"),
5115
+ domain: error.ErrorDomain.STORAGE,
5116
+ category: error.ErrorCategory.THIRD_PARTY
5117
+ },
5118
+ error$1
5119
+ );
5120
+ }
5121
+ }
5122
+ async getExperimentById({ id }) {
5123
+ try {
5124
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
5125
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5126
+ return result ? this.transformExperimentRow(result) : null;
5127
+ } catch (error$1) {
5128
+ throw new error.MastraError(
5129
+ {
5130
+ id: storage.createStorageErrorId("PG", "GET_EXPERIMENT", "FAILED"),
5131
+ domain: error.ErrorDomain.STORAGE,
5132
+ category: error.ErrorCategory.THIRD_PARTY
5133
+ },
5134
+ error$1
5135
+ );
5136
+ }
5137
+ }
5138
+ async listExperiments(args) {
5139
+ try {
5140
+ const { page, perPage: perPageInput } = args.pagination;
5141
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
5142
+ const conditions = [];
5143
+ const queryParams = [];
5144
+ let paramIndex = 1;
5145
+ if (args.datasetId) {
5146
+ conditions.push(`"datasetId" = $${paramIndex++}`);
5147
+ queryParams.push(args.datasetId);
5148
+ }
5149
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5150
+ const countResult = await this.#db.client.one(
5151
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
5152
+ queryParams
5153
+ );
5154
+ const total = parseInt(countResult.count, 10);
5155
+ if (total === 0) {
5156
+ return { experiments: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
5157
+ }
5158
+ const perPage = storage.normalizePerPage(perPageInput, 100);
5159
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
5160
+ const limitValue = perPageInput === false ? total : perPage;
5161
+ const rows = await this.#db.client.manyOrNone(
5162
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
5163
+ [...queryParams, limitValue, offset]
5164
+ );
5165
+ return {
5166
+ experiments: (rows || []).map((row) => this.transformExperimentRow(row)),
5167
+ pagination: {
5168
+ total,
5169
+ page,
5170
+ perPage: perPageForResponse,
5171
+ hasMore: perPageInput === false ? false : offset + perPage < total
5172
+ }
5173
+ };
5174
+ } catch (error$1) {
5175
+ throw new error.MastraError(
5176
+ {
5177
+ id: storage.createStorageErrorId("PG", "LIST_EXPERIMENTS", "FAILED"),
5178
+ domain: error.ErrorDomain.STORAGE,
5179
+ category: error.ErrorCategory.THIRD_PARTY
5180
+ },
5181
+ error$1
5182
+ );
5183
+ }
5184
+ }
5185
+ async deleteExperiment({ id }) {
5186
+ try {
5187
+ const resultsTable = getTableName2({
5188
+ indexName: storage.TABLE_EXPERIMENT_RESULTS,
5189
+ schemaName: getSchemaName2(this.#schema)
5190
+ });
5191
+ const experimentsTable = getTableName2({ indexName: storage.TABLE_EXPERIMENTS, schemaName: getSchemaName2(this.#schema) });
5192
+ await this.#db.client.none(`DELETE FROM ${resultsTable} WHERE "experimentId" = $1`, [id]);
5193
+ await this.#db.client.none(`DELETE FROM ${experimentsTable} WHERE "id" = $1`, [id]);
5194
+ } catch (error$1) {
5195
+ throw new error.MastraError(
5196
+ {
5197
+ id: storage.createStorageErrorId("PG", "DELETE_EXPERIMENT", "FAILED"),
5198
+ domain: error.ErrorDomain.STORAGE,
5199
+ category: error.ErrorCategory.THIRD_PARTY
5200
+ },
5201
+ error$1
5202
+ );
5203
+ }
5204
+ }
5205
+ // --- Experiment results ---
5206
+ async addExperimentResult(input) {
5207
+ try {
5208
+ const id = input.id ?? crypto.randomUUID();
5209
+ const now = /* @__PURE__ */ new Date();
5210
+ const nowIso = now.toISOString();
5211
+ await this.#db.insert({
5212
+ tableName: storage.TABLE_EXPERIMENT_RESULTS,
5213
+ record: {
5214
+ id,
5215
+ experimentId: input.experimentId,
5216
+ itemId: input.itemId,
5217
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
5218
+ input: input.input,
5219
+ output: input.output ?? null,
5220
+ groundTruth: input.groundTruth ?? null,
5221
+ error: input.error ?? null,
5222
+ startedAt: input.startedAt.toISOString(),
5223
+ completedAt: input.completedAt.toISOString(),
5224
+ retryCount: input.retryCount,
5225
+ traceId: input.traceId ?? null,
5226
+ createdAt: nowIso
5227
+ }
5228
+ });
5229
+ return {
5230
+ id,
5231
+ experimentId: input.experimentId,
5232
+ itemId: input.itemId,
5233
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
5234
+ input: input.input,
5235
+ output: input.output ?? null,
5236
+ groundTruth: input.groundTruth ?? null,
5237
+ error: input.error ?? null,
5238
+ startedAt: input.startedAt,
5239
+ completedAt: input.completedAt,
5240
+ retryCount: input.retryCount,
5241
+ traceId: input.traceId ?? null,
5242
+ createdAt: now
5243
+ };
5244
+ } catch (error$1) {
5245
+ throw new error.MastraError(
5246
+ {
5247
+ id: storage.createStorageErrorId("PG", "ADD_EXPERIMENT_RESULT", "FAILED"),
5248
+ domain: error.ErrorDomain.STORAGE,
5249
+ category: error.ErrorCategory.THIRD_PARTY
5250
+ },
5251
+ error$1
5252
+ );
5253
+ }
5254
+ }
5255
+ async getExperimentResultById({ id }) {
5256
+ try {
5257
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
5258
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5259
+ return result ? this.transformExperimentResultRow(result) : null;
5260
+ } catch (error$1) {
5261
+ throw new error.MastraError(
5262
+ {
5263
+ id: storage.createStorageErrorId("PG", "GET_EXPERIMENT_RESULT", "FAILED"),
5264
+ domain: error.ErrorDomain.STORAGE,
5265
+ category: error.ErrorCategory.THIRD_PARTY
5266
+ },
5267
+ error$1
5268
+ );
5269
+ }
5270
+ }
5271
+ async listExperimentResults(args) {
5272
+ try {
5273
+ const { page, perPage: perPageInput } = args.pagination;
5274
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
5275
+ const countResult = await this.#db.client.one(
5276
+ `SELECT COUNT(*) as count FROM ${tableName} WHERE "experimentId" = $1`,
5277
+ [args.experimentId]
5278
+ );
5279
+ const total = parseInt(countResult.count, 10);
5280
+ if (total === 0) {
5281
+ return { results: [], pagination: { total: 0, page, perPage: perPageInput, hasMore: false } };
5282
+ }
5283
+ const perPage = storage.normalizePerPage(perPageInput, 100);
5284
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
5285
+ const limitValue = perPageInput === false ? total : perPage;
5286
+ const rows = await this.#db.client.manyOrNone(
5287
+ `SELECT * FROM ${tableName} WHERE "experimentId" = $1 ORDER BY "startedAt" ASC LIMIT $2 OFFSET $3`,
5288
+ [args.experimentId, limitValue, offset]
5289
+ );
5290
+ return {
5291
+ results: (rows || []).map((row) => this.transformExperimentResultRow(row)),
5292
+ pagination: {
5293
+ total,
5294
+ page,
5295
+ perPage: perPageForResponse,
5296
+ hasMore: perPageInput === false ? false : offset + perPage < total
5297
+ }
5298
+ };
5299
+ } catch (error$1) {
5300
+ throw new error.MastraError(
5301
+ {
5302
+ id: storage.createStorageErrorId("PG", "LIST_EXPERIMENT_RESULTS", "FAILED"),
5303
+ domain: error.ErrorDomain.STORAGE,
5304
+ category: error.ErrorCategory.THIRD_PARTY
5305
+ },
5306
+ error$1
5307
+ );
5308
+ }
5309
+ }
5310
+ async deleteExperimentResults({ experimentId }) {
5311
+ try {
5312
+ const tableName = getTableName2({ indexName: storage.TABLE_EXPERIMENT_RESULTS, schemaName: getSchemaName2(this.#schema) });
5313
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "experimentId" = $1`, [experimentId]);
5314
+ } catch (error$1) {
5315
+ throw new error.MastraError(
5316
+ {
5317
+ id: storage.createStorageErrorId("PG", "DELETE_EXPERIMENT_RESULTS", "FAILED"),
5318
+ domain: error.ErrorDomain.STORAGE,
5319
+ category: error.ErrorCategory.THIRD_PARTY
5320
+ },
5321
+ error$1
5322
+ );
5323
+ }
5324
+ }
5325
+ // --- Clear ---
5326
+ async dangerouslyClearAll() {
5327
+ await this.#db.clearTable({ tableName: storage.TABLE_EXPERIMENT_RESULTS });
5328
+ await this.#db.clearTable({ tableName: storage.TABLE_EXPERIMENTS });
5329
+ }
5330
+ };
5331
+ var SNAPSHOT_FIELDS = ["name", "description", "servers"];
5332
+ var MCPClientsPG = class _MCPClientsPG extends storage.MCPClientsStorage {
5333
+ #db;
5334
+ #schema;
5335
+ #skipDefaultIndexes;
5336
+ #indexes;
5337
+ static MANAGED_TABLES = [storage.TABLE_MCP_CLIENTS, storage.TABLE_MCP_CLIENT_VERSIONS];
5338
+ constructor(config) {
5339
+ super();
5340
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5341
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
5342
+ this.#schema = schemaName || "public";
5343
+ this.#skipDefaultIndexes = skipDefaultIndexes;
5344
+ this.#indexes = indexes?.filter((idx) => _MCPClientsPG.MANAGED_TABLES.includes(idx.table));
5345
+ }
5346
+ getDefaultIndexDefinitions() {
5347
+ return [
5348
+ {
5349
+ name: "idx_mcp_client_versions_client_version",
5350
+ table: storage.TABLE_MCP_CLIENT_VERSIONS,
5351
+ columns: ["mcpClientId", "versionNumber"],
5352
+ unique: true
5353
+ }
5354
+ ];
5355
+ }
5356
+ async createDefaultIndexes() {
5357
+ if (this.#skipDefaultIndexes) {
5358
+ return;
5359
+ }
5360
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
5361
+ try {
5362
+ await this.#db.createIndex(indexDef);
5363
+ } catch {
5364
+ }
5365
+ }
5366
+ }
5367
+ async init() {
5368
+ await this.#db.createTable({
5369
+ tableName: storage.TABLE_MCP_CLIENTS,
5370
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_MCP_CLIENTS]
5371
+ });
5372
+ await this.#db.createTable({
5373
+ tableName: storage.TABLE_MCP_CLIENT_VERSIONS,
5374
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_MCP_CLIENT_VERSIONS]
5375
+ });
5376
+ await this.createDefaultIndexes();
5377
+ await this.createCustomIndexes();
5378
+ }
5379
+ async createCustomIndexes() {
5380
+ if (!this.#indexes || this.#indexes.length === 0) {
5381
+ return;
5382
+ }
5383
+ for (const indexDef of this.#indexes) {
5384
+ try {
5385
+ await this.#db.createIndex(indexDef);
5386
+ } catch (error) {
5387
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
5388
+ }
5389
+ }
5390
+ }
5391
+ async dangerouslyClearAll() {
5392
+ await this.#db.clearTable({ tableName: storage.TABLE_MCP_CLIENT_VERSIONS });
5393
+ await this.#db.clearTable({ tableName: storage.TABLE_MCP_CLIENTS });
5394
+ }
5395
+ // ==========================================================================
5396
+ // MCP Client CRUD Methods
5397
+ // ==========================================================================
5398
+ async getById(id) {
5399
+ try {
5400
+ const tableName = getTableName2({ indexName: storage.TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
5401
+ const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
5402
+ if (!result) {
5403
+ return null;
5404
+ }
5405
+ return this.parseMCPClientRow(result);
5406
+ } catch (error$1) {
5407
+ if (error$1 instanceof error.MastraError) throw error$1;
5408
+ throw new error.MastraError(
5409
+ {
5410
+ id: storage.createStorageErrorId("PG", "GET_MCP_CLIENT_BY_ID", "FAILED"),
5411
+ domain: error.ErrorDomain.STORAGE,
5412
+ category: error.ErrorCategory.THIRD_PARTY,
5413
+ details: { mcpClientId: id }
5414
+ },
5415
+ error$1
5416
+ );
5417
+ }
5418
+ }
5419
+ async create(input) {
5420
+ const { mcpClient } = input;
5421
+ try {
5422
+ const tableName = getTableName2({ indexName: storage.TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
5423
+ const now = /* @__PURE__ */ new Date();
5424
+ const nowIso = now.toISOString();
5425
+ await this.#db.client.none(
5426
+ `INSERT INTO ${tableName} (
5427
+ id, status, "activeVersionId", "authorId", metadata,
5428
+ "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
5429
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
5430
+ [
5431
+ mcpClient.id,
5432
+ "draft",
5433
+ null,
5434
+ mcpClient.authorId ?? null,
5435
+ mcpClient.metadata ? JSON.stringify(mcpClient.metadata) : null,
5436
+ nowIso,
5437
+ nowIso,
5438
+ nowIso,
5439
+ nowIso
5440
+ ]
5441
+ );
5442
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;
5443
+ const versionId = crypto.randomUUID();
5444
+ await this.createVersion({
5445
+ id: versionId,
5446
+ mcpClientId: mcpClient.id,
5447
+ versionNumber: 1,
5448
+ ...snapshotConfig,
5449
+ changedFields: [...SNAPSHOT_FIELDS],
5450
+ changeMessage: "Initial version"
5451
+ });
5452
+ return {
5453
+ id: mcpClient.id,
5454
+ status: "draft",
5455
+ activeVersionId: void 0,
5456
+ authorId: mcpClient.authorId,
5457
+ metadata: mcpClient.metadata,
5458
+ createdAt: now,
5459
+ updatedAt: now
5460
+ };
5461
+ } catch (error$1) {
5462
+ try {
5463
+ const tableName = getTableName2({
5464
+ indexName: storage.TABLE_MCP_CLIENTS,
5465
+ schemaName: getSchemaName2(this.#schema)
5466
+ });
5467
+ await this.#db.client.none(
5468
+ `DELETE FROM ${tableName} WHERE id = $1 AND status = 'draft' AND "activeVersionId" IS NULL`,
5469
+ [mcpClient.id]
5470
+ );
5471
+ } catch {
5472
+ }
5473
+ if (error$1 instanceof error.MastraError) throw error$1;
5474
+ throw new error.MastraError(
5475
+ {
5476
+ id: storage.createStorageErrorId("PG", "CREATE_MCP_CLIENT", "FAILED"),
5477
+ domain: error.ErrorDomain.STORAGE,
5478
+ category: error.ErrorCategory.THIRD_PARTY,
5479
+ details: { mcpClientId: mcpClient.id }
5480
+ },
5481
+ error$1
5482
+ );
5483
+ }
5484
+ }
5485
+ async update(input) {
5486
+ const { id, ...updates } = input;
5487
+ try {
5488
+ const tableName = getTableName2({ indexName: storage.TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
5489
+ const existingClient = await this.getById(id);
5490
+ if (!existingClient) {
5491
+ throw new error.MastraError({
5492
+ id: storage.createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND"),
5493
+ domain: error.ErrorDomain.STORAGE,
5494
+ category: error.ErrorCategory.USER,
5495
+ text: `MCP client ${id} not found`,
5496
+ details: { mcpClientId: id }
5497
+ });
5498
+ }
5499
+ const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
5500
+ let versionCreated = false;
5501
+ const hasConfigUpdate = SNAPSHOT_FIELDS.some((field) => field in configFields);
5502
+ if (hasConfigUpdate) {
5503
+ const latestVersion = await this.getLatestVersion(id);
5504
+ if (!latestVersion) {
5505
+ throw new error.MastraError({
5506
+ id: storage.createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NO_VERSIONS"),
5507
+ domain: error.ErrorDomain.STORAGE,
5508
+ category: error.ErrorCategory.SYSTEM,
5509
+ text: `No versions found for MCP client ${id}`,
5510
+ details: { mcpClientId: id }
5511
+ });
5512
+ }
5513
+ const {
5514
+ id: _versionId,
5515
+ mcpClientId: _mcpClientId,
5516
+ versionNumber: _versionNumber,
5517
+ changedFields: _changedFields,
5518
+ changeMessage: _changeMessage,
5519
+ createdAt: _createdAt,
5520
+ ...latestConfig
5521
+ } = latestVersion;
5522
+ const newConfig = { ...latestConfig, ...configFields };
5523
+ const changedFields = SNAPSHOT_FIELDS.filter(
5524
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
5525
+ );
5526
+ if (changedFields.length > 0) {
5527
+ versionCreated = true;
5528
+ const newVersionId = crypto.randomUUID();
5529
+ await this.createVersion({
5530
+ id: newVersionId,
5531
+ mcpClientId: id,
5532
+ versionNumber: latestVersion.versionNumber + 1,
5533
+ ...newConfig,
5534
+ changedFields: [...changedFields],
5535
+ changeMessage: `Updated ${changedFields.join(", ")}`
5536
+ });
5537
+ }
5538
+ }
5539
+ const setClauses = [];
5540
+ const values = [];
5541
+ let paramIndex = 1;
5542
+ if (authorId !== void 0) {
5543
+ setClauses.push(`"authorId" = $${paramIndex++}`);
5544
+ values.push(authorId);
5545
+ }
5546
+ if (activeVersionId !== void 0) {
5547
+ setClauses.push(`"activeVersionId" = $${paramIndex++}`);
5548
+ values.push(activeVersionId);
5549
+ if (status === void 0) {
5550
+ setClauses.push(`status = $${paramIndex++}`);
5551
+ values.push("published");
5552
+ }
5553
+ }
5554
+ if (status !== void 0) {
5555
+ setClauses.push(`status = $${paramIndex++}`);
5556
+ values.push(status);
5557
+ }
5558
+ if (metadata !== void 0) {
5559
+ const mergedMetadata = { ...existingClient.metadata || {}, ...metadata };
5560
+ setClauses.push(`metadata = $${paramIndex++}`);
5561
+ values.push(JSON.stringify(mergedMetadata));
5562
+ }
5563
+ const now = (/* @__PURE__ */ new Date()).toISOString();
5564
+ setClauses.push(`"updatedAt" = $${paramIndex++}`);
5565
+ values.push(now);
5566
+ setClauses.push(`"updatedAtZ" = $${paramIndex++}`);
5567
+ values.push(now);
5568
+ values.push(id);
5569
+ if (setClauses.length > 2 || versionCreated) {
5570
+ await this.#db.client.none(
5571
+ `UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`,
5572
+ values
5573
+ );
5574
+ }
5575
+ const updatedClient = await this.getById(id);
5576
+ if (!updatedClient) {
5577
+ throw new error.MastraError({
5578
+ id: storage.createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND_AFTER_UPDATE"),
5579
+ domain: error.ErrorDomain.STORAGE,
5580
+ category: error.ErrorCategory.SYSTEM,
5581
+ text: `MCP client ${id} not found after update`,
5582
+ details: { mcpClientId: id }
5583
+ });
5584
+ }
5585
+ return updatedClient;
5586
+ } catch (error$1) {
5587
+ if (error$1 instanceof error.MastraError) throw error$1;
5588
+ throw new error.MastraError(
5589
+ {
5590
+ id: storage.createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "FAILED"),
5591
+ domain: error.ErrorDomain.STORAGE,
5592
+ category: error.ErrorCategory.THIRD_PARTY,
5593
+ details: { mcpClientId: id }
5594
+ },
5595
+ error$1
5596
+ );
5597
+ }
5598
+ }
5599
+ async delete(id) {
5600
+ try {
5601
+ const tableName = getTableName2({ indexName: storage.TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
5602
+ await this.deleteVersionsByParentId(id);
5603
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
5604
+ } catch (error$1) {
5605
+ if (error$1 instanceof error.MastraError) throw error$1;
5606
+ throw new error.MastraError(
5607
+ {
5608
+ id: storage.createStorageErrorId("PG", "DELETE_MCP_CLIENT", "FAILED"),
5609
+ domain: error.ErrorDomain.STORAGE,
5610
+ category: error.ErrorCategory.THIRD_PARTY,
5611
+ details: { mcpClientId: id }
5612
+ },
5613
+ error$1
5614
+ );
5615
+ }
5616
+ }
5617
+ async list(args) {
5618
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
5619
+ const { field, direction } = this.parseOrderBy(orderBy);
5620
+ if (page < 0) {
5621
+ throw new error.MastraError(
5622
+ {
5623
+ id: storage.createStorageErrorId("PG", "LIST_MCP_CLIENTS", "INVALID_PAGE"),
5624
+ domain: error.ErrorDomain.STORAGE,
5625
+ category: error.ErrorCategory.USER,
5626
+ details: { page }
5627
+ },
5628
+ new Error("page must be >= 0")
5629
+ );
5630
+ }
5631
+ const perPage = storage.normalizePerPage(perPageInput, 100);
5632
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
5633
+ try {
5634
+ const tableName = getTableName2({ indexName: storage.TABLE_MCP_CLIENTS, schemaName: getSchemaName2(this.#schema) });
5635
+ const conditions = [];
5636
+ const queryParams = [];
5637
+ let paramIdx = 1;
5638
+ if (authorId !== void 0) {
5639
+ conditions.push(`"authorId" = $${paramIdx++}`);
5640
+ queryParams.push(authorId);
5641
+ }
5642
+ if (metadata && Object.keys(metadata).length > 0) {
5643
+ conditions.push(`metadata @> $${paramIdx++}::jsonb`);
5644
+ queryParams.push(JSON.stringify(metadata));
5645
+ }
5646
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5647
+ const countResult = await this.#db.client.one(
5648
+ `SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`,
5649
+ queryParams
5650
+ );
3651
5651
  const total = parseInt(countResult.count, 10);
3652
5652
  if (total === 0) {
3653
5653
  return {
3654
- agents: [],
5654
+ mcpClients: [],
3655
5655
  total: 0,
3656
5656
  page,
3657
5657
  perPage: perPageForResponse,
@@ -3660,12 +5660,12 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3660
5660
  }
3661
5661
  const limitValue = perPageInput === false ? total : perPage;
3662
5662
  const dataResult = await this.#db.client.manyOrNone(
3663
- `SELECT * FROM ${tableName} ORDER BY "${field}" ${direction} LIMIT $1 OFFSET $2`,
3664
- [limitValue, offset]
5663
+ `SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`,
5664
+ [...queryParams, limitValue, offset]
3665
5665
  );
3666
- const agents = (dataResult || []).map((row) => this.parseRow(row));
5666
+ const mcpClients = (dataResult || []).map((row) => this.parseMCPClientRow(row));
3667
5667
  return {
3668
- agents,
5668
+ mcpClients,
3669
5669
  total,
3670
5670
  page,
3671
5671
  perPage: perPageForResponse,
@@ -3675,7 +5675,7 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3675
5675
  if (error$1 instanceof error.MastraError) throw error$1;
3676
5676
  throw new error.MastraError(
3677
5677
  {
3678
- id: storage.createStorageErrorId("PG", "LIST_AGENTS", "FAILED"),
5678
+ id: storage.createStorageErrorId("PG", "LIST_MCP_CLIENTS", "FAILED"),
3679
5679
  domain: error.ErrorDomain.STORAGE,
3680
5680
  category: error.ErrorCategory.THIRD_PARTY
3681
5681
  },
@@ -3684,39 +5684,30 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3684
5684
  }
3685
5685
  }
3686
5686
  // ==========================================================================
3687
- // Agent Version Methods
5687
+ // MCP Client Version Methods
3688
5688
  // ==========================================================================
3689
5689
  async createVersion(input) {
3690
5690
  try {
3691
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
5691
+ const tableName = getTableName2({
5692
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5693
+ schemaName: getSchemaName2(this.#schema)
5694
+ });
3692
5695
  const now = /* @__PURE__ */ new Date();
3693
5696
  const nowIso = now.toISOString();
3694
5697
  await this.#db.client.none(
3695
5698
  `INSERT INTO ${tableName} (
3696
- id, "agentId", "versionNumber",
3697
- name, description, instructions, model, tools,
3698
- "defaultOptions", workflows, agents, "integrationTools",
3699
- "inputProcessors", "outputProcessors", memory, scorers,
5699
+ id, "mcpClientId", "versionNumber",
5700
+ name, description, servers,
3700
5701
  "changedFields", "changeMessage",
3701
5702
  "createdAt", "createdAtZ"
3702
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)`,
5703
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
3703
5704
  [
3704
5705
  input.id,
3705
- input.agentId,
5706
+ input.mcpClientId,
3706
5707
  input.versionNumber,
3707
5708
  input.name,
3708
5709
  input.description ?? null,
3709
- this.serializeInstructions(input.instructions),
3710
- JSON.stringify(input.model),
3711
- input.tools ? JSON.stringify(input.tools) : null,
3712
- input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
3713
- input.workflows ? JSON.stringify(input.workflows) : null,
3714
- input.agents ? JSON.stringify(input.agents) : null,
3715
- input.integrationTools ? JSON.stringify(input.integrationTools) : null,
3716
- input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
3717
- input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
3718
- input.memory ? JSON.stringify(input.memory) : null,
3719
- input.scorers ? JSON.stringify(input.scorers) : null,
5710
+ JSON.stringify(input.servers),
3720
5711
  input.changedFields ? JSON.stringify(input.changedFields) : null,
3721
5712
  input.changeMessage ?? null,
3722
5713
  nowIso,
@@ -3731,10 +5722,10 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3731
5722
  if (error$1 instanceof error.MastraError) throw error$1;
3732
5723
  throw new error.MastraError(
3733
5724
  {
3734
- id: storage.createStorageErrorId("PG", "CREATE_VERSION", "FAILED"),
5725
+ id: storage.createStorageErrorId("PG", "CREATE_MCP_CLIENT_VERSION", "FAILED"),
3735
5726
  domain: error.ErrorDomain.STORAGE,
3736
5727
  category: error.ErrorCategory.THIRD_PARTY,
3737
- details: { versionId: input.id, agentId: input.agentId }
5728
+ details: { versionId: input.id, mcpClientId: input.mcpClientId }
3738
5729
  },
3739
5730
  error$1
3740
5731
  );
@@ -3742,7 +5733,10 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3742
5733
  }
3743
5734
  async getVersion(id) {
3744
5735
  try {
3745
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
5736
+ const tableName = getTableName2({
5737
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5738
+ schemaName: getSchemaName2(this.#schema)
5739
+ });
3746
5740
  const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
3747
5741
  if (!result) {
3748
5742
  return null;
@@ -3752,7 +5746,7 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3752
5746
  if (error$1 instanceof error.MastraError) throw error$1;
3753
5747
  throw new error.MastraError(
3754
5748
  {
3755
- id: storage.createStorageErrorId("PG", "GET_VERSION", "FAILED"),
5749
+ id: storage.createStorageErrorId("PG", "GET_MCP_CLIENT_VERSION", "FAILED"),
3756
5750
  domain: error.ErrorDomain.STORAGE,
3757
5751
  category: error.ErrorCategory.THIRD_PARTY,
3758
5752
  details: { versionId: id }
@@ -3761,12 +5755,15 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3761
5755
  );
3762
5756
  }
3763
5757
  }
3764
- async getVersionByNumber(agentId, versionNumber) {
5758
+ async getVersionByNumber(mcpClientId, versionNumber) {
3765
5759
  try {
3766
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
5760
+ const tableName = getTableName2({
5761
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5762
+ schemaName: getSchemaName2(this.#schema)
5763
+ });
3767
5764
  const result = await this.#db.client.oneOrNone(
3768
- `SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`,
3769
- [agentId, versionNumber]
5765
+ `SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`,
5766
+ [mcpClientId, versionNumber]
3770
5767
  );
3771
5768
  if (!result) {
3772
5769
  return null;
@@ -3776,21 +5773,24 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3776
5773
  if (error$1 instanceof error.MastraError) throw error$1;
3777
5774
  throw new error.MastraError(
3778
5775
  {
3779
- id: storage.createStorageErrorId("PG", "GET_VERSION_BY_NUMBER", "FAILED"),
5776
+ id: storage.createStorageErrorId("PG", "GET_MCP_CLIENT_VERSION_BY_NUMBER", "FAILED"),
3780
5777
  domain: error.ErrorDomain.STORAGE,
3781
5778
  category: error.ErrorCategory.THIRD_PARTY,
3782
- details: { agentId, versionNumber }
5779
+ details: { mcpClientId, versionNumber }
3783
5780
  },
3784
5781
  error$1
3785
5782
  );
3786
5783
  }
3787
5784
  }
3788
- async getLatestVersion(agentId) {
5785
+ async getLatestVersion(mcpClientId) {
3789
5786
  try {
3790
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
5787
+ const tableName = getTableName2({
5788
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5789
+ schemaName: getSchemaName2(this.#schema)
5790
+ });
3791
5791
  const result = await this.#db.client.oneOrNone(
3792
- `SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
3793
- [agentId]
5792
+ `SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`,
5793
+ [mcpClientId]
3794
5794
  );
3795
5795
  if (!result) {
3796
5796
  return null;
@@ -3800,21 +5800,21 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3800
5800
  if (error$1 instanceof error.MastraError) throw error$1;
3801
5801
  throw new error.MastraError(
3802
5802
  {
3803
- id: storage.createStorageErrorId("PG", "GET_LATEST_VERSION", "FAILED"),
5803
+ id: storage.createStorageErrorId("PG", "GET_LATEST_MCP_CLIENT_VERSION", "FAILED"),
3804
5804
  domain: error.ErrorDomain.STORAGE,
3805
5805
  category: error.ErrorCategory.THIRD_PARTY,
3806
- details: { agentId }
5806
+ details: { mcpClientId }
3807
5807
  },
3808
5808
  error$1
3809
5809
  );
3810
5810
  }
3811
5811
  }
3812
5812
  async listVersions(input) {
3813
- const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
5813
+ const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;
3814
5814
  if (page < 0) {
3815
5815
  throw new error.MastraError(
3816
5816
  {
3817
- id: storage.createStorageErrorId("PG", "LIST_VERSIONS", "INVALID_PAGE"),
5817
+ id: storage.createStorageErrorId("PG", "LIST_MCP_CLIENT_VERSIONS", "INVALID_PAGE"),
3818
5818
  domain: error.ErrorDomain.STORAGE,
3819
5819
  category: error.ErrorCategory.USER,
3820
5820
  details: { page }
@@ -3826,10 +5826,14 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3826
5826
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3827
5827
  try {
3828
5828
  const { field, direction } = this.parseVersionOrderBy(orderBy);
3829
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3830
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
3831
- agentId
3832
- ]);
5829
+ const tableName = getTableName2({
5830
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5831
+ schemaName: getSchemaName2(this.#schema)
5832
+ });
5833
+ const countResult = await this.#db.client.one(
5834
+ `SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`,
5835
+ [mcpClientId]
5836
+ );
3833
5837
  const total = parseInt(countResult.count, 10);
3834
5838
  if (total === 0) {
3835
5839
  return {
@@ -3842,8 +5846,8 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3842
5846
  }
3843
5847
  const limitValue = perPageInput === false ? total : perPage;
3844
5848
  const dataResult = await this.#db.client.manyOrNone(
3845
- `SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
3846
- [agentId, limitValue, offset]
5849
+ `SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`,
5850
+ [mcpClientId, limitValue, offset]
3847
5851
  );
3848
5852
  const versions = (dataResult || []).map((row) => this.parseVersionRow(row));
3849
5853
  return {
@@ -3857,10 +5861,10 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3857
5861
  if (error$1 instanceof error.MastraError) throw error$1;
3858
5862
  throw new error.MastraError(
3859
5863
  {
3860
- id: storage.createStorageErrorId("PG", "LIST_VERSIONS", "FAILED"),
5864
+ id: storage.createStorageErrorId("PG", "LIST_MCP_CLIENT_VERSIONS", "FAILED"),
3861
5865
  domain: error.ErrorDomain.STORAGE,
3862
5866
  category: error.ErrorCategory.THIRD_PARTY,
3863
- details: { agentId }
5867
+ details: { mcpClientId }
3864
5868
  },
3865
5869
  error$1
3866
5870
  );
@@ -3868,13 +5872,16 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3868
5872
  }
3869
5873
  async deleteVersion(id) {
3870
5874
  try {
3871
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
5875
+ const tableName = getTableName2({
5876
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5877
+ schemaName: getSchemaName2(this.#schema)
5878
+ });
3872
5879
  await this.#db.client.none(`DELETE FROM ${tableName} WHERE id = $1`, [id]);
3873
5880
  } catch (error$1) {
3874
5881
  if (error$1 instanceof error.MastraError) throw error$1;
3875
5882
  throw new error.MastraError(
3876
5883
  {
3877
- id: storage.createStorageErrorId("PG", "DELETE_VERSION", "FAILED"),
5884
+ id: storage.createStorageErrorId("PG", "DELETE_MCP_CLIENT_VERSION", "FAILED"),
3878
5885
  domain: error.ErrorDomain.STORAGE,
3879
5886
  category: error.ErrorCategory.THIRD_PARTY,
3880
5887
  details: { versionId: id }
@@ -3885,36 +5892,42 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3885
5892
  }
3886
5893
  async deleteVersionsByParentId(entityId) {
3887
5894
  try {
3888
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3889
- await this.#db.client.none(`DELETE FROM ${tableName} WHERE "agentId" = $1`, [entityId]);
5895
+ const tableName = getTableName2({
5896
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5897
+ schemaName: getSchemaName2(this.#schema)
5898
+ });
5899
+ await this.#db.client.none(`DELETE FROM ${tableName} WHERE "mcpClientId" = $1`, [entityId]);
3890
5900
  } catch (error$1) {
3891
5901
  if (error$1 instanceof error.MastraError) throw error$1;
3892
5902
  throw new error.MastraError(
3893
5903
  {
3894
- id: storage.createStorageErrorId("PG", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
5904
+ id: storage.createStorageErrorId("PG", "DELETE_MCP_CLIENT_VERSIONS_BY_MCP_CLIENT_ID", "FAILED"),
3895
5905
  domain: error.ErrorDomain.STORAGE,
3896
5906
  category: error.ErrorCategory.THIRD_PARTY,
3897
- details: { agentId: entityId }
5907
+ details: { mcpClientId: entityId }
3898
5908
  },
3899
5909
  error$1
3900
5910
  );
3901
5911
  }
3902
5912
  }
3903
- async countVersions(agentId) {
5913
+ async countVersions(mcpClientId) {
3904
5914
  try {
3905
- const tableName = getTableName2({ indexName: storage.TABLE_AGENT_VERSIONS, schemaName: getSchemaName2(this.#schema) });
3906
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [
3907
- agentId
5915
+ const tableName = getTableName2({
5916
+ indexName: storage.TABLE_MCP_CLIENT_VERSIONS,
5917
+ schemaName: getSchemaName2(this.#schema)
5918
+ });
5919
+ const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [
5920
+ mcpClientId
3908
5921
  ]);
3909
5922
  return parseInt(result.count, 10);
3910
5923
  } catch (error$1) {
3911
5924
  if (error$1 instanceof error.MastraError) throw error$1;
3912
5925
  throw new error.MastraError(
3913
5926
  {
3914
- id: storage.createStorageErrorId("PG", "COUNT_VERSIONS", "FAILED"),
5927
+ id: storage.createStorageErrorId("PG", "COUNT_MCP_CLIENT_VERSIONS", "FAILED"),
3915
5928
  domain: error.ErrorDomain.STORAGE,
3916
5929
  category: error.ErrorCategory.THIRD_PARTY,
3917
- details: { agentId }
5930
+ details: { mcpClientId }
3918
5931
  },
3919
5932
  error$1
3920
5933
  );
@@ -3923,44 +5936,63 @@ var AgentsPG = class _AgentsPG extends storage.AgentsStorage {
3923
5936
  // ==========================================================================
3924
5937
  // Private Helper Methods
3925
5938
  // ==========================================================================
3926
- serializeInstructions(instructions) {
3927
- if (instructions == null) return void 0;
3928
- return Array.isArray(instructions) ? JSON.stringify(instructions) : instructions;
3929
- }
3930
- deserializeInstructions(raw) {
3931
- if (!raw) return "";
5939
+ parseJson(value, fieldName) {
5940
+ if (!value) return void 0;
5941
+ if (typeof value !== "string") return value;
3932
5942
  try {
3933
- const parsed = JSON.parse(raw);
3934
- if (Array.isArray(parsed)) return parsed;
3935
- } catch {
5943
+ return JSON.parse(value);
5944
+ } catch (error$1) {
5945
+ if (error$1 instanceof error.MastraError) throw error$1;
5946
+ const details = {
5947
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
5948
+ };
5949
+ if (fieldName) {
5950
+ details.field = fieldName;
5951
+ }
5952
+ throw new error.MastraError(
5953
+ {
5954
+ id: storage.createStorageErrorId("PG", "PARSE_JSON", "INVALID_JSON"),
5955
+ domain: error.ErrorDomain.STORAGE,
5956
+ category: error.ErrorCategory.SYSTEM,
5957
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`,
5958
+ details
5959
+ },
5960
+ error$1
5961
+ );
3936
5962
  }
3937
- return raw;
5963
+ }
5964
+ parseMCPClientRow(row) {
5965
+ return {
5966
+ id: row.id,
5967
+ status: row.status,
5968
+ activeVersionId: row.activeVersionId,
5969
+ authorId: row.authorId,
5970
+ metadata: this.parseJson(row.metadata, "metadata"),
5971
+ createdAt: new Date(row.createdAtZ || row.createdAt),
5972
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
5973
+ };
3938
5974
  }
3939
5975
  parseVersionRow(row) {
3940
5976
  return {
3941
5977
  id: row.id,
3942
- agentId: row.agentId,
5978
+ mcpClientId: row.mcpClientId,
3943
5979
  versionNumber: row.versionNumber,
3944
5980
  name: row.name,
3945
5981
  description: row.description,
3946
- instructions: this.deserializeInstructions(row.instructions),
3947
- model: this.parseJson(row.model, "model"),
3948
- tools: this.parseJson(row.tools, "tools"),
3949
- defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
3950
- workflows: this.parseJson(row.workflows, "workflows"),
3951
- agents: this.parseJson(row.agents, "agents"),
3952
- integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
3953
- inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
3954
- outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
3955
- memory: this.parseJson(row.memory, "memory"),
3956
- scorers: this.parseJson(row.scorers, "scorers"),
5982
+ servers: this.parseJson(row.servers, "servers"),
3957
5983
  changedFields: this.parseJson(row.changedFields, "changedFields"),
3958
5984
  changeMessage: row.changeMessage,
3959
- createdAt: row.createdAtZ || row.createdAt
5985
+ createdAt: new Date(row.createdAtZ || row.createdAt)
3960
5986
  };
3961
5987
  }
3962
5988
  };
3963
5989
  var OM_TABLE = "mastra_observational_memory";
5990
+ var _omTableSchema;
5991
+ try {
5992
+ const storage = __require("@mastra/core/storage");
5993
+ _omTableSchema = storage.OBSERVATIONAL_MEMORY_TABLE_SCHEMA;
5994
+ } catch {
5995
+ }
3964
5996
  function getSchemaName3(schema) {
3965
5997
  return schema ? `"${schema}"` : '"public"';
3966
5998
  }
@@ -4039,9 +6071,9 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
4039
6071
  }
4040
6072
  /**
4041
6073
  * Returns default index definitions for the memory domain tables.
6074
+ * @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
4042
6075
  */
4043
- getDefaultIndexDefinitions() {
4044
- const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
6076
+ static getDefaultIndexDefs(schemaPrefix) {
4045
6077
  return [
4046
6078
  {
4047
6079
  name: `${schemaPrefix}mastra_threads_resourceid_createdat_idx`,
@@ -4055,6 +6087,53 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
4055
6087
  }
4056
6088
  ];
4057
6089
  }
6090
+ /**
6091
+ * Returns all DDL statements for this domain: tables (threads, messages, resources, OM), indexes.
6092
+ * Used by exportSchemas to produce a complete, reproducible schema export.
6093
+ */
6094
+ static getExportDDL(schemaName) {
6095
+ const statements = [];
6096
+ const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
6097
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
6098
+ const quotedSchemaName = getSchemaName(schemaName);
6099
+ for (const tableName of [storage.TABLE_THREADS, storage.TABLE_MESSAGES, storage.TABLE_RESOURCES]) {
6100
+ statements.push(
6101
+ generateTableSQL({
6102
+ tableName,
6103
+ schema: storage.TABLE_SCHEMAS[tableName],
6104
+ schemaName,
6105
+ includeAllConstraints: true
6106
+ })
6107
+ );
6108
+ }
6109
+ const omSchema = _omTableSchema?.[OM_TABLE];
6110
+ if (omSchema) {
6111
+ statements.push(
6112
+ generateTableSQL({
6113
+ tableName: OM_TABLE,
6114
+ schema: omSchema,
6115
+ schemaName,
6116
+ includeAllConstraints: true
6117
+ })
6118
+ );
6119
+ const fullOmTableName = getTableName({ indexName: OM_TABLE, schemaName: quotedSchemaName });
6120
+ const idxPrefix = schemaPrefix ? `${schemaPrefix}` : "";
6121
+ statements.push(
6122
+ `CREATE INDEX IF NOT EXISTS "${idxPrefix}idx_om_lookup_key" ON ${fullOmTableName} ("lookupKey");`
6123
+ );
6124
+ }
6125
+ for (const idx of _MemoryPG.getDefaultIndexDefs(schemaPrefix)) {
6126
+ statements.push(generateIndexSQL(idx, schemaName));
6127
+ }
6128
+ return statements;
6129
+ }
6130
+ /**
6131
+ * Returns default index definitions for this instance's schema.
6132
+ */
6133
+ getDefaultIndexDefinitions() {
6134
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
6135
+ return _MemoryPG.getDefaultIndexDefs(schemaPrefix);
6136
+ }
4058
6137
  /**
4059
6138
  * Creates default indexes for optimal query performance.
4060
6139
  */
@@ -5416,8 +7495,8 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5416
7495
  input.observations,
5417
7496
  lastObservedAtStr,
5418
7497
  lastObservedAtStr,
5419
- input.tokenCount,
5420
- input.tokenCount,
7498
+ Math.round(input.tokenCount),
7499
+ Math.round(input.tokenCount),
5421
7500
  observedMessageIdsJson,
5422
7501
  nowStr,
5423
7502
  nowStr,
@@ -5512,8 +7591,8 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5512
7591
  nowStr,
5513
7592
  // lastReflectionAtZ
5514
7593
  record.pendingMessageTokens,
5515
- record.totalTokensObserved,
5516
- record.observationTokenCount,
7594
+ Math.round(record.totalTokensObserved),
7595
+ Math.round(record.observationTokenCount),
5517
7596
  false,
5518
7597
  // isObserving
5519
7598
  false,
@@ -5631,7 +7710,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5631
7710
  let values;
5632
7711
  if (lastBufferedAtTokens !== void 0) {
5633
7712
  query = `UPDATE ${tableName} SET "isBufferingObservation" = $1, "lastBufferedAtTokens" = $2, "updatedAt" = $3, "updatedAtZ" = $4 WHERE id = $5`;
5634
- values = [isBuffering, lastBufferedAtTokens, nowStr, nowStr, id];
7713
+ values = [isBuffering, Math.round(lastBufferedAtTokens), nowStr, nowStr, id];
5635
7714
  } else {
5636
7715
  query = `UPDATE ${tableName} SET "isBufferingObservation" = $1, "updatedAt" = $2, "updatedAtZ" = $3 WHERE id = $4`;
5637
7716
  values = [isBuffering, nowStr, nowStr, id];
@@ -5729,7 +7808,7 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5729
7808
  "updatedAt" = $2,
5730
7809
  "updatedAtZ" = $3
5731
7810
  WHERE id = $4`,
5732
- [tokenCount, nowStr, nowStr, id]
7811
+ [Math.round(tokenCount), nowStr, nowStr, id]
5733
7812
  );
5734
7813
  if (result.rowCount === 0) {
5735
7814
  throw new error.MastraError({
@@ -5769,9 +7848,9 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5769
7848
  id: `ombuf-${crypto$1.randomUUID()}`,
5770
7849
  cycleId: input.chunk.cycleId,
5771
7850
  observations: input.chunk.observations,
5772
- tokenCount: input.chunk.tokenCount,
7851
+ tokenCount: Math.round(input.chunk.tokenCount),
5773
7852
  messageIds: input.chunk.messageIds,
5774
- messageTokens: input.chunk.messageTokens,
7853
+ messageTokens: Math.round(input.chunk.messageTokens ?? 0),
5775
7854
  lastObservedAt: input.chunk.lastObservedAt,
5776
7855
  createdAt: /* @__PURE__ */ new Date(),
5777
7856
  suggestedContinuation: input.chunk.suggestedContinuation,
@@ -5880,8 +7959,8 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5880
7959
  const activatedChunks = chunks.slice(0, chunksToActivate);
5881
7960
  const remainingChunks = chunks.slice(chunksToActivate);
5882
7961
  const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
5883
- const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
5884
- const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
7962
+ const activatedTokens = Math.round(activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0));
7963
+ const activatedMessageTokens = Math.round(activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0));
5885
7964
  const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
5886
7965
  const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
5887
7966
  const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
@@ -5968,8 +8047,8 @@ var MemoryPG = class _MemoryPG extends storage.MemoryStorage {
5968
8047
  WHERE id = $7`,
5969
8048
  [
5970
8049
  input.reflection,
5971
- input.tokenCount,
5972
- input.inputTokenCount,
8050
+ Math.round(input.tokenCount),
8051
+ Math.round(input.inputTokenCount),
5973
8052
  input.reflectedObservationLineCount,
5974
8053
  nowStr,
5975
8054
  nowStr,
@@ -6092,9 +8171,9 @@ var ObservabilityPG = class _ObservabilityPG extends storage.ObservabilityStorag
6092
8171
  }
6093
8172
  /**
6094
8173
  * Returns default index definitions for the observability domain tables.
8174
+ * @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
6095
8175
  */
6096
- getDefaultIndexDefinitions() {
6097
- const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
8176
+ static getDefaultIndexDefs(schemaPrefix) {
6098
8177
  return [
6099
8178
  {
6100
8179
  name: `${schemaPrefix}mastra_ai_spans_traceid_startedat_idx`,
@@ -6156,6 +8235,35 @@ var ObservabilityPG = class _ObservabilityPG extends storage.ObservabilityStorag
6156
8235
  }
6157
8236
  ];
6158
8237
  }
8238
+ /**
8239
+ * Returns all DDL statements for this domain: table, constraints, timestamp trigger, and indexes.
8240
+ * Used by exportSchemas to produce a complete, reproducible schema export.
8241
+ */
8242
+ static getExportDDL(schemaName) {
8243
+ const statements = [];
8244
+ const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
8245
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
8246
+ statements.push(
8247
+ generateTableSQL({
8248
+ tableName: storage.TABLE_SPANS,
8249
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_SPANS],
8250
+ schemaName,
8251
+ includeAllConstraints: true
8252
+ })
8253
+ );
8254
+ statements.push(generateTimestampTriggerSQL(storage.TABLE_SPANS, schemaName));
8255
+ for (const idx of _ObservabilityPG.getDefaultIndexDefs(schemaPrefix)) {
8256
+ statements.push(generateIndexSQL(idx, schemaName));
8257
+ }
8258
+ return statements;
8259
+ }
8260
+ /**
8261
+ * Returns default index definitions for this instance's schema.
8262
+ */
8263
+ getDefaultIndexDefinitions() {
8264
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
8265
+ return _ObservabilityPG.getDefaultIndexDefs(schemaPrefix);
8266
+ }
6159
8267
  /**
6160
8268
  * Creates default indexes for optimal query performance.
6161
8269
  */
@@ -6684,7 +8792,7 @@ var ObservabilityPG = class _ObservabilityPG extends storage.ObservabilityStorag
6684
8792
  }
6685
8793
  }
6686
8794
  };
6687
- var SNAPSHOT_FIELDS = ["name", "description", "content", "rules"];
8795
+ var SNAPSHOT_FIELDS2 = ["name", "description", "content", "rules"];
6688
8796
  var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
6689
8797
  #db;
6690
8798
  #schema;
@@ -6699,16 +8807,47 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
6699
8807
  this.#skipDefaultIndexes = skipDefaultIndexes;
6700
8808
  this.#indexes = indexes?.filter((idx) => _PromptBlocksPG.MANAGED_TABLES.includes(idx.table));
6701
8809
  }
6702
- getDefaultIndexDefinitions() {
8810
+ /**
8811
+ * Returns default index definitions for the prompt blocks domain tables.
8812
+ * @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
8813
+ */
8814
+ static getDefaultIndexDefs(schemaPrefix) {
6703
8815
  return [
6704
8816
  {
6705
- name: "idx_prompt_block_versions_block_version",
8817
+ name: `${schemaPrefix}idx_prompt_block_versions_block_version`,
6706
8818
  table: storage.TABLE_PROMPT_BLOCK_VERSIONS,
6707
8819
  columns: ["blockId", "versionNumber"],
6708
8820
  unique: true
6709
8821
  }
6710
8822
  ];
6711
8823
  }
8824
+ /**
8825
+ * Returns all DDL statements for this domain: tables and indexes.
8826
+ * Used by exportSchemas to produce a complete, reproducible schema export.
8827
+ */
8828
+ static getExportDDL(schemaName) {
8829
+ const statements = [];
8830
+ const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
8831
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
8832
+ for (const tableName of _PromptBlocksPG.MANAGED_TABLES) {
8833
+ statements.push(
8834
+ generateTableSQL({
8835
+ tableName,
8836
+ schema: storage.TABLE_SCHEMAS[tableName],
8837
+ schemaName,
8838
+ includeAllConstraints: true
8839
+ })
8840
+ );
8841
+ }
8842
+ for (const idx of _PromptBlocksPG.getDefaultIndexDefs(schemaPrefix)) {
8843
+ statements.push(generateIndexSQL(idx, schemaName));
8844
+ }
8845
+ return statements;
8846
+ }
8847
+ getDefaultIndexDefinitions() {
8848
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
8849
+ return _PromptBlocksPG.getDefaultIndexDefs(schemaPrefix);
8850
+ }
6712
8851
  async createDefaultIndexes() {
6713
8852
  if (this.#skipDefaultIndexes) {
6714
8853
  return;
@@ -6799,7 +8938,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
6799
8938
  blockId: promptBlock.id,
6800
8939
  versionNumber: 1,
6801
8940
  ...snapshotConfig,
6802
- changedFields: [...SNAPSHOT_FIELDS],
8941
+ changedFields: [...SNAPSHOT_FIELDS2],
6803
8942
  changeMessage: "Initial version"
6804
8943
  });
6805
8944
  return {
@@ -6848,7 +8987,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
6848
8987
  }
6849
8988
  const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
6850
8989
  let versionCreated = false;
6851
- const hasConfigUpdate = SNAPSHOT_FIELDS.some((field) => field in configFields);
8990
+ const hasConfigUpdate = SNAPSHOT_FIELDS2.some((field) => field in configFields);
6852
8991
  if (hasConfigUpdate) {
6853
8992
  const latestVersion = await this.getLatestVersion(id);
6854
8993
  if (!latestVersion) {
@@ -6870,7 +9009,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
6870
9009
  ...latestConfig
6871
9010
  } = latestVersion;
6872
9011
  const newConfig = { ...latestConfig, ...configFields };
6873
- const changedFields = SNAPSHOT_FIELDS.filter(
9012
+ const changedFields = SNAPSHOT_FIELDS2.filter(
6874
9013
  (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
6875
9014
  );
6876
9015
  if (changedFields.length > 0) {
@@ -7336,7 +9475,7 @@ var PromptBlocksPG = class _PromptBlocksPG extends storage.PromptBlocksStorage {
7336
9475
  };
7337
9476
  }
7338
9477
  };
7339
- var SNAPSHOT_FIELDS2 = [
9478
+ var SNAPSHOT_FIELDS3 = [
7340
9479
  "name",
7341
9480
  "description",
7342
9481
  "type",
@@ -7362,16 +9501,47 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
7362
9501
  (idx) => _ScorerDefinitionsPG.MANAGED_TABLES.includes(idx.table)
7363
9502
  );
7364
9503
  }
7365
- getDefaultIndexDefinitions() {
9504
+ /**
9505
+ * Returns default index definitions for the scorer definitions domain tables.
9506
+ * @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
9507
+ */
9508
+ static getDefaultIndexDefs(schemaPrefix) {
7366
9509
  return [
7367
9510
  {
7368
- name: "idx_scorer_definition_versions_def_version",
9511
+ name: `${schemaPrefix}idx_scorer_definition_versions_def_version`,
7369
9512
  table: storage.TABLE_SCORER_DEFINITION_VERSIONS,
7370
9513
  columns: ["scorerDefinitionId", "versionNumber"],
7371
9514
  unique: true
7372
9515
  }
7373
9516
  ];
7374
9517
  }
9518
+ /**
9519
+ * Returns all DDL statements for this domain: tables and indexes.
9520
+ * Used by exportSchemas to produce a complete, reproducible schema export.
9521
+ */
9522
+ static getExportDDL(schemaName) {
9523
+ const statements = [];
9524
+ const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
9525
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
9526
+ for (const tableName of _ScorerDefinitionsPG.MANAGED_TABLES) {
9527
+ statements.push(
9528
+ generateTableSQL({
9529
+ tableName,
9530
+ schema: storage.TABLE_SCHEMAS[tableName],
9531
+ schemaName,
9532
+ includeAllConstraints: true
9533
+ })
9534
+ );
9535
+ }
9536
+ for (const idx of _ScorerDefinitionsPG.getDefaultIndexDefs(schemaPrefix)) {
9537
+ statements.push(generateIndexSQL(idx, schemaName));
9538
+ }
9539
+ return statements;
9540
+ }
9541
+ getDefaultIndexDefinitions() {
9542
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
9543
+ return _ScorerDefinitionsPG.getDefaultIndexDefs(schemaPrefix);
9544
+ }
7375
9545
  async createDefaultIndexes() {
7376
9546
  if (this.#skipDefaultIndexes) {
7377
9547
  return;
@@ -7465,7 +9635,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
7465
9635
  scorerDefinitionId: scorerDefinition.id,
7466
9636
  versionNumber: 1,
7467
9637
  ...snapshotConfig,
7468
- changedFields: [...SNAPSHOT_FIELDS2],
9638
+ changedFields: [...SNAPSHOT_FIELDS3],
7469
9639
  changeMessage: "Initial version"
7470
9640
  });
7471
9641
  return {
@@ -7517,7 +9687,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
7517
9687
  }
7518
9688
  const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
7519
9689
  let versionCreated = false;
7520
- const hasConfigUpdate = SNAPSHOT_FIELDS2.some((field) => field in configFields);
9690
+ const hasConfigUpdate = SNAPSHOT_FIELDS3.some((field) => field in configFields);
7521
9691
  if (hasConfigUpdate) {
7522
9692
  const latestVersion = await this.getLatestVersion(id);
7523
9693
  if (!latestVersion) {
@@ -7539,7 +9709,7 @@ var ScorerDefinitionsPG = class _ScorerDefinitionsPG extends storage.ScorerDefin
7539
9709
  ...latestConfig
7540
9710
  } = latestVersion;
7541
9711
  const newConfig = { ...latestConfig, ...configFields };
7542
- const changedFields = SNAPSHOT_FIELDS2.filter(
9712
+ const changedFields = SNAPSHOT_FIELDS3.filter(
7543
9713
  (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
7544
9714
  );
7545
9715
  if (changedFields.length > 0) {
@@ -8058,9 +10228,9 @@ var ScoresPG = class _ScoresPG extends storage.ScoresStorage {
8058
10228
  }
8059
10229
  /**
8060
10230
  * Returns default index definitions for the scores domain tables.
10231
+ * @param schemaPrefix - Prefix for index names (e.g. "my_schema_" or "")
8061
10232
  */
8062
- getDefaultIndexDefinitions() {
8063
- const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
10233
+ static getDefaultIndexDefs(schemaPrefix) {
8064
10234
  return [
8065
10235
  {
8066
10236
  name: `${schemaPrefix}mastra_scores_trace_id_span_id_created_at_idx`,
@@ -8069,6 +10239,34 @@ var ScoresPG = class _ScoresPG extends storage.ScoresStorage {
8069
10239
  }
8070
10240
  ];
8071
10241
  }
10242
+ /**
10243
+ * Returns all DDL statements for this domain: table and indexes.
10244
+ * Used by exportSchemas to produce a complete, reproducible schema export.
10245
+ */
10246
+ static getExportDDL(schemaName) {
10247
+ const statements = [];
10248
+ const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
10249
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
10250
+ statements.push(
10251
+ generateTableSQL({
10252
+ tableName: storage.TABLE_SCORERS,
10253
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_SCORERS],
10254
+ schemaName,
10255
+ includeAllConstraints: true
10256
+ })
10257
+ );
10258
+ for (const idx of _ScoresPG.getDefaultIndexDefs(schemaPrefix)) {
10259
+ statements.push(generateIndexSQL(idx, schemaName));
10260
+ }
10261
+ return statements;
10262
+ }
10263
+ /**
10264
+ * Returns default index definitions for this instance's schema.
10265
+ */
10266
+ getDefaultIndexDefinitions() {
10267
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
10268
+ return _ScoresPG.getDefaultIndexDefs(schemaPrefix);
10269
+ }
8072
10270
  /**
8073
10271
  * Creates default indexes for optimal query performance.
8074
10272
  */
@@ -8440,6 +10638,22 @@ var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
8440
10638
  updatedAt: new Date(row.updatedAtZ || row.updatedAt)
8441
10639
  };
8442
10640
  }
10641
+ /**
10642
+ * Returns all DDL statements for this domain: table with unique constraint.
10643
+ * Used by exportSchemas to produce a complete, reproducible schema export.
10644
+ */
10645
+ static getExportDDL(schemaName) {
10646
+ const statements = [];
10647
+ statements.push(
10648
+ generateTableSQL({
10649
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
10650
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT],
10651
+ schemaName,
10652
+ includeAllConstraints: true
10653
+ })
10654
+ );
10655
+ return statements;
10656
+ }
8443
10657
  /**
8444
10658
  * Returns default index definitions for the workflows domain tables.
8445
10659
  * Currently no default indexes are defined for workflows.
@@ -8706,6 +10920,29 @@ var WorkflowsPG = class _WorkflowsPG extends storage.WorkflowsStorage {
8706
10920
  // src/storage/index.ts
8707
10921
  var DEFAULT_MAX_CONNECTIONS = 20;
8708
10922
  var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
10923
+ var ALL_DOMAINS = [
10924
+ MemoryPG,
10925
+ ObservabilityPG,
10926
+ ScoresPG,
10927
+ ScorerDefinitionsPG,
10928
+ PromptBlocksPG,
10929
+ AgentsPG,
10930
+ WorkflowsPG,
10931
+ DatasetsPG,
10932
+ ExperimentsPG
10933
+ ];
10934
+ function exportSchemas(schemaName) {
10935
+ const statements = [];
10936
+ if (schemaName) {
10937
+ const quotedSchemaName = getSchemaName(schemaName);
10938
+ statements.push(`CREATE SCHEMA IF NOT EXISTS ${quotedSchemaName};`);
10939
+ statements.push("");
10940
+ }
10941
+ for (const Domain of ALL_DOMAINS) {
10942
+ statements.push(...Domain.getExportDDL(schemaName));
10943
+ }
10944
+ return statements.join("\n");
10945
+ }
8709
10946
  var PostgresStore = class extends storage.MastraCompositeStore {
8710
10947
  #pool;
8711
10948
  #db;
@@ -8739,7 +10976,10 @@ var PostgresStore = class extends storage.MastraCompositeStore {
8739
10976
  observability: new ObservabilityPG(domainConfig),
8740
10977
  agents: new AgentsPG(domainConfig),
8741
10978
  promptBlocks: new PromptBlocksPG(domainConfig),
8742
- scorerDefinitions: new ScorerDefinitionsPG(domainConfig)
10979
+ scorerDefinitions: new ScorerDefinitionsPG(domainConfig),
10980
+ mcpClients: new MCPClientsPG(domainConfig),
10981
+ datasets: new DatasetsPG(domainConfig),
10982
+ experiments: new ExperimentsPG(domainConfig)
8743
10983
  };
8744
10984
  } catch (e) {
8745
10985
  throw new error.MastraError(
@@ -8929,6 +11169,9 @@ Example Complex Query:
8929
11169
  }`;
8930
11170
 
8931
11171
  exports.AgentsPG = AgentsPG;
11172
+ exports.DatasetsPG = DatasetsPG;
11173
+ exports.ExperimentsPG = ExperimentsPG;
11174
+ exports.MCPClientsPG = MCPClientsPG;
8932
11175
  exports.MemoryPG = MemoryPG;
8933
11176
  exports.ObservabilityPG = ObservabilityPG;
8934
11177
  exports.PGVECTOR_PROMPT = PGVECTOR_PROMPT;