@mastra/libsql 1.17.0 → 1.17.1-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
@@ -8304,46 +8304,49 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8304
8304
  config: input.config,
8305
8305
  observedTimezone: input.observedTimezone
8306
8306
  };
8307
- await this.#client.execute({
8308
- sql: `INSERT INTO "${OM_TABLE}" (
8309
- id, "lookupKey", scope, "resourceId", "threadId",
8310
- "activeObservations", "activeObservationsPendingUpdate",
8311
- "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8312
- "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8313
- "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
8314
- "observedTimezone", "createdAt", "updatedAt"
8315
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8316
- args: [
8317
- id,
8318
- lookupKey,
8319
- input.scope,
8320
- input.resourceId,
8321
- input.threadId || null,
8322
- "",
8323
- null,
8324
- "initial",
8325
- JSON.stringify(input.config),
8326
- 0,
8327
- null,
8328
- null,
8329
- 0,
8330
- 0,
8331
- 0,
8332
- false,
8333
- false,
8334
- false,
8335
- // isBufferingObservation
8336
- false,
8337
- // isBufferingReflection
8338
- 0,
8339
- // lastBufferedAtTokens
8340
- null,
8341
- // lastBufferedAtTime
8342
- input.observedTimezone || null,
8343
- now.toISOString(),
8344
- now.toISOString()
8345
- ]
8346
- });
8307
+ await withClientWriteLock(
8308
+ this.#client,
8309
+ () => this.#client.execute({
8310
+ sql: `INSERT INTO "${OM_TABLE}" (
8311
+ id, "lookupKey", scope, "resourceId", "threadId",
8312
+ "activeObservations", "activeObservationsPendingUpdate",
8313
+ "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8314
+ "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8315
+ "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
8316
+ "observedTimezone", "createdAt", "updatedAt"
8317
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8318
+ args: [
8319
+ id,
8320
+ lookupKey,
8321
+ input.scope,
8322
+ input.resourceId,
8323
+ input.threadId || null,
8324
+ "",
8325
+ null,
8326
+ "initial",
8327
+ JSON.stringify(input.config),
8328
+ 0,
8329
+ null,
8330
+ null,
8331
+ 0,
8332
+ 0,
8333
+ 0,
8334
+ false,
8335
+ false,
8336
+ false,
8337
+ // isBufferingObservation
8338
+ false,
8339
+ // isBufferingReflection
8340
+ 0,
8341
+ // lastBufferedAtTokens
8342
+ null,
8343
+ // lastBufferedAtTime
8344
+ input.observedTimezone || null,
8345
+ now.toISOString(),
8346
+ now.toISOString()
8347
+ ]
8348
+ })
8349
+ );
8347
8350
  return record;
8348
8351
  } catch (error) {
8349
8352
  throw new MastraError(
@@ -8360,53 +8363,56 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8360
8363
  async insertObservationalMemoryRecord(record) {
8361
8364
  try {
8362
8365
  const lookupKey = this.getOMKey(record.threadId, record.resourceId);
8363
- await this.#client.execute({
8364
- sql: `INSERT INTO "${OM_TABLE}" (
8365
- id, "lookupKey", scope, "resourceId", "threadId",
8366
- "activeObservations", "activeObservationsPendingUpdate",
8367
- "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8368
- "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8369
- "observedMessageIds", "bufferedObservationChunks",
8370
- "bufferedReflection", "bufferedReflectionTokens", "bufferedReflectionInputTokens",
8371
- "reflectedObservationLineCount",
8372
- "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection",
8373
- "lastBufferedAtTokens", "lastBufferedAtTime",
8374
- "observedTimezone", metadata, "createdAt", "updatedAt"
8375
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8376
- args: [
8377
- record.id,
8378
- lookupKey,
8379
- record.scope,
8380
- record.resourceId,
8381
- record.threadId || null,
8382
- record.activeObservations || "",
8383
- null,
8384
- record.originType || "initial",
8385
- record.config ? JSON.stringify(record.config) : null,
8386
- record.generationCount || 0,
8387
- record.lastObservedAt ? record.lastObservedAt.toISOString() : null,
8388
- null,
8389
- record.pendingMessageTokens || 0,
8390
- record.totalTokensObserved || 0,
8391
- record.observationTokenCount || 0,
8392
- record.observedMessageIds ? JSON.stringify(record.observedMessageIds) : null,
8393
- record.bufferedObservationChunks ? JSON.stringify(record.bufferedObservationChunks) : null,
8394
- record.bufferedReflection || null,
8395
- record.bufferedReflectionTokens ?? null,
8396
- record.bufferedReflectionInputTokens ?? null,
8397
- record.reflectedObservationLineCount ?? null,
8398
- record.isObserving || false,
8399
- record.isReflecting || false,
8400
- record.isBufferingObservation || false,
8401
- record.isBufferingReflection || false,
8402
- record.lastBufferedAtTokens || 0,
8403
- record.lastBufferedAtTime ? record.lastBufferedAtTime.toISOString() : null,
8404
- record.observedTimezone || null,
8405
- record.metadata ? JSON.stringify(record.metadata) : null,
8406
- record.createdAt.toISOString(),
8407
- record.updatedAt.toISOString()
8408
- ]
8409
- });
8366
+ await withClientWriteLock(
8367
+ this.#client,
8368
+ () => this.#client.execute({
8369
+ sql: `INSERT INTO "${OM_TABLE}" (
8370
+ id, "lookupKey", scope, "resourceId", "threadId",
8371
+ "activeObservations", "activeObservationsPendingUpdate",
8372
+ "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8373
+ "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8374
+ "observedMessageIds", "bufferedObservationChunks",
8375
+ "bufferedReflection", "bufferedReflectionTokens", "bufferedReflectionInputTokens",
8376
+ "reflectedObservationLineCount",
8377
+ "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection",
8378
+ "lastBufferedAtTokens", "lastBufferedAtTime",
8379
+ "observedTimezone", metadata, "createdAt", "updatedAt"
8380
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8381
+ args: [
8382
+ record.id,
8383
+ lookupKey,
8384
+ record.scope,
8385
+ record.resourceId,
8386
+ record.threadId || null,
8387
+ record.activeObservations || "",
8388
+ null,
8389
+ record.originType || "initial",
8390
+ record.config ? JSON.stringify(record.config) : null,
8391
+ record.generationCount || 0,
8392
+ record.lastObservedAt ? record.lastObservedAt.toISOString() : null,
8393
+ null,
8394
+ record.pendingMessageTokens || 0,
8395
+ record.totalTokensObserved || 0,
8396
+ record.observationTokenCount || 0,
8397
+ record.observedMessageIds ? JSON.stringify(record.observedMessageIds) : null,
8398
+ record.bufferedObservationChunks ? JSON.stringify(record.bufferedObservationChunks) : null,
8399
+ record.bufferedReflection || null,
8400
+ record.bufferedReflectionTokens ?? null,
8401
+ record.bufferedReflectionInputTokens ?? null,
8402
+ record.reflectedObservationLineCount ?? null,
8403
+ record.isObserving || false,
8404
+ record.isReflecting || false,
8405
+ record.isBufferingObservation || false,
8406
+ record.isBufferingReflection || false,
8407
+ record.lastBufferedAtTokens || 0,
8408
+ record.lastBufferedAtTime ? record.lastBufferedAtTime.toISOString() : null,
8409
+ record.observedTimezone || null,
8410
+ record.metadata ? JSON.stringify(record.metadata) : null,
8411
+ record.createdAt.toISOString(),
8412
+ record.updatedAt.toISOString()
8413
+ ]
8414
+ })
8415
+ );
8410
8416
  } catch (error) {
8411
8417
  throw new MastraError(
8412
8418
  {
@@ -8423,26 +8429,29 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8423
8429
  try {
8424
8430
  const now = /* @__PURE__ */ new Date();
8425
8431
  const observedMessageIdsJson = input.observedMessageIds ? JSON.stringify(input.observedMessageIds) : null;
8426
- const result = await this.#client.execute({
8427
- sql: `UPDATE "${OM_TABLE}" SET
8428
- "activeObservations" = ?,
8429
- "lastObservedAt" = ?,
8430
- "pendingMessageTokens" = 0,
8431
- "observationTokenCount" = ?,
8432
- "totalTokensObserved" = "totalTokensObserved" + ?,
8433
- "observedMessageIds" = ?,
8434
- "updatedAt" = ?
8435
- WHERE id = ?`,
8436
- args: [
8437
- input.observations,
8438
- input.lastObservedAt.toISOString(),
8439
- input.tokenCount,
8440
- input.tokenCount,
8441
- observedMessageIdsJson,
8442
- now.toISOString(),
8443
- input.id
8444
- ]
8445
- });
8432
+ const result = await withClientWriteLock(
8433
+ this.#client,
8434
+ () => this.#client.execute({
8435
+ sql: `UPDATE "${OM_TABLE}" SET
8436
+ "activeObservations" = ?,
8437
+ "lastObservedAt" = ?,
8438
+ "pendingMessageTokens" = 0,
8439
+ "observationTokenCount" = ?,
8440
+ "totalTokensObserved" = "totalTokensObserved" + ?,
8441
+ "observedMessageIds" = ?,
8442
+ "updatedAt" = ?
8443
+ WHERE id = ?`,
8444
+ args: [
8445
+ input.observations,
8446
+ input.lastObservedAt.toISOString(),
8447
+ input.tokenCount,
8448
+ input.tokenCount,
8449
+ observedMessageIdsJson,
8450
+ now.toISOString(),
8451
+ input.id
8452
+ ]
8453
+ })
8454
+ );
8446
8455
  if (result.rowsAffected === 0) {
8447
8456
  throw new MastraError({
8448
8457
  id: createStorageErrorId("LIBSQL", "UPDATE_ACTIVE_OBSERVATIONS", "NOT_FOUND"),
@@ -8469,78 +8478,21 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8469
8478
  }
8470
8479
  async createReflectionGeneration(input) {
8471
8480
  try {
8472
- const id = crypto.randomUUID();
8473
- const now = /* @__PURE__ */ new Date();
8474
- const lookupKey = this.getOMKey(input.currentRecord.threadId, input.currentRecord.resourceId);
8475
- const record = {
8476
- id,
8477
- scope: input.currentRecord.scope,
8478
- threadId: input.currentRecord.threadId,
8479
- resourceId: input.currentRecord.resourceId,
8480
- createdAt: now,
8481
- updatedAt: now,
8482
- lastObservedAt: input.currentRecord.lastObservedAt,
8483
- originType: "reflection",
8484
- generationCount: input.currentRecord.generationCount + 1,
8485
- activeObservations: input.reflection,
8486
- totalTokensObserved: input.currentRecord.totalTokensObserved,
8487
- observationTokenCount: input.tokenCount,
8488
- pendingMessageTokens: 0,
8489
- isReflecting: false,
8490
- isObserving: false,
8491
- isBufferingObservation: false,
8492
- isBufferingReflection: false,
8493
- lastBufferedAtTokens: 0,
8494
- lastBufferedAtTime: null,
8495
- config: input.currentRecord.config,
8496
- metadata: input.currentRecord.metadata,
8497
- observedTimezone: input.currentRecord.observedTimezone
8498
- };
8499
- await this.#client.execute({
8500
- sql: `INSERT INTO "${OM_TABLE}" (
8501
- id, "lookupKey", scope, "resourceId", "threadId",
8502
- "activeObservations", "activeObservationsPendingUpdate",
8503
- "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8504
- "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8505
- "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
8506
- "observedTimezone", metadata, "createdAt", "updatedAt"
8507
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8508
- args: [
8509
- id,
8510
- lookupKey,
8511
- record.scope,
8512
- record.resourceId,
8513
- record.threadId || null,
8514
- input.reflection,
8515
- null,
8516
- "reflection",
8517
- JSON.stringify(record.config),
8518
- input.currentRecord.generationCount + 1,
8519
- record.lastObservedAt?.toISOString() || null,
8520
- now.toISOString(),
8521
- record.pendingMessageTokens,
8522
- record.totalTokensObserved,
8523
- record.observationTokenCount,
8524
- false,
8525
- // isObserving
8526
- false,
8527
- // isReflecting
8528
- false,
8529
- // isBufferingObservation
8530
- false,
8531
- // isBufferingReflection
8532
- 0,
8533
- // lastBufferedAtTokens
8534
- null,
8535
- // lastBufferedAtTime
8536
- record.observedTimezone || null,
8537
- record.metadata ? JSON.stringify(record.metadata) : null,
8538
- now.toISOString(),
8539
- now.toISOString()
8540
- ]
8481
+ return await withClientWriteLock(this.#client, async () => {
8482
+ const tx = await this.#client.transaction("write");
8483
+ try {
8484
+ const record = await this.#insertReflectionGeneration(tx, input);
8485
+ await tx.commit();
8486
+ return record;
8487
+ } catch (error) {
8488
+ if (!tx.closed) await tx.rollback();
8489
+ throw error;
8490
+ }
8541
8491
  });
8542
- return record;
8543
8492
  } catch (error) {
8493
+ if (error instanceof MastraError) {
8494
+ throw error;
8495
+ }
8544
8496
  throw new MastraError(
8545
8497
  {
8546
8498
  id: createStorageErrorId("LIBSQL", "CREATE_REFLECTION_GENERATION", "FAILED"),
@@ -8552,12 +8504,94 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8552
8504
  );
8553
8505
  }
8554
8506
  }
8507
+ /**
8508
+ * Inserts a new reflection-generation row. Called inside a locked write
8509
+ * transaction — either from {@link createReflectionGeneration} (standalone)
8510
+ * or from {@link swapBufferedReflectionToActive} (as part of a compound
8511
+ * swap). Must not acquire the write lock itself; the caller owns it.
8512
+ */
8513
+ async #insertReflectionGeneration(tx, input) {
8514
+ const id = crypto.randomUUID();
8515
+ const now = /* @__PURE__ */ new Date();
8516
+ const lookupKey = this.getOMKey(input.currentRecord.threadId, input.currentRecord.resourceId);
8517
+ const record = {
8518
+ id,
8519
+ scope: input.currentRecord.scope,
8520
+ threadId: input.currentRecord.threadId,
8521
+ resourceId: input.currentRecord.resourceId,
8522
+ createdAt: now,
8523
+ updatedAt: now,
8524
+ lastObservedAt: input.currentRecord.lastObservedAt,
8525
+ originType: "reflection",
8526
+ generationCount: input.currentRecord.generationCount + 1,
8527
+ activeObservations: input.reflection,
8528
+ totalTokensObserved: input.currentRecord.totalTokensObserved,
8529
+ observationTokenCount: input.tokenCount,
8530
+ pendingMessageTokens: 0,
8531
+ isReflecting: false,
8532
+ isObserving: false,
8533
+ isBufferingObservation: false,
8534
+ isBufferingReflection: false,
8535
+ lastBufferedAtTokens: 0,
8536
+ lastBufferedAtTime: null,
8537
+ config: input.currentRecord.config,
8538
+ metadata: input.currentRecord.metadata,
8539
+ observedTimezone: input.currentRecord.observedTimezone
8540
+ };
8541
+ await tx.execute({
8542
+ sql: `INSERT INTO "${OM_TABLE}" (
8543
+ id, "lookupKey", scope, "resourceId", "threadId",
8544
+ "activeObservations", "activeObservationsPendingUpdate",
8545
+ "originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
8546
+ "pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
8547
+ "isObserving", "isReflecting", "isBufferingObservation", "isBufferingReflection", "lastBufferedAtTokens", "lastBufferedAtTime",
8548
+ "observedTimezone", metadata, "createdAt", "updatedAt"
8549
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
8550
+ args: [
8551
+ id,
8552
+ lookupKey,
8553
+ record.scope,
8554
+ record.resourceId,
8555
+ record.threadId || null,
8556
+ input.reflection,
8557
+ null,
8558
+ "reflection",
8559
+ JSON.stringify(record.config),
8560
+ input.currentRecord.generationCount + 1,
8561
+ record.lastObservedAt?.toISOString() || null,
8562
+ now.toISOString(),
8563
+ record.pendingMessageTokens,
8564
+ record.totalTokensObserved,
8565
+ record.observationTokenCount,
8566
+ false,
8567
+ // isObserving
8568
+ false,
8569
+ // isReflecting
8570
+ false,
8571
+ // isBufferingObservation
8572
+ false,
8573
+ // isBufferingReflection
8574
+ 0,
8575
+ // lastBufferedAtTokens
8576
+ null,
8577
+ // lastBufferedAtTime
8578
+ record.observedTimezone || null,
8579
+ record.metadata ? JSON.stringify(record.metadata) : null,
8580
+ now.toISOString(),
8581
+ now.toISOString()
8582
+ ]
8583
+ });
8584
+ return record;
8585
+ }
8555
8586
  async setReflectingFlag(id, isReflecting) {
8556
8587
  try {
8557
- const result = await this.#client.execute({
8558
- sql: `UPDATE "${OM_TABLE}" SET "isReflecting" = ?, "updatedAt" = ? WHERE id = ?`,
8559
- args: [isReflecting, (/* @__PURE__ */ new Date()).toISOString(), id]
8560
- });
8588
+ const result = await withClientWriteLock(
8589
+ this.#client,
8590
+ () => this.#client.execute({
8591
+ sql: `UPDATE "${OM_TABLE}" SET "isReflecting" = ?, "updatedAt" = ? WHERE id = ?`,
8592
+ args: [isReflecting, (/* @__PURE__ */ new Date()).toISOString(), id]
8593
+ })
8594
+ );
8561
8595
  if (result.rowsAffected === 0) {
8562
8596
  throw new MastraError({
8563
8597
  id: createStorageErrorId("LIBSQL", "SET_REFLECTING_FLAG", "NOT_FOUND"),
@@ -8584,10 +8618,13 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8584
8618
  }
8585
8619
  async setObservingFlag(id, isObserving) {
8586
8620
  try {
8587
- const result = await this.#client.execute({
8588
- sql: `UPDATE "${OM_TABLE}" SET "isObserving" = ?, "updatedAt" = ? WHERE id = ?`,
8589
- args: [isObserving, (/* @__PURE__ */ new Date()).toISOString(), id]
8590
- });
8621
+ const result = await withClientWriteLock(
8622
+ this.#client,
8623
+ () => this.#client.execute({
8624
+ sql: `UPDATE "${OM_TABLE}" SET "isObserving" = ?, "updatedAt" = ? WHERE id = ?`,
8625
+ args: [isObserving, (/* @__PURE__ */ new Date()).toISOString(), id]
8626
+ })
8627
+ );
8591
8628
  if (result.rowsAffected === 0) {
8592
8629
  throw new MastraError({
8593
8630
  id: createStorageErrorId("LIBSQL", "SET_OBSERVING_FLAG", "NOT_FOUND"),
@@ -8624,7 +8661,7 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8624
8661
  sql = `UPDATE "${OM_TABLE}" SET "isBufferingObservation" = ?, "updatedAt" = ? WHERE id = ?`;
8625
8662
  args = [isBuffering, nowStr, id];
8626
8663
  }
8627
- const result = await this.#client.execute({ sql, args });
8664
+ const result = await withClientWriteLock(this.#client, () => this.#client.execute({ sql, args }));
8628
8665
  if (result.rowsAffected === 0) {
8629
8666
  throw new MastraError({
8630
8667
  id: createStorageErrorId("LIBSQL", "SET_BUFFERING_OBSERVATION_FLAG", "NOT_FOUND"),
@@ -8651,10 +8688,13 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8651
8688
  }
8652
8689
  async setBufferingReflectionFlag(id, isBuffering) {
8653
8690
  try {
8654
- const result = await this.#client.execute({
8655
- sql: `UPDATE "${OM_TABLE}" SET "isBufferingReflection" = ?, "updatedAt" = ? WHERE id = ?`,
8656
- args: [isBuffering, (/* @__PURE__ */ new Date()).toISOString(), id]
8657
- });
8691
+ const result = await withClientWriteLock(
8692
+ this.#client,
8693
+ () => this.#client.execute({
8694
+ sql: `UPDATE "${OM_TABLE}" SET "isBufferingReflection" = ?, "updatedAt" = ? WHERE id = ?`,
8695
+ args: [isBuffering, (/* @__PURE__ */ new Date()).toISOString(), id]
8696
+ })
8697
+ );
8658
8698
  if (result.rowsAffected === 0) {
8659
8699
  throw new MastraError({
8660
8700
  id: createStorageErrorId("LIBSQL", "SET_BUFFERING_REFLECTION_FLAG", "NOT_FOUND"),
@@ -8682,10 +8722,13 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8682
8722
  async clearObservationalMemory(threadId, resourceId) {
8683
8723
  try {
8684
8724
  const lookupKey = this.getOMKey(threadId, resourceId);
8685
- await this.#client.execute({
8686
- sql: `DELETE FROM "${OM_TABLE}" WHERE "lookupKey" = ?`,
8687
- args: [lookupKey]
8688
- });
8725
+ await withClientWriteLock(
8726
+ this.#client,
8727
+ () => this.#client.execute({
8728
+ sql: `DELETE FROM "${OM_TABLE}" WHERE "lookupKey" = ?`,
8729
+ args: [lookupKey]
8730
+ })
8731
+ );
8689
8732
  } catch (error) {
8690
8733
  throw new MastraError(
8691
8734
  {
@@ -8700,13 +8743,16 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8700
8743
  }
8701
8744
  async setPendingMessageTokens(id, tokenCount) {
8702
8745
  try {
8703
- const result = await this.#client.execute({
8704
- sql: `UPDATE "${OM_TABLE}" SET
8705
- "pendingMessageTokens" = ?,
8706
- "updatedAt" = ?
8707
- WHERE id = ?`,
8708
- args: [tokenCount, (/* @__PURE__ */ new Date()).toISOString(), id]
8709
- });
8746
+ const result = await withClientWriteLock(
8747
+ this.#client,
8748
+ () => this.#client.execute({
8749
+ sql: `UPDATE "${OM_TABLE}" SET
8750
+ "pendingMessageTokens" = ?,
8751
+ "updatedAt" = ?
8752
+ WHERE id = ?`,
8753
+ args: [tokenCount, (/* @__PURE__ */ new Date()).toISOString(), id]
8754
+ })
8755
+ );
8710
8756
  if (result.rowsAffected === 0) {
8711
8757
  throw new MastraError({
8712
8758
  id: createStorageErrorId("LIBSQL", "SET_PENDING_MESSAGE_TOKENS", "NOT_FOUND"),
@@ -8733,25 +8779,34 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8733
8779
  }
8734
8780
  async updateObservationalMemoryConfig(input) {
8735
8781
  try {
8736
- const selectResult = await this.#client.execute({
8737
- sql: `SELECT config FROM "${OM_TABLE}" WHERE id = ?`,
8738
- args: [input.id]
8739
- });
8740
- if (selectResult.rows.length === 0) {
8741
- throw new MastraError({
8742
- id: createStorageErrorId("LIBSQL", "UPDATE_OM_CONFIG", "NOT_FOUND"),
8743
- text: `Observational memory record not found: ${input.id}`,
8744
- domain: ErrorDomain.STORAGE,
8745
- category: ErrorCategory.THIRD_PARTY,
8746
- details: { id: input.id }
8747
- });
8748
- }
8749
- const row = selectResult.rows[0];
8750
- const existing = row.config ? JSON.parse(row.config) : {};
8751
- const merged = this.deepMergeConfig(existing, input.config);
8752
- await this.#client.execute({
8753
- sql: `UPDATE "${OM_TABLE}" SET config = ?, "updatedAt" = ? WHERE id = ?`,
8754
- args: [JSON.stringify(merged), (/* @__PURE__ */ new Date()).toISOString(), input.id]
8782
+ await withClientWriteLock(this.#client, async () => {
8783
+ const tx = await this.#client.transaction("write");
8784
+ try {
8785
+ const selectResult = await tx.execute({
8786
+ sql: `SELECT config FROM "${OM_TABLE}" WHERE id = ?`,
8787
+ args: [input.id]
8788
+ });
8789
+ if (selectResult.rows.length === 0) {
8790
+ throw new MastraError({
8791
+ id: createStorageErrorId("LIBSQL", "UPDATE_OM_CONFIG", "NOT_FOUND"),
8792
+ text: `Observational memory record not found: ${input.id}`,
8793
+ domain: ErrorDomain.STORAGE,
8794
+ category: ErrorCategory.THIRD_PARTY,
8795
+ details: { id: input.id }
8796
+ });
8797
+ }
8798
+ const row = selectResult.rows[0];
8799
+ const existing = row.config ? JSON.parse(row.config) : {};
8800
+ const merged = this.deepMergeConfig(existing, input.config);
8801
+ await tx.execute({
8802
+ sql: `UPDATE "${OM_TABLE}" SET config = ?, "updatedAt" = ? WHERE id = ?`,
8803
+ args: [JSON.stringify(merged), (/* @__PURE__ */ new Date()).toISOString(), input.id]
8804
+ });
8805
+ await tx.commit();
8806
+ } catch (error) {
8807
+ if (!tx.closed) await tx.rollback();
8808
+ throw error;
8809
+ }
8755
8810
  });
8756
8811
  } catch (error) {
8757
8812
  if (error instanceof MastraError) {
@@ -8774,63 +8829,72 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8774
8829
  async updateBufferedObservations(input) {
8775
8830
  try {
8776
8831
  const nowStr = (/* @__PURE__ */ new Date()).toISOString();
8777
- const current = await this.#client.execute({
8778
- sql: `SELECT "bufferedObservationChunks" FROM "${OM_TABLE}" WHERE id = ?`,
8779
- args: [input.id]
8780
- });
8781
- if (!current.rows || current.rows.length === 0) {
8782
- throw new MastraError({
8783
- id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
8784
- text: `Observational memory record not found: ${input.id}`,
8785
- domain: ErrorDomain.STORAGE,
8786
- category: ErrorCategory.THIRD_PARTY,
8787
- details: { id: input.id }
8788
- });
8789
- }
8790
- const row = current.rows[0];
8791
- let existingChunks = [];
8792
- if (row.bufferedObservationChunks) {
8832
+ await withClientWriteLock(this.#client, async () => {
8833
+ const tx = await this.#client.transaction("write");
8793
8834
  try {
8794
- const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
8795
- existingChunks = Array.isArray(parsed) ? parsed : [];
8796
- } catch {
8797
- existingChunks = [];
8835
+ const current = await tx.execute({
8836
+ sql: `SELECT "bufferedObservationChunks" FROM "${OM_TABLE}" WHERE id = ?`,
8837
+ args: [input.id]
8838
+ });
8839
+ if (!current.rows || current.rows.length === 0) {
8840
+ throw new MastraError({
8841
+ id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
8842
+ text: `Observational memory record not found: ${input.id}`,
8843
+ domain: ErrorDomain.STORAGE,
8844
+ category: ErrorCategory.THIRD_PARTY,
8845
+ details: { id: input.id }
8846
+ });
8847
+ }
8848
+ const row = current.rows[0];
8849
+ let existingChunks = [];
8850
+ if (row.bufferedObservationChunks) {
8851
+ try {
8852
+ const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
8853
+ existingChunks = Array.isArray(parsed) ? parsed : [];
8854
+ } catch {
8855
+ existingChunks = [];
8856
+ }
8857
+ }
8858
+ const newChunk = {
8859
+ id: `ombuf-${randomUUID()}`,
8860
+ cycleId: input.chunk.cycleId,
8861
+ observations: input.chunk.observations,
8862
+ tokenCount: input.chunk.tokenCount,
8863
+ messageIds: input.chunk.messageIds,
8864
+ messageTokens: input.chunk.messageTokens,
8865
+ lastObservedAt: input.chunk.lastObservedAt,
8866
+ createdAt: /* @__PURE__ */ new Date(),
8867
+ suggestedContinuation: input.chunk.suggestedContinuation,
8868
+ currentTask: input.chunk.currentTask,
8869
+ threadTitle: input.chunk.threadTitle,
8870
+ extractedValues: input.chunk.extractedValues,
8871
+ extractionFailures: input.chunk.extractionFailures
8872
+ };
8873
+ const newChunks = [...existingChunks, newChunk];
8874
+ const lastBufferedAtTime = input.lastBufferedAtTime ? input.lastBufferedAtTime.toISOString() : null;
8875
+ const result = await tx.execute({
8876
+ sql: `UPDATE "${OM_TABLE}" SET
8877
+ "bufferedObservationChunks" = ?,
8878
+ "lastBufferedAtTime" = COALESCE(?, "lastBufferedAtTime"),
8879
+ "updatedAt" = ?
8880
+ WHERE id = ?`,
8881
+ args: [JSON.stringify(newChunks), lastBufferedAtTime, nowStr, input.id]
8882
+ });
8883
+ if (result.rowsAffected === 0) {
8884
+ throw new MastraError({
8885
+ id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
8886
+ text: `Observational memory record not found: ${input.id}`,
8887
+ domain: ErrorDomain.STORAGE,
8888
+ category: ErrorCategory.THIRD_PARTY,
8889
+ details: { id: input.id }
8890
+ });
8891
+ }
8892
+ await tx.commit();
8893
+ } catch (error) {
8894
+ if (!tx.closed) await tx.rollback();
8895
+ throw error;
8798
8896
  }
8799
- }
8800
- const newChunk = {
8801
- id: `ombuf-${randomUUID()}`,
8802
- cycleId: input.chunk.cycleId,
8803
- observations: input.chunk.observations,
8804
- tokenCount: input.chunk.tokenCount,
8805
- messageIds: input.chunk.messageIds,
8806
- messageTokens: input.chunk.messageTokens,
8807
- lastObservedAt: input.chunk.lastObservedAt,
8808
- createdAt: /* @__PURE__ */ new Date(),
8809
- suggestedContinuation: input.chunk.suggestedContinuation,
8810
- currentTask: input.chunk.currentTask,
8811
- threadTitle: input.chunk.threadTitle,
8812
- extractedValues: input.chunk.extractedValues,
8813
- extractionFailures: input.chunk.extractionFailures
8814
- };
8815
- const newChunks = [...existingChunks, newChunk];
8816
- const lastBufferedAtTime = input.lastBufferedAtTime ? input.lastBufferedAtTime.toISOString() : null;
8817
- const result = await this.#client.execute({
8818
- sql: `UPDATE "${OM_TABLE}" SET
8819
- "bufferedObservationChunks" = ?,
8820
- "lastBufferedAtTime" = COALESCE(?, "lastBufferedAtTime"),
8821
- "updatedAt" = ?
8822
- WHERE id = ?`,
8823
- args: [JSON.stringify(newChunks), lastBufferedAtTime, nowStr, input.id]
8824
8897
  });
8825
- if (result.rowsAffected === 0) {
8826
- throw new MastraError({
8827
- id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
8828
- text: `Observational memory record not found: ${input.id}`,
8829
- domain: ErrorDomain.STORAGE,
8830
- category: ErrorCategory.THIRD_PARTY,
8831
- details: { id: input.id }
8832
- });
8833
- }
8834
8898
  } catch (error) {
8835
8899
  if (error instanceof MastraError) {
8836
8900
  throw error;
@@ -8849,150 +8913,160 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
8849
8913
  async swapBufferedToActive(input) {
8850
8914
  try {
8851
8915
  const nowStr = (/* @__PURE__ */ new Date()).toISOString();
8852
- const current = await this.#client.execute({
8853
- sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
8854
- args: [input.id]
8855
- });
8856
- if (!current.rows || current.rows.length === 0) {
8857
- throw new MastraError({
8858
- id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_TO_ACTIVE", "NOT_FOUND"),
8859
- text: `Observational memory record not found: ${input.id}`,
8860
- domain: ErrorDomain.STORAGE,
8861
- category: ErrorCategory.THIRD_PARTY,
8862
- details: { id: input.id }
8863
- });
8864
- }
8865
- const row = current.rows[0];
8866
- let chunks = [];
8867
- if (row.bufferedObservationChunks) {
8916
+ return await withClientWriteLock(this.#client, async () => {
8917
+ const tx = await this.#client.transaction("write");
8868
8918
  try {
8869
- const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
8870
- chunks = Array.isArray(parsed) ? parsed : [];
8871
- } catch {
8872
- chunks = [];
8873
- }
8874
- }
8875
- if (chunks.length === 0) {
8876
- return {
8877
- chunksActivated: 0,
8878
- messageTokensActivated: 0,
8879
- observationTokensActivated: 0,
8880
- messagesActivated: 0,
8881
- activatedCycleIds: [],
8882
- activatedMessageIds: []
8883
- };
8884
- }
8885
- const retentionFloor = input.messageTokensThreshold * (1 - input.activationRatio);
8886
- const targetMessageTokens = Math.max(0, input.currentPendingTokens - retentionFloor);
8887
- let cumulativeMessageTokens = 0;
8888
- let bestOverBoundary = 0;
8889
- let bestOverTokens = 0;
8890
- let bestUnderBoundary = 0;
8891
- let bestUnderTokens = 0;
8892
- for (let i = 0; i < chunks.length; i++) {
8893
- cumulativeMessageTokens += chunks[i].messageTokens ?? 0;
8894
- const boundary2 = i + 1;
8895
- if (cumulativeMessageTokens >= targetMessageTokens) {
8896
- if (bestOverBoundary === 0 || cumulativeMessageTokens < bestOverTokens) {
8897
- bestOverBoundary = boundary2;
8898
- bestOverTokens = cumulativeMessageTokens;
8919
+ const current = await tx.execute({
8920
+ sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
8921
+ args: [input.id]
8922
+ });
8923
+ if (!current.rows || current.rows.length === 0) {
8924
+ throw new MastraError({
8925
+ id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_TO_ACTIVE", "NOT_FOUND"),
8926
+ text: `Observational memory record not found: ${input.id}`,
8927
+ domain: ErrorDomain.STORAGE,
8928
+ category: ErrorCategory.THIRD_PARTY,
8929
+ details: { id: input.id }
8930
+ });
8899
8931
  }
8900
- } else {
8901
- if (cumulativeMessageTokens > bestUnderTokens) {
8902
- bestUnderBoundary = boundary2;
8903
- bestUnderTokens = cumulativeMessageTokens;
8932
+ const row = current.rows[0];
8933
+ let chunks = [];
8934
+ if (row.bufferedObservationChunks) {
8935
+ try {
8936
+ const parsed = typeof row.bufferedObservationChunks === "string" ? JSON.parse(row.bufferedObservationChunks) : row.bufferedObservationChunks;
8937
+ chunks = Array.isArray(parsed) ? parsed : [];
8938
+ } catch {
8939
+ chunks = [];
8940
+ }
8904
8941
  }
8905
- }
8906
- }
8907
- const maxOvershoot = retentionFloor * 0.95;
8908
- const overshoot = bestOverTokens - targetMessageTokens;
8909
- const remainingAfterOver = input.currentPendingTokens - bestOverTokens;
8910
- const remainingAfterUnder = input.currentPendingTokens - bestUnderTokens;
8911
- const minRemaining = Math.min(1e3, retentionFloor);
8912
- let chunksToActivate;
8913
- if (input.forceMaxActivation && bestOverBoundary > 0 && remainingAfterOver >= minRemaining) {
8914
- chunksToActivate = bestOverBoundary;
8915
- } else if (bestOverBoundary > 0 && overshoot <= maxOvershoot && remainingAfterOver >= minRemaining) {
8916
- chunksToActivate = bestOverBoundary;
8917
- } else if (bestUnderBoundary > 0 && remainingAfterUnder >= minRemaining) {
8918
- chunksToActivate = bestUnderBoundary;
8919
- } else if (bestOverBoundary > 0) {
8920
- chunksToActivate = bestOverBoundary;
8921
- } else {
8922
- chunksToActivate = 1;
8923
- }
8924
- const activatedChunks = chunks.slice(0, chunksToActivate);
8925
- const remainingChunks = chunks.slice(chunksToActivate);
8926
- const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
8927
- const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
8928
- const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
8929
- const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
8930
- const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
8931
- const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
8932
- const latestChunk = activatedChunks[activatedChunks.length - 1];
8933
- const lastObservedAt = input.lastObservedAt ?? (latestChunk?.lastObservedAt ? new Date(latestChunk.lastObservedAt) : /* @__PURE__ */ new Date());
8934
- const lastObservedAtStr = lastObservedAt.toISOString();
8935
- const existingActive = row.activeObservations || "";
8936
- const existingTokenCount = Number(row.observationTokenCount || 0);
8937
- const boundary = `
8942
+ if (chunks.length === 0) {
8943
+ await tx.commit();
8944
+ return {
8945
+ chunksActivated: 0,
8946
+ messageTokensActivated: 0,
8947
+ observationTokensActivated: 0,
8948
+ messagesActivated: 0,
8949
+ activatedCycleIds: [],
8950
+ activatedMessageIds: []
8951
+ };
8952
+ }
8953
+ const retentionFloor = input.messageTokensThreshold * (1 - input.activationRatio);
8954
+ const targetMessageTokens = Math.max(0, input.currentPendingTokens - retentionFloor);
8955
+ let cumulativeMessageTokens = 0;
8956
+ let bestOverBoundary = 0;
8957
+ let bestOverTokens = 0;
8958
+ let bestUnderBoundary = 0;
8959
+ let bestUnderTokens = 0;
8960
+ for (let i = 0; i < chunks.length; i++) {
8961
+ cumulativeMessageTokens += chunks[i].messageTokens ?? 0;
8962
+ const boundary2 = i + 1;
8963
+ if (cumulativeMessageTokens >= targetMessageTokens) {
8964
+ if (bestOverBoundary === 0 || cumulativeMessageTokens < bestOverTokens) {
8965
+ bestOverBoundary = boundary2;
8966
+ bestOverTokens = cumulativeMessageTokens;
8967
+ }
8968
+ } else {
8969
+ if (cumulativeMessageTokens > bestUnderTokens) {
8970
+ bestUnderBoundary = boundary2;
8971
+ bestUnderTokens = cumulativeMessageTokens;
8972
+ }
8973
+ }
8974
+ }
8975
+ const maxOvershoot = retentionFloor * 0.95;
8976
+ const overshoot = bestOverTokens - targetMessageTokens;
8977
+ const remainingAfterOver = input.currentPendingTokens - bestOverTokens;
8978
+ const remainingAfterUnder = input.currentPendingTokens - bestUnderTokens;
8979
+ const minRemaining = Math.min(1e3, retentionFloor);
8980
+ let chunksToActivate;
8981
+ if (input.forceMaxActivation && bestOverBoundary > 0 && remainingAfterOver >= minRemaining) {
8982
+ chunksToActivate = bestOverBoundary;
8983
+ } else if (bestOverBoundary > 0 && overshoot <= maxOvershoot && remainingAfterOver >= minRemaining) {
8984
+ chunksToActivate = bestOverBoundary;
8985
+ } else if (bestUnderBoundary > 0 && remainingAfterUnder >= minRemaining) {
8986
+ chunksToActivate = bestUnderBoundary;
8987
+ } else if (bestOverBoundary > 0) {
8988
+ chunksToActivate = bestOverBoundary;
8989
+ } else {
8990
+ chunksToActivate = 1;
8991
+ }
8992
+ const activatedChunks = chunks.slice(0, chunksToActivate);
8993
+ const remainingChunks = chunks.slice(chunksToActivate);
8994
+ const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
8995
+ const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
8996
+ const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
8997
+ const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
8998
+ const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
8999
+ const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
9000
+ const latestChunk = activatedChunks[activatedChunks.length - 1];
9001
+ const lastObservedAt = input.lastObservedAt ?? (latestChunk?.lastObservedAt ? new Date(latestChunk.lastObservedAt) : /* @__PURE__ */ new Date());
9002
+ const lastObservedAtStr = lastObservedAt.toISOString();
9003
+ const existingActive = row.activeObservations || "";
9004
+ const existingTokenCount = Number(row.observationTokenCount || 0);
9005
+ const boundary = `
8938
9006
 
8939
9007
  --- message boundary (${lastObservedAt.toISOString()}) ---
8940
9008
 
8941
9009
  `;
8942
- const newActive = existingActive ? `${existingActive}${boundary}${activatedContent}` : activatedContent;
8943
- const newTokenCount = existingTokenCount + activatedTokens;
8944
- const existingPending = Number(row.pendingMessageTokens || 0);
8945
- const newPending = Math.max(0, existingPending - activatedMessageTokens);
8946
- const updateResult = await this.#client.execute({
8947
- sql: `UPDATE "${OM_TABLE}" SET
8948
- "activeObservations" = ?,
8949
- "observationTokenCount" = ?,
8950
- "pendingMessageTokens" = ?,
8951
- "bufferedObservationChunks" = ?,
8952
- "lastObservedAt" = ?,
8953
- "updatedAt" = ?
8954
- WHERE id = ?
8955
- AND "bufferedObservationChunks" IS NOT NULL
8956
- AND "bufferedObservationChunks" != '[]'`,
8957
- args: [
8958
- newActive,
8959
- newTokenCount,
8960
- newPending,
8961
- remainingChunks.length > 0 ? JSON.stringify(remainingChunks) : null,
8962
- lastObservedAtStr,
8963
- nowStr,
8964
- input.id
8965
- ]
9010
+ const newActive = existingActive ? `${existingActive}${boundary}${activatedContent}` : activatedContent;
9011
+ const newTokenCount = existingTokenCount + activatedTokens;
9012
+ const existingPending = Number(row.pendingMessageTokens || 0);
9013
+ const newPending = Math.max(0, existingPending - activatedMessageTokens);
9014
+ const updateResult = await tx.execute({
9015
+ sql: `UPDATE "${OM_TABLE}" SET
9016
+ "activeObservations" = ?,
9017
+ "observationTokenCount" = ?,
9018
+ "pendingMessageTokens" = ?,
9019
+ "bufferedObservationChunks" = ?,
9020
+ "lastObservedAt" = ?,
9021
+ "updatedAt" = ?
9022
+ WHERE id = ?
9023
+ AND "bufferedObservationChunks" IS NOT NULL
9024
+ AND "bufferedObservationChunks" != '[]'`,
9025
+ args: [
9026
+ newActive,
9027
+ newTokenCount,
9028
+ newPending,
9029
+ remainingChunks.length > 0 ? JSON.stringify(remainingChunks) : null,
9030
+ lastObservedAtStr,
9031
+ nowStr,
9032
+ input.id
9033
+ ]
9034
+ });
9035
+ await tx.commit();
9036
+ if (updateResult.rowsAffected === 0) {
9037
+ return {
9038
+ chunksActivated: 0,
9039
+ messageTokensActivated: 0,
9040
+ observationTokensActivated: 0,
9041
+ messagesActivated: 0,
9042
+ activatedCycleIds: [],
9043
+ activatedMessageIds: []
9044
+ };
9045
+ }
9046
+ const latestChunkHints = activatedChunks[activatedChunks.length - 1];
9047
+ return {
9048
+ chunksActivated: activatedChunks.length,
9049
+ messageTokensActivated: activatedMessageTokens,
9050
+ observationTokensActivated: activatedTokens,
9051
+ messagesActivated: activatedMessageCount,
9052
+ activatedCycleIds,
9053
+ activatedMessageIds,
9054
+ observations: activatedContent,
9055
+ perChunk: activatedChunks.map((c) => ({
9056
+ cycleId: c.cycleId ?? "",
9057
+ messageTokens: c.messageTokens ?? 0,
9058
+ observationTokens: c.tokenCount,
9059
+ messageCount: c.messageIds.length,
9060
+ observations: c.observations
9061
+ })),
9062
+ suggestedContinuation: latestChunkHints?.suggestedContinuation ?? void 0,
9063
+ currentTask: latestChunkHints?.currentTask ?? void 0
9064
+ };
9065
+ } catch (error) {
9066
+ if (!tx.closed) await tx.rollback();
9067
+ throw error;
9068
+ }
8966
9069
  });
8967
- if (updateResult.rowsAffected === 0) {
8968
- return {
8969
- chunksActivated: 0,
8970
- messageTokensActivated: 0,
8971
- observationTokensActivated: 0,
8972
- messagesActivated: 0,
8973
- activatedCycleIds: [],
8974
- activatedMessageIds: []
8975
- };
8976
- }
8977
- const latestChunkHints = activatedChunks[activatedChunks.length - 1];
8978
- return {
8979
- chunksActivated: activatedChunks.length,
8980
- messageTokensActivated: activatedMessageTokens,
8981
- observationTokensActivated: activatedTokens,
8982
- messagesActivated: activatedMessageCount,
8983
- activatedCycleIds,
8984
- activatedMessageIds,
8985
- observations: activatedContent,
8986
- perChunk: activatedChunks.map((c) => ({
8987
- cycleId: c.cycleId ?? "",
8988
- messageTokens: c.messageTokens ?? 0,
8989
- observationTokens: c.tokenCount,
8990
- messageCount: c.messageIds.length,
8991
- observations: c.observations
8992
- })),
8993
- suggestedContinuation: latestChunkHints?.suggestedContinuation ?? void 0,
8994
- currentTask: latestChunkHints?.currentTask ?? void 0
8995
- };
8996
9070
  } catch (error) {
8997
9071
  if (error instanceof MastraError) {
8998
9072
  throw error;
@@ -9011,28 +9085,31 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
9011
9085
  async updateBufferedReflection(input) {
9012
9086
  try {
9013
9087
  const nowStr = (/* @__PURE__ */ new Date()).toISOString();
9014
- const result = await this.#client.execute({
9015
- sql: `UPDATE "${OM_TABLE}" SET
9016
- "bufferedReflection" = CASE
9017
- WHEN "bufferedReflection" IS NOT NULL AND "bufferedReflection" != ''
9018
- THEN "bufferedReflection" || char(10) || char(10) || ?
9019
- ELSE ?
9020
- END,
9021
- "bufferedReflectionTokens" = COALESCE("bufferedReflectionTokens", 0) + ?,
9022
- "bufferedReflectionInputTokens" = COALESCE("bufferedReflectionInputTokens", 0) + ?,
9023
- "reflectedObservationLineCount" = ?,
9024
- "updatedAt" = ?
9025
- WHERE id = ?`,
9026
- args: [
9027
- input.reflection,
9028
- input.reflection,
9029
- input.tokenCount,
9030
- input.inputTokenCount,
9031
- input.reflectedObservationLineCount,
9032
- nowStr,
9033
- input.id
9034
- ]
9035
- });
9088
+ const result = await withClientWriteLock(
9089
+ this.#client,
9090
+ () => this.#client.execute({
9091
+ sql: `UPDATE "${OM_TABLE}" SET
9092
+ "bufferedReflection" = CASE
9093
+ WHEN "bufferedReflection" IS NOT NULL AND "bufferedReflection" != ''
9094
+ THEN "bufferedReflection" || char(10) || char(10) || ?
9095
+ ELSE ?
9096
+ END,
9097
+ "bufferedReflectionTokens" = COALESCE("bufferedReflectionTokens", 0) + ?,
9098
+ "bufferedReflectionInputTokens" = COALESCE("bufferedReflectionInputTokens", 0) + ?,
9099
+ "reflectedObservationLineCount" = ?,
9100
+ "updatedAt" = ?
9101
+ WHERE id = ?`,
9102
+ args: [
9103
+ input.reflection,
9104
+ input.reflection,
9105
+ input.tokenCount,
9106
+ input.inputTokenCount,
9107
+ input.reflectedObservationLineCount,
9108
+ nowStr,
9109
+ input.id
9110
+ ]
9111
+ })
9112
+ );
9036
9113
  if (result.rowsAffected === 0) {
9037
9114
  throw new MastraError({
9038
9115
  id: createStorageErrorId("LIBSQL", "UPDATE_BUFFERED_REFLECTION", "NOT_FOUND"),
@@ -9059,55 +9136,64 @@ var MemoryLibSQL = class _MemoryLibSQL extends MemoryStorage {
9059
9136
  }
9060
9137
  async swapBufferedReflectionToActive(input) {
9061
9138
  try {
9062
- const current = await this.#client.execute({
9063
- sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
9064
- args: [input.currentRecord.id]
9065
- });
9066
- if (!current.rows || current.rows.length === 0) {
9067
- throw new MastraError({
9068
- id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NOT_FOUND"),
9069
- text: `Observational memory record not found: ${input.currentRecord.id}`,
9070
- domain: ErrorDomain.STORAGE,
9071
- category: ErrorCategory.THIRD_PARTY,
9072
- details: { id: input.currentRecord.id }
9073
- });
9074
- }
9075
- const row = current.rows[0];
9076
- const bufferedReflection = row.bufferedReflection || "";
9077
- const reflectedLineCount = Number(row.reflectedObservationLineCount || 0);
9078
- if (!bufferedReflection) {
9079
- throw new MastraError({
9080
- id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NO_CONTENT"),
9081
- text: "No buffered reflection to swap",
9082
- domain: ErrorDomain.STORAGE,
9083
- category: ErrorCategory.USER,
9084
- details: { id: input.currentRecord.id }
9085
- });
9086
- }
9087
- const currentObservations = row.activeObservations || "";
9088
- const allLines = currentObservations.split("\n");
9089
- const unreflectedLines = allLines.slice(reflectedLineCount);
9090
- const unreflectedContent = unreflectedLines.join("\n").trim();
9091
- const newObservations = unreflectedContent ? `${bufferedReflection}
9139
+ return await withClientWriteLock(this.#client, async () => {
9140
+ const tx = await this.#client.transaction("write");
9141
+ try {
9142
+ const current = await tx.execute({
9143
+ sql: `SELECT * FROM "${OM_TABLE}" WHERE id = ?`,
9144
+ args: [input.currentRecord.id]
9145
+ });
9146
+ if (!current.rows || current.rows.length === 0) {
9147
+ throw new MastraError({
9148
+ id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NOT_FOUND"),
9149
+ text: `Observational memory record not found: ${input.currentRecord.id}`,
9150
+ domain: ErrorDomain.STORAGE,
9151
+ category: ErrorCategory.THIRD_PARTY,
9152
+ details: { id: input.currentRecord.id }
9153
+ });
9154
+ }
9155
+ const row = current.rows[0];
9156
+ const bufferedReflection = row.bufferedReflection || "";
9157
+ const reflectedLineCount = Number(row.reflectedObservationLineCount || 0);
9158
+ if (!bufferedReflection) {
9159
+ throw new MastraError({
9160
+ id: createStorageErrorId("LIBSQL", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NO_CONTENT"),
9161
+ text: "No buffered reflection to swap",
9162
+ domain: ErrorDomain.STORAGE,
9163
+ category: ErrorCategory.USER,
9164
+ details: { id: input.currentRecord.id }
9165
+ });
9166
+ }
9167
+ const currentObservations = row.activeObservations || "";
9168
+ const allLines = currentObservations.split("\n");
9169
+ const unreflectedLines = allLines.slice(reflectedLineCount);
9170
+ const unreflectedContent = unreflectedLines.join("\n").trim();
9171
+ const newObservations = unreflectedContent ? `${bufferedReflection}
9092
9172
 
9093
9173
  ${unreflectedContent}` : bufferedReflection;
9094
- const newRecord = await this.createReflectionGeneration({
9095
- currentRecord: input.currentRecord,
9096
- reflection: newObservations,
9097
- tokenCount: input.tokenCount
9174
+ const newRecord = await this.#insertReflectionGeneration(tx, {
9175
+ currentRecord: input.currentRecord,
9176
+ reflection: newObservations,
9177
+ tokenCount: input.tokenCount
9178
+ });
9179
+ const nowStr = (/* @__PURE__ */ new Date()).toISOString();
9180
+ await tx.execute({
9181
+ sql: `UPDATE "${OM_TABLE}" SET
9182
+ "bufferedReflection" = NULL,
9183
+ "bufferedReflectionTokens" = NULL,
9184
+ "bufferedReflectionInputTokens" = NULL,
9185
+ "reflectedObservationLineCount" = NULL,
9186
+ "updatedAt" = ?
9187
+ WHERE id = ?`,
9188
+ args: [nowStr, input.currentRecord.id]
9189
+ });
9190
+ await tx.commit();
9191
+ return newRecord;
9192
+ } catch (error) {
9193
+ if (!tx.closed) await tx.rollback();
9194
+ throw error;
9195
+ }
9098
9196
  });
9099
- const nowStr = (/* @__PURE__ */ new Date()).toISOString();
9100
- await this.#client.execute({
9101
- sql: `UPDATE "${OM_TABLE}" SET
9102
- "bufferedReflection" = NULL,
9103
- "bufferedReflectionTokens" = NULL,
9104
- "bufferedReflectionInputTokens" = NULL,
9105
- "reflectedObservationLineCount" = NULL,
9106
- "updatedAt" = ?
9107
- WHERE id = ?`,
9108
- args: [nowStr, input.currentRecord.id]
9109
- });
9110
- return newRecord;
9111
9197
  } catch (error) {
9112
9198
  if (error instanceof MastraError) {
9113
9199
  throw error;