@mastra/libsql 1.3.0-alpha.1 → 1.4.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1692,17 +1692,30 @@ var LibSQLDB = class extends base.MastraBase {
1692
1692
  */
1693
1693
  async createTable({
1694
1694
  tableName,
1695
- schema
1695
+ schema,
1696
+ compositePrimaryKey
1696
1697
  }) {
1697
1698
  try {
1698
1699
  const parsedTableName = utils.parseSqlIdentifier(tableName, "table name");
1700
+ if (compositePrimaryKey) {
1701
+ for (const col of compositePrimaryKey) {
1702
+ if (!(col in schema)) {
1703
+ throw new Error(`compositePrimaryKey column "${col}" does not exist in schema for table "${tableName}"`);
1704
+ }
1705
+ }
1706
+ }
1707
+ const compositePKSet = compositePrimaryKey ? new Set(compositePrimaryKey) : null;
1699
1708
  const columnDefinitions = Object.entries(schema).map(([colName, colDef]) => {
1700
1709
  const type = this.getSqlType(colDef.type);
1701
1710
  const nullable = colDef.nullable === false ? "NOT NULL" : "";
1702
- const primaryKey = colDef.primaryKey ? "PRIMARY KEY" : "";
1711
+ const primaryKey = colDef.primaryKey && !compositePKSet?.has(colName) ? "PRIMARY KEY" : "";
1703
1712
  return `"${colName}" ${type} ${nullable} ${primaryKey}`.trim();
1704
1713
  });
1705
1714
  const tableConstraints = [];
1715
+ if (compositePrimaryKey) {
1716
+ const pkCols = compositePrimaryKey.map((c) => `"${c}"`).join(", ");
1717
+ tableConstraints.push(`PRIMARY KEY (${pkCols})`);
1718
+ }
1706
1719
  if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
1707
1720
  tableConstraints.push("UNIQUE (workflow_name, run_id)");
1708
1721
  }
@@ -2055,7 +2068,9 @@ var SNAPSHOT_FIELDS = [
2055
2068
  "inputProcessors",
2056
2069
  "outputProcessors",
2057
2070
  "memory",
2058
- "scorers"
2071
+ "scorers",
2072
+ "mcpClients",
2073
+ "requestContextSchema"
2059
2074
  ];
2060
2075
  var AgentsLibSQL = class extends storage.AgentsStorage {
2061
2076
  #db;
@@ -2485,33 +2500,1858 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2485
2500
  const total = await this.#db.selectTotalCount({ tableName: storage.TABLE_AGENTS });
2486
2501
  if (total === 0) {
2487
2502
  return {
2488
- agents: [],
2503
+ agents: [],
2504
+ total: 0,
2505
+ page,
2506
+ perPage: perPageForResponse,
2507
+ hasMore: false
2508
+ };
2509
+ }
2510
+ const limitValue = perPageInput === false ? total : perPage;
2511
+ const rows = await this.#db.selectMany({
2512
+ tableName: storage.TABLE_AGENTS,
2513
+ orderBy: `"${field}" ${direction}`,
2514
+ limit: limitValue,
2515
+ offset
2516
+ });
2517
+ const agents = rows.map((row) => this.parseRow(row));
2518
+ return {
2519
+ agents,
2520
+ total,
2521
+ page,
2522
+ perPage: perPageForResponse,
2523
+ hasMore: perPageInput === false ? false : offset + perPage < total
2524
+ };
2525
+ } catch (error$1) {
2526
+ if (error$1 instanceof error.MastraError) throw error$1;
2527
+ throw new error.MastraError(
2528
+ {
2529
+ id: storage.createStorageErrorId("LIBSQL", "LIST_AGENTS", "FAILED"),
2530
+ domain: error.ErrorDomain.STORAGE,
2531
+ category: error.ErrorCategory.THIRD_PARTY
2532
+ },
2533
+ error$1
2534
+ );
2535
+ }
2536
+ }
2537
+ // ==========================================================================
2538
+ // Agent Version Methods
2539
+ // ==========================================================================
2540
+ async createVersion(input) {
2541
+ try {
2542
+ const now = /* @__PURE__ */ new Date();
2543
+ await this.#db.insert({
2544
+ tableName: storage.TABLE_AGENT_VERSIONS,
2545
+ record: {
2546
+ id: input.id,
2547
+ agentId: input.agentId,
2548
+ versionNumber: input.versionNumber,
2549
+ name: input.name ?? null,
2550
+ description: input.description ?? null,
2551
+ instructions: this.serializeInstructions(input.instructions),
2552
+ model: input.model,
2553
+ tools: input.tools ?? null,
2554
+ defaultOptions: input.defaultOptions ?? null,
2555
+ workflows: input.workflows ?? null,
2556
+ agents: input.agents ?? null,
2557
+ integrationTools: input.integrationTools ?? null,
2558
+ inputProcessors: input.inputProcessors ?? null,
2559
+ outputProcessors: input.outputProcessors ?? null,
2560
+ memory: input.memory ?? null,
2561
+ scorers: input.scorers ?? null,
2562
+ mcpClients: input.mcpClients ?? null,
2563
+ requestContextSchema: input.requestContextSchema ?? null,
2564
+ changedFields: input.changedFields ?? null,
2565
+ changeMessage: input.changeMessage ?? null,
2566
+ createdAt: now
2567
+ }
2568
+ });
2569
+ return {
2570
+ ...input,
2571
+ createdAt: now
2572
+ };
2573
+ } catch (error$1) {
2574
+ if (error$1 instanceof error.MastraError) throw error$1;
2575
+ throw new error.MastraError(
2576
+ {
2577
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_VERSION", "FAILED"),
2578
+ domain: error.ErrorDomain.STORAGE,
2579
+ category: error.ErrorCategory.THIRD_PARTY,
2580
+ details: { versionId: input.id, agentId: input.agentId }
2581
+ },
2582
+ error$1
2583
+ );
2584
+ }
2585
+ }
2586
+ async getVersion(id) {
2587
+ try {
2588
+ const result = await this.#db.select({
2589
+ tableName: storage.TABLE_AGENT_VERSIONS,
2590
+ keys: { id }
2591
+ });
2592
+ if (!result) {
2593
+ return null;
2594
+ }
2595
+ return this.parseVersionRow(result);
2596
+ } catch (error$1) {
2597
+ if (error$1 instanceof error.MastraError) throw error$1;
2598
+ throw new error.MastraError(
2599
+ {
2600
+ id: storage.createStorageErrorId("LIBSQL", "GET_VERSION", "FAILED"),
2601
+ domain: error.ErrorDomain.STORAGE,
2602
+ category: error.ErrorCategory.THIRD_PARTY,
2603
+ details: { versionId: id }
2604
+ },
2605
+ error$1
2606
+ );
2607
+ }
2608
+ }
2609
+ async getVersionByNumber(agentId, versionNumber) {
2610
+ try {
2611
+ const rows = await this.#db.selectMany({
2612
+ tableName: storage.TABLE_AGENT_VERSIONS,
2613
+ whereClause: {
2614
+ sql: "WHERE agentId = ? AND versionNumber = ?",
2615
+ args: [agentId, versionNumber]
2616
+ },
2617
+ limit: 1
2618
+ });
2619
+ if (!rows || rows.length === 0) {
2620
+ return null;
2621
+ }
2622
+ return this.parseVersionRow(rows[0]);
2623
+ } catch (error$1) {
2624
+ if (error$1 instanceof error.MastraError) throw error$1;
2625
+ throw new error.MastraError(
2626
+ {
2627
+ id: storage.createStorageErrorId("LIBSQL", "GET_VERSION_BY_NUMBER", "FAILED"),
2628
+ domain: error.ErrorDomain.STORAGE,
2629
+ category: error.ErrorCategory.THIRD_PARTY,
2630
+ details: { agentId, versionNumber }
2631
+ },
2632
+ error$1
2633
+ );
2634
+ }
2635
+ }
2636
+ async getLatestVersion(agentId) {
2637
+ try {
2638
+ const rows = await this.#db.selectMany({
2639
+ tableName: storage.TABLE_AGENT_VERSIONS,
2640
+ whereClause: {
2641
+ sql: "WHERE agentId = ?",
2642
+ args: [agentId]
2643
+ },
2644
+ orderBy: "versionNumber DESC",
2645
+ limit: 1
2646
+ });
2647
+ if (!rows || rows.length === 0) {
2648
+ return null;
2649
+ }
2650
+ return this.parseVersionRow(rows[0]);
2651
+ } catch (error$1) {
2652
+ if (error$1 instanceof error.MastraError) throw error$1;
2653
+ throw new error.MastraError(
2654
+ {
2655
+ id: storage.createStorageErrorId("LIBSQL", "GET_LATEST_VERSION", "FAILED"),
2656
+ domain: error.ErrorDomain.STORAGE,
2657
+ category: error.ErrorCategory.THIRD_PARTY,
2658
+ details: { agentId }
2659
+ },
2660
+ error$1
2661
+ );
2662
+ }
2663
+ }
2664
+ async listVersions(input) {
2665
+ const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
2666
+ if (page < 0) {
2667
+ throw new error.MastraError(
2668
+ {
2669
+ id: storage.createStorageErrorId("LIBSQL", "LIST_VERSIONS", "INVALID_PAGE"),
2670
+ domain: error.ErrorDomain.STORAGE,
2671
+ category: error.ErrorCategory.USER,
2672
+ details: { page }
2673
+ },
2674
+ new Error("page must be >= 0")
2675
+ );
2676
+ }
2677
+ const perPage = storage.normalizePerPage(perPageInput, 20);
2678
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2679
+ try {
2680
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
2681
+ const total = await this.#db.selectTotalCount({
2682
+ tableName: storage.TABLE_AGENT_VERSIONS,
2683
+ whereClause: {
2684
+ sql: "WHERE agentId = ?",
2685
+ args: [agentId]
2686
+ }
2687
+ });
2688
+ if (total === 0) {
2689
+ return {
2690
+ versions: [],
2691
+ total: 0,
2692
+ page,
2693
+ perPage: perPageForResponse,
2694
+ hasMore: false
2695
+ };
2696
+ }
2697
+ const limitValue = perPageInput === false ? total : perPage;
2698
+ const rows = await this.#db.selectMany({
2699
+ tableName: storage.TABLE_AGENT_VERSIONS,
2700
+ whereClause: {
2701
+ sql: "WHERE agentId = ?",
2702
+ args: [agentId]
2703
+ },
2704
+ orderBy: `"${field}" ${direction}`,
2705
+ limit: limitValue,
2706
+ offset
2707
+ });
2708
+ const versions = rows.map((row) => this.parseVersionRow(row));
2709
+ return {
2710
+ versions,
2711
+ total,
2712
+ page,
2713
+ perPage: perPageForResponse,
2714
+ hasMore: perPageInput === false ? false : offset + perPage < total
2715
+ };
2716
+ } catch (error$1) {
2717
+ if (error$1 instanceof error.MastraError) throw error$1;
2718
+ throw new error.MastraError(
2719
+ {
2720
+ id: storage.createStorageErrorId("LIBSQL", "LIST_VERSIONS", "FAILED"),
2721
+ domain: error.ErrorDomain.STORAGE,
2722
+ category: error.ErrorCategory.THIRD_PARTY,
2723
+ details: { agentId }
2724
+ },
2725
+ error$1
2726
+ );
2727
+ }
2728
+ }
2729
+ async deleteVersion(id) {
2730
+ try {
2731
+ await this.#db.delete({
2732
+ tableName: storage.TABLE_AGENT_VERSIONS,
2733
+ keys: { id }
2734
+ });
2735
+ } catch (error$1) {
2736
+ if (error$1 instanceof error.MastraError) throw error$1;
2737
+ throw new error.MastraError(
2738
+ {
2739
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_VERSION", "FAILED"),
2740
+ domain: error.ErrorDomain.STORAGE,
2741
+ category: error.ErrorCategory.THIRD_PARTY,
2742
+ details: { versionId: id }
2743
+ },
2744
+ error$1
2745
+ );
2746
+ }
2747
+ }
2748
+ async deleteVersionsByParentId(entityId) {
2749
+ try {
2750
+ const versions = await this.#db.selectMany({
2751
+ tableName: storage.TABLE_AGENT_VERSIONS,
2752
+ whereClause: {
2753
+ sql: "WHERE agentId = ?",
2754
+ args: [entityId]
2755
+ }
2756
+ });
2757
+ for (const version of versions) {
2758
+ await this.#db.delete({
2759
+ tableName: storage.TABLE_AGENT_VERSIONS,
2760
+ keys: { id: version.id }
2761
+ });
2762
+ }
2763
+ } catch (error$1) {
2764
+ if (error$1 instanceof error.MastraError) throw error$1;
2765
+ throw new error.MastraError(
2766
+ {
2767
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
2768
+ domain: error.ErrorDomain.STORAGE,
2769
+ category: error.ErrorCategory.THIRD_PARTY,
2770
+ details: { agentId: entityId }
2771
+ },
2772
+ error$1
2773
+ );
2774
+ }
2775
+ }
2776
+ async countVersions(agentId) {
2777
+ try {
2778
+ const count = await this.#db.selectTotalCount({
2779
+ tableName: storage.TABLE_AGENT_VERSIONS,
2780
+ whereClause: {
2781
+ sql: "WHERE agentId = ?",
2782
+ args: [agentId]
2783
+ }
2784
+ });
2785
+ return count;
2786
+ } catch (error$1) {
2787
+ if (error$1 instanceof error.MastraError) throw error$1;
2788
+ throw new error.MastraError(
2789
+ {
2790
+ id: storage.createStorageErrorId("LIBSQL", "COUNT_VERSIONS", "FAILED"),
2791
+ domain: error.ErrorDomain.STORAGE,
2792
+ category: error.ErrorCategory.THIRD_PARTY,
2793
+ details: { agentId }
2794
+ },
2795
+ error$1
2796
+ );
2797
+ }
2798
+ }
2799
+ // ==========================================================================
2800
+ // Private Helper Methods
2801
+ // ==========================================================================
2802
+ serializeInstructions(instructions) {
2803
+ return Array.isArray(instructions) ? JSON.stringify(instructions) : instructions;
2804
+ }
2805
+ deserializeInstructions(raw) {
2806
+ if (!raw) return raw;
2807
+ try {
2808
+ const parsed = JSON.parse(raw);
2809
+ if (Array.isArray(parsed)) return parsed;
2810
+ } catch {
2811
+ }
2812
+ return raw;
2813
+ }
2814
+ parseVersionRow(row) {
2815
+ return {
2816
+ id: row.id,
2817
+ agentId: row.agentId,
2818
+ versionNumber: row.versionNumber,
2819
+ name: row.name,
2820
+ description: row.description,
2821
+ instructions: this.deserializeInstructions(row.instructions),
2822
+ model: this.parseJson(row.model, "model"),
2823
+ tools: this.parseJson(row.tools, "tools"),
2824
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
2825
+ workflows: this.parseJson(row.workflows, "workflows"),
2826
+ agents: this.parseJson(row.agents, "agents"),
2827
+ integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
2828
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
2829
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
2830
+ memory: this.parseJson(row.memory, "memory"),
2831
+ scorers: this.parseJson(row.scorers, "scorers"),
2832
+ mcpClients: this.parseJson(row.mcpClients, "mcpClients"),
2833
+ requestContextSchema: this.parseJson(row.requestContextSchema, "requestContextSchema"),
2834
+ changedFields: this.parseJson(row.changedFields, "changedFields"),
2835
+ changeMessage: row.changeMessage,
2836
+ createdAt: new Date(row.createdAt)
2837
+ };
2838
+ }
2839
+ };
2840
+ function jsonbArg(value) {
2841
+ return value === void 0 || value === null ? null : JSON.stringify(value);
2842
+ }
2843
+ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2844
+ #db;
2845
+ #client;
2846
+ constructor(config) {
2847
+ super();
2848
+ const client = resolveClient(config);
2849
+ this.#client = client;
2850
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
2851
+ }
2852
+ async init() {
2853
+ await this.#db.createTable({ tableName: storage.TABLE_DATASETS, schema: storage.DATASETS_SCHEMA });
2854
+ await this.#db.createTable({ tableName: storage.TABLE_DATASET_ITEMS, schema: storage.DATASET_ITEMS_SCHEMA });
2855
+ await this.#db.createTable({ tableName: storage.TABLE_DATASET_VERSIONS, schema: storage.DATASET_VERSIONS_SCHEMA });
2856
+ await this.#client.execute({
2857
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "validTo")`,
2858
+ args: []
2859
+ });
2860
+ await this.#client.execute({
2861
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_version ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "datasetVersion")`,
2862
+ args: []
2863
+ });
2864
+ await this.#client.execute({
2865
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto_deleted ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "validTo", "isDeleted")`,
2866
+ args: []
2867
+ });
2868
+ await this.#client.execute({
2869
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version ON "${storage.TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
2870
+ args: []
2871
+ });
2872
+ await this.#client.execute({
2873
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version_unique ON "${storage.TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
2874
+ args: []
2875
+ });
2876
+ }
2877
+ async dangerouslyClearAll() {
2878
+ await this.#db.deleteData({ tableName: storage.TABLE_DATASET_VERSIONS });
2879
+ await this.#db.deleteData({ tableName: storage.TABLE_DATASET_ITEMS });
2880
+ await this.#db.deleteData({ tableName: storage.TABLE_DATASETS });
2881
+ }
2882
+ // --- Row transformers ---
2883
+ transformDatasetRow(row) {
2884
+ return {
2885
+ id: row.id,
2886
+ name: row.name,
2887
+ description: row.description,
2888
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2889
+ inputSchema: row.inputSchema ? storage.safelyParseJSON(row.inputSchema) : void 0,
2890
+ groundTruthSchema: row.groundTruthSchema ? storage.safelyParseJSON(row.groundTruthSchema) : void 0,
2891
+ version: row.version,
2892
+ createdAt: storage.ensureDate(row.createdAt),
2893
+ updatedAt: storage.ensureDate(row.updatedAt)
2894
+ };
2895
+ }
2896
+ transformItemRow(row) {
2897
+ return {
2898
+ id: row.id,
2899
+ datasetId: row.datasetId,
2900
+ datasetVersion: row.datasetVersion,
2901
+ input: storage.safelyParseJSON(row.input),
2902
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
2903
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2904
+ createdAt: storage.ensureDate(row.createdAt),
2905
+ updatedAt: storage.ensureDate(row.updatedAt)
2906
+ };
2907
+ }
2908
+ transformItemRowFull(row) {
2909
+ return {
2910
+ id: row.id,
2911
+ datasetId: row.datasetId,
2912
+ datasetVersion: row.datasetVersion,
2913
+ validTo: row.validTo,
2914
+ isDeleted: Boolean(row.isDeleted),
2915
+ input: storage.safelyParseJSON(row.input),
2916
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
2917
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2918
+ createdAt: storage.ensureDate(row.createdAt),
2919
+ updatedAt: storage.ensureDate(row.updatedAt)
2920
+ };
2921
+ }
2922
+ transformDatasetVersionRow(row) {
2923
+ return {
2924
+ id: row.id,
2925
+ datasetId: row.datasetId,
2926
+ version: row.version,
2927
+ createdAt: storage.ensureDate(row.createdAt)
2928
+ };
2929
+ }
2930
+ // --- Dataset CRUD ---
2931
+ async createDataset(input) {
2932
+ try {
2933
+ const id = crypto.randomUUID();
2934
+ const now = /* @__PURE__ */ new Date();
2935
+ const nowIso = now.toISOString();
2936
+ await this.#db.insert({
2937
+ tableName: storage.TABLE_DATASETS,
2938
+ record: {
2939
+ id,
2940
+ name: input.name,
2941
+ description: input.description ?? null,
2942
+ metadata: input.metadata,
2943
+ inputSchema: input.inputSchema ?? null,
2944
+ groundTruthSchema: input.groundTruthSchema ?? null,
2945
+ version: 0,
2946
+ createdAt: nowIso,
2947
+ updatedAt: nowIso
2948
+ }
2949
+ });
2950
+ return {
2951
+ id,
2952
+ name: input.name,
2953
+ description: input.description,
2954
+ metadata: input.metadata,
2955
+ inputSchema: input.inputSchema,
2956
+ groundTruthSchema: input.groundTruthSchema,
2957
+ version: 0,
2958
+ createdAt: now,
2959
+ updatedAt: now
2960
+ };
2961
+ } catch (error$1) {
2962
+ throw new error.MastraError(
2963
+ {
2964
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_DATASET", "FAILED"),
2965
+ domain: error.ErrorDomain.STORAGE,
2966
+ category: error.ErrorCategory.THIRD_PARTY
2967
+ },
2968
+ error$1
2969
+ );
2970
+ }
2971
+ }
2972
+ async getDatasetById({ id }) {
2973
+ try {
2974
+ const result = await this.#client.execute({
2975
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASETS)} FROM ${storage.TABLE_DATASETS} WHERE id = ?`,
2976
+ args: [id]
2977
+ });
2978
+ return result.rows?.[0] ? this.transformDatasetRow(result.rows[0]) : null;
2979
+ } catch (error$1) {
2980
+ throw new error.MastraError(
2981
+ {
2982
+ id: storage.createStorageErrorId("LIBSQL", "GET_DATASET", "FAILED"),
2983
+ domain: error.ErrorDomain.STORAGE,
2984
+ category: error.ErrorCategory.THIRD_PARTY
2985
+ },
2986
+ error$1
2987
+ );
2988
+ }
2989
+ }
2990
+ async _doUpdateDataset(args) {
2991
+ try {
2992
+ const existing = await this.getDatasetById({ id: args.id });
2993
+ if (!existing) {
2994
+ throw new error.MastraError({
2995
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_DATASET", "NOT_FOUND"),
2996
+ domain: error.ErrorDomain.STORAGE,
2997
+ category: error.ErrorCategory.USER,
2998
+ details: { datasetId: args.id }
2999
+ });
3000
+ }
3001
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3002
+ const updates = ["updatedAt = ?"];
3003
+ const values = [now];
3004
+ if (args.name !== void 0) {
3005
+ updates.push("name = ?");
3006
+ values.push(args.name);
3007
+ }
3008
+ if (args.description !== void 0) {
3009
+ updates.push("description = ?");
3010
+ values.push(args.description);
3011
+ }
3012
+ if (args.metadata !== void 0) {
3013
+ updates.push("metadata = ?");
3014
+ values.push(JSON.stringify(args.metadata));
3015
+ }
3016
+ if (args.inputSchema !== void 0) {
3017
+ updates.push("inputSchema = ?");
3018
+ values.push(args.inputSchema === null ? null : JSON.stringify(args.inputSchema));
3019
+ }
3020
+ if (args.groundTruthSchema !== void 0) {
3021
+ updates.push("groundTruthSchema = ?");
3022
+ values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
3023
+ }
3024
+ values.push(args.id);
3025
+ await this.#client.execute({
3026
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET ${updates.join(", ")} WHERE id = ?`,
3027
+ args: values
3028
+ });
3029
+ return {
3030
+ ...existing,
3031
+ name: args.name ?? existing.name,
3032
+ description: args.description ?? existing.description,
3033
+ metadata: args.metadata ?? existing.metadata,
3034
+ inputSchema: args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema,
3035
+ groundTruthSchema: args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema,
3036
+ updatedAt: new Date(now)
3037
+ };
3038
+ } catch (error$1) {
3039
+ if (error$1 instanceof error.MastraError) throw error$1;
3040
+ throw new error.MastraError(
3041
+ {
3042
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_DATASET", "FAILED"),
3043
+ domain: error.ErrorDomain.STORAGE,
3044
+ category: error.ErrorCategory.THIRD_PARTY
3045
+ },
3046
+ error$1
3047
+ );
3048
+ }
3049
+ }
3050
+ async deleteDataset({ id }) {
3051
+ try {
3052
+ try {
3053
+ await this.#client.execute({
3054
+ sql: `DELETE FROM ${storage.TABLE_EXPERIMENT_RESULTS} WHERE experimentId IN (SELECT id FROM ${storage.TABLE_EXPERIMENTS} WHERE datasetId = ?)`,
3055
+ args: [id]
3056
+ });
3057
+ } catch {
3058
+ }
3059
+ try {
3060
+ await this.#client.execute({
3061
+ sql: `UPDATE ${storage.TABLE_EXPERIMENTS} SET datasetId = NULL, datasetVersion = NULL WHERE datasetId = ?`,
3062
+ args: [id]
3063
+ });
3064
+ } catch {
3065
+ }
3066
+ await this.#client.batch(
3067
+ [
3068
+ { sql: `DELETE FROM ${storage.TABLE_DATASET_VERSIONS} WHERE datasetId = ?`, args: [id] },
3069
+ { sql: `DELETE FROM ${storage.TABLE_DATASET_ITEMS} WHERE datasetId = ?`, args: [id] },
3070
+ { sql: `DELETE FROM ${storage.TABLE_DATASETS} WHERE id = ?`, args: [id] }
3071
+ ],
3072
+ "write"
3073
+ );
3074
+ } catch (error$1) {
3075
+ throw new error.MastraError(
3076
+ {
3077
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_DATASET", "FAILED"),
3078
+ domain: error.ErrorDomain.STORAGE,
3079
+ category: error.ErrorCategory.THIRD_PARTY
3080
+ },
3081
+ error$1
3082
+ );
3083
+ }
3084
+ }
3085
+ async listDatasets(args) {
3086
+ try {
3087
+ const { page, perPage: perPageInput } = args.pagination;
3088
+ const countResult = await this.#client.execute({
3089
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASETS}`,
3090
+ args: []
3091
+ });
3092
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
3093
+ if (total === 0) {
3094
+ return {
3095
+ datasets: [],
3096
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
3097
+ };
3098
+ }
3099
+ const perPage = storage.normalizePerPage(perPageInput, 100);
3100
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3101
+ const limitValue = perPageInput === false ? total : perPage;
3102
+ const end = perPageInput === false ? total : start + perPage;
3103
+ const result = await this.#client.execute({
3104
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASETS)} FROM ${storage.TABLE_DATASETS} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
3105
+ args: [limitValue, start]
3106
+ });
3107
+ return {
3108
+ datasets: result.rows?.map((row) => this.transformDatasetRow(row)) ?? [],
3109
+ pagination: {
3110
+ total,
3111
+ page,
3112
+ perPage: perPageForResponse,
3113
+ hasMore: end < total
3114
+ }
3115
+ };
3116
+ } catch (error$1) {
3117
+ throw new error.MastraError(
3118
+ {
3119
+ id: storage.createStorageErrorId("LIBSQL", "LIST_DATASETS", "FAILED"),
3120
+ domain: error.ErrorDomain.STORAGE,
3121
+ category: error.ErrorCategory.THIRD_PARTY
3122
+ },
3123
+ error$1
3124
+ );
3125
+ }
3126
+ }
3127
+ // --- SCD-2 item mutations ---
3128
+ async _doAddItem(args) {
3129
+ try {
3130
+ const id = crypto.randomUUID();
3131
+ const versionId = crypto.randomUUID();
3132
+ const now = /* @__PURE__ */ new Date();
3133
+ const nowIso = now.toISOString();
3134
+ const results = await this.#client.batch(
3135
+ [
3136
+ {
3137
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
3138
+ args: [args.datasetId]
3139
+ },
3140
+ {
3141
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3142
+ args: [
3143
+ id,
3144
+ args.datasetId,
3145
+ args.datasetId,
3146
+ jsonbArg(args.input),
3147
+ jsonbArg(args.groundTruth),
3148
+ jsonbArg(args.metadata),
3149
+ nowIso,
3150
+ nowIso
3151
+ ]
3152
+ },
3153
+ {
3154
+ sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
3155
+ args: [versionId, args.datasetId, args.datasetId, nowIso]
3156
+ }
3157
+ ],
3158
+ "write"
3159
+ );
3160
+ const newVersion = Number(results[0].rows[0].version);
3161
+ return {
3162
+ id,
3163
+ datasetId: args.datasetId,
3164
+ datasetVersion: newVersion,
3165
+ input: args.input,
3166
+ groundTruth: args.groundTruth,
3167
+ metadata: args.metadata,
3168
+ createdAt: now,
3169
+ updatedAt: now
3170
+ };
3171
+ } catch (error$1) {
3172
+ if (error$1 instanceof error.MastraError) throw error$1;
3173
+ throw new error.MastraError(
3174
+ {
3175
+ id: storage.createStorageErrorId("LIBSQL", "ADD_ITEM", "FAILED"),
3176
+ domain: error.ErrorDomain.STORAGE,
3177
+ category: error.ErrorCategory.THIRD_PARTY
3178
+ },
3179
+ error$1
3180
+ );
3181
+ }
3182
+ }
3183
+ async _doUpdateItem(args) {
3184
+ try {
3185
+ const existing = await this.getItemById({ id: args.id });
3186
+ if (!existing) {
3187
+ throw new error.MastraError({
3188
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_ITEM", "NOT_FOUND"),
3189
+ domain: error.ErrorDomain.STORAGE,
3190
+ category: error.ErrorCategory.USER,
3191
+ details: { itemId: args.id }
3192
+ });
3193
+ }
3194
+ if (existing.datasetId !== args.datasetId) {
3195
+ throw new error.MastraError({
3196
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_ITEM", "DATASET_MISMATCH"),
3197
+ domain: error.ErrorDomain.STORAGE,
3198
+ category: error.ErrorCategory.USER,
3199
+ details: { itemId: args.id, expectedDatasetId: args.datasetId, actualDatasetId: existing.datasetId }
3200
+ });
3201
+ }
3202
+ const versionId = crypto.randomUUID();
3203
+ const now = /* @__PURE__ */ new Date();
3204
+ const nowIso = now.toISOString();
3205
+ const mergedInput = args.input ?? existing.input;
3206
+ const mergedGroundTruth = args.groundTruth ?? existing.groundTruth;
3207
+ const mergedMetadata = args.metadata ?? existing.metadata;
3208
+ const results = await this.#client.batch(
3209
+ [
3210
+ {
3211
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
3212
+ args: [args.datasetId]
3213
+ },
3214
+ {
3215
+ sql: `UPDATE ${storage.TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
3216
+ args: [args.datasetId, args.id]
3217
+ },
3218
+ {
3219
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3220
+ args: [
3221
+ args.id,
3222
+ args.datasetId,
3223
+ args.datasetId,
3224
+ jsonbArg(mergedInput),
3225
+ jsonbArg(mergedGroundTruth),
3226
+ jsonbArg(mergedMetadata),
3227
+ existing.createdAt.toISOString(),
3228
+ nowIso
3229
+ ]
3230
+ },
3231
+ {
3232
+ sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
3233
+ args: [versionId, args.datasetId, args.datasetId, nowIso]
3234
+ }
3235
+ ],
3236
+ "write"
3237
+ );
3238
+ const newVersion = Number(results[0].rows[0].version);
3239
+ return {
3240
+ ...existing,
3241
+ datasetVersion: newVersion,
3242
+ input: mergedInput,
3243
+ groundTruth: mergedGroundTruth,
3244
+ metadata: mergedMetadata,
3245
+ updatedAt: now
3246
+ };
3247
+ } catch (error$1) {
3248
+ if (error$1 instanceof error.MastraError) throw error$1;
3249
+ throw new error.MastraError(
3250
+ {
3251
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_ITEM", "FAILED"),
3252
+ domain: error.ErrorDomain.STORAGE,
3253
+ category: error.ErrorCategory.THIRD_PARTY
3254
+ },
3255
+ error$1
3256
+ );
3257
+ }
3258
+ }
3259
+ async _doDeleteItem({ id, datasetId }) {
3260
+ try {
3261
+ const existing = await this.getItemById({ id });
3262
+ if (!existing) return;
3263
+ if (existing.datasetId !== datasetId) {
3264
+ throw new error.MastraError({
3265
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_ITEM", "DATASET_MISMATCH"),
3266
+ domain: error.ErrorDomain.STORAGE,
3267
+ category: error.ErrorCategory.USER,
3268
+ details: { itemId: id, expectedDatasetId: datasetId, actualDatasetId: existing.datasetId }
3269
+ });
3270
+ }
3271
+ const versionId = crypto.randomUUID();
3272
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3273
+ await this.#client.batch(
3274
+ [
3275
+ {
3276
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
3277
+ args: [datasetId]
3278
+ },
3279
+ {
3280
+ sql: `UPDATE ${storage.TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
3281
+ args: [datasetId, id]
3282
+ },
3283
+ {
3284
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3285
+ args: [
3286
+ id,
3287
+ datasetId,
3288
+ datasetId,
3289
+ jsonbArg(existing.input),
3290
+ jsonbArg(existing.groundTruth),
3291
+ jsonbArg(existing.metadata),
3292
+ existing.createdAt.toISOString(),
3293
+ nowIso
3294
+ ]
3295
+ },
3296
+ {
3297
+ sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
3298
+ args: [versionId, datasetId, datasetId, nowIso]
3299
+ }
3300
+ ],
3301
+ "write"
3302
+ );
3303
+ } catch (error$1) {
3304
+ if (error$1 instanceof error.MastraError) throw error$1;
3305
+ throw new error.MastraError(
3306
+ {
3307
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_ITEM", "FAILED"),
3308
+ domain: error.ErrorDomain.STORAGE,
3309
+ category: error.ErrorCategory.THIRD_PARTY
3310
+ },
3311
+ error$1
3312
+ );
3313
+ }
3314
+ }
3315
+ // --- SCD-2 queries ---
3316
+ async getItemById(args) {
3317
+ try {
3318
+ let result;
3319
+ if (args.datasetVersion !== void 0) {
3320
+ result = await this.#client.execute({
3321
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} WHERE id = ? AND datasetVersion = ? AND isDeleted = 0`,
3322
+ args: [args.id, args.datasetVersion]
3323
+ });
3324
+ } else {
3325
+ result = await this.#client.execute({
3326
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
3327
+ args: [args.id]
3328
+ });
3329
+ }
3330
+ return result.rows?.[0] ? this.transformItemRow(result.rows[0]) : null;
3331
+ } catch (error$1) {
3332
+ throw new error.MastraError(
3333
+ {
3334
+ id: storage.createStorageErrorId("LIBSQL", "GET_ITEM", "FAILED"),
3335
+ domain: error.ErrorDomain.STORAGE,
3336
+ category: error.ErrorCategory.THIRD_PARTY
3337
+ },
3338
+ error$1
3339
+ );
3340
+ }
3341
+ }
3342
+ async getItemsByVersion({ datasetId, version }) {
3343
+ try {
3344
+ const result = await this.#client.execute({
3345
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} WHERE datasetId = ? AND datasetVersion <= ? AND (validTo IS NULL OR validTo > ?) AND isDeleted = 0 ORDER BY createdAt DESC`,
3346
+ args: [datasetId, version, version]
3347
+ });
3348
+ return result.rows?.map((row) => this.transformItemRow(row)) ?? [];
3349
+ } catch (error$1) {
3350
+ throw new error.MastraError(
3351
+ {
3352
+ id: storage.createStorageErrorId("LIBSQL", "GET_ITEMS_BY_VERSION", "FAILED"),
3353
+ domain: error.ErrorDomain.STORAGE,
3354
+ category: error.ErrorCategory.THIRD_PARTY
3355
+ },
3356
+ error$1
3357
+ );
3358
+ }
3359
+ }
3360
+ async getItemHistory(itemId) {
3361
+ try {
3362
+ const result = await this.#client.execute({
3363
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} WHERE id = ? ORDER BY datasetVersion DESC`,
3364
+ args: [itemId]
3365
+ });
3366
+ return result.rows?.map((row) => this.transformItemRowFull(row)) ?? [];
3367
+ } catch (error$1) {
3368
+ throw new error.MastraError(
3369
+ {
3370
+ id: storage.createStorageErrorId("LIBSQL", "GET_ITEM_HISTORY", "FAILED"),
3371
+ domain: error.ErrorDomain.STORAGE,
3372
+ category: error.ErrorCategory.THIRD_PARTY
3373
+ },
3374
+ error$1
3375
+ );
3376
+ }
3377
+ }
3378
+ async listItems(args) {
3379
+ try {
3380
+ const { page, perPage: perPageInput } = args.pagination;
3381
+ if (args.version !== void 0) {
3382
+ const conditions2 = [
3383
+ "datasetId = ?",
3384
+ "datasetVersion <= ?",
3385
+ "(validTo IS NULL OR validTo > ?)",
3386
+ "isDeleted = 0"
3387
+ ];
3388
+ const queryParams2 = [args.datasetId, args.version, args.version];
3389
+ if (args.search) {
3390
+ conditions2.push(`(LOWER(json(input)) LIKE ? OR LOWER(COALESCE(json(groundTruth), '')) LIKE ?)`);
3391
+ const searchPattern = `%${args.search.toLowerCase()}%`;
3392
+ queryParams2.push(searchPattern, searchPattern);
3393
+ }
3394
+ const whereClause2 = `WHERE ${conditions2.join(" AND ")}`;
3395
+ const countResult2 = await this.#client.execute({
3396
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASET_ITEMS} ${whereClause2}`,
3397
+ args: queryParams2
3398
+ });
3399
+ const total2 = Number(countResult2.rows?.[0]?.count ?? 0);
3400
+ if (total2 === 0) {
3401
+ return {
3402
+ items: [],
3403
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
3404
+ };
3405
+ }
3406
+ const perPage2 = storage.normalizePerPage(perPageInput, 100);
3407
+ const { offset: start2, perPage: perPageForResponse2 } = storage.calculatePagination(page, perPageInput, perPage2);
3408
+ const limitValue2 = perPageInput === false ? total2 : perPage2;
3409
+ const end2 = perPageInput === false ? total2 : start2 + perPage2;
3410
+ const result2 = await this.#client.execute({
3411
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} ${whereClause2} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
3412
+ args: [...queryParams2, limitValue2, start2]
3413
+ });
3414
+ return {
3415
+ items: result2.rows?.map((row) => this.transformItemRow(row)) ?? [],
3416
+ pagination: {
3417
+ total: total2,
3418
+ page,
3419
+ perPage: perPageForResponse2,
3420
+ hasMore: end2 < total2
3421
+ }
3422
+ };
3423
+ }
3424
+ const conditions = ["datasetId = ?", "validTo IS NULL", "isDeleted = 0"];
3425
+ const queryParams = [args.datasetId];
3426
+ if (args.search) {
3427
+ conditions.push(`(LOWER(json(input)) LIKE ? OR LOWER(COALESCE(json(groundTruth), '')) LIKE ?)`);
3428
+ const searchPattern = `%${args.search.toLowerCase()}%`;
3429
+ queryParams.push(searchPattern, searchPattern);
3430
+ }
3431
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
3432
+ const countResult = await this.#client.execute({
3433
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASET_ITEMS} ${whereClause}`,
3434
+ args: queryParams
3435
+ });
3436
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
3437
+ if (total === 0) {
3438
+ return {
3439
+ items: [],
3440
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
3441
+ };
3442
+ }
3443
+ const perPage = storage.normalizePerPage(perPageInput, 100);
3444
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3445
+ const limitValue = perPageInput === false ? total : perPage;
3446
+ const end = perPageInput === false ? total : start + perPage;
3447
+ const result = await this.#client.execute({
3448
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_ITEMS)} FROM ${storage.TABLE_DATASET_ITEMS} ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
3449
+ args: [...queryParams, limitValue, start]
3450
+ });
3451
+ return {
3452
+ items: result.rows?.map((row) => this.transformItemRow(row)) ?? [],
3453
+ pagination: {
3454
+ total,
3455
+ page,
3456
+ perPage: perPageForResponse,
3457
+ hasMore: end < total
3458
+ }
3459
+ };
3460
+ } catch (error$1) {
3461
+ throw new error.MastraError(
3462
+ {
3463
+ id: storage.createStorageErrorId("LIBSQL", "LIST_ITEMS", "FAILED"),
3464
+ domain: error.ErrorDomain.STORAGE,
3465
+ category: error.ErrorCategory.THIRD_PARTY
3466
+ },
3467
+ error$1
3468
+ );
3469
+ }
3470
+ }
3471
+ // --- Dataset version methods ---
3472
+ async createDatasetVersion(datasetId, version) {
3473
+ try {
3474
+ const id = crypto.randomUUID();
3475
+ const now = /* @__PURE__ */ new Date();
3476
+ const nowIso = now.toISOString();
3477
+ await this.#db.insert({
3478
+ tableName: storage.TABLE_DATASET_VERSIONS,
3479
+ record: {
3480
+ id,
3481
+ datasetId,
3482
+ version,
3483
+ createdAt: nowIso
3484
+ }
3485
+ });
3486
+ return {
3487
+ id,
3488
+ datasetId,
3489
+ version,
3490
+ createdAt: now
3491
+ };
3492
+ } catch (error$1) {
3493
+ throw new error.MastraError(
3494
+ {
3495
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_DATASET_VERSION", "FAILED"),
3496
+ domain: error.ErrorDomain.STORAGE,
3497
+ category: error.ErrorCategory.THIRD_PARTY
3498
+ },
3499
+ error$1
3500
+ );
3501
+ }
3502
+ }
3503
+ async listDatasetVersions(input) {
3504
+ try {
3505
+ const { page, perPage: perPageInput } = input.pagination;
3506
+ const countResult = await this.#client.execute({
3507
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_DATASET_VERSIONS} WHERE datasetId = ?`,
3508
+ args: [input.datasetId]
3509
+ });
3510
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
3511
+ if (total === 0) {
3512
+ return {
3513
+ versions: [],
3514
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
3515
+ };
3516
+ }
3517
+ const perPage = storage.normalizePerPage(perPageInput, 100);
3518
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3519
+ const limitValue = perPageInput === false ? total : perPage;
3520
+ const end = perPageInput === false ? total : start + perPage;
3521
+ const result = await this.#client.execute({
3522
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_DATASET_VERSIONS)} FROM ${storage.TABLE_DATASET_VERSIONS} WHERE datasetId = ? ORDER BY version DESC LIMIT ? OFFSET ?`,
3523
+ args: [input.datasetId, limitValue, start]
3524
+ });
3525
+ return {
3526
+ versions: result.rows?.map((row) => this.transformDatasetVersionRow(row)) ?? [],
3527
+ pagination: {
3528
+ total,
3529
+ page,
3530
+ perPage: perPageForResponse,
3531
+ hasMore: end < total
3532
+ }
3533
+ };
3534
+ } catch (error$1) {
3535
+ throw new error.MastraError(
3536
+ {
3537
+ id: storage.createStorageErrorId("LIBSQL", "LIST_DATASET_VERSIONS", "FAILED"),
3538
+ domain: error.ErrorDomain.STORAGE,
3539
+ category: error.ErrorCategory.THIRD_PARTY
3540
+ },
3541
+ error$1
3542
+ );
3543
+ }
3544
+ }
3545
+ // --- Bulk operations (SCD-2 internally) ---
3546
+ async _doBatchInsertItems(input) {
3547
+ try {
3548
+ const dataset = await this.getDatasetById({ id: input.datasetId });
3549
+ if (!dataset) {
3550
+ throw new error.MastraError({
3551
+ id: storage.createStorageErrorId("LIBSQL", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
3552
+ domain: error.ErrorDomain.STORAGE,
3553
+ category: error.ErrorCategory.USER,
3554
+ details: { datasetId: input.datasetId }
3555
+ });
3556
+ }
3557
+ const now = /* @__PURE__ */ new Date();
3558
+ const nowIso = now.toISOString();
3559
+ const versionId = crypto.randomUUID();
3560
+ const statements = [
3561
+ {
3562
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
3563
+ args: [input.datasetId]
3564
+ }
3565
+ ];
3566
+ const items = [];
3567
+ for (const itemInput of input.items) {
3568
+ const id = crypto.randomUUID();
3569
+ items.push({ id, input: itemInput });
3570
+ statements.push({
3571
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3572
+ args: [
3573
+ id,
3574
+ input.datasetId,
3575
+ input.datasetId,
3576
+ jsonbArg(itemInput.input),
3577
+ jsonbArg(itemInput.groundTruth),
3578
+ jsonbArg(itemInput.metadata),
3579
+ nowIso,
3580
+ nowIso
3581
+ ]
3582
+ });
3583
+ }
3584
+ statements.push({
3585
+ sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
3586
+ args: [versionId, input.datasetId, input.datasetId, nowIso]
3587
+ });
3588
+ const results = await this.#client.batch(statements, "write");
3589
+ const newVersion = Number(results[0].rows[0].version);
3590
+ return items.map(({ id, input: itemInput }) => ({
3591
+ id,
3592
+ datasetId: input.datasetId,
3593
+ datasetVersion: newVersion,
3594
+ input: itemInput.input,
3595
+ groundTruth: itemInput.groundTruth,
3596
+ metadata: itemInput.metadata,
3597
+ createdAt: now,
3598
+ updatedAt: now
3599
+ }));
3600
+ } catch (error$1) {
3601
+ if (error$1 instanceof error.MastraError) throw error$1;
3602
+ throw new error.MastraError(
3603
+ {
3604
+ id: storage.createStorageErrorId("LIBSQL", "BULK_ADD_ITEMS", "FAILED"),
3605
+ domain: error.ErrorDomain.STORAGE,
3606
+ category: error.ErrorCategory.THIRD_PARTY
3607
+ },
3608
+ error$1
3609
+ );
3610
+ }
3611
+ }
3612
+ async _doBatchDeleteItems(input) {
3613
+ try {
3614
+ const dataset = await this.getDatasetById({ id: input.datasetId });
3615
+ if (!dataset) {
3616
+ throw new error.MastraError({
3617
+ id: storage.createStorageErrorId("LIBSQL", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
3618
+ domain: error.ErrorDomain.STORAGE,
3619
+ category: error.ErrorCategory.USER,
3620
+ details: { datasetId: input.datasetId }
3621
+ });
3622
+ }
3623
+ const currentItems = [];
3624
+ for (const itemId of input.itemIds) {
3625
+ const item = await this.getItemById({ id: itemId });
3626
+ if (item && item.datasetId === input.datasetId) {
3627
+ currentItems.push(item);
3628
+ }
3629
+ }
3630
+ if (currentItems.length === 0) return;
3631
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
3632
+ const versionId = crypto.randomUUID();
3633
+ const statements = [
3634
+ {
3635
+ sql: `UPDATE ${storage.TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
3636
+ args: [input.datasetId]
3637
+ }
3638
+ ];
3639
+ for (const item of currentItems) {
3640
+ statements.push({
3641
+ sql: `UPDATE ${storage.TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
3642
+ args: [input.datasetId, item.id]
3643
+ });
3644
+ statements.push({
3645
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3646
+ args: [
3647
+ item.id,
3648
+ input.datasetId,
3649
+ input.datasetId,
3650
+ jsonbArg(item.input),
3651
+ jsonbArg(item.groundTruth),
3652
+ jsonbArg(item.metadata),
3653
+ item.createdAt.toISOString(),
3654
+ nowIso
3655
+ ]
3656
+ });
3657
+ }
3658
+ statements.push({
3659
+ sql: `INSERT INTO ${storage.TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), ?)`,
3660
+ args: [versionId, input.datasetId, input.datasetId, nowIso]
3661
+ });
3662
+ await this.#client.batch(statements, "write");
3663
+ } catch (error$1) {
3664
+ if (error$1 instanceof error.MastraError) throw error$1;
3665
+ throw new error.MastraError(
3666
+ {
3667
+ id: storage.createStorageErrorId("LIBSQL", "BULK_DELETE_ITEMS", "FAILED"),
3668
+ domain: error.ErrorDomain.STORAGE,
3669
+ category: error.ErrorCategory.THIRD_PARTY
3670
+ },
3671
+ error$1
3672
+ );
3673
+ }
3674
+ }
3675
+ };
3676
+ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
3677
+ #db;
3678
+ #client;
3679
+ constructor(config) {
3680
+ super();
3681
+ const client = resolveClient(config);
3682
+ this.#client = client;
3683
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
3684
+ }
3685
+ async init() {
3686
+ await this.#db.createTable({ tableName: storage.TABLE_EXPERIMENTS, schema: storage.EXPERIMENTS_SCHEMA });
3687
+ await this.#db.createTable({
3688
+ tableName: storage.TABLE_EXPERIMENT_RESULTS,
3689
+ schema: storage.EXPERIMENT_RESULTS_SCHEMA
3690
+ });
3691
+ await this.#client.execute({
3692
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiments_datasetid ON "${storage.TABLE_EXPERIMENTS}" ("datasetId")`,
3693
+ args: []
3694
+ });
3695
+ await this.#client.execute({
3696
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiment_results_experimentid ON "${storage.TABLE_EXPERIMENT_RESULTS}" ("experimentId")`,
3697
+ args: []
3698
+ });
3699
+ await this.#client.execute({
3700
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_experiment_results_exp_item ON "${storage.TABLE_EXPERIMENT_RESULTS}" ("experimentId", "itemId")`,
3701
+ args: []
3702
+ });
3703
+ }
3704
+ async dangerouslyClearAll() {
3705
+ await this.#db.deleteData({ tableName: storage.TABLE_EXPERIMENT_RESULTS });
3706
+ await this.#db.deleteData({ tableName: storage.TABLE_EXPERIMENTS });
3707
+ }
3708
+ // Helper to transform row to Experiment
3709
+ transformExperimentRow(row) {
3710
+ return {
3711
+ id: row.id,
3712
+ datasetId: row.datasetId ?? null,
3713
+ datasetVersion: row.datasetVersion != null ? row.datasetVersion : null,
3714
+ targetType: row.targetType,
3715
+ targetId: row.targetId,
3716
+ name: row.name ?? void 0,
3717
+ description: row.description ?? void 0,
3718
+ metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
3719
+ status: row.status,
3720
+ totalItems: row.totalItems,
3721
+ succeededCount: row.succeededCount,
3722
+ failedCount: row.failedCount,
3723
+ skippedCount: row.skippedCount ?? 0,
3724
+ startedAt: row.startedAt ? storage.ensureDate(row.startedAt) : null,
3725
+ completedAt: row.completedAt ? storage.ensureDate(row.completedAt) : null,
3726
+ createdAt: storage.ensureDate(row.createdAt),
3727
+ updatedAt: storage.ensureDate(row.updatedAt)
3728
+ };
3729
+ }
3730
+ // Helper to transform row to ExperimentResult
3731
+ transformExperimentResultRow(row) {
3732
+ return {
3733
+ id: row.id,
3734
+ experimentId: row.experimentId,
3735
+ itemId: row.itemId,
3736
+ itemDatasetVersion: row.itemDatasetVersion != null ? row.itemDatasetVersion : null,
3737
+ input: storage.safelyParseJSON(row.input),
3738
+ output: row.output ? storage.safelyParseJSON(row.output) : null,
3739
+ groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : null,
3740
+ error: row.error ? storage.safelyParseJSON(row.error) : null,
3741
+ startedAt: storage.ensureDate(row.startedAt),
3742
+ completedAt: storage.ensureDate(row.completedAt),
3743
+ retryCount: row.retryCount,
3744
+ traceId: row.traceId ?? null,
3745
+ createdAt: storage.ensureDate(row.createdAt)
3746
+ };
3747
+ }
3748
+ // Experiment lifecycle
3749
+ async createExperiment(input) {
3750
+ try {
3751
+ const id = input.id ?? crypto.randomUUID();
3752
+ const now = /* @__PURE__ */ new Date();
3753
+ const nowIso = now.toISOString();
3754
+ await this.#db.insert({
3755
+ tableName: storage.TABLE_EXPERIMENTS,
3756
+ record: {
3757
+ id,
3758
+ datasetId: input.datasetId ?? null,
3759
+ datasetVersion: input.datasetVersion ?? null,
3760
+ targetType: input.targetType,
3761
+ targetId: input.targetId,
3762
+ name: input.name ?? null,
3763
+ description: input.description ?? null,
3764
+ metadata: input.metadata ?? null,
3765
+ status: "pending",
3766
+ totalItems: input.totalItems,
3767
+ succeededCount: 0,
3768
+ failedCount: 0,
3769
+ skippedCount: 0,
3770
+ startedAt: null,
3771
+ completedAt: null,
3772
+ createdAt: nowIso,
3773
+ updatedAt: nowIso
3774
+ }
3775
+ });
3776
+ return {
3777
+ id,
3778
+ datasetId: input.datasetId,
3779
+ datasetVersion: input.datasetVersion,
3780
+ targetType: input.targetType,
3781
+ targetId: input.targetId,
3782
+ name: input.name,
3783
+ description: input.description,
3784
+ metadata: input.metadata,
3785
+ status: "pending",
3786
+ totalItems: input.totalItems,
3787
+ succeededCount: 0,
3788
+ failedCount: 0,
3789
+ skippedCount: 0,
3790
+ startedAt: null,
3791
+ completedAt: null,
3792
+ createdAt: now,
3793
+ updatedAt: now
3794
+ };
3795
+ } catch (error$1) {
3796
+ throw new error.MastraError(
3797
+ {
3798
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_EXPERIMENT", "FAILED"),
3799
+ domain: error.ErrorDomain.STORAGE,
3800
+ category: error.ErrorCategory.THIRD_PARTY
3801
+ },
3802
+ error$1
3803
+ );
3804
+ }
3805
+ }
3806
+ async updateExperiment(input) {
3807
+ try {
3808
+ const existing = await this.getExperimentById({ id: input.id });
3809
+ if (!existing) {
3810
+ throw new error.MastraError({
3811
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_EXPERIMENT", "NOT_FOUND"),
3812
+ domain: error.ErrorDomain.STORAGE,
3813
+ category: error.ErrorCategory.USER,
3814
+ details: { experimentId: input.id }
3815
+ });
3816
+ }
3817
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3818
+ const updates = ["updatedAt = ?"];
3819
+ const values = [now];
3820
+ if (input.status !== void 0) {
3821
+ updates.push("status = ?");
3822
+ values.push(input.status);
3823
+ }
3824
+ if (input.succeededCount !== void 0) {
3825
+ updates.push("succeededCount = ?");
3826
+ values.push(input.succeededCount);
3827
+ }
3828
+ if (input.failedCount !== void 0) {
3829
+ updates.push("failedCount = ?");
3830
+ values.push(input.failedCount);
3831
+ }
3832
+ if (input.startedAt !== void 0) {
3833
+ updates.push("startedAt = ?");
3834
+ values.push(input.startedAt?.toISOString() ?? null);
3835
+ }
3836
+ if (input.completedAt !== void 0) {
3837
+ updates.push("completedAt = ?");
3838
+ values.push(input.completedAt?.toISOString() ?? null);
3839
+ }
3840
+ if (input.skippedCount !== void 0) {
3841
+ updates.push("skippedCount = ?");
3842
+ values.push(input.skippedCount);
3843
+ }
3844
+ if (input.name !== void 0) {
3845
+ updates.push("name = ?");
3846
+ values.push(input.name);
3847
+ }
3848
+ if (input.description !== void 0) {
3849
+ updates.push("description = ?");
3850
+ values.push(input.description);
3851
+ }
3852
+ if (input.metadata !== void 0) {
3853
+ updates.push("metadata = ?");
3854
+ values.push(JSON.stringify(input.metadata));
3855
+ }
3856
+ values.push(input.id);
3857
+ await this.#client.execute({
3858
+ sql: `UPDATE ${storage.TABLE_EXPERIMENTS} SET ${updates.join(", ")} WHERE id = ?`,
3859
+ args: values
3860
+ });
3861
+ const updated = await this.getExperimentById({ id: input.id });
3862
+ return updated;
3863
+ } catch (error$1) {
3864
+ if (error$1 instanceof error.MastraError) throw error$1;
3865
+ throw new error.MastraError(
3866
+ {
3867
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_EXPERIMENT", "FAILED"),
3868
+ domain: error.ErrorDomain.STORAGE,
3869
+ category: error.ErrorCategory.THIRD_PARTY
3870
+ },
3871
+ error$1
3872
+ );
3873
+ }
3874
+ }
3875
+ async getExperimentById(args) {
3876
+ try {
3877
+ const result = await this.#client.execute({
3878
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_EXPERIMENTS)} FROM ${storage.TABLE_EXPERIMENTS} WHERE id = ?`,
3879
+ args: [args.id]
3880
+ });
3881
+ return result.rows?.[0] ? this.transformExperimentRow(result.rows[0]) : null;
3882
+ } catch (error$1) {
3883
+ throw new error.MastraError(
3884
+ {
3885
+ id: storage.createStorageErrorId("LIBSQL", "GET_EXPERIMENT", "FAILED"),
3886
+ domain: error.ErrorDomain.STORAGE,
3887
+ category: error.ErrorCategory.THIRD_PARTY
3888
+ },
3889
+ error$1
3890
+ );
3891
+ }
3892
+ }
3893
+ async listExperiments(args) {
3894
+ try {
3895
+ const { page, perPage: perPageInput } = args.pagination;
3896
+ const conditions = [];
3897
+ const queryParams = [];
3898
+ if (args.datasetId) {
3899
+ conditions.push("datasetId = ?");
3900
+ queryParams.push(args.datasetId);
3901
+ }
3902
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
3903
+ const countResult = await this.#client.execute({
3904
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENTS} ${whereClause}`,
3905
+ args: queryParams
3906
+ });
3907
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
3908
+ if (total === 0) {
3909
+ return {
3910
+ experiments: [],
3911
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
3912
+ };
3913
+ }
3914
+ const perPage = storage.normalizePerPage(perPageInput, 100);
3915
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
3916
+ const limitValue = perPageInput === false ? total : perPage;
3917
+ const end = perPageInput === false ? total : start + perPage;
3918
+ const result = await this.#client.execute({
3919
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_EXPERIMENTS)} FROM ${storage.TABLE_EXPERIMENTS} ${whereClause} ORDER BY createdAt DESC LIMIT ? OFFSET ?`,
3920
+ args: [...queryParams, limitValue, start]
3921
+ });
3922
+ return {
3923
+ experiments: result.rows?.map((row) => this.transformExperimentRow(row)) ?? [],
3924
+ pagination: {
3925
+ total,
3926
+ page,
3927
+ perPage: perPageForResponse,
3928
+ hasMore: end < total
3929
+ }
3930
+ };
3931
+ } catch (error$1) {
3932
+ throw new error.MastraError(
3933
+ {
3934
+ id: storage.createStorageErrorId("LIBSQL", "LIST_EXPERIMENTS", "FAILED"),
3935
+ domain: error.ErrorDomain.STORAGE,
3936
+ category: error.ErrorCategory.THIRD_PARTY
3937
+ },
3938
+ error$1
3939
+ );
3940
+ }
3941
+ }
3942
+ async deleteExperiment(args) {
3943
+ try {
3944
+ await this.#client.execute({
3945
+ sql: `DELETE FROM ${storage.TABLE_EXPERIMENT_RESULTS} WHERE experimentId = ?`,
3946
+ args: [args.id]
3947
+ });
3948
+ await this.#client.execute({
3949
+ sql: `DELETE FROM ${storage.TABLE_EXPERIMENTS} WHERE id = ?`,
3950
+ args: [args.id]
3951
+ });
3952
+ } catch (error$1) {
3953
+ throw new error.MastraError(
3954
+ {
3955
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_EXPERIMENT", "FAILED"),
3956
+ domain: error.ErrorDomain.STORAGE,
3957
+ category: error.ErrorCategory.THIRD_PARTY
3958
+ },
3959
+ error$1
3960
+ );
3961
+ }
3962
+ }
3963
+ // Results (per-item)
3964
+ async addExperimentResult(input) {
3965
+ try {
3966
+ const id = input.id ?? crypto.randomUUID();
3967
+ const now = /* @__PURE__ */ new Date();
3968
+ const nowIso = now.toISOString();
3969
+ await this.#db.insert({
3970
+ tableName: storage.TABLE_EXPERIMENT_RESULTS,
3971
+ record: {
3972
+ id,
3973
+ experimentId: input.experimentId,
3974
+ itemId: input.itemId,
3975
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
3976
+ input: input.input,
3977
+ output: input.output,
3978
+ groundTruth: input.groundTruth,
3979
+ error: input.error ?? null,
3980
+ startedAt: input.startedAt.toISOString(),
3981
+ completedAt: input.completedAt.toISOString(),
3982
+ retryCount: input.retryCount,
3983
+ traceId: input.traceId ?? null,
3984
+ createdAt: nowIso
3985
+ }
3986
+ });
3987
+ return {
3988
+ id,
3989
+ experimentId: input.experimentId,
3990
+ itemId: input.itemId,
3991
+ itemDatasetVersion: input.itemDatasetVersion,
3992
+ input: input.input,
3993
+ output: input.output,
3994
+ groundTruth: input.groundTruth,
3995
+ error: input.error,
3996
+ startedAt: input.startedAt,
3997
+ completedAt: input.completedAt,
3998
+ retryCount: input.retryCount,
3999
+ traceId: input.traceId ?? null,
4000
+ createdAt: now
4001
+ };
4002
+ } catch (error$1) {
4003
+ throw new error.MastraError(
4004
+ {
4005
+ id: storage.createStorageErrorId("LIBSQL", "ADD_EXPERIMENT_RESULT", "FAILED"),
4006
+ domain: error.ErrorDomain.STORAGE,
4007
+ category: error.ErrorCategory.THIRD_PARTY
4008
+ },
4009
+ error$1
4010
+ );
4011
+ }
4012
+ }
4013
+ async getExperimentResultById(args) {
4014
+ try {
4015
+ const result = await this.#client.execute({
4016
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_EXPERIMENT_RESULTS)} FROM ${storage.TABLE_EXPERIMENT_RESULTS} WHERE id = ?`,
4017
+ args: [args.id]
4018
+ });
4019
+ return result.rows?.[0] ? this.transformExperimentResultRow(result.rows[0]) : null;
4020
+ } catch (error$1) {
4021
+ throw new error.MastraError(
4022
+ {
4023
+ id: storage.createStorageErrorId("LIBSQL", "GET_EXPERIMENT_RESULT", "FAILED"),
4024
+ domain: error.ErrorDomain.STORAGE,
4025
+ category: error.ErrorCategory.THIRD_PARTY
4026
+ },
4027
+ error$1
4028
+ );
4029
+ }
4030
+ }
4031
+ async listExperimentResults(args) {
4032
+ try {
4033
+ const { page, perPage: perPageInput } = args.pagination;
4034
+ const conditions = ["experimentId = ?"];
4035
+ const queryParams = [args.experimentId];
4036
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
4037
+ const countResult = await this.#client.execute({
4038
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENT_RESULTS} ${whereClause}`,
4039
+ args: queryParams
4040
+ });
4041
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
4042
+ if (total === 0) {
4043
+ return {
4044
+ results: [],
4045
+ pagination: { total: 0, page, perPage: perPageInput, hasMore: false }
4046
+ };
4047
+ }
4048
+ const perPage = storage.normalizePerPage(perPageInput, 100);
4049
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
4050
+ const limitValue = perPageInput === false ? total : perPage;
4051
+ const end = perPageInput === false ? total : start + perPage;
4052
+ const result = await this.#client.execute({
4053
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_EXPERIMENT_RESULTS)} FROM ${storage.TABLE_EXPERIMENT_RESULTS} ${whereClause} ORDER BY startedAt ASC LIMIT ? OFFSET ?`,
4054
+ args: [...queryParams, limitValue, start]
4055
+ });
4056
+ return {
4057
+ results: result.rows?.map((row) => this.transformExperimentResultRow(row)) ?? [],
4058
+ pagination: {
4059
+ total,
4060
+ page,
4061
+ perPage: perPageForResponse,
4062
+ hasMore: end < total
4063
+ }
4064
+ };
4065
+ } catch (error$1) {
4066
+ throw new error.MastraError(
4067
+ {
4068
+ id: storage.createStorageErrorId("LIBSQL", "LIST_EXPERIMENT_RESULTS", "FAILED"),
4069
+ domain: error.ErrorDomain.STORAGE,
4070
+ category: error.ErrorCategory.THIRD_PARTY
4071
+ },
4072
+ error$1
4073
+ );
4074
+ }
4075
+ }
4076
+ async deleteExperimentResults(args) {
4077
+ try {
4078
+ await this.#client.execute({
4079
+ sql: `DELETE FROM ${storage.TABLE_EXPERIMENT_RESULTS} WHERE experimentId = ?`,
4080
+ args: [args.experimentId]
4081
+ });
4082
+ } catch (error$1) {
4083
+ throw new error.MastraError(
4084
+ {
4085
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_EXPERIMENT_RESULTS", "FAILED"),
4086
+ domain: error.ErrorDomain.STORAGE,
4087
+ category: error.ErrorCategory.THIRD_PARTY
4088
+ },
4089
+ error$1
4090
+ );
4091
+ }
4092
+ }
4093
+ };
4094
+ var SNAPSHOT_FIELDS2 = ["name", "description", "servers"];
4095
+ var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4096
+ #db;
4097
+ #client;
4098
+ constructor(config) {
4099
+ super();
4100
+ const client = resolveClient(config);
4101
+ this.#client = client;
4102
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
4103
+ }
4104
+ async init() {
4105
+ await this.#db.createTable({ tableName: storage.TABLE_MCP_CLIENTS, schema: storage.MCP_CLIENTS_SCHEMA });
4106
+ await this.#db.createTable({
4107
+ tableName: storage.TABLE_MCP_CLIENT_VERSIONS,
4108
+ schema: storage.MCP_CLIENT_VERSIONS_SCHEMA
4109
+ });
4110
+ await this.#client.execute(
4111
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_mcp_client_versions_client_version ON "${storage.TABLE_MCP_CLIENT_VERSIONS}" ("mcpClientId", "versionNumber")`
4112
+ );
4113
+ }
4114
+ async dangerouslyClearAll() {
4115
+ await this.#db.deleteData({ tableName: storage.TABLE_MCP_CLIENTS });
4116
+ await this.#db.deleteData({ tableName: storage.TABLE_MCP_CLIENT_VERSIONS });
4117
+ }
4118
+ // ==========================================================================
4119
+ // MCP Client CRUD
4120
+ // ==========================================================================
4121
+ async getById(id) {
4122
+ try {
4123
+ const result = await this.#client.execute({
4124
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENTS)} FROM "${storage.TABLE_MCP_CLIENTS}" WHERE id = ?`,
4125
+ args: [id]
4126
+ });
4127
+ const row = result.rows?.[0];
4128
+ return row ? this.#parseMCPClientRow(row) : null;
4129
+ } catch (error$1) {
4130
+ if (error$1 instanceof error.MastraError) throw error$1;
4131
+ throw new error.MastraError(
4132
+ {
4133
+ id: storage.createStorageErrorId("LIBSQL", "GET_MCP_CLIENT", "FAILED"),
4134
+ domain: error.ErrorDomain.STORAGE,
4135
+ category: error.ErrorCategory.THIRD_PARTY
4136
+ },
4137
+ error$1
4138
+ );
4139
+ }
4140
+ }
4141
+ async create(input) {
4142
+ const { mcpClient } = input;
4143
+ try {
4144
+ const now = /* @__PURE__ */ new Date();
4145
+ await this.#db.insert({
4146
+ tableName: storage.TABLE_MCP_CLIENTS,
4147
+ record: {
4148
+ id: mcpClient.id,
4149
+ status: "draft",
4150
+ activeVersionId: null,
4151
+ authorId: mcpClient.authorId ?? null,
4152
+ metadata: mcpClient.metadata ?? null,
4153
+ createdAt: now.toISOString(),
4154
+ updatedAt: now.toISOString()
4155
+ }
4156
+ });
4157
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = mcpClient;
4158
+ const versionId = crypto.randomUUID();
4159
+ try {
4160
+ await this.createVersion({
4161
+ id: versionId,
4162
+ mcpClientId: mcpClient.id,
4163
+ versionNumber: 1,
4164
+ ...snapshotConfig,
4165
+ changedFields: Object.keys(snapshotConfig),
4166
+ changeMessage: "Initial version"
4167
+ });
4168
+ } catch (versionError) {
4169
+ await this.#db.delete({ tableName: storage.TABLE_MCP_CLIENTS, keys: { id: mcpClient.id } });
4170
+ throw versionError;
4171
+ }
4172
+ return {
4173
+ id: mcpClient.id,
4174
+ status: "draft",
4175
+ activeVersionId: void 0,
4176
+ authorId: mcpClient.authorId,
4177
+ metadata: mcpClient.metadata,
4178
+ createdAt: now,
4179
+ updatedAt: now
4180
+ };
4181
+ } catch (error$1) {
4182
+ if (error$1 instanceof error.MastraError) throw error$1;
4183
+ throw new error.MastraError(
4184
+ {
4185
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_MCP_CLIENT", "FAILED"),
4186
+ domain: error.ErrorDomain.STORAGE,
4187
+ category: error.ErrorCategory.THIRD_PARTY
4188
+ },
4189
+ error$1
4190
+ );
4191
+ }
4192
+ }
4193
+ async update(input) {
4194
+ const { id, ...updates } = input;
4195
+ try {
4196
+ const existing = await this.getById(id);
4197
+ if (!existing) {
4198
+ throw new Error(`MCP client with id ${id} not found`);
4199
+ }
4200
+ const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
4201
+ const configFieldNames = SNAPSHOT_FIELDS2;
4202
+ const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
4203
+ const updateData = {
4204
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
4205
+ };
4206
+ if (authorId !== void 0) updateData.authorId = authorId;
4207
+ if (activeVersionId !== void 0) {
4208
+ updateData.activeVersionId = activeVersionId;
4209
+ if (status === void 0) {
4210
+ updateData.status = "published";
4211
+ }
4212
+ }
4213
+ if (status !== void 0) updateData.status = status;
4214
+ if (metadata !== void 0) {
4215
+ updateData.metadata = { ...existing.metadata, ...metadata };
4216
+ }
4217
+ await this.#db.update({
4218
+ tableName: storage.TABLE_MCP_CLIENTS,
4219
+ keys: { id },
4220
+ data: updateData
4221
+ });
4222
+ if (hasConfigUpdate) {
4223
+ const latestVersion = await this.getLatestVersion(id);
4224
+ if (!latestVersion) {
4225
+ throw new Error(`No versions found for MCP client ${id}`);
4226
+ }
4227
+ const {
4228
+ id: _versionId,
4229
+ mcpClientId: _mcpClientId,
4230
+ versionNumber: _versionNumber,
4231
+ changedFields: _changedFields,
4232
+ changeMessage: _changeMessage,
4233
+ createdAt: _createdAt,
4234
+ ...latestConfig
4235
+ } = latestVersion;
4236
+ const newConfig = { ...latestConfig, ...configFields };
4237
+ const changedFields = configFieldNames.filter(
4238
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
4239
+ );
4240
+ if (changedFields.length > 0) {
4241
+ const newVersionId = crypto.randomUUID();
4242
+ await this.createVersion({
4243
+ id: newVersionId,
4244
+ mcpClientId: id,
4245
+ versionNumber: latestVersion.versionNumber + 1,
4246
+ ...newConfig,
4247
+ changedFields,
4248
+ changeMessage: `Updated ${changedFields.join(", ")}`
4249
+ });
4250
+ }
4251
+ }
4252
+ const updated = await this.getById(id);
4253
+ if (!updated) {
4254
+ throw new error.MastraError({
4255
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_MCP_CLIENT", "NOT_FOUND_AFTER_UPDATE"),
4256
+ domain: error.ErrorDomain.STORAGE,
4257
+ category: error.ErrorCategory.SYSTEM,
4258
+ text: `MCP client ${id} not found after update`,
4259
+ details: { id }
4260
+ });
4261
+ }
4262
+ return updated;
4263
+ } catch (error$1) {
4264
+ if (error$1 instanceof error.MastraError) throw error$1;
4265
+ throw new error.MastraError(
4266
+ {
4267
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_MCP_CLIENT", "FAILED"),
4268
+ domain: error.ErrorDomain.STORAGE,
4269
+ category: error.ErrorCategory.THIRD_PARTY
4270
+ },
4271
+ error$1
4272
+ );
4273
+ }
4274
+ }
4275
+ async delete(id) {
4276
+ try {
4277
+ await this.deleteVersionsByParentId(id);
4278
+ await this.#client.execute({
4279
+ sql: `DELETE FROM "${storage.TABLE_MCP_CLIENTS}" WHERE "id" = ?`,
4280
+ args: [id]
4281
+ });
4282
+ } catch (error$1) {
4283
+ if (error$1 instanceof error.MastraError) throw error$1;
4284
+ throw new error.MastraError(
4285
+ {
4286
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_MCP_CLIENT", "FAILED"),
4287
+ domain: error.ErrorDomain.STORAGE,
4288
+ category: error.ErrorCategory.THIRD_PARTY
4289
+ },
4290
+ error$1
4291
+ );
4292
+ }
4293
+ }
4294
+ async list(args) {
4295
+ try {
4296
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
4297
+ const { field, direction } = this.parseOrderBy(orderBy);
4298
+ const conditions = [];
4299
+ const queryParams = [];
4300
+ if (authorId !== void 0) {
4301
+ conditions.push("authorId = ?");
4302
+ queryParams.push(authorId);
4303
+ }
4304
+ if (metadata && Object.keys(metadata).length > 0) {
4305
+ for (const [key, value] of Object.entries(metadata)) {
4306
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
4307
+ throw new error.MastraError({
4308
+ id: storage.createStorageErrorId("LIBSQL", "LIST_MCP_CLIENTS", "INVALID_METADATA_KEY"),
4309
+ domain: error.ErrorDomain.STORAGE,
4310
+ category: error.ErrorCategory.USER,
4311
+ text: `Invalid metadata key: ${key}. Keys must be alphanumeric with underscores.`,
4312
+ details: { key }
4313
+ });
4314
+ }
4315
+ conditions.push(`json_extract(metadata, '$.${key}') = ?`);
4316
+ queryParams.push(typeof value === "string" ? value : JSON.stringify(value));
4317
+ }
4318
+ }
4319
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
4320
+ const countResult = await this.#client.execute({
4321
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_MCP_CLIENTS}" ${whereClause}`,
4322
+ args: queryParams
4323
+ });
4324
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
4325
+ if (total === 0) {
4326
+ return {
4327
+ mcpClients: [],
2489
4328
  total: 0,
2490
4329
  page,
2491
- perPage: perPageForResponse,
4330
+ perPage: perPageInput ?? 100,
2492
4331
  hasMore: false
2493
4332
  };
2494
4333
  }
4334
+ const perPage = storage.normalizePerPage(perPageInput, 100);
4335
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2495
4336
  const limitValue = perPageInput === false ? total : perPage;
2496
- const rows = await this.#db.selectMany({
2497
- tableName: storage.TABLE_AGENTS,
2498
- orderBy: `"${field}" ${direction}`,
2499
- limit: limitValue,
2500
- offset
4337
+ const end = perPageInput === false ? total : start + perPage;
4338
+ const result = await this.#client.execute({
4339
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENTS)} FROM "${storage.TABLE_MCP_CLIENTS}" ${whereClause} ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
4340
+ args: [...queryParams, limitValue, start]
2501
4341
  });
2502
- const agents = rows.map((row) => this.parseRow(row));
4342
+ const mcpClients = result.rows?.map((row) => this.#parseMCPClientRow(row)) ?? [];
2503
4343
  return {
2504
- agents,
4344
+ mcpClients,
2505
4345
  total,
2506
4346
  page,
2507
4347
  perPage: perPageForResponse,
2508
- hasMore: perPageInput === false ? false : offset + perPage < total
4348
+ hasMore: end < total
2509
4349
  };
2510
4350
  } catch (error$1) {
2511
4351
  if (error$1 instanceof error.MastraError) throw error$1;
2512
4352
  throw new error.MastraError(
2513
4353
  {
2514
- id: storage.createStorageErrorId("LIBSQL", "LIST_AGENTS", "FAILED"),
4354
+ id: storage.createStorageErrorId("LIBSQL", "LIST_MCP_CLIENTS", "FAILED"),
2515
4355
  domain: error.ErrorDomain.STORAGE,
2516
4356
  category: error.ErrorCategory.THIRD_PARTY
2517
4357
  },
@@ -2520,33 +4360,23 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2520
4360
  }
2521
4361
  }
2522
4362
  // ==========================================================================
2523
- // Agent Version Methods
4363
+ // MCP Client Version Methods
2524
4364
  // ==========================================================================
2525
4365
  async createVersion(input) {
2526
4366
  try {
2527
4367
  const now = /* @__PURE__ */ new Date();
2528
4368
  await this.#db.insert({
2529
- tableName: storage.TABLE_AGENT_VERSIONS,
4369
+ tableName: storage.TABLE_MCP_CLIENT_VERSIONS,
2530
4370
  record: {
2531
4371
  id: input.id,
2532
- agentId: input.agentId,
4372
+ mcpClientId: input.mcpClientId,
2533
4373
  versionNumber: input.versionNumber,
2534
- name: input.name ?? null,
4374
+ name: input.name,
2535
4375
  description: input.description ?? null,
2536
- instructions: this.serializeInstructions(input.instructions),
2537
- model: input.model,
2538
- tools: input.tools ?? null,
2539
- defaultOptions: input.defaultOptions ?? null,
2540
- workflows: input.workflows ?? null,
2541
- agents: input.agents ?? null,
2542
- integrationTools: input.integrationTools ?? null,
2543
- inputProcessors: input.inputProcessors ?? null,
2544
- outputProcessors: input.outputProcessors ?? null,
2545
- memory: input.memory ?? null,
2546
- scorers: input.scorers ?? null,
4376
+ servers: input.servers ?? null,
2547
4377
  changedFields: input.changedFields ?? null,
2548
4378
  changeMessage: input.changeMessage ?? null,
2549
- createdAt: now
4379
+ createdAt: now.toISOString()
2550
4380
  }
2551
4381
  });
2552
4382
  return {
@@ -2557,10 +4387,9 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2557
4387
  if (error$1 instanceof error.MastraError) throw error$1;
2558
4388
  throw new error.MastraError(
2559
4389
  {
2560
- id: storage.createStorageErrorId("LIBSQL", "CREATE_VERSION", "FAILED"),
4390
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_MCP_CLIENT_VERSION", "FAILED"),
2561
4391
  domain: error.ErrorDomain.STORAGE,
2562
- category: error.ErrorCategory.THIRD_PARTY,
2563
- details: { versionId: input.id, agentId: input.agentId }
4392
+ category: error.ErrorCategory.THIRD_PARTY
2564
4393
  },
2565
4394
  error$1
2566
4395
  );
@@ -2568,142 +4397,105 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2568
4397
  }
2569
4398
  async getVersion(id) {
2570
4399
  try {
2571
- const result = await this.#db.select({
2572
- tableName: storage.TABLE_AGENT_VERSIONS,
2573
- keys: { id }
4400
+ const result = await this.#client.execute({
4401
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENT_VERSIONS)} FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE id = ?`,
4402
+ args: [id]
2574
4403
  });
2575
- if (!result) {
2576
- return null;
2577
- }
2578
- return this.parseVersionRow(result);
4404
+ const row = result.rows?.[0];
4405
+ return row ? this.#parseVersionRow(row) : null;
2579
4406
  } catch (error$1) {
2580
4407
  if (error$1 instanceof error.MastraError) throw error$1;
2581
4408
  throw new error.MastraError(
2582
4409
  {
2583
- id: storage.createStorageErrorId("LIBSQL", "GET_VERSION", "FAILED"),
4410
+ id: storage.createStorageErrorId("LIBSQL", "GET_MCP_CLIENT_VERSION", "FAILED"),
2584
4411
  domain: error.ErrorDomain.STORAGE,
2585
- category: error.ErrorCategory.THIRD_PARTY,
2586
- details: { versionId: id }
4412
+ category: error.ErrorCategory.THIRD_PARTY
2587
4413
  },
2588
4414
  error$1
2589
4415
  );
2590
4416
  }
2591
4417
  }
2592
- async getVersionByNumber(agentId, versionNumber) {
4418
+ async getVersionByNumber(mcpClientId, versionNumber) {
2593
4419
  try {
2594
- const rows = await this.#db.selectMany({
2595
- tableName: storage.TABLE_AGENT_VERSIONS,
2596
- whereClause: {
2597
- sql: "WHERE agentId = ? AND versionNumber = ?",
2598
- args: [agentId, versionNumber]
2599
- },
2600
- limit: 1
4420
+ const result = await this.#client.execute({
4421
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENT_VERSIONS)} FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE mcpClientId = ? AND versionNumber = ?`,
4422
+ args: [mcpClientId, versionNumber]
2601
4423
  });
2602
- if (!rows || rows.length === 0) {
2603
- return null;
2604
- }
2605
- return this.parseVersionRow(rows[0]);
4424
+ const row = result.rows?.[0];
4425
+ return row ? this.#parseVersionRow(row) : null;
2606
4426
  } catch (error$1) {
2607
4427
  if (error$1 instanceof error.MastraError) throw error$1;
2608
4428
  throw new error.MastraError(
2609
4429
  {
2610
- id: storage.createStorageErrorId("LIBSQL", "GET_VERSION_BY_NUMBER", "FAILED"),
4430
+ id: storage.createStorageErrorId("LIBSQL", "GET_MCP_CLIENT_VERSION_BY_NUMBER", "FAILED"),
2611
4431
  domain: error.ErrorDomain.STORAGE,
2612
- category: error.ErrorCategory.THIRD_PARTY,
2613
- details: { agentId, versionNumber }
4432
+ category: error.ErrorCategory.THIRD_PARTY
2614
4433
  },
2615
4434
  error$1
2616
4435
  );
2617
4436
  }
2618
4437
  }
2619
- async getLatestVersion(agentId) {
4438
+ async getLatestVersion(mcpClientId) {
2620
4439
  try {
2621
- const rows = await this.#db.selectMany({
2622
- tableName: storage.TABLE_AGENT_VERSIONS,
2623
- whereClause: {
2624
- sql: "WHERE agentId = ?",
2625
- args: [agentId]
2626
- },
2627
- orderBy: "versionNumber DESC",
2628
- limit: 1
4440
+ const result = await this.#client.execute({
4441
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENT_VERSIONS)} FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE mcpClientId = ? ORDER BY versionNumber DESC LIMIT 1`,
4442
+ args: [mcpClientId]
2629
4443
  });
2630
- if (!rows || rows.length === 0) {
2631
- return null;
2632
- }
2633
- return this.parseVersionRow(rows[0]);
4444
+ const row = result.rows?.[0];
4445
+ return row ? this.#parseVersionRow(row) : null;
2634
4446
  } catch (error$1) {
2635
4447
  if (error$1 instanceof error.MastraError) throw error$1;
2636
4448
  throw new error.MastraError(
2637
4449
  {
2638
- id: storage.createStorageErrorId("LIBSQL", "GET_LATEST_VERSION", "FAILED"),
4450
+ id: storage.createStorageErrorId("LIBSQL", "GET_LATEST_MCP_CLIENT_VERSION", "FAILED"),
2639
4451
  domain: error.ErrorDomain.STORAGE,
2640
- category: error.ErrorCategory.THIRD_PARTY,
2641
- details: { agentId }
4452
+ category: error.ErrorCategory.THIRD_PARTY
2642
4453
  },
2643
4454
  error$1
2644
4455
  );
2645
4456
  }
2646
4457
  }
2647
4458
  async listVersions(input) {
2648
- const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
2649
- if (page < 0) {
2650
- throw new error.MastraError(
2651
- {
2652
- id: storage.createStorageErrorId("LIBSQL", "LIST_VERSIONS", "INVALID_PAGE"),
2653
- domain: error.ErrorDomain.STORAGE,
2654
- category: error.ErrorCategory.USER,
2655
- details: { page }
2656
- },
2657
- new Error("page must be >= 0")
2658
- );
2659
- }
2660
- const perPage = storage.normalizePerPage(perPageInput, 20);
2661
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2662
4459
  try {
4460
+ const { mcpClientId, page = 0, perPage: perPageInput, orderBy } = input;
2663
4461
  const { field, direction } = this.parseVersionOrderBy(orderBy);
2664
- const total = await this.#db.selectTotalCount({
2665
- tableName: storage.TABLE_AGENT_VERSIONS,
2666
- whereClause: {
2667
- sql: "WHERE agentId = ?",
2668
- args: [agentId]
2669
- }
4462
+ const countResult = await this.#client.execute({
4463
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE mcpClientId = ?`,
4464
+ args: [mcpClientId]
2670
4465
  });
4466
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
2671
4467
  if (total === 0) {
2672
4468
  return {
2673
4469
  versions: [],
2674
4470
  total: 0,
2675
4471
  page,
2676
- perPage: perPageForResponse,
4472
+ perPage: perPageInput ?? 20,
2677
4473
  hasMore: false
2678
4474
  };
2679
4475
  }
4476
+ const perPage = storage.normalizePerPage(perPageInput, 20);
4477
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2680
4478
  const limitValue = perPageInput === false ? total : perPage;
2681
- const rows = await this.#db.selectMany({
2682
- tableName: storage.TABLE_AGENT_VERSIONS,
2683
- whereClause: {
2684
- sql: "WHERE agentId = ?",
2685
- args: [agentId]
2686
- },
2687
- orderBy: `"${field}" ${direction}`,
2688
- limit: limitValue,
2689
- offset
4479
+ const end = perPageInput === false ? total : start + perPage;
4480
+ const result = await this.#client.execute({
4481
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_MCP_CLIENT_VERSIONS)} FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE mcpClientId = ? ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
4482
+ args: [mcpClientId, limitValue, start]
2690
4483
  });
2691
- const versions = rows.map((row) => this.parseVersionRow(row));
4484
+ const versions = result.rows?.map((row) => this.#parseVersionRow(row)) ?? [];
2692
4485
  return {
2693
4486
  versions,
2694
4487
  total,
2695
4488
  page,
2696
4489
  perPage: perPageForResponse,
2697
- hasMore: perPageInput === false ? false : offset + perPage < total
4490
+ hasMore: end < total
2698
4491
  };
2699
4492
  } catch (error$1) {
2700
4493
  if (error$1 instanceof error.MastraError) throw error$1;
2701
4494
  throw new error.MastraError(
2702
4495
  {
2703
- id: storage.createStorageErrorId("LIBSQL", "LIST_VERSIONS", "FAILED"),
4496
+ id: storage.createStorageErrorId("LIBSQL", "LIST_MCP_CLIENT_VERSIONS", "FAILED"),
2704
4497
  domain: error.ErrorDomain.STORAGE,
2705
- category: error.ErrorCategory.THIRD_PARTY,
2706
- details: { agentId }
4498
+ category: error.ErrorCategory.THIRD_PARTY
2707
4499
  },
2708
4500
  error$1
2709
4501
  );
@@ -2711,18 +4503,17 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2711
4503
  }
2712
4504
  async deleteVersion(id) {
2713
4505
  try {
2714
- await this.#db.delete({
2715
- tableName: storage.TABLE_AGENT_VERSIONS,
2716
- keys: { id }
4506
+ await this.#client.execute({
4507
+ sql: `DELETE FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE "id" = ?`,
4508
+ args: [id]
2717
4509
  });
2718
4510
  } catch (error$1) {
2719
4511
  if (error$1 instanceof error.MastraError) throw error$1;
2720
4512
  throw new error.MastraError(
2721
4513
  {
2722
- id: storage.createStorageErrorId("LIBSQL", "DELETE_VERSION", "FAILED"),
4514
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_MCP_CLIENT_VERSION", "FAILED"),
2723
4515
  domain: error.ErrorDomain.STORAGE,
2724
- category: error.ErrorCategory.THIRD_PARTY,
2725
- details: { versionId: id }
4516
+ category: error.ErrorCategory.THIRD_PARTY
2726
4517
  },
2727
4518
  error$1
2728
4519
  );
@@ -2730,90 +4521,87 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2730
4521
  }
2731
4522
  async deleteVersionsByParentId(entityId) {
2732
4523
  try {
2733
- const versions = await this.#db.selectMany({
2734
- tableName: storage.TABLE_AGENT_VERSIONS,
2735
- whereClause: {
2736
- sql: "WHERE agentId = ?",
2737
- args: [entityId]
2738
- }
4524
+ await this.#client.execute({
4525
+ sql: `DELETE FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE "mcpClientId" = ?`,
4526
+ args: [entityId]
2739
4527
  });
2740
- for (const version of versions) {
2741
- await this.#db.delete({
2742
- tableName: storage.TABLE_AGENT_VERSIONS,
2743
- keys: { id: version.id }
2744
- });
2745
- }
2746
4528
  } catch (error$1) {
2747
4529
  if (error$1 instanceof error.MastraError) throw error$1;
2748
4530
  throw new error.MastraError(
2749
4531
  {
2750
- id: storage.createStorageErrorId("LIBSQL", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
4532
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_MCP_CLIENT_VERSIONS_BY_CLIENT", "FAILED"),
2751
4533
  domain: error.ErrorDomain.STORAGE,
2752
- category: error.ErrorCategory.THIRD_PARTY,
2753
- details: { agentId: entityId }
4534
+ category: error.ErrorCategory.THIRD_PARTY
2754
4535
  },
2755
4536
  error$1
2756
4537
  );
2757
4538
  }
2758
4539
  }
2759
- async countVersions(agentId) {
4540
+ async countVersions(mcpClientId) {
2760
4541
  try {
2761
- const count = await this.#db.selectTotalCount({
2762
- tableName: storage.TABLE_AGENT_VERSIONS,
2763
- whereClause: {
2764
- sql: "WHERE agentId = ?",
2765
- args: [agentId]
2766
- }
4542
+ const result = await this.#client.execute({
4543
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_MCP_CLIENT_VERSIONS}" WHERE mcpClientId = ?`,
4544
+ args: [mcpClientId]
2767
4545
  });
2768
- return count;
4546
+ return Number(result.rows?.[0]?.count ?? 0);
2769
4547
  } catch (error$1) {
2770
4548
  if (error$1 instanceof error.MastraError) throw error$1;
2771
4549
  throw new error.MastraError(
2772
4550
  {
2773
- id: storage.createStorageErrorId("LIBSQL", "COUNT_VERSIONS", "FAILED"),
4551
+ id: storage.createStorageErrorId("LIBSQL", "COUNT_MCP_CLIENT_VERSIONS", "FAILED"),
2774
4552
  domain: error.ErrorDomain.STORAGE,
2775
- category: error.ErrorCategory.THIRD_PARTY,
2776
- details: { agentId }
4553
+ category: error.ErrorCategory.THIRD_PARTY
2777
4554
  },
2778
4555
  error$1
2779
4556
  );
2780
4557
  }
2781
4558
  }
2782
4559
  // ==========================================================================
2783
- // Private Helper Methods
4560
+ // Private Helpers
2784
4561
  // ==========================================================================
2785
- serializeInstructions(instructions) {
2786
- return Array.isArray(instructions) ? JSON.stringify(instructions) : instructions;
2787
- }
2788
- deserializeInstructions(raw) {
2789
- if (!raw) return raw;
2790
- try {
2791
- const parsed = JSON.parse(raw);
2792
- if (Array.isArray(parsed)) return parsed;
2793
- } catch {
2794
- }
2795
- return raw;
4562
+ #parseMCPClientRow(row) {
4563
+ const safeParseJSON = (val) => {
4564
+ if (val === null || val === void 0) return void 0;
4565
+ if (typeof val === "string") {
4566
+ try {
4567
+ return JSON.parse(val);
4568
+ } catch {
4569
+ return val;
4570
+ }
4571
+ }
4572
+ return val;
4573
+ };
4574
+ return {
4575
+ id: row.id,
4576
+ status: row.status ?? "draft",
4577
+ activeVersionId: row.activeVersionId ?? void 0,
4578
+ authorId: row.authorId ?? void 0,
4579
+ metadata: safeParseJSON(row.metadata),
4580
+ createdAt: new Date(row.createdAt),
4581
+ updatedAt: new Date(row.updatedAt)
4582
+ };
2796
4583
  }
2797
- parseVersionRow(row) {
4584
+ #parseVersionRow(row) {
4585
+ const safeParseJSON = (val) => {
4586
+ if (val === null || val === void 0) return void 0;
4587
+ if (typeof val === "string") {
4588
+ try {
4589
+ return JSON.parse(val);
4590
+ } catch {
4591
+ return val;
4592
+ }
4593
+ }
4594
+ return val;
4595
+ };
2798
4596
  return {
2799
4597
  id: row.id,
2800
- agentId: row.agentId,
2801
- versionNumber: row.versionNumber,
4598
+ mcpClientId: row.mcpClientId,
4599
+ versionNumber: Number(row.versionNumber),
2802
4600
  name: row.name,
2803
- description: row.description,
2804
- instructions: this.deserializeInstructions(row.instructions),
2805
- model: this.parseJson(row.model, "model"),
2806
- tools: this.parseJson(row.tools, "tools"),
2807
- defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
2808
- workflows: this.parseJson(row.workflows, "workflows"),
2809
- agents: this.parseJson(row.agents, "agents"),
2810
- integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
2811
- inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
2812
- outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
2813
- memory: this.parseJson(row.memory, "memory"),
2814
- scorers: this.parseJson(row.scorers, "scorers"),
2815
- changedFields: this.parseJson(row.changedFields, "changedFields"),
2816
- changeMessage: row.changeMessage,
4601
+ description: row.description ?? void 0,
4602
+ servers: safeParseJSON(row.servers),
4603
+ changedFields: safeParseJSON(row.changedFields),
4604
+ changeMessage: row.changeMessage ?? void 0,
2817
4605
  createdAt: new Date(row.createdAt)
2818
4606
  };
2819
4607
  }
@@ -5144,7 +6932,7 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
5144
6932
  }
5145
6933
  }
5146
6934
  };
5147
- var SNAPSHOT_FIELDS2 = ["name", "description", "content", "rules"];
6935
+ var SNAPSHOT_FIELDS3 = ["name", "description", "content", "rules"];
5148
6936
  var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
5149
6937
  #db;
5150
6938
  #client;
@@ -5243,7 +7031,7 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
5243
7031
  throw new Error(`Prompt block with id ${id} not found`);
5244
7032
  }
5245
7033
  const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
5246
- const configFieldNames = SNAPSHOT_FIELDS2;
7034
+ const configFieldNames = SNAPSHOT_FIELDS3;
5247
7035
  const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
5248
7036
  const updateData = {
5249
7037
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -5651,7 +7439,7 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
5651
7439
  };
5652
7440
  }
5653
7441
  };
5654
- var SNAPSHOT_FIELDS3 = [
7442
+ var SNAPSHOT_FIELDS4 = [
5655
7443
  "name",
5656
7444
  "description",
5657
7445
  "type",
@@ -5762,7 +7550,7 @@ var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
5762
7550
  throw new Error(`Scorer definition with id ${id} not found`);
5763
7551
  }
5764
7552
  const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
5765
- const configFieldNames = SNAPSHOT_FIELDS3;
7553
+ const configFieldNames = SNAPSHOT_FIELDS4;
5766
7554
  const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
5767
7555
  const updateData = {
5768
7556
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -6830,16 +8618,22 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
6830
8618
  const memory = new MemoryLibSQL(domainConfig);
6831
8619
  const observability = new ObservabilityLibSQL(domainConfig);
6832
8620
  const agents = new AgentsLibSQL(domainConfig);
8621
+ const datasets = new DatasetsLibSQL(domainConfig);
8622
+ const experiments = new ExperimentsLibSQL(domainConfig);
6833
8623
  const promptBlocks = new PromptBlocksLibSQL(domainConfig);
6834
8624
  const scorerDefinitions = new ScorerDefinitionsLibSQL(domainConfig);
8625
+ const mcpClients = new MCPClientsLibSQL(domainConfig);
6835
8626
  this.stores = {
6836
8627
  scores,
6837
8628
  workflows,
6838
8629
  memory,
6839
8630
  observability,
6840
8631
  agents,
8632
+ datasets,
8633
+ experiments,
6841
8634
  promptBlocks,
6842
- scorerDefinitions
8635
+ scorerDefinitions,
8636
+ mcpClients
6843
8637
  };
6844
8638
  }
6845
8639
  };
@@ -6944,10 +8738,13 @@ Example Complex Query:
6944
8738
  }`;
6945
8739
 
6946
8740
  exports.AgentsLibSQL = AgentsLibSQL;
8741
+ exports.DatasetsLibSQL = DatasetsLibSQL;
6947
8742
  exports.DefaultStorage = LibSQLStore;
8743
+ exports.ExperimentsLibSQL = ExperimentsLibSQL;
6948
8744
  exports.LIBSQL_PROMPT = LIBSQL_PROMPT;
6949
8745
  exports.LibSQLStore = LibSQLStore;
6950
8746
  exports.LibSQLVector = LibSQLVector;
8747
+ exports.MCPClientsLibSQL = MCPClientsLibSQL;
6951
8748
  exports.MemoryLibSQL = MemoryLibSQL;
6952
8749
  exports.ObservabilityLibSQL = ObservabilityLibSQL;
6953
8750
  exports.PromptBlocksLibSQL = PromptBlocksLibSQL;