@mastra/libsql 1.12.1 → 1.13.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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createClient } from '@libsql/client';
2
2
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
- import { createVectorErrorId, AgentsStorage, AGENTS_SCHEMA, TABLE_AGENTS, AGENT_VERSIONS_SCHEMA, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_SCHEMAS, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, SKILL_BLOBS_SCHEMA, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, DATASETS_SCHEMA, TABLE_DATASETS, DATASET_ITEMS_SCHEMA, TABLE_DATASET_ITEMS, DATASET_VERSIONS_SCHEMA, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, ExperimentsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, FAVORITES_SCHEMA, TABLE_FAVORITES, TABLE_SKILLS, MCPClientsStorage, MCP_CLIENTS_SCHEMA, TABLE_MCP_CLIENTS, MCP_CLIENT_VERSIONS_SCHEMA, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, MCP_SERVERS_SCHEMA, TABLE_MCP_SERVERS, MCP_SERVER_VERSIONS_SCHEMA, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, SPAN_SCHEMA, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, PROMPT_BLOCKS_SCHEMA, TABLE_PROMPT_BLOCKS, PROMPT_BLOCK_VERSIONS_SCHEMA, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, SCORER_DEFINITIONS_SCHEMA, TABLE_SCORER_DEFINITIONS, SCORER_DEFINITION_VERSIONS_SCHEMA, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, transformScoreRow, SkillsStorage, SKILLS_SCHEMA, SKILL_VERSIONS_SCHEMA, TABLE_SKILL_VERSIONS, ToolProviderConnectionsStorage, TOOL_PROVIDER_CONNECTIONS_SCHEMA, TABLE_TOOL_PROVIDER_CONNECTIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, WORKSPACES_SCHEMA, TABLE_WORKSPACES, WORKSPACE_VERSIONS_SCHEMA, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, getSqlType, TraceStatus } from '@mastra/core/storage';
3
+ import { createVectorErrorId, AgentsStorage, AGENTS_SCHEMA, TABLE_AGENTS, AGENT_VERSIONS_SCHEMA, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_SCHEMAS, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, SKILL_BLOBS_SCHEMA, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, DATASETS_SCHEMA, TABLE_DATASETS, DATASET_ITEMS_SCHEMA, TABLE_DATASET_ITEMS, DATASET_VERSIONS_SCHEMA, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, ExperimentsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, FAVORITES_SCHEMA, TABLE_FAVORITES, TABLE_SKILLS, HarnessStorage, TABLE_HARNESS_SESSIONS, MCPClientsStorage, MCP_CLIENTS_SCHEMA, TABLE_MCP_CLIENTS, MCP_CLIENT_VERSIONS_SCHEMA, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, MCP_SERVERS_SCHEMA, TABLE_MCP_SERVERS, MCP_SERVER_VERSIONS_SCHEMA, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, SPAN_SCHEMA, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, PROMPT_BLOCKS_SCHEMA, TABLE_PROMPT_BLOCKS, PROMPT_BLOCK_VERSIONS_SCHEMA, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, SCORER_DEFINITIONS_SCHEMA, TABLE_SCORER_DEFINITIONS, SCORER_DEFINITION_VERSIONS_SCHEMA, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, transformScoreRow, SkillsStorage, SKILLS_SCHEMA, SKILL_VERSIONS_SCHEMA, TABLE_SKILL_VERSIONS, ThreadStateStorage, THREAD_STATE_SCHEMA, TABLE_THREAD_STATE, ToolProviderConnectionsStorage, TOOL_PROVIDER_CONNECTIONS_SCHEMA, TABLE_TOOL_PROVIDER_CONNECTIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, WORKSPACES_SCHEMA, TABLE_WORKSPACES, WORKSPACE_VERSIONS_SCHEMA, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, getSqlType, TraceStatus, mergeWorkflowStepResult } from '@mastra/core/storage';
4
4
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
5
5
  import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
6
6
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -1424,6 +1424,21 @@ function transformFromSqlRow({
1424
1424
  return result;
1425
1425
  }
1426
1426
 
1427
+ // src/storage/db/write-lock.ts
1428
+ var clientWriteChains = /* @__PURE__ */ new WeakMap();
1429
+ function withClientWriteLock(client, fn) {
1430
+ const previous = clientWriteChains.get(client) ?? Promise.resolve();
1431
+ const result = previous.then(fn, fn);
1432
+ clientWriteChains.set(
1433
+ client,
1434
+ result.then(
1435
+ () => void 0,
1436
+ () => void 0
1437
+ )
1438
+ );
1439
+ return result;
1440
+ }
1441
+
1427
1442
  // src/storage/db/index.ts
1428
1443
  function resolveClient(config) {
1429
1444
  if ("client" in config) {
@@ -1523,11 +1538,14 @@ var LibSQLDB = class extends MastraBase {
1523
1538
  }) {
1524
1539
  const filteredRecord = await this.filterRecordToKnownColumns(tableName, record);
1525
1540
  if (Object.keys(filteredRecord).length === 0) return;
1526
- await this.client.execute(
1527
- prepareStatement({
1528
- tableName,
1529
- record: filteredRecord
1530
- })
1541
+ await withClientWriteLock(
1542
+ this.client,
1543
+ () => this.client.execute(
1544
+ prepareStatement({
1545
+ tableName,
1546
+ record: filteredRecord
1547
+ })
1548
+ )
1531
1549
  );
1532
1550
  }
1533
1551
  /**
@@ -1550,7 +1568,10 @@ var LibSQLDB = class extends MastraBase {
1550
1568
  }) {
1551
1569
  const filteredData = await this.filterRecordToKnownColumns(tableName, data);
1552
1570
  if (Object.keys(filteredData).length === 0) return;
1553
- await this.client.execute(prepareUpdateStatement({ tableName, updates: filteredData, keys }));
1571
+ await withClientWriteLock(
1572
+ this.client,
1573
+ () => this.client.execute(prepareUpdateStatement({ tableName, updates: filteredData, keys }))
1574
+ );
1554
1575
  }
1555
1576
  /**
1556
1577
  * Updates a record in the specified table with automatic retry on lock errors.
@@ -1575,7 +1596,7 @@ var LibSQLDB = class extends MastraBase {
1575
1596
  const nonEmptyRecords = filteredRecords.filter((r) => Object.keys(r).length > 0);
1576
1597
  if (nonEmptyRecords.length === 0) return;
1577
1598
  const batchStatements = nonEmptyRecords.map((r) => prepareStatement({ tableName, record: r }));
1578
- await this.client.batch(batchStatements, "write");
1599
+ await withClientWriteLock(this.client, () => this.client.batch(batchStatements, "write"));
1579
1600
  }
1580
1601
  /**
1581
1602
  * Inserts multiple records in a single batch transaction with automatic retry on lock errors.
@@ -1627,7 +1648,7 @@ var LibSQLDB = class extends MastraBase {
1627
1648
  keys
1628
1649
  })
1629
1650
  );
1630
- await this.client.batch(batchStatements, "write");
1651
+ await withClientWriteLock(this.client, () => this.client.batch(batchStatements, "write"));
1631
1652
  }
1632
1653
  /**
1633
1654
  * Updates multiple records in a single batch transaction with automatic retry on lock errors.
@@ -1671,7 +1692,7 @@ var LibSQLDB = class extends MastraBase {
1671
1692
  keys: keyObj
1672
1693
  })
1673
1694
  );
1674
- await this.client.batch(batchStatements, "write");
1695
+ await withClientWriteLock(this.client, () => this.client.batch(batchStatements, "write"));
1675
1696
  }
1676
1697
  /**
1677
1698
  * Deletes multiple records in a single batch transaction with automatic retry on lock errors.
@@ -1707,7 +1728,7 @@ var LibSQLDB = class extends MastraBase {
1707
1728
  * Internal single-record delete implementation without retry logic.
1708
1729
  */
1709
1730
  async doDelete({ tableName, keys }) {
1710
- await this.client.execute(prepareDeleteStatement({ tableName, keys }));
1731
+ await withClientWriteLock(this.client, () => this.client.execute(prepareDeleteStatement({ tableName, keys })));
1711
1732
  }
1712
1733
  /**
1713
1734
  * Deletes a single record from the specified table with automatic retry on lock errors.
@@ -2231,7 +2252,7 @@ Note: This migration may take some time for large tables.
2231
2252
  async deleteData({ tableName }) {
2232
2253
  const parsedTableName = parseSqlIdentifier(tableName, "table name");
2233
2254
  try {
2234
- await this.client.execute(`DELETE FROM ${parsedTableName}`);
2255
+ await withClientWriteLock(this.client, () => this.client.execute(`DELETE FROM ${parsedTableName}`));
2235
2256
  } catch (e) {
2236
2257
  const mastraError = new MastraError(
2237
2258
  {
@@ -5311,6 +5332,126 @@ var FavoritesLibSQL = class extends FavoritesStorage {
5311
5332
  }
5312
5333
  }
5313
5334
  };
5335
+ var toDate = (value) => new Date(value);
5336
+ var toOptionalDate = (value) => {
5337
+ if (value == null) return void 0;
5338
+ return toDate(value);
5339
+ };
5340
+ function cloneJson(value) {
5341
+ return value === void 0 ? void 0 : structuredClone(value);
5342
+ }
5343
+ function hydratePendingItem(item) {
5344
+ const record = {
5345
+ id: item.id,
5346
+ kind: item.kind,
5347
+ status: item.status,
5348
+ sessionId: item.sessionId,
5349
+ createdAt: toDate(item.createdAt),
5350
+ updatedAt: toDate(item.updatedAt)
5351
+ };
5352
+ if (item.runId !== void 0) record.runId = item.runId;
5353
+ if (item.traceId !== void 0) record.traceId = item.traceId;
5354
+ if (item.runtimeCompatibilityGeneration !== void 0) {
5355
+ record.runtimeCompatibilityGeneration = item.runtimeCompatibilityGeneration;
5356
+ }
5357
+ if (item.payload !== void 0) record.payload = cloneJson(item.payload);
5358
+ if (item.response !== void 0) record.response = cloneJson(item.response);
5359
+ return record;
5360
+ }
5361
+ function rowToSession(row) {
5362
+ const record = {
5363
+ id: row.id,
5364
+ ownerId: row.ownerId,
5365
+ resourceId: row.resourceId,
5366
+ threadId: row.threadId,
5367
+ origin: row.origin,
5368
+ modeId: row.modeId,
5369
+ modelId: row.modelId,
5370
+ createdAt: toDate(row.createdAt),
5371
+ lastActivityAt: toDate(row.lastActivityAt)
5372
+ };
5373
+ if (row.parentSessionId != null) record.parentSessionId = row.parentSessionId;
5374
+ if (row.subagentDepth != null) record.subagentDepth = row.subagentDepth;
5375
+ if (row.source != null) record.source = { ...row.source, type: row.source.type };
5376
+ if (row.runtimeCompatibilityGeneration != null) {
5377
+ record.runtimeCompatibilityGeneration = row.runtimeCompatibilityGeneration;
5378
+ }
5379
+ if (row.title != null) record.title = row.title;
5380
+ if (row.metadata != null) record.metadata = cloneJson(row.metadata);
5381
+ if (row.state != null) record.state = cloneJson(row.state);
5382
+ if (row.pending != null) record.pending = row.pending.map(hydratePendingItem);
5383
+ const closingAt = toOptionalDate(row.closingAt);
5384
+ const closeDeadlineAt = toOptionalDate(row.closeDeadlineAt);
5385
+ const closedAt = toOptionalDate(row.closedAt);
5386
+ const deletedAt = toOptionalDate(row.deletedAt);
5387
+ if (closingAt) record.closingAt = closingAt;
5388
+ if (closeDeadlineAt) record.closeDeadlineAt = closeDeadlineAt;
5389
+ if (closedAt) record.closedAt = closedAt;
5390
+ if (deletedAt) record.deletedAt = deletedAt;
5391
+ return record;
5392
+ }
5393
+ function sessionToRecord(record) {
5394
+ return {
5395
+ id: record.id,
5396
+ ownerId: record.ownerId,
5397
+ resourceId: record.resourceId,
5398
+ threadId: record.threadId,
5399
+ parentSessionId: record.parentSessionId ?? null,
5400
+ subagentDepth: record.subagentDepth ?? null,
5401
+ source: record.source ?? null,
5402
+ origin: record.origin,
5403
+ runtimeCompatibilityGeneration: record.runtimeCompatibilityGeneration ?? null,
5404
+ modeId: record.modeId,
5405
+ modelId: record.modelId,
5406
+ title: record.title ?? null,
5407
+ metadata: record.metadata ?? null,
5408
+ state: record.state ?? null,
5409
+ pending: record.pending ?? null,
5410
+ createdAt: record.createdAt,
5411
+ lastActivityAt: record.lastActivityAt,
5412
+ closingAt: record.closingAt ?? null,
5413
+ closeDeadlineAt: record.closeDeadlineAt ?? null,
5414
+ closedAt: record.closedAt ?? null,
5415
+ deletedAt: record.deletedAt ?? null
5416
+ };
5417
+ }
5418
+ var HarnessLibSQL = class extends HarnessStorage {
5419
+ #db;
5420
+ constructor(config) {
5421
+ super();
5422
+ const client = resolveClient(config);
5423
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
5424
+ }
5425
+ async init() {
5426
+ await this.#db.createTable({
5427
+ tableName: TABLE_HARNESS_SESSIONS,
5428
+ schema: TABLE_SCHEMAS[TABLE_HARNESS_SESSIONS]
5429
+ });
5430
+ }
5431
+ async dangerouslyClearAll() {
5432
+ await this.#db.deleteData({ tableName: TABLE_HARNESS_SESSIONS });
5433
+ }
5434
+ async loadSession(sessionId) {
5435
+ const row = await this.#db.select({
5436
+ tableName: TABLE_HARNESS_SESSIONS,
5437
+ keys: { id: sessionId }
5438
+ });
5439
+ return row ? rowToSession(row) : null;
5440
+ }
5441
+ async saveSession(record) {
5442
+ await this.#db.insert({
5443
+ tableName: TABLE_HARNESS_SESSIONS,
5444
+ record: sessionToRecord(record)
5445
+ });
5446
+ }
5447
+ async listSessions() {
5448
+ const rows = await this.#db.selectMany({
5449
+ tableName: TABLE_HARNESS_SESSIONS,
5450
+ orderBy: '"lastActivityAt" DESC'
5451
+ });
5452
+ return rows.map(rowToSession);
5453
+ }
5454
+ };
5314
5455
  var MCPClientsLibSQL = class extends MCPClientsStorage {
5315
5456
  #db;
5316
5457
  #client;
@@ -11278,6 +11419,99 @@ var SkillsLibSQL = class extends SkillsStorage {
11278
11419
  };
11279
11420
  }
11280
11421
  };
11422
+ var ThreadStateLibSQL = class extends ThreadStateStorage {
11423
+ #db;
11424
+ #client;
11425
+ constructor(config) {
11426
+ super();
11427
+ const client = resolveClient(config);
11428
+ this.#client = client;
11429
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
11430
+ }
11431
+ async init() {
11432
+ await this.#db.createTable({
11433
+ tableName: TABLE_THREAD_STATE,
11434
+ schema: THREAD_STATE_SCHEMA,
11435
+ compositePrimaryKey: ["threadId", "type"]
11436
+ });
11437
+ }
11438
+ async dangerouslyClearAll() {
11439
+ try {
11440
+ await this.#client.execute(`DELETE FROM "${TABLE_THREAD_STATE}"`);
11441
+ } catch (error) {
11442
+ throw new MastraError(
11443
+ {
11444
+ id: createStorageErrorId("LIBSQL", "THREAD_STATE_CLEAR_ALL", "FAILED"),
11445
+ domain: ErrorDomain.STORAGE,
11446
+ category: ErrorCategory.THIRD_PARTY
11447
+ },
11448
+ error
11449
+ );
11450
+ }
11451
+ }
11452
+ async getState({ threadId, type }) {
11453
+ try {
11454
+ const result = await this.#client.execute({
11455
+ sql: `SELECT "value" FROM "${TABLE_THREAD_STATE}" WHERE "threadId" = ? AND "type" = ? LIMIT 1`,
11456
+ args: [threadId, type]
11457
+ });
11458
+ const raw = result.rows?.[0]?.value;
11459
+ if (raw === void 0 || raw === null) return void 0;
11460
+ return typeof raw === "string" ? JSON.parse(raw) : raw;
11461
+ } catch (error) {
11462
+ throw new MastraError(
11463
+ {
11464
+ id: createStorageErrorId("LIBSQL", "THREAD_STATE_GET", "FAILED"),
11465
+ domain: ErrorDomain.STORAGE,
11466
+ category: ErrorCategory.THIRD_PARTY,
11467
+ details: { threadId, type }
11468
+ },
11469
+ error
11470
+ );
11471
+ }
11472
+ }
11473
+ async setState({ threadId, type, value }) {
11474
+ const now = (/* @__PURE__ */ new Date()).toISOString();
11475
+ const serialized = JSON.stringify(value ?? null);
11476
+ try {
11477
+ await this.#client.execute({
11478
+ sql: `INSERT INTO "${TABLE_THREAD_STATE}" ("threadId", "type", "value", "createdAt", "updatedAt")
11479
+ VALUES (?, ?, ?, ?, ?)
11480
+ ON CONFLICT ("threadId", "type")
11481
+ DO UPDATE SET "value" = excluded."value", "updatedAt" = excluded."updatedAt"`,
11482
+ args: [threadId, type, serialized, now, now]
11483
+ });
11484
+ } catch (error) {
11485
+ throw new MastraError(
11486
+ {
11487
+ id: createStorageErrorId("LIBSQL", "THREAD_STATE_SET", "FAILED"),
11488
+ domain: ErrorDomain.STORAGE,
11489
+ category: ErrorCategory.THIRD_PARTY,
11490
+ details: { threadId, type }
11491
+ },
11492
+ error
11493
+ );
11494
+ }
11495
+ }
11496
+ async deleteState({ threadId, type }) {
11497
+ try {
11498
+ await this.#client.execute({
11499
+ sql: `DELETE FROM "${TABLE_THREAD_STATE}" WHERE "threadId" = ? AND "type" = ?`,
11500
+ args: [threadId, type]
11501
+ });
11502
+ } catch (error) {
11503
+ throw new MastraError(
11504
+ {
11505
+ id: createStorageErrorId("LIBSQL", "THREAD_STATE_DELETE", "FAILED"),
11506
+ domain: ErrorDomain.STORAGE,
11507
+ category: ErrorCategory.THIRD_PARTY,
11508
+ details: { threadId, type }
11509
+ },
11510
+ error
11511
+ );
11512
+ }
11513
+ }
11514
+ };
11281
11515
  function normaliseScope(raw) {
11282
11516
  const value = raw == null ? "per-author" : String(raw);
11283
11517
  if (value === "shared") return "shared";
@@ -11549,89 +11783,102 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
11549
11783
  result,
11550
11784
  requestContext
11551
11785
  }) {
11552
- return this.executeWithRetry(async () => {
11553
- const tx = await this.#client.transaction("write");
11554
- try {
11555
- const existingSnapshotResult = await tx.execute({
11556
- sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
11557
- args: [workflowName, runId]
11558
- });
11559
- let snapshot;
11560
- if (!existingSnapshotResult.rows?.[0]) {
11561
- snapshot = {
11562
- context: {},
11563
- activePaths: [],
11564
- timestamp: Date.now(),
11565
- suspendedPaths: {},
11566
- activeStepsPath: {},
11567
- resumeLabels: {},
11568
- serializedStepGraph: [],
11569
- status: "pending",
11570
- value: {},
11571
- waitingPaths: {},
11572
- runId,
11573
- requestContext: {}
11574
- };
11575
- } else {
11576
- const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
11577
- snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
11578
- }
11579
- snapshot.context[stepId] = result;
11580
- snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
11581
- const now = (/* @__PURE__ */ new Date()).toISOString();
11582
- await tx.execute({
11583
- sql: `INSERT INTO ${TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, snapshot, createdAt, updatedAt)
11786
+ return this.executeWithRetry(
11787
+ () => (
11788
+ // Serialize the interactive transaction against all other writes on the shared
11789
+ // connection so a concurrent autocommit write can't leak into this open BEGIN.
11790
+ withClientWriteLock(this.#client, async () => {
11791
+ const tx = await this.#client.transaction("write");
11792
+ try {
11793
+ const existingSnapshotResult = await tx.execute({
11794
+ sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
11795
+ args: [workflowName, runId]
11796
+ });
11797
+ let snapshot;
11798
+ if (!existingSnapshotResult.rows?.[0]) {
11799
+ snapshot = {
11800
+ context: {},
11801
+ activePaths: [],
11802
+ timestamp: Date.now(),
11803
+ suspendedPaths: {},
11804
+ activeStepsPath: {},
11805
+ resumeLabels: {},
11806
+ serializedStepGraph: [],
11807
+ status: "pending",
11808
+ value: {},
11809
+ waitingPaths: {},
11810
+ runId,
11811
+ requestContext: {}
11812
+ };
11813
+ } else {
11814
+ const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
11815
+ snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
11816
+ }
11817
+ mergeWorkflowStepResult({ snapshot, stepId, result, requestContext });
11818
+ const now = (/* @__PURE__ */ new Date()).toISOString();
11819
+ await tx.execute({
11820
+ sql: `INSERT INTO ${TABLE_WORKFLOW_SNAPSHOT} (workflow_name, run_id, snapshot, createdAt, updatedAt)
11584
11821
  VALUES (?, ?, jsonb(?), ?, ?)
11585
11822
  ON CONFLICT(workflow_name, run_id)
11586
11823
  DO UPDATE SET snapshot = excluded.snapshot, updatedAt = excluded.updatedAt`,
11587
- args: [workflowName, runId, safeStringify(snapshot), now, now]
11588
- });
11589
- await tx.commit();
11590
- return snapshot.context;
11591
- } catch (error) {
11592
- if (!tx.closed) {
11593
- await tx.rollback();
11594
- }
11595
- throw error;
11596
- }
11597
- }, "updateWorkflowResults");
11824
+ args: [workflowName, runId, safeStringify(snapshot), now, now]
11825
+ });
11826
+ await tx.commit();
11827
+ return snapshot.context;
11828
+ } catch (error) {
11829
+ if (!tx.closed) {
11830
+ await tx.rollback();
11831
+ }
11832
+ throw error;
11833
+ }
11834
+ })
11835
+ ),
11836
+ "updateWorkflowResults"
11837
+ );
11598
11838
  }
11599
11839
  async updateWorkflowState({
11600
11840
  workflowName,
11601
11841
  runId,
11602
11842
  opts
11603
11843
  }) {
11604
- return this.executeWithRetry(async () => {
11605
- const tx = await this.#client.transaction("write");
11606
- try {
11607
- const existingSnapshotResult = await tx.execute({
11608
- sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
11609
- args: [workflowName, runId]
11610
- });
11611
- if (!existingSnapshotResult.rows?.[0]) {
11612
- await tx.rollback();
11613
- return void 0;
11614
- }
11615
- const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
11616
- const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
11617
- if (!snapshot || !snapshot?.context) {
11618
- await tx.rollback();
11619
- throw new Error(`Snapshot not found for runId ${runId}`);
11620
- }
11621
- const updatedSnapshot = { ...snapshot, ...opts };
11622
- await tx.execute({
11623
- sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
11624
- args: [safeStringify(updatedSnapshot), workflowName, runId]
11625
- });
11626
- await tx.commit();
11627
- return updatedSnapshot;
11628
- } catch (error) {
11629
- if (!tx.closed) {
11630
- await tx.rollback();
11631
- }
11632
- throw error;
11633
- }
11634
- }, "updateWorkflowState");
11844
+ return this.executeWithRetry(
11845
+ () => (
11846
+ // Serialize the interactive transaction against all other writes on the shared
11847
+ // connection so a concurrent autocommit write can't leak into this open BEGIN.
11848
+ withClientWriteLock(this.#client, async () => {
11849
+ const tx = await this.#client.transaction("write");
11850
+ try {
11851
+ const existingSnapshotResult = await tx.execute({
11852
+ sql: `SELECT json(snapshot) as snapshot FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE workflow_name = ? AND run_id = ?`,
11853
+ args: [workflowName, runId]
11854
+ });
11855
+ if (!existingSnapshotResult.rows?.[0]) {
11856
+ await tx.rollback();
11857
+ return void 0;
11858
+ }
11859
+ const existingSnapshot = existingSnapshotResult.rows[0].snapshot;
11860
+ const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
11861
+ if (!snapshot || !snapshot?.context) {
11862
+ await tx.rollback();
11863
+ throw new Error(`Snapshot not found for runId ${runId}`);
11864
+ }
11865
+ const updatedSnapshot = { ...snapshot, ...opts };
11866
+ await tx.execute({
11867
+ sql: `UPDATE ${TABLE_WORKFLOW_SNAPSHOT} SET snapshot = jsonb(?) WHERE workflow_name = ? AND run_id = ?`,
11868
+ args: [safeStringify(updatedSnapshot), workflowName, runId]
11869
+ });
11870
+ await tx.commit();
11871
+ return updatedSnapshot;
11872
+ } catch (error) {
11873
+ if (!tx.closed) {
11874
+ await tx.rollback();
11875
+ }
11876
+ throw error;
11877
+ }
11878
+ })
11879
+ ),
11880
+ "updateWorkflowState"
11881
+ );
11635
11882
  }
11636
11883
  async persistWorkflowSnapshot({
11637
11884
  workflowName,
@@ -11725,7 +11972,7 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
11725
11972
  async listWorkflowRuns({
11726
11973
  workflowName,
11727
11974
  fromDate,
11728
- toDate,
11975
+ toDate: toDate2,
11729
11976
  page,
11730
11977
  perPage,
11731
11978
  resourceId,
@@ -11746,9 +11993,9 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
11746
11993
  conditions.push("createdAt >= ?");
11747
11994
  args.push(fromDate.toISOString());
11748
11995
  }
11749
- if (toDate) {
11996
+ if (toDate2) {
11750
11997
  conditions.push("createdAt <= ?");
11751
- args.push(toDate.toISOString());
11998
+ args.push(toDate2.toISOString());
11752
11999
  }
11753
12000
  if (resourceId) {
11754
12001
  const hasResourceId = await this.#db.hasColumn(TABLE_WORKFLOW_SNAPSHOT, "resourceId");
@@ -12405,8 +12652,10 @@ var LibSQLStore = class extends MastraCompositeStore {
12405
12652
  const blobs = new BlobsLibSQL(domainConfig);
12406
12653
  const backgroundTasks = new BackgroundTasksLibSQL(domainConfig);
12407
12654
  const schedules = new SchedulesLibSQL(domainConfig);
12655
+ const harness = new HarnessLibSQL(domainConfig);
12408
12656
  const toolProviderConnections = new ToolProviderConnectionsLibSQL(domainConfig);
12409
12657
  const notifications = new NotificationsLibSQL(domainConfig);
12658
+ const threadState = new ThreadStateLibSQL(domainConfig);
12410
12659
  this.stores = {
12411
12660
  scores,
12412
12661
  workflows,
@@ -12426,8 +12675,10 @@ var LibSQLStore = class extends MastraCompositeStore {
12426
12675
  blobs,
12427
12676
  backgroundTasks,
12428
12677
  schedules,
12678
+ harness,
12429
12679
  toolProviderConnections,
12430
- notifications
12680
+ notifications,
12681
+ threadState
12431
12682
  };
12432
12683
  }
12433
12684
  async applyLocalPragmas() {
@@ -12616,6 +12867,6 @@ Example Complex Query:
12616
12867
  ]
12617
12868
  }`;
12618
12869
 
12619
- export { AgentsLibSQL, BackgroundTasksLibSQL, BlobsLibSQL, ChannelsLibSQL, DatasetsLibSQL, LibSQLStore as DefaultStorage, ExperimentsLibSQL, FavoritesLibSQL, LIBSQL_PROMPT, LibSQLStore, LibSQLVector, MCPClientsLibSQL, MCPServersLibSQL, MemoryLibSQL, NotificationsLibSQL, ObservabilityLibSQL, PromptBlocksLibSQL, SchedulesLibSQL, ScorerDefinitionsLibSQL, ScoresLibSQL, SkillsLibSQL, ToolProviderConnectionsLibSQL, WorkflowsLibSQL, WorkspacesLibSQL };
12870
+ export { AgentsLibSQL, BackgroundTasksLibSQL, BlobsLibSQL, ChannelsLibSQL, DatasetsLibSQL, LibSQLStore as DefaultStorage, ExperimentsLibSQL, FavoritesLibSQL, HarnessLibSQL, LIBSQL_PROMPT, LibSQLStore, LibSQLVector, MCPClientsLibSQL, MCPServersLibSQL, MemoryLibSQL, NotificationsLibSQL, ObservabilityLibSQL, PromptBlocksLibSQL, SchedulesLibSQL, ScorerDefinitionsLibSQL, ScoresLibSQL, SkillsLibSQL, ThreadStateLibSQL, ToolProviderConnectionsLibSQL, WorkflowsLibSQL, WorkspacesLibSQL };
12620
12871
  //# sourceMappingURL=index.js.map
12621
12872
  //# sourceMappingURL=index.js.map