@mastra/libsql 1.3.0 → 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/CHANGELOG.md +60 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/guides-agent-frameworks-ai-sdk.md +6 -2
- package/dist/index.cjs +1972 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1971 -177
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +2 -1
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/datasets/index.d.ts +43 -0
- package/dist/storage/domains/datasets/index.d.ts.map +1 -0
- package/dist/storage/domains/experiments/index.d.ts +29 -0
- package/dist/storage/domains/experiments/index.d.ts.map +1 -0
- package/dist/storage/domains/mcp-clients/index.d.ts +26 -0
- package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +4 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +4 -4
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:
|
|
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
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
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
|
|
4342
|
+
const mcpClients = result.rows?.map((row) => this.#parseMCPClientRow(row)) ?? [];
|
|
2503
4343
|
return {
|
|
2504
|
-
|
|
4344
|
+
mcpClients,
|
|
2505
4345
|
total,
|
|
2506
4346
|
page,
|
|
2507
4347
|
perPage: perPageForResponse,
|
|
2508
|
-
hasMore:
|
|
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", "
|
|
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
|
-
//
|
|
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.
|
|
4369
|
+
tableName: storage.TABLE_MCP_CLIENT_VERSIONS,
|
|
2530
4370
|
record: {
|
|
2531
4371
|
id: input.id,
|
|
2532
|
-
|
|
4372
|
+
mcpClientId: input.mcpClientId,
|
|
2533
4373
|
versionNumber: input.versionNumber,
|
|
2534
|
-
name: input.name
|
|
4374
|
+
name: input.name,
|
|
2535
4375
|
description: input.description ?? null,
|
|
2536
|
-
|
|
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", "
|
|
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.#
|
|
2572
|
-
|
|
2573
|
-
|
|
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
|
-
|
|
2576
|
-
|
|
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", "
|
|
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(
|
|
4418
|
+
async getVersionByNumber(mcpClientId, versionNumber) {
|
|
2593
4419
|
try {
|
|
2594
|
-
const
|
|
2595
|
-
|
|
2596
|
-
|
|
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
|
-
|
|
2603
|
-
|
|
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", "
|
|
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(
|
|
4438
|
+
async getLatestVersion(mcpClientId) {
|
|
2620
4439
|
try {
|
|
2621
|
-
const
|
|
2622
|
-
|
|
2623
|
-
|
|
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
|
-
|
|
2631
|
-
|
|
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", "
|
|
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
|
|
2665
|
-
|
|
2666
|
-
|
|
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:
|
|
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
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
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
|
|
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:
|
|
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", "
|
|
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.#
|
|
2715
|
-
|
|
2716
|
-
|
|
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", "
|
|
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
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
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", "
|
|
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(
|
|
4540
|
+
async countVersions(mcpClientId) {
|
|
2760
4541
|
try {
|
|
2761
|
-
const
|
|
2762
|
-
|
|
2763
|
-
|
|
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", "
|
|
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
|
|
4560
|
+
// Private Helpers
|
|
2784
4561
|
// ==========================================================================
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
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
|
-
|
|
2801
|
-
versionNumber: row.versionNumber,
|
|
4598
|
+
mcpClientId: row.mcpClientId,
|
|
4599
|
+
versionNumber: Number(row.versionNumber),
|
|
2802
4600
|
name: row.name,
|
|
2803
|
-
description: row.description,
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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;
|