@mastra/libsql 1.4.0 → 1.5.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1094,7 +1094,7 @@ function buildSelectColumns(tableName) {
1094
1094
  return Object.keys(schema).map((col) => {
1095
1095
  const colDef = schema[col];
1096
1096
  const parsedCol = utils.parseSqlIdentifier(col, "column name");
1097
- return colDef?.type === "jsonb" ? `json(${parsedCol}) as ${parsedCol}` : parsedCol;
1097
+ return colDef?.type === "jsonb" ? `json("${parsedCol}") as "${parsedCol}"` : `"${parsedCol}"`;
1098
1098
  }).join(", ");
1099
1099
  }
1100
1100
  function isLockError(error) {
@@ -2055,23 +2055,6 @@ Note: This migration may take some time for large tables.
2055
2055
  };
2056
2056
 
2057
2057
  // src/storage/domains/agents/index.ts
2058
- var SNAPSHOT_FIELDS = [
2059
- "name",
2060
- "description",
2061
- "instructions",
2062
- "model",
2063
- "tools",
2064
- "defaultOptions",
2065
- "workflows",
2066
- "agents",
2067
- "integrationTools",
2068
- "inputProcessors",
2069
- "outputProcessors",
2070
- "memory",
2071
- "scorers",
2072
- "mcpClients",
2073
- "requestContextSchema"
2074
- ];
2075
2058
  var AgentsLibSQL = class extends storage.AgentsStorage {
2076
2059
  #db;
2077
2060
  #client;
@@ -2091,6 +2074,11 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2091
2074
  schema: storage.AGENTS_SCHEMA,
2092
2075
  ifNotExists: ["status", "authorId"]
2093
2076
  });
2077
+ await this.#db.alterTable({
2078
+ tableName: storage.TABLE_AGENT_VERSIONS,
2079
+ schema: storage.AGENT_VERSIONS_SCHEMA,
2080
+ ifNotExists: ["mcpClients", "requestContextSchema", "workspace", "skills", "skillsFormat"]
2081
+ });
2094
2082
  await this.#migrateToolsToJsonbFormat();
2095
2083
  await this.#cleanupStaleDrafts();
2096
2084
  }
@@ -2362,8 +2350,8 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2362
2350
  async update(input) {
2363
2351
  const { id, ...updates } = input;
2364
2352
  try {
2365
- const existingAgent = await this.getById(id);
2366
- if (!existingAgent) {
2353
+ const existing = await this.getById(id);
2354
+ if (!existing) {
2367
2355
  throw new error.MastraError({
2368
2356
  id: storage.createStorageErrorId("LIBSQL", "UPDATE_AGENT", "NOT_FOUND"),
2369
2357
  domain: error.ErrorDomain.STORAGE,
@@ -2372,68 +2360,21 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2372
2360
  details: { agentId: id }
2373
2361
  });
2374
2362
  }
2375
- const metadataFields = {
2376
- authorId: updates.authorId,
2377
- activeVersionId: updates.activeVersionId,
2378
- metadata: updates.metadata
2379
- };
2380
- const configFields = {};
2381
- for (const field of SNAPSHOT_FIELDS) {
2382
- if (updates[field] !== void 0) {
2383
- configFields[field] = updates[field];
2384
- }
2385
- }
2386
- if (Object.keys(configFields).length > 0) {
2387
- const latestVersion = await this.getLatestVersion(id);
2388
- const nextVersionNumber = latestVersion ? latestVersion.versionNumber + 1 : 1;
2389
- if (!latestVersion) {
2390
- throw new error.MastraError({
2391
- id: storage.createStorageErrorId("LIBSQL", "UPDATE_AGENT", "NO_VERSION"),
2392
- domain: error.ErrorDomain.STORAGE,
2393
- category: error.ErrorCategory.USER,
2394
- text: `Cannot update config fields for agent ${id} - no versions exist`,
2395
- details: { id }
2396
- });
2397
- }
2398
- const latestSnapshot = {};
2399
- for (const field of SNAPSHOT_FIELDS) {
2400
- if (latestVersion[field] !== void 0) {
2401
- latestSnapshot[field] = latestVersion[field];
2402
- }
2403
- }
2404
- const sanitizedConfigFields = Object.fromEntries(
2405
- Object.entries(configFields).map(([key, value]) => [key, value === null ? void 0 : value])
2406
- );
2407
- const versionInput = {
2408
- id: crypto.randomUUID(),
2409
- agentId: id,
2410
- versionNumber: nextVersionNumber,
2411
- ...latestSnapshot,
2412
- // Start from latest version
2413
- ...sanitizedConfigFields,
2414
- // Apply updates (null values converted to undefined)
2415
- changedFields: Object.keys(configFields),
2416
- changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
2417
- };
2418
- await this.createVersion(versionInput);
2419
- }
2420
- const data = {
2421
- updatedAt: /* @__PURE__ */ new Date()
2363
+ const { authorId, activeVersionId, metadata, status } = updates;
2364
+ const updateData = {
2365
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2422
2366
  };
2423
- if (metadataFields.authorId !== void 0) data.authorId = metadataFields.authorId;
2424
- if (metadataFields.activeVersionId !== void 0) {
2425
- data.activeVersionId = metadataFields.activeVersionId;
2426
- }
2427
- if (metadataFields.metadata !== void 0) {
2428
- data.metadata = metadataFields.metadata;
2429
- }
2430
- if (Object.keys(data).length > 1) {
2431
- await this.#db.update({
2432
- tableName: storage.TABLE_AGENTS,
2433
- keys: { id },
2434
- data
2435
- });
2367
+ if (authorId !== void 0) updateData.authorId = authorId;
2368
+ if (activeVersionId !== void 0) updateData.activeVersionId = activeVersionId;
2369
+ if (status !== void 0) updateData.status = status;
2370
+ if (metadata !== void 0) {
2371
+ updateData.metadata = { ...existing.metadata, ...metadata };
2436
2372
  }
2373
+ await this.#db.update({
2374
+ tableName: storage.TABLE_AGENTS,
2375
+ keys: { id },
2376
+ data: updateData
2377
+ });
2437
2378
  const updatedAgent = await this.getById(id);
2438
2379
  if (!updatedAgent) {
2439
2380
  throw new error.MastraError({
@@ -2481,7 +2422,7 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2481
2422
  }
2482
2423
  }
2483
2424
  async list(args) {
2484
- const { page = 0, perPage: perPageInput, orderBy } = args || {};
2425
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};
2485
2426
  const { field, direction } = this.parseOrderBy(orderBy);
2486
2427
  if (page < 0) {
2487
2428
  throw new error.MastraError(
@@ -2497,7 +2438,37 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2497
2438
  const perPage = storage.normalizePerPage(perPageInput, 100);
2498
2439
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2499
2440
  try {
2500
- const total = await this.#db.selectTotalCount({ tableName: storage.TABLE_AGENTS });
2441
+ const conditions = [];
2442
+ const queryParams = [];
2443
+ if (status) {
2444
+ conditions.push("status = ?");
2445
+ queryParams.push(status);
2446
+ }
2447
+ if (authorId !== void 0) {
2448
+ conditions.push("authorId = ?");
2449
+ queryParams.push(authorId);
2450
+ }
2451
+ if (metadata && Object.keys(metadata).length > 0) {
2452
+ for (const [key, value] of Object.entries(metadata)) {
2453
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
2454
+ throw new error.MastraError({
2455
+ id: storage.createStorageErrorId("LIBSQL", "LIST_AGENTS", "INVALID_METADATA_KEY"),
2456
+ domain: error.ErrorDomain.STORAGE,
2457
+ category: error.ErrorCategory.USER,
2458
+ text: `Invalid metadata key: ${key}. Keys must be alphanumeric with underscores.`,
2459
+ details: { key }
2460
+ });
2461
+ }
2462
+ conditions.push(`json_extract(metadata, '$.${key}') = ?`);
2463
+ queryParams.push(typeof value === "string" ? value : JSON.stringify(value));
2464
+ }
2465
+ }
2466
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2467
+ const countResult = await this.#client.execute({
2468
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_AGENTS}" ${whereClause}`,
2469
+ args: queryParams
2470
+ });
2471
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
2501
2472
  if (total === 0) {
2502
2473
  return {
2503
2474
  agents: [],
@@ -2508,12 +2479,11 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2508
2479
  };
2509
2480
  }
2510
2481
  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
2482
+ const result = await this.#client.execute({
2483
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_AGENTS)} FROM "${storage.TABLE_AGENTS}" ${whereClause} ORDER BY "${field}" ${direction} LIMIT ? OFFSET ?`,
2484
+ args: [...queryParams, limitValue, offset]
2516
2485
  });
2486
+ const rows = result.rows ?? [];
2517
2487
  const agents = rows.map((row) => this.parseRow(row));
2518
2488
  return {
2519
2489
  agents,
@@ -2561,6 +2531,9 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2561
2531
  scorers: input.scorers ?? null,
2562
2532
  mcpClients: input.mcpClients ?? null,
2563
2533
  requestContextSchema: input.requestContextSchema ?? null,
2534
+ workspace: input.workspace ?? null,
2535
+ skills: input.skills ?? null,
2536
+ skillsFormat: input.skillsFormat ?? null,
2564
2537
  changedFields: input.changedFields ?? null,
2565
2538
  changeMessage: input.changeMessage ?? null,
2566
2539
  createdAt: now
@@ -2831,12 +2804,101 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
2831
2804
  scorers: this.parseJson(row.scorers, "scorers"),
2832
2805
  mcpClients: this.parseJson(row.mcpClients, "mcpClients"),
2833
2806
  requestContextSchema: this.parseJson(row.requestContextSchema, "requestContextSchema"),
2807
+ workspace: this.parseJson(row.workspace, "workspace"),
2808
+ skills: this.parseJson(row.skills, "skills"),
2809
+ skillsFormat: row.skillsFormat,
2834
2810
  changedFields: this.parseJson(row.changedFields, "changedFields"),
2835
2811
  changeMessage: row.changeMessage,
2836
2812
  createdAt: new Date(row.createdAt)
2837
2813
  };
2838
2814
  }
2839
2815
  };
2816
+ var BlobsLibSQL = class extends storage.BlobStore {
2817
+ #db;
2818
+ #client;
2819
+ static MANAGED_TABLES = [storage.TABLE_SKILL_BLOBS];
2820
+ constructor(config) {
2821
+ super();
2822
+ const client = resolveClient(config);
2823
+ this.#client = client;
2824
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
2825
+ }
2826
+ async init() {
2827
+ await this.#db.createTable({ tableName: storage.TABLE_SKILL_BLOBS, schema: storage.SKILL_BLOBS_SCHEMA });
2828
+ }
2829
+ async put(entry) {
2830
+ const now = entry.createdAt ?? /* @__PURE__ */ new Date();
2831
+ await this.#client.execute({
2832
+ sql: `INSERT OR IGNORE INTO "${storage.TABLE_SKILL_BLOBS}" ("hash", "content", "size", "mimeType", "createdAt") VALUES (?, ?, ?, ?, ?)`,
2833
+ args: [entry.hash, entry.content, entry.size, entry.mimeType ?? null, now.toISOString()]
2834
+ });
2835
+ }
2836
+ async get(hash) {
2837
+ const result = await this.#client.execute({
2838
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_BLOBS)} FROM "${storage.TABLE_SKILL_BLOBS}" WHERE "hash" = ?`,
2839
+ args: [hash]
2840
+ });
2841
+ if (!result.rows.length) return null;
2842
+ return this.#parseRow(result.rows[0]);
2843
+ }
2844
+ async has(hash) {
2845
+ const result = await this.#client.execute({
2846
+ sql: `SELECT 1 FROM "${storage.TABLE_SKILL_BLOBS}" WHERE "hash" = ? LIMIT 1`,
2847
+ args: [hash]
2848
+ });
2849
+ return result.rows.length > 0;
2850
+ }
2851
+ async delete(hash) {
2852
+ const result = await this.#client.execute({
2853
+ sql: `DELETE FROM "${storage.TABLE_SKILL_BLOBS}" WHERE "hash" = ?`,
2854
+ args: [hash]
2855
+ });
2856
+ return result.rowsAffected > 0;
2857
+ }
2858
+ async putMany(entries) {
2859
+ if (entries.length === 0) return;
2860
+ await this.#db.batchInsert({
2861
+ tableName: storage.TABLE_SKILL_BLOBS,
2862
+ records: entries.map((entry) => ({
2863
+ hash: entry.hash,
2864
+ content: entry.content,
2865
+ size: entry.size,
2866
+ mimeType: entry.mimeType ?? null,
2867
+ createdAt: (entry.createdAt ?? /* @__PURE__ */ new Date()).toISOString()
2868
+ }))
2869
+ });
2870
+ }
2871
+ async getMany(hashes) {
2872
+ const result = /* @__PURE__ */ new Map();
2873
+ if (hashes.length === 0) return result;
2874
+ const batchSize = 500;
2875
+ for (let i = 0; i < hashes.length; i += batchSize) {
2876
+ const batch = hashes.slice(i, i + batchSize);
2877
+ const placeholders = batch.map(() => "?").join(", ");
2878
+ const queryResult = await this.#client.execute({
2879
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_BLOBS)} FROM "${storage.TABLE_SKILL_BLOBS}" WHERE "hash" IN (${placeholders})`,
2880
+ args: batch
2881
+ });
2882
+ for (const row of queryResult.rows) {
2883
+ const entry = this.#parseRow(row);
2884
+ result.set(entry.hash, entry);
2885
+ }
2886
+ }
2887
+ return result;
2888
+ }
2889
+ async dangerouslyClearAll() {
2890
+ await this.#db.deleteData({ tableName: storage.TABLE_SKILL_BLOBS });
2891
+ }
2892
+ #parseRow(row) {
2893
+ return {
2894
+ hash: row.hash,
2895
+ content: row.content,
2896
+ size: Number(row.size),
2897
+ mimeType: row.mimeType || void 0,
2898
+ createdAt: new Date(row.createdAt)
2899
+ };
2900
+ }
2901
+ };
2840
2902
  function jsonbArg(value) {
2841
2903
  return value === void 0 || value === null ? null : JSON.stringify(value);
2842
2904
  }
@@ -2952,8 +3014,8 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2952
3014
  name: input.name,
2953
3015
  description: input.description,
2954
3016
  metadata: input.metadata,
2955
- inputSchema: input.inputSchema,
2956
- groundTruthSchema: input.groundTruthSchema,
3017
+ inputSchema: input.inputSchema ?? void 0,
3018
+ groundTruthSchema: input.groundTruthSchema ?? void 0,
2957
3019
  version: 0,
2958
3020
  createdAt: now,
2959
3021
  updatedAt: now
@@ -3031,8 +3093,8 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3031
3093
  name: args.name ?? existing.name,
3032
3094
  description: args.description ?? existing.description,
3033
3095
  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,
3096
+ inputSchema: (args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema) ?? void 0,
3097
+ groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
3036
3098
  updatedAt: new Date(now)
3037
3099
  };
3038
3100
  } catch (error$1) {
@@ -4091,7 +4153,6 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
4091
4153
  }
4092
4154
  }
4093
4155
  };
4094
- var SNAPSHOT_FIELDS2 = ["name", "description", "servers"];
4095
4156
  var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4096
4157
  #db;
4097
4158
  #client;
@@ -4197,19 +4258,12 @@ var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4197
4258
  if (!existing) {
4198
4259
  throw new Error(`MCP client with id ${id} not found`);
4199
4260
  }
4200
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
4201
- const configFieldNames = SNAPSHOT_FIELDS2;
4202
- const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
4261
+ const { authorId, activeVersionId, metadata, status } = updates;
4203
4262
  const updateData = {
4204
4263
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
4205
4264
  };
4206
4265
  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
- }
4266
+ if (activeVersionId !== void 0) updateData.activeVersionId = activeVersionId;
4213
4267
  if (status !== void 0) updateData.status = status;
4214
4268
  if (metadata !== void 0) {
4215
4269
  updateData.metadata = { ...existing.metadata, ...metadata };
@@ -4219,36 +4273,6 @@ var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4219
4273
  keys: { id },
4220
4274
  data: updateData
4221
4275
  });
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
4276
  const updated = await this.getById(id);
4253
4277
  if (!updated) {
4254
4278
  throw new error.MastraError({
@@ -4293,10 +4317,12 @@ var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4293
4317
  }
4294
4318
  async list(args) {
4295
4319
  try {
4296
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
4320
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {};
4297
4321
  const { field, direction } = this.parseOrderBy(orderBy);
4298
4322
  const conditions = [];
4299
4323
  const queryParams = [];
4324
+ conditions.push("status = ?");
4325
+ queryParams.push(status);
4300
4326
  if (authorId !== void 0) {
4301
4327
  conditions.push("authorId = ?");
4302
4328
  queryParams.push(authorId);
@@ -4316,7 +4342,7 @@ var MCPClientsLibSQL = class extends storage.MCPClientsStorage {
4316
4342
  queryParams.push(typeof value === "string" ? value : JSON.stringify(value));
4317
4343
  }
4318
4344
  }
4319
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
4345
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
4320
4346
  const countResult = await this.#client.execute({
4321
4347
  sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_MCP_CLIENTS}" ${whereClause}`,
4322
4348
  args: queryParams
@@ -5596,7 +5622,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5596
5622
  const newThread = {
5597
5623
  id: newThreadId,
5598
5624
  resourceId: resourceId || sourceThread.resourceId,
5599
- title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : void 0),
5625
+ title: title || (sourceThread.title ? `Clone of ${sourceThread.title}` : ""),
5600
5626
  metadata: {
5601
5627
  ...metadata,
5602
5628
  clone: cloneMetadata
@@ -5612,7 +5638,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5612
5638
  args: [
5613
5639
  newThread.id,
5614
5640
  newThread.resourceId,
5615
- newThread.title || null,
5641
+ newThread.title ?? "",
5616
5642
  JSON.stringify(newThread.metadata),
5617
5643
  nowStr,
5618
5644
  nowStr
@@ -6932,7 +6958,6 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
6932
6958
  }
6933
6959
  }
6934
6960
  };
6935
- var SNAPSHOT_FIELDS3 = ["name", "description", "content", "rules"];
6936
6961
  var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
6937
6962
  #db;
6938
6963
  #client;
@@ -7030,19 +7055,12 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
7030
7055
  if (!existing) {
7031
7056
  throw new Error(`Prompt block with id ${id} not found`);
7032
7057
  }
7033
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
7034
- const configFieldNames = SNAPSHOT_FIELDS3;
7035
- const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
7058
+ const { authorId, activeVersionId, metadata, status } = updates;
7036
7059
  const updateData = {
7037
7060
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7038
7061
  };
7039
7062
  if (authorId !== void 0) updateData.authorId = authorId;
7040
- if (activeVersionId !== void 0) {
7041
- updateData.activeVersionId = activeVersionId;
7042
- if (status === void 0) {
7043
- updateData.status = "published";
7044
- }
7045
- }
7063
+ if (activeVersionId !== void 0) updateData.activeVersionId = activeVersionId;
7046
7064
  if (status !== void 0) updateData.status = status;
7047
7065
  if (metadata !== void 0) {
7048
7066
  updateData.metadata = { ...existing.metadata, ...metadata };
@@ -7052,34 +7070,6 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
7052
7070
  keys: { id },
7053
7071
  data: updateData
7054
7072
  });
7055
- if (hasConfigUpdate) {
7056
- const latestVersion = await this.getLatestVersion(id);
7057
- if (!latestVersion) {
7058
- throw new Error(`No versions found for prompt block ${id}`);
7059
- }
7060
- const {
7061
- id: _versionId,
7062
- blockId: _blockId,
7063
- versionNumber: _versionNumber,
7064
- changedFields: _changedFields,
7065
- changeMessage: _changeMessage,
7066
- createdAt: _createdAt,
7067
- ...latestConfig
7068
- } = latestVersion;
7069
- const newConfig = { ...latestConfig, ...configFields };
7070
- const changedFields = configFieldNames.filter(
7071
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
7072
- );
7073
- const newVersionId = crypto.randomUUID();
7074
- await this.createVersion({
7075
- id: newVersionId,
7076
- blockId: id,
7077
- versionNumber: latestVersion.versionNumber + 1,
7078
- ...newConfig,
7079
- changedFields,
7080
- changeMessage: `Updated ${changedFields.join(", ")}`
7081
- });
7082
- }
7083
7073
  const updated = await this.getById(id);
7084
7074
  if (!updated) {
7085
7075
  throw new error.MastraError({
@@ -7124,10 +7114,12 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
7124
7114
  }
7125
7115
  async list(args) {
7126
7116
  try {
7127
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
7117
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status = "published" } = args || {};
7128
7118
  const { field, direction } = this.parseOrderBy(orderBy);
7129
7119
  const conditions = [];
7130
7120
  const queryParams = [];
7121
+ conditions.push("status = ?");
7122
+ queryParams.push(status);
7131
7123
  if (authorId !== void 0) {
7132
7124
  conditions.push("authorId = ?");
7133
7125
  queryParams.push(authorId);
@@ -7147,7 +7139,7 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
7147
7139
  queryParams.push(typeof value === "string" ? value : JSON.stringify(value));
7148
7140
  }
7149
7141
  }
7150
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
7142
+ const whereClause = `WHERE ${conditions.join(" AND ")}`;
7151
7143
  const countResult = await this.#client.execute({
7152
7144
  sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_PROMPT_BLOCKS}" ${whereClause}`,
7153
7145
  args: queryParams
@@ -7439,16 +7431,6 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
7439
7431
  };
7440
7432
  }
7441
7433
  };
7442
- var SNAPSHOT_FIELDS4 = [
7443
- "name",
7444
- "description",
7445
- "type",
7446
- "model",
7447
- "instructions",
7448
- "scoreRange",
7449
- "presetConfig",
7450
- "defaultSampling"
7451
- ];
7452
7434
  var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
7453
7435
  #db;
7454
7436
  #client;
@@ -7549,19 +7531,12 @@ var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
7549
7531
  if (!existing) {
7550
7532
  throw new Error(`Scorer definition with id ${id} not found`);
7551
7533
  }
7552
- const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
7553
- const configFieldNames = SNAPSHOT_FIELDS4;
7554
- const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
7534
+ const { authorId, activeVersionId, metadata, status } = updates;
7555
7535
  const updateData = {
7556
7536
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
7557
7537
  };
7558
7538
  if (authorId !== void 0) updateData.authorId = authorId;
7559
- if (activeVersionId !== void 0) {
7560
- updateData.activeVersionId = activeVersionId;
7561
- if (status === void 0) {
7562
- updateData.status = "published";
7563
- }
7564
- }
7539
+ if (activeVersionId !== void 0) updateData.activeVersionId = activeVersionId;
7565
7540
  if (status !== void 0) updateData.status = status;
7566
7541
  if (metadata !== void 0) {
7567
7542
  updateData.metadata = { ...existing.metadata, ...metadata };
@@ -7571,34 +7546,6 @@ var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
7571
7546
  keys: { id },
7572
7547
  data: updateData
7573
7548
  });
7574
- if (hasConfigUpdate) {
7575
- const latestVersion = await this.getLatestVersion(id);
7576
- if (!latestVersion) {
7577
- throw new Error(`No versions found for scorer definition ${id}`);
7578
- }
7579
- const {
7580
- id: _versionId,
7581
- scorerDefinitionId: _scorerDefinitionId,
7582
- versionNumber: _versionNumber,
7583
- changedFields: _changedFields,
7584
- changeMessage: _changeMessage,
7585
- createdAt: _createdAt,
7586
- ...latestConfig
7587
- } = latestVersion;
7588
- const newConfig = { ...latestConfig, ...configFields };
7589
- const changedFields = configFieldNames.filter(
7590
- (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
7591
- );
7592
- const newVersionId = crypto.randomUUID();
7593
- await this.createVersion({
7594
- id: newVersionId,
7595
- scorerDefinitionId: id,
7596
- versionNumber: latestVersion.versionNumber + 1,
7597
- ...newConfig,
7598
- changedFields,
7599
- changeMessage: `Updated ${changedFields.join(", ")}`
7600
- });
7601
- }
7602
7549
  const updated = await this.getById(id);
7603
7550
  if (!updated) {
7604
7551
  throw new error.MastraError({
@@ -7643,10 +7590,14 @@ var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
7643
7590
  }
7644
7591
  async list(args) {
7645
7592
  try {
7646
- const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
7593
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata, status } = args || {};
7647
7594
  const { field, direction } = this.parseOrderBy(orderBy);
7648
7595
  const conditions = [];
7649
7596
  const queryParams = [];
7597
+ if (status) {
7598
+ conditions.push("status = ?");
7599
+ queryParams.push(status);
7600
+ }
7650
7601
  if (authorId !== void 0) {
7651
7602
  conditions.push("authorId = ?");
7652
7603
  queryParams.push(authorId);
@@ -8262,229 +8213,1237 @@ var ScoresLibSQL = class extends storage.ScoresStorage {
8262
8213
  }
8263
8214
  }
8264
8215
  };
8265
- var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
8216
+ var SNAPSHOT_FIELDS = [
8217
+ "name",
8218
+ "description",
8219
+ "instructions",
8220
+ "license",
8221
+ "compatibility",
8222
+ "source",
8223
+ "references",
8224
+ "scripts",
8225
+ "assets",
8226
+ "metadata",
8227
+ "tree"
8228
+ ];
8229
+ var SkillsLibSQL = class extends storage.SkillsStorage {
8266
8230
  #db;
8267
8231
  #client;
8268
- executeWithRetry;
8269
8232
  constructor(config) {
8270
8233
  super();
8271
8234
  const client = resolveClient(config);
8272
- const maxRetries = config.maxRetries ?? 5;
8273
- const initialBackoffMs = config.initialBackoffMs ?? 500;
8274
8235
  this.#client = client;
8275
- this.#db = new LibSQLDB({ client, maxRetries, initialBackoffMs });
8276
- this.executeWithRetry = createExecuteWriteOperationWithRetry({
8277
- logger: this.logger,
8278
- maxRetries,
8279
- initialBackoffMs
8236
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
8237
+ }
8238
+ async init() {
8239
+ await this.#db.createTable({ tableName: storage.TABLE_SKILLS, schema: storage.SKILLS_SCHEMA });
8240
+ await this.#db.createTable({
8241
+ tableName: storage.TABLE_SKILL_VERSIONS,
8242
+ schema: storage.SKILL_VERSIONS_SCHEMA
8280
8243
  });
8281
- this.setupPragmaSettings().catch(
8282
- (err) => this.logger.warn("LibSQL Workflows: Failed to setup PRAGMA settings.", err)
8244
+ await this.#client.execute(
8245
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_skill_versions_skill_version ON "${storage.TABLE_SKILL_VERSIONS}" ("skillId", "versionNumber")`
8283
8246
  );
8284
8247
  }
8285
- parseWorkflowRun(row) {
8286
- let parsedSnapshot = row.snapshot;
8287
- if (typeof parsedSnapshot === "string") {
8288
- try {
8289
- parsedSnapshot = JSON.parse(row.snapshot);
8290
- } catch (e) {
8291
- this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
8292
- }
8293
- }
8294
- return {
8295
- workflowName: row.workflow_name,
8296
- runId: row.run_id,
8297
- snapshot: parsedSnapshot,
8298
- resourceId: row.resourceId,
8299
- createdAt: new Date(row.createdAt),
8300
- updatedAt: new Date(row.updatedAt)
8301
- };
8248
+ async dangerouslyClearAll() {
8249
+ await this.#db.deleteData({ tableName: storage.TABLE_SKILLS });
8250
+ await this.#db.deleteData({ tableName: storage.TABLE_SKILL_VERSIONS });
8302
8251
  }
8303
- async init() {
8304
- const schema = storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT];
8305
- await this.#db.createTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, schema });
8306
- await this.#db.alterTable({
8307
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8308
- schema,
8309
- ifNotExists: ["resourceId"]
8310
- });
8311
- }
8312
- async dangerouslyClearAll() {
8313
- await this.#db.deleteData({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
8252
+ // ==========================================================================
8253
+ // Skill CRUD
8254
+ // ==========================================================================
8255
+ async getById(id) {
8256
+ try {
8257
+ const result = await this.#client.execute({
8258
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILLS)} FROM "${storage.TABLE_SKILLS}" WHERE id = ?`,
8259
+ args: [id]
8260
+ });
8261
+ const row = result.rows?.[0];
8262
+ return row ? this.#parseSkillRow(row) : null;
8263
+ } catch (error$1) {
8264
+ if (error$1 instanceof error.MastraError) throw error$1;
8265
+ throw new error.MastraError(
8266
+ {
8267
+ id: storage.createStorageErrorId("LIBSQL", "GET_SKILL", "FAILED"),
8268
+ domain: error.ErrorDomain.STORAGE,
8269
+ category: error.ErrorCategory.THIRD_PARTY
8270
+ },
8271
+ error$1
8272
+ );
8273
+ }
8314
8274
  }
8315
- async setupPragmaSettings() {
8275
+ async create(input) {
8276
+ const { skill } = input;
8316
8277
  try {
8317
- await this.#client.execute("PRAGMA busy_timeout = 10000;");
8318
- this.logger.debug("LibSQL Workflows: PRAGMA busy_timeout=10000 set.");
8319
- try {
8320
- await this.#client.execute("PRAGMA journal_mode = WAL;");
8321
- this.logger.debug("LibSQL Workflows: PRAGMA journal_mode=WAL set.");
8322
- } catch {
8323
- this.logger.debug("LibSQL Workflows: WAL mode not supported, using default journal mode.");
8324
- }
8278
+ const now = /* @__PURE__ */ new Date();
8279
+ await this.#db.insert({
8280
+ tableName: storage.TABLE_SKILLS,
8281
+ record: {
8282
+ id: skill.id,
8283
+ status: "draft",
8284
+ activeVersionId: null,
8285
+ authorId: skill.authorId ?? null,
8286
+ createdAt: now.toISOString(),
8287
+ updatedAt: now.toISOString()
8288
+ }
8289
+ });
8290
+ const { id: _id, authorId: _authorId, ...snapshotConfig } = skill;
8291
+ const versionId = crypto.randomUUID();
8325
8292
  try {
8326
- await this.#client.execute("PRAGMA synchronous = NORMAL;");
8327
- this.logger.debug("LibSQL Workflows: PRAGMA synchronous=NORMAL set.");
8328
- } catch {
8329
- this.logger.debug("LibSQL Workflows: Failed to set synchronous mode.");
8293
+ await this.createVersion({
8294
+ id: versionId,
8295
+ skillId: skill.id,
8296
+ versionNumber: 1,
8297
+ ...snapshotConfig,
8298
+ changedFields: Object.keys(snapshotConfig),
8299
+ changeMessage: "Initial version"
8300
+ });
8301
+ } catch (versionError) {
8302
+ await this.#db.delete({ tableName: storage.TABLE_SKILLS, keys: { id: skill.id } });
8303
+ throw versionError;
8330
8304
  }
8331
- } catch (err) {
8332
- this.logger.warn("LibSQL Workflows: Failed to set PRAGMA settings.", err);
8305
+ return {
8306
+ id: skill.id,
8307
+ status: "draft",
8308
+ activeVersionId: void 0,
8309
+ authorId: skill.authorId,
8310
+ createdAt: now,
8311
+ updatedAt: now
8312
+ };
8313
+ } catch (error$1) {
8314
+ if (error$1 instanceof error.MastraError) throw error$1;
8315
+ throw new error.MastraError(
8316
+ {
8317
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_SKILL", "FAILED"),
8318
+ domain: error.ErrorDomain.STORAGE,
8319
+ category: error.ErrorCategory.THIRD_PARTY
8320
+ },
8321
+ error$1
8322
+ );
8333
8323
  }
8334
8324
  }
8335
- async updateWorkflowResults({
8336
- workflowName,
8337
- runId,
8338
- stepId,
8339
- result,
8340
- requestContext
8341
- }) {
8342
- return this.executeWithRetry(async () => {
8343
- const tx = await this.#client.transaction("write");
8344
- try {
8345
- const existingSnapshotResult = await tx.execute({
8346
- sql: `SELECT json(snapshot) as snapshot FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8347
- args: [workflowName, runId]
8348
- });
8349
- let snapshot;
8350
- if (!existingSnapshotResult.rows?.[0]) {
8351
- snapshot = {
8352
- context: {},
8353
- activePaths: [],
8354
- timestamp: Date.now(),
8355
- suspendedPaths: {},
8356
- activeStepsPath: {},
8357
- resumeLabels: {},
8358
- serializedStepGraph: [],
8359
- status: "pending",
8360
- value: {},
8361
- waitingPaths: {},
8362
- runId,
8363
- requestContext: {}
8364
- };
8365
- } else {
8366
- const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
8367
- snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
8368
- }
8369
- snapshot.context[stepId] = result;
8370
- snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
8371
- const now = (/* @__PURE__ */ new Date()).toISOString();
8372
- await tx.execute({
8373
- sql: `INSERT INTO ${storage.TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, snapshot, createdAt, updatedAt)
8374
- VALUES (?, ?, jsonb(?), ?, ?)
8375
- ON CONFLICT(workflow_name, run_id)
8376
- DO UPDATE SET snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
8377
- args: [workflowName, runId, JSON.stringify(snapshot), now, now]
8325
+ async update(input) {
8326
+ const { id, ...updates } = input;
8327
+ try {
8328
+ const existing = await this.getById(id);
8329
+ if (!existing) {
8330
+ throw new error.MastraError({
8331
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_SKILL", "NOT_FOUND"),
8332
+ domain: error.ErrorDomain.STORAGE,
8333
+ category: error.ErrorCategory.USER,
8334
+ text: `Skill ${id} not found`,
8335
+ details: { skillId: id }
8378
8336
  });
8379
- await tx.commit();
8380
- return snapshot.context;
8381
- } catch (error) {
8382
- if (!tx.closed) {
8383
- await tx.rollback();
8337
+ }
8338
+ const { authorId, activeVersionId, status, ...configFields } = updates;
8339
+ const configFieldNames = SNAPSHOT_FIELDS;
8340
+ const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
8341
+ const updateData = {
8342
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
8343
+ };
8344
+ if (authorId !== void 0) updateData.authorId = authorId;
8345
+ if (activeVersionId !== void 0) {
8346
+ updateData.activeVersionId = activeVersionId;
8347
+ if (status === void 0) {
8348
+ updateData.status = "published";
8384
8349
  }
8385
- throw error;
8386
8350
  }
8387
- }, "updateWorkflowResults");
8388
- }
8389
- async updateWorkflowState({
8390
- workflowName,
8391
- runId,
8392
- opts
8393
- }) {
8394
- return this.executeWithRetry(async () => {
8395
- const tx = await this.#client.transaction("write");
8396
- try {
8397
- const existingSnapshotResult = await tx.execute({
8398
- sql: `SELECT json(snapshot) as snapshot FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8399
- args: [workflowName, runId]
8400
- });
8401
- if (!existingSnapshotResult.rows?.[0]) {
8402
- await tx.rollback();
8403
- return void 0;
8351
+ if (status !== void 0) updateData.status = status;
8352
+ await this.#db.update({
8353
+ tableName: storage.TABLE_SKILLS,
8354
+ keys: { id },
8355
+ data: updateData
8356
+ });
8357
+ if (hasConfigUpdate) {
8358
+ const latestVersion = await this.getLatestVersion(id);
8359
+ if (!latestVersion) {
8360
+ throw new error.MastraError({
8361
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_SKILL", "NO_VERSIONS"),
8362
+ domain: error.ErrorDomain.STORAGE,
8363
+ category: error.ErrorCategory.USER,
8364
+ text: `No versions found for skill ${id}`,
8365
+ details: { skillId: id }
8366
+ });
8404
8367
  }
8405
- const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
8406
- const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
8407
- if (!snapshot || !snapshot?.context) {
8408
- await tx.rollback();
8409
- throw new Error(`Snapshot not found for runId ${runId}`);
8368
+ const {
8369
+ id: _versionId,
8370
+ skillId: _skillId,
8371
+ versionNumber: _versionNumber,
8372
+ changedFields: _changedFields,
8373
+ changeMessage: _changeMessage,
8374
+ createdAt: _createdAt,
8375
+ ...latestConfig
8376
+ } = latestVersion;
8377
+ const newConfig = { ...latestConfig, ...configFields };
8378
+ const changedFields = configFieldNames.filter(
8379
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
8380
+ );
8381
+ if (changedFields.length > 0) {
8382
+ const newVersionId = crypto.randomUUID();
8383
+ await this.createVersion({
8384
+ id: newVersionId,
8385
+ skillId: id,
8386
+ versionNumber: latestVersion.versionNumber + 1,
8387
+ ...newConfig,
8388
+ changedFields,
8389
+ changeMessage: `Updated ${changedFields.join(", ")}`
8390
+ });
8410
8391
  }
8411
- const updatedSnapshot = { ...snapshot, ...opts };
8412
- await tx.execute({
8413
- sql: `UPDATE ${storage.TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
8414
- args: [JSON.stringify(updatedSnapshot), workflowName, runId]
8392
+ }
8393
+ const updated = await this.getById(id);
8394
+ if (!updated) {
8395
+ throw new error.MastraError({
8396
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_SKILL", "NOT_FOUND_AFTER_UPDATE"),
8397
+ domain: error.ErrorDomain.STORAGE,
8398
+ category: error.ErrorCategory.SYSTEM,
8399
+ text: `Skill ${id} not found after update`,
8400
+ details: { id }
8415
8401
  });
8416
- await tx.commit();
8417
- return updatedSnapshot;
8418
- } catch (error) {
8419
- if (!tx.closed) {
8420
- await tx.rollback();
8421
- }
8422
- throw error;
8423
8402
  }
8424
- }, "updateWorkflowState");
8425
- }
8426
- async persistWorkflowSnapshot({
8427
- workflowName,
8428
- runId,
8429
- resourceId,
8430
- snapshot,
8431
- createdAt,
8432
- updatedAt
8433
- }) {
8434
- const now = /* @__PURE__ */ new Date();
8435
- const data = {
8436
- workflow_name: workflowName,
8437
- run_id: runId,
8438
- resourceId,
8439
- snapshot,
8440
- createdAt: createdAt ?? now,
8441
- updatedAt: updatedAt ?? now
8442
- };
8443
- this.logger.debug("Persisting workflow snapshot", { workflowName, runId, data });
8444
- await this.#db.insert({
8445
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8446
- record: data
8447
- });
8403
+ return updated;
8404
+ } catch (error$1) {
8405
+ if (error$1 instanceof error.MastraError) throw error$1;
8406
+ throw new error.MastraError(
8407
+ {
8408
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_SKILL", "FAILED"),
8409
+ domain: error.ErrorDomain.STORAGE,
8410
+ category: error.ErrorCategory.THIRD_PARTY
8411
+ },
8412
+ error$1
8413
+ );
8414
+ }
8448
8415
  }
8449
- async loadWorkflowSnapshot({
8450
- workflowName,
8451
- runId
8452
- }) {
8453
- this.logger.debug("Loading workflow snapshot", { workflowName, runId });
8454
- const d = await this.#db.select({
8455
- tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8456
- keys: { workflow_name: workflowName, run_id: runId }
8416
+ async delete(id) {
8417
+ try {
8418
+ await this.deleteVersionsByParentId(id);
8419
+ await this.#client.execute({
8420
+ sql: `DELETE FROM "${storage.TABLE_SKILLS}" WHERE "id" = ?`,
8421
+ args: [id]
8422
+ });
8423
+ } catch (error$1) {
8424
+ if (error$1 instanceof error.MastraError) throw error$1;
8425
+ throw new error.MastraError(
8426
+ {
8427
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_SKILL", "FAILED"),
8428
+ domain: error.ErrorDomain.STORAGE,
8429
+ category: error.ErrorCategory.THIRD_PARTY
8430
+ },
8431
+ error$1
8432
+ );
8433
+ }
8434
+ }
8435
+ async list(args) {
8436
+ try {
8437
+ const { page = 0, perPage: perPageInput, orderBy, authorId } = args || {};
8438
+ const { field, direction } = this.parseOrderBy(orderBy);
8439
+ const conditions = [];
8440
+ const queryParams = [];
8441
+ if (authorId !== void 0) {
8442
+ conditions.push("authorId = ?");
8443
+ queryParams.push(authorId);
8444
+ }
8445
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
8446
+ const countResult = await this.#client.execute({
8447
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_SKILLS}" ${whereClause}`,
8448
+ args: queryParams
8449
+ });
8450
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
8451
+ if (total === 0) {
8452
+ return {
8453
+ skills: [],
8454
+ total: 0,
8455
+ page,
8456
+ perPage: perPageInput ?? 100,
8457
+ hasMore: false
8458
+ };
8459
+ }
8460
+ const perPage = storage.normalizePerPage(perPageInput, 100);
8461
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
8462
+ const limitValue = perPageInput === false ? total : perPage;
8463
+ const end = perPageInput === false ? total : start + perPage;
8464
+ const result = await this.#client.execute({
8465
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILLS)} FROM "${storage.TABLE_SKILLS}" ${whereClause} ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
8466
+ args: [...queryParams, limitValue, start]
8467
+ });
8468
+ const skills = result.rows?.map((row) => this.#parseSkillRow(row)) ?? [];
8469
+ return {
8470
+ skills,
8471
+ total,
8472
+ page,
8473
+ perPage: perPageForResponse,
8474
+ hasMore: end < total
8475
+ };
8476
+ } catch (error$1) {
8477
+ if (error$1 instanceof error.MastraError) throw error$1;
8478
+ throw new error.MastraError(
8479
+ {
8480
+ id: storage.createStorageErrorId("LIBSQL", "LIST_SKILLS", "FAILED"),
8481
+ domain: error.ErrorDomain.STORAGE,
8482
+ category: error.ErrorCategory.THIRD_PARTY
8483
+ },
8484
+ error$1
8485
+ );
8486
+ }
8487
+ }
8488
+ // ==========================================================================
8489
+ // Skill Version Methods
8490
+ // ==========================================================================
8491
+ async createVersion(input) {
8492
+ try {
8493
+ const now = /* @__PURE__ */ new Date();
8494
+ await this.#client.execute({
8495
+ sql: `INSERT INTO "${storage.TABLE_SKILL_VERSIONS}" (
8496
+ id, "skillId", "versionNumber",
8497
+ name, description, instructions, license, compatibility,
8498
+ source, "references", scripts, assets, metadata, tree,
8499
+ "changedFields", "changeMessage", "createdAt"
8500
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8501
+ args: [
8502
+ input.id,
8503
+ input.skillId,
8504
+ input.versionNumber,
8505
+ input.name,
8506
+ input.description ?? null,
8507
+ input.instructions ?? null,
8508
+ input.license ?? null,
8509
+ input.compatibility ? JSON.stringify(input.compatibility) : null,
8510
+ input.source ? JSON.stringify(input.source) : null,
8511
+ input.references ? JSON.stringify(input.references) : null,
8512
+ input.scripts ? JSON.stringify(input.scripts) : null,
8513
+ input.assets ? JSON.stringify(input.assets) : null,
8514
+ input.metadata ? JSON.stringify(input.metadata) : null,
8515
+ input.tree ? JSON.stringify(input.tree) : null,
8516
+ input.changedFields ? JSON.stringify(input.changedFields) : null,
8517
+ input.changeMessage ?? null,
8518
+ now.toISOString()
8519
+ ]
8520
+ });
8521
+ return {
8522
+ ...input,
8523
+ createdAt: now
8524
+ };
8525
+ } catch (error$1) {
8526
+ if (error$1 instanceof error.MastraError) throw error$1;
8527
+ throw new error.MastraError(
8528
+ {
8529
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_SKILL_VERSION", "FAILED"),
8530
+ domain: error.ErrorDomain.STORAGE,
8531
+ category: error.ErrorCategory.THIRD_PARTY
8532
+ },
8533
+ error$1
8534
+ );
8535
+ }
8536
+ }
8537
+ async getVersion(id) {
8538
+ try {
8539
+ const result = await this.#client.execute({
8540
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_VERSIONS)} FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE id = ?`,
8541
+ args: [id]
8542
+ });
8543
+ const row = result.rows?.[0];
8544
+ return row ? this.#parseVersionRow(row) : null;
8545
+ } catch (error$1) {
8546
+ if (error$1 instanceof error.MastraError) throw error$1;
8547
+ throw new error.MastraError(
8548
+ {
8549
+ id: storage.createStorageErrorId("LIBSQL", "GET_SKILL_VERSION", "FAILED"),
8550
+ domain: error.ErrorDomain.STORAGE,
8551
+ category: error.ErrorCategory.THIRD_PARTY
8552
+ },
8553
+ error$1
8554
+ );
8555
+ }
8556
+ }
8557
+ async getVersionByNumber(skillId, versionNumber) {
8558
+ try {
8559
+ const result = await this.#client.execute({
8560
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_VERSIONS)} FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE skillId = ? AND versionNumber = ?`,
8561
+ args: [skillId, versionNumber]
8562
+ });
8563
+ const row = result.rows?.[0];
8564
+ return row ? this.#parseVersionRow(row) : null;
8565
+ } catch (error$1) {
8566
+ if (error$1 instanceof error.MastraError) throw error$1;
8567
+ throw new error.MastraError(
8568
+ {
8569
+ id: storage.createStorageErrorId("LIBSQL", "GET_SKILL_VERSION_BY_NUMBER", "FAILED"),
8570
+ domain: error.ErrorDomain.STORAGE,
8571
+ category: error.ErrorCategory.THIRD_PARTY
8572
+ },
8573
+ error$1
8574
+ );
8575
+ }
8576
+ }
8577
+ async getLatestVersion(skillId) {
8578
+ try {
8579
+ const result = await this.#client.execute({
8580
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_VERSIONS)} FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE skillId = ? ORDER BY versionNumber DESC LIMIT 1`,
8581
+ args: [skillId]
8582
+ });
8583
+ const row = result.rows?.[0];
8584
+ return row ? this.#parseVersionRow(row) : null;
8585
+ } catch (error$1) {
8586
+ if (error$1 instanceof error.MastraError) throw error$1;
8587
+ throw new error.MastraError(
8588
+ {
8589
+ id: storage.createStorageErrorId("LIBSQL", "GET_LATEST_SKILL_VERSION", "FAILED"),
8590
+ domain: error.ErrorDomain.STORAGE,
8591
+ category: error.ErrorCategory.THIRD_PARTY
8592
+ },
8593
+ error$1
8594
+ );
8595
+ }
8596
+ }
8597
+ async listVersions(input) {
8598
+ try {
8599
+ const { skillId, page = 0, perPage: perPageInput, orderBy } = input;
8600
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
8601
+ const countResult = await this.#client.execute({
8602
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE skillId = ?`,
8603
+ args: [skillId]
8604
+ });
8605
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
8606
+ if (total === 0) {
8607
+ return {
8608
+ versions: [],
8609
+ total: 0,
8610
+ page,
8611
+ perPage: perPageInput ?? 20,
8612
+ hasMore: false
8613
+ };
8614
+ }
8615
+ const perPage = storage.normalizePerPage(perPageInput, 20);
8616
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
8617
+ const limitValue = perPageInput === false ? total : perPage;
8618
+ const end = perPageInput === false ? total : start + perPage;
8619
+ const result = await this.#client.execute({
8620
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_SKILL_VERSIONS)} FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE skillId = ? ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
8621
+ args: [skillId, limitValue, start]
8622
+ });
8623
+ const versions = result.rows?.map((row) => this.#parseVersionRow(row)) ?? [];
8624
+ return {
8625
+ versions,
8626
+ total,
8627
+ page,
8628
+ perPage: perPageForResponse,
8629
+ hasMore: end < total
8630
+ };
8631
+ } catch (error$1) {
8632
+ if (error$1 instanceof error.MastraError) throw error$1;
8633
+ throw new error.MastraError(
8634
+ {
8635
+ id: storage.createStorageErrorId("LIBSQL", "LIST_SKILL_VERSIONS", "FAILED"),
8636
+ domain: error.ErrorDomain.STORAGE,
8637
+ category: error.ErrorCategory.THIRD_PARTY
8638
+ },
8639
+ error$1
8640
+ );
8641
+ }
8642
+ }
8643
+ async deleteVersion(id) {
8644
+ try {
8645
+ await this.#client.execute({
8646
+ sql: `DELETE FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE "id" = ?`,
8647
+ args: [id]
8648
+ });
8649
+ } catch (error$1) {
8650
+ if (error$1 instanceof error.MastraError) throw error$1;
8651
+ throw new error.MastraError(
8652
+ {
8653
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_SKILL_VERSION", "FAILED"),
8654
+ domain: error.ErrorDomain.STORAGE,
8655
+ category: error.ErrorCategory.THIRD_PARTY
8656
+ },
8657
+ error$1
8658
+ );
8659
+ }
8660
+ }
8661
+ async deleteVersionsByParentId(entityId) {
8662
+ try {
8663
+ await this.#client.execute({
8664
+ sql: `DELETE FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE "skillId" = ?`,
8665
+ args: [entityId]
8666
+ });
8667
+ } catch (error$1) {
8668
+ if (error$1 instanceof error.MastraError) throw error$1;
8669
+ throw new error.MastraError(
8670
+ {
8671
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_SKILL_VERSIONS_BY_SKILL", "FAILED"),
8672
+ domain: error.ErrorDomain.STORAGE,
8673
+ category: error.ErrorCategory.THIRD_PARTY
8674
+ },
8675
+ error$1
8676
+ );
8677
+ }
8678
+ }
8679
+ async countVersions(skillId) {
8680
+ try {
8681
+ const result = await this.#client.execute({
8682
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_SKILL_VERSIONS}" WHERE skillId = ?`,
8683
+ args: [skillId]
8684
+ });
8685
+ return Number(result.rows?.[0]?.count ?? 0);
8686
+ } catch (error$1) {
8687
+ if (error$1 instanceof error.MastraError) throw error$1;
8688
+ throw new error.MastraError(
8689
+ {
8690
+ id: storage.createStorageErrorId("LIBSQL", "COUNT_SKILL_VERSIONS", "FAILED"),
8691
+ domain: error.ErrorDomain.STORAGE,
8692
+ category: error.ErrorCategory.THIRD_PARTY
8693
+ },
8694
+ error$1
8695
+ );
8696
+ }
8697
+ }
8698
+ // ==========================================================================
8699
+ // Private Helpers
8700
+ // ==========================================================================
8701
+ #parseSkillRow(row) {
8702
+ return {
8703
+ id: row.id,
8704
+ status: row.status ?? "draft",
8705
+ activeVersionId: row.activeVersionId ?? void 0,
8706
+ authorId: row.authorId ?? void 0,
8707
+ createdAt: new Date(row.createdAt),
8708
+ updatedAt: new Date(row.updatedAt)
8709
+ };
8710
+ }
8711
+ #parseVersionRow(row) {
8712
+ const safeParseJSON = (val) => {
8713
+ if (val === null || val === void 0) return void 0;
8714
+ if (typeof val === "string") {
8715
+ try {
8716
+ return JSON.parse(val);
8717
+ } catch {
8718
+ return val;
8719
+ }
8720
+ }
8721
+ return val;
8722
+ };
8723
+ return {
8724
+ id: row.id,
8725
+ skillId: row.skillId,
8726
+ versionNumber: Number(row.versionNumber),
8727
+ name: row.name,
8728
+ description: row.description ?? void 0,
8729
+ instructions: row.instructions ?? void 0,
8730
+ license: row.license ?? void 0,
8731
+ compatibility: safeParseJSON(row.compatibility),
8732
+ source: safeParseJSON(row.source),
8733
+ references: safeParseJSON(row.references),
8734
+ scripts: safeParseJSON(row.scripts),
8735
+ assets: safeParseJSON(row.assets),
8736
+ metadata: safeParseJSON(row.metadata),
8737
+ tree: safeParseJSON(row.tree),
8738
+ changedFields: safeParseJSON(row.changedFields),
8739
+ changeMessage: row.changeMessage ?? void 0,
8740
+ createdAt: new Date(row.createdAt)
8741
+ };
8742
+ }
8743
+ };
8744
+ var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
8745
+ #db;
8746
+ #client;
8747
+ executeWithRetry;
8748
+ constructor(config) {
8749
+ super();
8750
+ const client = resolveClient(config);
8751
+ const maxRetries = config.maxRetries ?? 5;
8752
+ const initialBackoffMs = config.initialBackoffMs ?? 500;
8753
+ this.#client = client;
8754
+ this.#db = new LibSQLDB({ client, maxRetries, initialBackoffMs });
8755
+ this.executeWithRetry = createExecuteWriteOperationWithRetry({
8756
+ logger: this.logger,
8757
+ maxRetries,
8758
+ initialBackoffMs
8759
+ });
8760
+ this.setupPragmaSettings().catch(
8761
+ (err) => this.logger.warn("LibSQL Workflows: Failed to setup PRAGMA settings.", err)
8762
+ );
8763
+ }
8764
+ parseWorkflowRun(row) {
8765
+ let parsedSnapshot = row.snapshot;
8766
+ if (typeof parsedSnapshot === "string") {
8767
+ try {
8768
+ parsedSnapshot = JSON.parse(row.snapshot);
8769
+ } catch (e) {
8770
+ this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
8771
+ }
8772
+ }
8773
+ return {
8774
+ workflowName: row.workflow_name,
8775
+ runId: row.run_id,
8776
+ snapshot: parsedSnapshot,
8777
+ resourceId: row.resourceId,
8778
+ createdAt: new Date(row.createdAt),
8779
+ updatedAt: new Date(row.updatedAt)
8780
+ };
8781
+ }
8782
+ async init() {
8783
+ const schema = storage.TABLE_SCHEMAS[storage.TABLE_WORKFLOW_SNAPSHOT];
8784
+ await this.#db.createTable({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, schema });
8785
+ await this.#db.alterTable({
8786
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8787
+ schema,
8788
+ ifNotExists: ["resourceId"]
8789
+ });
8790
+ }
8791
+ async dangerouslyClearAll() {
8792
+ await this.#db.deleteData({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
8793
+ }
8794
+ async setupPragmaSettings() {
8795
+ try {
8796
+ await this.#client.execute("PRAGMA busy_timeout = 10000;");
8797
+ this.logger.debug("LibSQL Workflows: PRAGMA busy_timeout=10000 set.");
8798
+ try {
8799
+ await this.#client.execute("PRAGMA journal_mode = WAL;");
8800
+ this.logger.debug("LibSQL Workflows: PRAGMA journal_mode=WAL set.");
8801
+ } catch {
8802
+ this.logger.debug("LibSQL Workflows: WAL mode not supported, using default journal mode.");
8803
+ }
8804
+ try {
8805
+ await this.#client.execute("PRAGMA synchronous = NORMAL;");
8806
+ this.logger.debug("LibSQL Workflows: PRAGMA synchronous=NORMAL set.");
8807
+ } catch {
8808
+ this.logger.debug("LibSQL Workflows: Failed to set synchronous mode.");
8809
+ }
8810
+ } catch (err) {
8811
+ this.logger.warn("LibSQL Workflows: Failed to set PRAGMA settings.", err);
8812
+ }
8813
+ }
8814
+ async updateWorkflowResults({
8815
+ workflowName,
8816
+ runId,
8817
+ stepId,
8818
+ result,
8819
+ requestContext
8820
+ }) {
8821
+ return this.executeWithRetry(async () => {
8822
+ const tx = await this.#client.transaction("write");
8823
+ try {
8824
+ const existingSnapshotResult = await tx.execute({
8825
+ sql: `SELECT json(snapshot) as snapshot FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8826
+ args: [workflowName, runId]
8827
+ });
8828
+ let snapshot;
8829
+ if (!existingSnapshotResult.rows?.[0]) {
8830
+ snapshot = {
8831
+ context: {},
8832
+ activePaths: [],
8833
+ timestamp: Date.now(),
8834
+ suspendedPaths: {},
8835
+ activeStepsPath: {},
8836
+ resumeLabels: {},
8837
+ serializedStepGraph: [],
8838
+ status: "pending",
8839
+ value: {},
8840
+ waitingPaths: {},
8841
+ runId,
8842
+ requestContext: {}
8843
+ };
8844
+ } else {
8845
+ const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
8846
+ snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
8847
+ }
8848
+ snapshot.context[stepId] = result;
8849
+ snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
8850
+ const now = (/* @__PURE__ */ new Date()).toISOString();
8851
+ await tx.execute({
8852
+ sql: `INSERT INTO ${storage.TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, snapshot, createdAt, updatedAt)
8853
+ VALUES (?, ?, jsonb(?), ?, ?)
8854
+ ON CONFLICT(workflow_name, run_id)
8855
+ DO UPDATE SET snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
8856
+ args: [workflowName, runId, JSON.stringify(snapshot), now, now]
8857
+ });
8858
+ await tx.commit();
8859
+ return snapshot.context;
8860
+ } catch (error) {
8861
+ if (!tx.closed) {
8862
+ await tx.rollback();
8863
+ }
8864
+ throw error;
8865
+ }
8866
+ }, "updateWorkflowResults");
8867
+ }
8868
+ async updateWorkflowState({
8869
+ workflowName,
8870
+ runId,
8871
+ opts
8872
+ }) {
8873
+ return this.executeWithRetry(async () => {
8874
+ const tx = await this.#client.transaction("write");
8875
+ try {
8876
+ const existingSnapshotResult = await tx.execute({
8877
+ sql: `SELECT json(snapshot) as snapshot FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8878
+ args: [workflowName, runId]
8879
+ });
8880
+ if (!existingSnapshotResult.rows?.[0]) {
8881
+ await tx.rollback();
8882
+ return void 0;
8883
+ }
8884
+ const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
8885
+ const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
8886
+ if (!snapshot || !snapshot?.context) {
8887
+ await tx.rollback();
8888
+ throw new Error(`Snapshot not found for runId ${runId}`);
8889
+ }
8890
+ const updatedSnapshot = { ...snapshot, ...opts };
8891
+ await tx.execute({
8892
+ sql: `UPDATE ${storage.TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
8893
+ args: [JSON.stringify(updatedSnapshot), workflowName, runId]
8894
+ });
8895
+ await tx.commit();
8896
+ return updatedSnapshot;
8897
+ } catch (error) {
8898
+ if (!tx.closed) {
8899
+ await tx.rollback();
8900
+ }
8901
+ throw error;
8902
+ }
8903
+ }, "updateWorkflowState");
8904
+ }
8905
+ async persistWorkflowSnapshot({
8906
+ workflowName,
8907
+ runId,
8908
+ resourceId,
8909
+ snapshot,
8910
+ createdAt,
8911
+ updatedAt
8912
+ }) {
8913
+ const now = /* @__PURE__ */ new Date();
8914
+ const data = {
8915
+ workflow_name: workflowName,
8916
+ run_id: runId,
8917
+ resourceId,
8918
+ snapshot,
8919
+ createdAt: createdAt ?? now,
8920
+ updatedAt: updatedAt ?? now
8921
+ };
8922
+ this.logger.debug("Persisting workflow snapshot", { workflowName, runId, data });
8923
+ await this.#db.insert({
8924
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8925
+ record: data
8926
+ });
8927
+ }
8928
+ async loadWorkflowSnapshot({
8929
+ workflowName,
8930
+ runId
8931
+ }) {
8932
+ this.logger.debug("Loading workflow snapshot", { workflowName, runId });
8933
+ const d = await this.#db.select({
8934
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
8935
+ keys: { workflow_name: workflowName, run_id: runId }
8936
+ });
8937
+ return d ? d.snapshot : null;
8938
+ }
8939
+ async getWorkflowRunById({
8940
+ runId,
8941
+ workflowName
8942
+ }) {
8943
+ const conditions = [];
8944
+ const args = [];
8945
+ if (runId) {
8946
+ conditions.push("run_id = ?");
8947
+ args.push(runId);
8948
+ }
8949
+ if (workflowName) {
8950
+ conditions.push("workflow_name = ?");
8951
+ args.push(workflowName);
8952
+ }
8953
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
8954
+ try {
8955
+ const result = await this.#client.execute({
8956
+ sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC LIMIT 1`,
8957
+ args
8958
+ });
8959
+ if (!result.rows?.[0]) {
8960
+ return null;
8961
+ }
8962
+ return this.parseWorkflowRun(result.rows[0]);
8963
+ } catch (error$1) {
8964
+ throw new error.MastraError(
8965
+ {
8966
+ id: storage.createStorageErrorId("LIBSQL", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
8967
+ domain: error.ErrorDomain.STORAGE,
8968
+ category: error.ErrorCategory.THIRD_PARTY
8969
+ },
8970
+ error$1
8971
+ );
8972
+ }
8973
+ }
8974
+ async deleteWorkflowRunById({ runId, workflowName }) {
8975
+ return this.executeWithRetry(async () => {
8976
+ try {
8977
+ await this.#client.execute({
8978
+ sql: `DELETE FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8979
+ args: [workflowName, runId]
8980
+ });
8981
+ } catch (error$1) {
8982
+ throw new error.MastraError(
8983
+ {
8984
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
8985
+ domain: error.ErrorDomain.STORAGE,
8986
+ category: error.ErrorCategory.THIRD_PARTY,
8987
+ details: { runId, workflowName }
8988
+ },
8989
+ error$1
8990
+ );
8991
+ }
8992
+ }, "deleteWorkflowRunById");
8993
+ }
8994
+ async listWorkflowRuns({
8995
+ workflowName,
8996
+ fromDate,
8997
+ toDate,
8998
+ page,
8999
+ perPage,
9000
+ resourceId,
9001
+ status
9002
+ } = {}) {
9003
+ try {
9004
+ const conditions = [];
9005
+ const args = [];
9006
+ if (workflowName) {
9007
+ conditions.push("workflow_name = ?");
9008
+ args.push(workflowName);
9009
+ }
9010
+ if (status) {
9011
+ conditions.push("json_extract(snapshot, '$.status') = ?");
9012
+ args.push(status);
9013
+ }
9014
+ if (fromDate) {
9015
+ conditions.push("createdAt >= ?");
9016
+ args.push(fromDate.toISOString());
9017
+ }
9018
+ if (toDate) {
9019
+ conditions.push("createdAt <= ?");
9020
+ args.push(toDate.toISOString());
9021
+ }
9022
+ if (resourceId) {
9023
+ const hasResourceId = await this.#db.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
9024
+ if (hasResourceId) {
9025
+ conditions.push("resourceId = ?");
9026
+ args.push(resourceId);
9027
+ } else {
9028
+ this.logger.warn(`[${storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
9029
+ }
9030
+ }
9031
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
9032
+ let total = 0;
9033
+ const usePagination = typeof perPage === "number" && typeof page === "number";
9034
+ if (usePagination) {
9035
+ const countResult = await this.#client.execute({
9036
+ sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
9037
+ args
9038
+ });
9039
+ total = Number(countResult.rows?.[0]?.count ?? 0);
9040
+ }
9041
+ const normalizedPerPage = usePagination ? storage.normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
9042
+ const offset = usePagination ? page * normalizedPerPage : 0;
9043
+ const result = await this.#client.execute({
9044
+ sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC${usePagination ? ` LIMIT ? OFFSET ?` : ""}`,
9045
+ args: usePagination ? [...args, normalizedPerPage, offset] : args
9046
+ });
9047
+ const runs = (result.rows || []).map((row) => this.parseWorkflowRun(row));
9048
+ return { runs, total: total || runs.length };
9049
+ } catch (error$1) {
9050
+ throw new error.MastraError(
9051
+ {
9052
+ id: storage.createStorageErrorId("LIBSQL", "LIST_WORKFLOW_RUNS", "FAILED"),
9053
+ domain: error.ErrorDomain.STORAGE,
9054
+ category: error.ErrorCategory.THIRD_PARTY
9055
+ },
9056
+ error$1
9057
+ );
9058
+ }
9059
+ }
9060
+ };
9061
+ var SNAPSHOT_FIELDS2 = [
9062
+ "name",
9063
+ "description",
9064
+ "filesystem",
9065
+ "sandbox",
9066
+ "mounts",
9067
+ "search",
9068
+ "skills",
9069
+ "tools",
9070
+ "autoSync",
9071
+ "operationTimeout"
9072
+ ];
9073
+ var WorkspacesLibSQL = class extends storage.WorkspacesStorage {
9074
+ #db;
9075
+ #client;
9076
+ constructor(config) {
9077
+ super();
9078
+ const client = resolveClient(config);
9079
+ this.#client = client;
9080
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
9081
+ }
9082
+ async init() {
9083
+ await this.#db.createTable({ tableName: storage.TABLE_WORKSPACES, schema: storage.WORKSPACES_SCHEMA });
9084
+ await this.#db.createTable({
9085
+ tableName: storage.TABLE_WORKSPACE_VERSIONS,
9086
+ schema: storage.WORKSPACE_VERSIONS_SCHEMA
8457
9087
  });
8458
- return d ? d.snapshot : null;
9088
+ await this.#client.execute(
9089
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_workspace_versions_workspace_version ON "${storage.TABLE_WORKSPACE_VERSIONS}" ("workspaceId", "versionNumber")`
9090
+ );
9091
+ }
9092
+ async dangerouslyClearAll() {
9093
+ await this.#db.deleteData({ tableName: storage.TABLE_WORKSPACES });
9094
+ await this.#db.deleteData({ tableName: storage.TABLE_WORKSPACE_VERSIONS });
9095
+ }
9096
+ // ==========================================================================
9097
+ // Workspace CRUD
9098
+ // ==========================================================================
9099
+ async getById(id) {
9100
+ try {
9101
+ const result = await this.#client.execute({
9102
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACES)} FROM "${storage.TABLE_WORKSPACES}" WHERE id = ?`,
9103
+ args: [id]
9104
+ });
9105
+ const row = result.rows?.[0];
9106
+ return row ? this.#parseWorkspaceRow(row) : null;
9107
+ } catch (error$1) {
9108
+ if (error$1 instanceof error.MastraError) throw error$1;
9109
+ throw new error.MastraError(
9110
+ {
9111
+ id: storage.createStorageErrorId("LIBSQL", "GET_WORKSPACE", "FAILED"),
9112
+ domain: error.ErrorDomain.STORAGE,
9113
+ category: error.ErrorCategory.THIRD_PARTY
9114
+ },
9115
+ error$1
9116
+ );
9117
+ }
9118
+ }
9119
+ async create(input) {
9120
+ const { workspace } = input;
9121
+ try {
9122
+ const now = /* @__PURE__ */ new Date();
9123
+ await this.#db.insert({
9124
+ tableName: storage.TABLE_WORKSPACES,
9125
+ record: {
9126
+ id: workspace.id,
9127
+ status: "draft",
9128
+ activeVersionId: null,
9129
+ authorId: workspace.authorId ?? null,
9130
+ metadata: workspace.metadata ?? null,
9131
+ createdAt: now.toISOString(),
9132
+ updatedAt: now.toISOString()
9133
+ }
9134
+ });
9135
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = workspace;
9136
+ const versionId = crypto.randomUUID();
9137
+ try {
9138
+ await this.createVersion({
9139
+ id: versionId,
9140
+ workspaceId: workspace.id,
9141
+ versionNumber: 1,
9142
+ ...snapshotConfig,
9143
+ changedFields: Object.keys(snapshotConfig),
9144
+ changeMessage: "Initial version"
9145
+ });
9146
+ } catch (versionError) {
9147
+ await this.#db.delete({ tableName: storage.TABLE_WORKSPACES, keys: { id: workspace.id } });
9148
+ throw versionError;
9149
+ }
9150
+ return {
9151
+ id: workspace.id,
9152
+ status: "draft",
9153
+ activeVersionId: void 0,
9154
+ authorId: workspace.authorId,
9155
+ metadata: workspace.metadata,
9156
+ createdAt: now,
9157
+ updatedAt: now
9158
+ };
9159
+ } catch (error$1) {
9160
+ if (error$1 instanceof error.MastraError) throw error$1;
9161
+ throw new error.MastraError(
9162
+ {
9163
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_WORKSPACE", "FAILED"),
9164
+ domain: error.ErrorDomain.STORAGE,
9165
+ category: error.ErrorCategory.THIRD_PARTY
9166
+ },
9167
+ error$1
9168
+ );
9169
+ }
9170
+ }
9171
+ async update(input) {
9172
+ const { id, ...updates } = input;
9173
+ try {
9174
+ const existing = await this.getById(id);
9175
+ if (!existing) {
9176
+ throw new error.MastraError({
9177
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_WORKSPACE", "NOT_FOUND"),
9178
+ domain: error.ErrorDomain.STORAGE,
9179
+ category: error.ErrorCategory.USER,
9180
+ text: `Workspace ${id} not found`,
9181
+ details: { workspaceId: id }
9182
+ });
9183
+ }
9184
+ const { authorId, activeVersionId, metadata, status, ...configFields } = updates;
9185
+ const configFieldNames = SNAPSHOT_FIELDS2;
9186
+ const hasConfigUpdate = configFieldNames.some((field) => field in configFields);
9187
+ const updateData = {
9188
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
9189
+ };
9190
+ if (authorId !== void 0) updateData.authorId = authorId;
9191
+ if (activeVersionId !== void 0) {
9192
+ updateData.activeVersionId = activeVersionId;
9193
+ if (status === void 0) {
9194
+ updateData.status = "published";
9195
+ }
9196
+ }
9197
+ if (status !== void 0) updateData.status = status;
9198
+ if (metadata !== void 0) {
9199
+ updateData.metadata = { ...existing.metadata || {}, ...metadata };
9200
+ }
9201
+ await this.#db.update({
9202
+ tableName: storage.TABLE_WORKSPACES,
9203
+ keys: { id },
9204
+ data: updateData
9205
+ });
9206
+ if (hasConfigUpdate) {
9207
+ const latestVersion = await this.getLatestVersion(id);
9208
+ if (!latestVersion) {
9209
+ throw new Error(`No versions found for workspace ${id}`);
9210
+ }
9211
+ const {
9212
+ id: _versionId,
9213
+ workspaceId: _workspaceId,
9214
+ versionNumber: _versionNumber,
9215
+ changedFields: _changedFields,
9216
+ changeMessage: _changeMessage,
9217
+ createdAt: _createdAt,
9218
+ ...latestConfig
9219
+ } = latestVersion;
9220
+ const newConfig = { ...latestConfig, ...configFields };
9221
+ const changedFields = configFieldNames.filter(
9222
+ (field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field])
9223
+ );
9224
+ if (changedFields.length > 0) {
9225
+ const newVersionId = crypto.randomUUID();
9226
+ await this.createVersion({
9227
+ id: newVersionId,
9228
+ workspaceId: id,
9229
+ versionNumber: latestVersion.versionNumber + 1,
9230
+ ...newConfig,
9231
+ changedFields,
9232
+ changeMessage: `Updated ${changedFields.join(", ")}`
9233
+ });
9234
+ }
9235
+ }
9236
+ const updated = await this.getById(id);
9237
+ if (!updated) {
9238
+ throw new error.MastraError({
9239
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_WORKSPACE", "NOT_FOUND_AFTER_UPDATE"),
9240
+ domain: error.ErrorDomain.STORAGE,
9241
+ category: error.ErrorCategory.SYSTEM,
9242
+ text: `Workspace ${id} not found after update`,
9243
+ details: { id }
9244
+ });
9245
+ }
9246
+ return updated;
9247
+ } catch (error$1) {
9248
+ if (error$1 instanceof error.MastraError) throw error$1;
9249
+ throw new error.MastraError(
9250
+ {
9251
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_WORKSPACE", "FAILED"),
9252
+ domain: error.ErrorDomain.STORAGE,
9253
+ category: error.ErrorCategory.THIRD_PARTY
9254
+ },
9255
+ error$1
9256
+ );
9257
+ }
9258
+ }
9259
+ async delete(id) {
9260
+ try {
9261
+ await this.deleteVersionsByParentId(id);
9262
+ await this.#client.execute({
9263
+ sql: `DELETE FROM "${storage.TABLE_WORKSPACES}" WHERE "id" = ?`,
9264
+ args: [id]
9265
+ });
9266
+ } catch (error$1) {
9267
+ if (error$1 instanceof error.MastraError) throw error$1;
9268
+ throw new error.MastraError(
9269
+ {
9270
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_WORKSPACE", "FAILED"),
9271
+ domain: error.ErrorDomain.STORAGE,
9272
+ category: error.ErrorCategory.THIRD_PARTY
9273
+ },
9274
+ error$1
9275
+ );
9276
+ }
9277
+ }
9278
+ async list(args) {
9279
+ try {
9280
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
9281
+ const { field, direction } = this.parseOrderBy(orderBy);
9282
+ const conditions = [];
9283
+ const queryParams = [];
9284
+ if (authorId !== void 0) {
9285
+ conditions.push("authorId = ?");
9286
+ queryParams.push(authorId);
9287
+ }
9288
+ if (metadata && Object.keys(metadata).length > 0) {
9289
+ for (const [key, value] of Object.entries(metadata)) {
9290
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
9291
+ throw new error.MastraError({
9292
+ id: storage.createStorageErrorId("LIBSQL", "LIST_WORKSPACES", "INVALID_METADATA_KEY"),
9293
+ domain: error.ErrorDomain.STORAGE,
9294
+ category: error.ErrorCategory.USER,
9295
+ text: `Invalid metadata key: ${key}. Keys must be alphanumeric with underscores.`,
9296
+ details: { key }
9297
+ });
9298
+ }
9299
+ conditions.push(`json_extract(metadata, '$.${key}') = ?`);
9300
+ queryParams.push(typeof value === "string" ? value : JSON.stringify(value));
9301
+ }
9302
+ }
9303
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
9304
+ const countResult = await this.#client.execute({
9305
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_WORKSPACES}" ${whereClause}`,
9306
+ args: queryParams
9307
+ });
9308
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
9309
+ if (total === 0) {
9310
+ return {
9311
+ workspaces: [],
9312
+ total: 0,
9313
+ page,
9314
+ perPage: perPageInput ?? 100,
9315
+ hasMore: false
9316
+ };
9317
+ }
9318
+ const perPage = storage.normalizePerPage(perPageInput, 100);
9319
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
9320
+ const limitValue = perPageInput === false ? total : perPage;
9321
+ const end = perPageInput === false ? total : start + perPage;
9322
+ const result = await this.#client.execute({
9323
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACES)} FROM "${storage.TABLE_WORKSPACES}" ${whereClause} ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
9324
+ args: [...queryParams, limitValue, start]
9325
+ });
9326
+ const workspaces = result.rows?.map((row) => this.#parseWorkspaceRow(row)) ?? [];
9327
+ return {
9328
+ workspaces,
9329
+ total,
9330
+ page,
9331
+ perPage: perPageForResponse,
9332
+ hasMore: end < total
9333
+ };
9334
+ } catch (error$1) {
9335
+ if (error$1 instanceof error.MastraError) throw error$1;
9336
+ throw new error.MastraError(
9337
+ {
9338
+ id: storage.createStorageErrorId("LIBSQL", "LIST_WORKSPACES", "FAILED"),
9339
+ domain: error.ErrorDomain.STORAGE,
9340
+ category: error.ErrorCategory.THIRD_PARTY
9341
+ },
9342
+ error$1
9343
+ );
9344
+ }
9345
+ }
9346
+ // ==========================================================================
9347
+ // Workspace Version Methods
9348
+ // ==========================================================================
9349
+ async createVersion(input) {
9350
+ try {
9351
+ const now = /* @__PURE__ */ new Date();
9352
+ await this.#client.execute({
9353
+ sql: `INSERT INTO "${storage.TABLE_WORKSPACE_VERSIONS}" (
9354
+ id, "workspaceId", "versionNumber",
9355
+ name, description, filesystem, sandbox, mounts, search, skills, tools,
9356
+ "autoSync", "operationTimeout",
9357
+ "changedFields", "changeMessage", "createdAt"
9358
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
9359
+ args: [
9360
+ input.id,
9361
+ input.workspaceId,
9362
+ input.versionNumber,
9363
+ input.name,
9364
+ input.description ?? null,
9365
+ input.filesystem ? JSON.stringify(input.filesystem) : null,
9366
+ input.sandbox ? JSON.stringify(input.sandbox) : null,
9367
+ input.mounts ? JSON.stringify(input.mounts) : null,
9368
+ input.search ? JSON.stringify(input.search) : null,
9369
+ input.skills ? JSON.stringify(input.skills) : null,
9370
+ input.tools ? JSON.stringify(input.tools) : null,
9371
+ input.autoSync ? 1 : 0,
9372
+ input.operationTimeout ?? null,
9373
+ input.changedFields ? JSON.stringify(input.changedFields) : null,
9374
+ input.changeMessage ?? null,
9375
+ now.toISOString()
9376
+ ]
9377
+ });
9378
+ return {
9379
+ ...input,
9380
+ createdAt: now
9381
+ };
9382
+ } catch (error$1) {
9383
+ if (error$1 instanceof error.MastraError) throw error$1;
9384
+ throw new error.MastraError(
9385
+ {
9386
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_WORKSPACE_VERSION", "FAILED"),
9387
+ domain: error.ErrorDomain.STORAGE,
9388
+ category: error.ErrorCategory.THIRD_PARTY
9389
+ },
9390
+ error$1
9391
+ );
9392
+ }
8459
9393
  }
8460
- async getWorkflowRunById({
8461
- runId,
8462
- workflowName
8463
- }) {
8464
- const conditions = [];
8465
- const args = [];
8466
- if (runId) {
8467
- conditions.push("run_id = ?");
8468
- args.push(runId);
9394
+ async getVersion(id) {
9395
+ try {
9396
+ const result = await this.#client.execute({
9397
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACE_VERSIONS)} FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE id = ?`,
9398
+ args: [id]
9399
+ });
9400
+ const row = result.rows?.[0];
9401
+ return row ? this.#parseVersionRow(row) : null;
9402
+ } catch (error$1) {
9403
+ if (error$1 instanceof error.MastraError) throw error$1;
9404
+ throw new error.MastraError(
9405
+ {
9406
+ id: storage.createStorageErrorId("LIBSQL", "GET_WORKSPACE_VERSION", "FAILED"),
9407
+ domain: error.ErrorDomain.STORAGE,
9408
+ category: error.ErrorCategory.THIRD_PARTY
9409
+ },
9410
+ error$1
9411
+ );
8469
9412
  }
8470
- if (workflowName) {
8471
- conditions.push("workflow_name = ?");
8472
- args.push(workflowName);
9413
+ }
9414
+ async getVersionByNumber(workspaceId, versionNumber) {
9415
+ try {
9416
+ const result = await this.#client.execute({
9417
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACE_VERSIONS)} FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ? AND "versionNumber" = ?`,
9418
+ args: [workspaceId, versionNumber]
9419
+ });
9420
+ const row = result.rows?.[0];
9421
+ return row ? this.#parseVersionRow(row) : null;
9422
+ } catch (error$1) {
9423
+ if (error$1 instanceof error.MastraError) throw error$1;
9424
+ throw new error.MastraError(
9425
+ {
9426
+ id: storage.createStorageErrorId("LIBSQL", "GET_WORKSPACE_VERSION_BY_NUMBER", "FAILED"),
9427
+ domain: error.ErrorDomain.STORAGE,
9428
+ category: error.ErrorCategory.THIRD_PARTY
9429
+ },
9430
+ error$1
9431
+ );
8473
9432
  }
8474
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
9433
+ }
9434
+ async getLatestVersion(workspaceId) {
8475
9435
  try {
8476
9436
  const result = await this.#client.execute({
8477
- sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC LIMIT 1`,
8478
- args
9437
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACE_VERSIONS)} FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ? ORDER BY "versionNumber" DESC LIMIT 1`,
9438
+ args: [workspaceId]
8479
9439
  });
8480
- if (!result.rows?.[0]) {
8481
- return null;
8482
- }
8483
- return this.parseWorkflowRun(result.rows[0]);
9440
+ const row = result.rows?.[0];
9441
+ return row ? this.#parseVersionRow(row) : null;
8484
9442
  } catch (error$1) {
9443
+ if (error$1 instanceof error.MastraError) throw error$1;
8485
9444
  throw new error.MastraError(
8486
9445
  {
8487
- id: storage.createStorageErrorId("LIBSQL", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
9446
+ id: storage.createStorageErrorId("LIBSQL", "GET_LATEST_WORKSPACE_VERSION", "FAILED"),
8488
9447
  domain: error.ErrorDomain.STORAGE,
8489
9448
  category: error.ErrorCategory.THIRD_PARTY
8490
9449
  },
@@ -8492,85 +9451,100 @@ var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
8492
9451
  );
8493
9452
  }
8494
9453
  }
8495
- async deleteWorkflowRunById({ runId, workflowName }) {
8496
- return this.executeWithRetry(async () => {
8497
- try {
8498
- await this.#client.execute({
8499
- sql: `DELETE FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
8500
- args: [workflowName, runId]
8501
- });
8502
- } catch (error$1) {
8503
- throw new error.MastraError(
8504
- {
8505
- id: storage.createStorageErrorId("LIBSQL", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
8506
- domain: error.ErrorDomain.STORAGE,
8507
- category: error.ErrorCategory.THIRD_PARTY,
8508
- details: { runId, workflowName }
8509
- },
8510
- error$1
8511
- );
9454
+ async listVersions(input) {
9455
+ try {
9456
+ const { workspaceId, page = 0, perPage: perPageInput, orderBy } = input;
9457
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
9458
+ const countResult = await this.#client.execute({
9459
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ?`,
9460
+ args: [workspaceId]
9461
+ });
9462
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
9463
+ if (total === 0) {
9464
+ return {
9465
+ versions: [],
9466
+ total: 0,
9467
+ page,
9468
+ perPage: perPageInput ?? 20,
9469
+ hasMore: false
9470
+ };
8512
9471
  }
8513
- }, "deleteWorkflowRunById");
9472
+ const perPage = storage.normalizePerPage(perPageInput, 20);
9473
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
9474
+ const limitValue = perPageInput === false ? total : perPage;
9475
+ const end = perPageInput === false ? total : start + perPage;
9476
+ const result = await this.#client.execute({
9477
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_WORKSPACE_VERSIONS)} FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ? ORDER BY ${field} ${direction} LIMIT ? OFFSET ?`,
9478
+ args: [workspaceId, limitValue, start]
9479
+ });
9480
+ const versions = result.rows?.map((row) => this.#parseVersionRow(row)) ?? [];
9481
+ return {
9482
+ versions,
9483
+ total,
9484
+ page,
9485
+ perPage: perPageForResponse,
9486
+ hasMore: end < total
9487
+ };
9488
+ } catch (error$1) {
9489
+ if (error$1 instanceof error.MastraError) throw error$1;
9490
+ throw new error.MastraError(
9491
+ {
9492
+ id: storage.createStorageErrorId("LIBSQL", "LIST_WORKSPACE_VERSIONS", "FAILED"),
9493
+ domain: error.ErrorDomain.STORAGE,
9494
+ category: error.ErrorCategory.THIRD_PARTY
9495
+ },
9496
+ error$1
9497
+ );
9498
+ }
8514
9499
  }
8515
- async listWorkflowRuns({
8516
- workflowName,
8517
- fromDate,
8518
- toDate,
8519
- page,
8520
- perPage,
8521
- resourceId,
8522
- status
8523
- } = {}) {
9500
+ async deleteVersion(id) {
9501
+ try {
9502
+ await this.#client.execute({
9503
+ sql: `DELETE FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "id" = ?`,
9504
+ args: [id]
9505
+ });
9506
+ } catch (error$1) {
9507
+ if (error$1 instanceof error.MastraError) throw error$1;
9508
+ throw new error.MastraError(
9509
+ {
9510
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_WORKSPACE_VERSION", "FAILED"),
9511
+ domain: error.ErrorDomain.STORAGE,
9512
+ category: error.ErrorCategory.THIRD_PARTY
9513
+ },
9514
+ error$1
9515
+ );
9516
+ }
9517
+ }
9518
+ async deleteVersionsByParentId(entityId) {
9519
+ try {
9520
+ await this.#client.execute({
9521
+ sql: `DELETE FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ?`,
9522
+ args: [entityId]
9523
+ });
9524
+ } catch (error$1) {
9525
+ if (error$1 instanceof error.MastraError) throw error$1;
9526
+ throw new error.MastraError(
9527
+ {
9528
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_WORKSPACE_VERSIONS_BY_WORKSPACE", "FAILED"),
9529
+ domain: error.ErrorDomain.STORAGE,
9530
+ category: error.ErrorCategory.THIRD_PARTY
9531
+ },
9532
+ error$1
9533
+ );
9534
+ }
9535
+ }
9536
+ async countVersions(workspaceId) {
8524
9537
  try {
8525
- const conditions = [];
8526
- const args = [];
8527
- if (workflowName) {
8528
- conditions.push("workflow_name = ?");
8529
- args.push(workflowName);
8530
- }
8531
- if (status) {
8532
- conditions.push("json_extract(snapshot, '$.status') = ?");
8533
- args.push(status);
8534
- }
8535
- if (fromDate) {
8536
- conditions.push("createdAt >= ?");
8537
- args.push(fromDate.toISOString());
8538
- }
8539
- if (toDate) {
8540
- conditions.push("createdAt <= ?");
8541
- args.push(toDate.toISOString());
8542
- }
8543
- if (resourceId) {
8544
- const hasResourceId = await this.#db.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
8545
- if (hasResourceId) {
8546
- conditions.push("resourceId = ?");
8547
- args.push(resourceId);
8548
- } else {
8549
- this.logger.warn(`[${storage.TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
8550
- }
8551
- }
8552
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
8553
- let total = 0;
8554
- const usePagination = typeof perPage === "number" && typeof page === "number";
8555
- if (usePagination) {
8556
- const countResult = await this.#client.execute({
8557
- sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
8558
- args
8559
- });
8560
- total = Number(countResult.rows?.[0]?.count ?? 0);
8561
- }
8562
- const normalizedPerPage = usePagination ? storage.normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
8563
- const offset = usePagination ? page * normalizedPerPage : 0;
8564
9538
  const result = await this.#client.execute({
8565
- sql: `SELECT workflow_name, run_id, resourceId, json(snapshot) as snapshot, createdAt, updatedAt FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${whereClause} ORDER BY createdAt DESC${usePagination ? ` LIMIT ? OFFSET ?` : ""}`,
8566
- args: usePagination ? [...args, normalizedPerPage, offset] : args
9539
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_WORKSPACE_VERSIONS}" WHERE "workspaceId" = ?`,
9540
+ args: [workspaceId]
8567
9541
  });
8568
- const runs = (result.rows || []).map((row) => this.parseWorkflowRun(row));
8569
- return { runs, total: total || runs.length };
9542
+ return Number(result.rows?.[0]?.count ?? 0);
8570
9543
  } catch (error$1) {
9544
+ if (error$1 instanceof error.MastraError) throw error$1;
8571
9545
  throw new error.MastraError(
8572
9546
  {
8573
- id: storage.createStorageErrorId("LIBSQL", "LIST_WORKFLOW_RUNS", "FAILED"),
9547
+ id: storage.createStorageErrorId("LIBSQL", "COUNT_WORKSPACE_VERSIONS", "FAILED"),
8574
9548
  domain: error.ErrorDomain.STORAGE,
8575
9549
  category: error.ErrorCategory.THIRD_PARTY
8576
9550
  },
@@ -8578,6 +9552,62 @@ var WorkflowsLibSQL = class extends storage.WorkflowsStorage {
8578
9552
  );
8579
9553
  }
8580
9554
  }
9555
+ // ==========================================================================
9556
+ // Private Helpers
9557
+ // ==========================================================================
9558
+ #parseWorkspaceRow(row) {
9559
+ const safeParseJSON = (val) => {
9560
+ if (val === null || val === void 0) return void 0;
9561
+ if (typeof val === "string") {
9562
+ try {
9563
+ return JSON.parse(val);
9564
+ } catch {
9565
+ return val;
9566
+ }
9567
+ }
9568
+ return val;
9569
+ };
9570
+ return {
9571
+ id: row.id,
9572
+ status: row.status ?? "draft",
9573
+ activeVersionId: row.activeVersionId ?? void 0,
9574
+ authorId: row.authorId ?? void 0,
9575
+ metadata: safeParseJSON(row.metadata),
9576
+ createdAt: new Date(row.createdAt),
9577
+ updatedAt: new Date(row.updatedAt)
9578
+ };
9579
+ }
9580
+ #parseVersionRow(row) {
9581
+ const safeParseJSON = (val) => {
9582
+ if (val === null || val === void 0) return void 0;
9583
+ if (typeof val === "string") {
9584
+ try {
9585
+ return JSON.parse(val);
9586
+ } catch {
9587
+ return val;
9588
+ }
9589
+ }
9590
+ return val;
9591
+ };
9592
+ return {
9593
+ id: row.id,
9594
+ workspaceId: row.workspaceId,
9595
+ versionNumber: Number(row.versionNumber),
9596
+ name: row.name,
9597
+ description: row.description ?? void 0,
9598
+ filesystem: safeParseJSON(row.filesystem),
9599
+ sandbox: safeParseJSON(row.sandbox),
9600
+ mounts: safeParseJSON(row.mounts),
9601
+ search: safeParseJSON(row.search),
9602
+ skills: safeParseJSON(row.skills),
9603
+ tools: safeParseJSON(row.tools),
9604
+ autoSync: Boolean(row.autoSync),
9605
+ operationTimeout: row.operationTimeout != null ? Number(row.operationTimeout) : void 0,
9606
+ changedFields: safeParseJSON(row.changedFields),
9607
+ changeMessage: row.changeMessage ?? void 0,
9608
+ createdAt: new Date(row.createdAt)
9609
+ };
9610
+ }
8581
9611
  };
8582
9612
 
8583
9613
  // src/storage/index.ts
@@ -8623,6 +9653,9 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
8623
9653
  const promptBlocks = new PromptBlocksLibSQL(domainConfig);
8624
9654
  const scorerDefinitions = new ScorerDefinitionsLibSQL(domainConfig);
8625
9655
  const mcpClients = new MCPClientsLibSQL(domainConfig);
9656
+ const workspaces = new WorkspacesLibSQL(domainConfig);
9657
+ const skills = new SkillsLibSQL(domainConfig);
9658
+ const blobs = new BlobsLibSQL(domainConfig);
8626
9659
  this.stores = {
8627
9660
  scores,
8628
9661
  workflows,
@@ -8633,7 +9666,10 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
8633
9666
  experiments,
8634
9667
  promptBlocks,
8635
9668
  scorerDefinitions,
8636
- mcpClients
9669
+ mcpClients,
9670
+ workspaces,
9671
+ skills,
9672
+ blobs
8637
9673
  };
8638
9674
  }
8639
9675
  };
@@ -8738,6 +9774,7 @@ Example Complex Query:
8738
9774
  }`;
8739
9775
 
8740
9776
  exports.AgentsLibSQL = AgentsLibSQL;
9777
+ exports.BlobsLibSQL = BlobsLibSQL;
8741
9778
  exports.DatasetsLibSQL = DatasetsLibSQL;
8742
9779
  exports.DefaultStorage = LibSQLStore;
8743
9780
  exports.ExperimentsLibSQL = ExperimentsLibSQL;
@@ -8750,6 +9787,8 @@ exports.ObservabilityLibSQL = ObservabilityLibSQL;
8750
9787
  exports.PromptBlocksLibSQL = PromptBlocksLibSQL;
8751
9788
  exports.ScorerDefinitionsLibSQL = ScorerDefinitionsLibSQL;
8752
9789
  exports.ScoresLibSQL = ScoresLibSQL;
9790
+ exports.SkillsLibSQL = SkillsLibSQL;
8753
9791
  exports.WorkflowsLibSQL = WorkflowsLibSQL;
9792
+ exports.WorkspacesLibSQL = WorkspacesLibSQL;
8754
9793
  //# sourceMappingURL=index.cjs.map
8755
9794
  //# sourceMappingURL=index.cjs.map