@mastra/libsql 1.22.5 → 1.22.6-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
@@ -4140,94 +4140,122 @@ var DatasetsLibSQL = class extends DatasetsStorage {
4140
4140
  }
4141
4141
  async _doUpdateItem(args) {
4142
4142
  try {
4143
- const existing = await this.getItemById({ id: args.id });
4144
- if (!existing) throw new MastraError({
4145
- id: createStorageErrorId("LIBSQL", "UPDATE_ITEM", "NOT_FOUND"),
4146
- domain: ErrorDomain.STORAGE,
4147
- category: ErrorCategory.USER,
4148
- details: { itemId: args.id }
4149
- });
4150
- if (existing.datasetId !== args.datasetId) throw new MastraError({
4151
- id: createStorageErrorId("LIBSQL", "UPDATE_ITEM", "DATASET_MISMATCH"),
4152
- domain: ErrorDomain.STORAGE,
4153
- category: ErrorCategory.USER,
4154
- details: {
4155
- itemId: args.id,
4156
- expectedDatasetId: args.datasetId,
4157
- actualDatasetId: existing.datasetId
4143
+ return await withClientWriteLock(this.#client, async () => {
4144
+ const tx = await this.#client.transaction("write");
4145
+ try {
4146
+ const itemResult = await tx.execute({
4147
+ sql: `SELECT ${buildSelectColumns(TABLE_DATASET_ITEMS)} FROM ${TABLE_DATASET_ITEMS} WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4148
+ args: [args.id]
4149
+ });
4150
+ const existing = itemResult.rows[0] ? this.transformItemRow(itemResult.rows[0]) : null;
4151
+ if (!existing) throw new MastraError({
4152
+ id: createStorageErrorId("LIBSQL", "UPDATE_ITEM", "NOT_FOUND"),
4153
+ domain: ErrorDomain.STORAGE,
4154
+ category: ErrorCategory.USER,
4155
+ details: { itemId: args.id }
4156
+ });
4157
+ if (existing.datasetId !== args.datasetId) throw new MastraError({
4158
+ id: createStorageErrorId("LIBSQL", "UPDATE_ITEM", "DATASET_MISMATCH"),
4159
+ domain: ErrorDomain.STORAGE,
4160
+ category: ErrorCategory.USER,
4161
+ details: {
4162
+ itemId: args.id,
4163
+ expectedDatasetId: args.datasetId,
4164
+ actualDatasetId: existing.datasetId
4165
+ }
4166
+ });
4167
+ if (existing.metadata?.__purged === true) throw new MastraError({
4168
+ id: "DATASET_ITEM_PURGED",
4169
+ domain: ErrorDomain.STORAGE,
4170
+ category: ErrorCategory.USER,
4171
+ details: {
4172
+ datasetId: args.datasetId,
4173
+ itemId: args.id
4174
+ },
4175
+ text: `Purged dataset item cannot be updated: ${args.id}`
4176
+ });
4177
+ const dataset = (await tx.execute({
4178
+ sql: `SELECT organizationId, projectId FROM ${TABLE_DATASETS} WHERE id = ?`,
4179
+ args: [args.datasetId]
4180
+ })).rows[0];
4181
+ const organizationId = typeof dataset?.organizationId === "string" ? dataset.organizationId : null;
4182
+ const projectId = typeof dataset?.projectId === "string" ? dataset.projectId : null;
4183
+ const versionId = crypto.randomUUID();
4184
+ const now = /* @__PURE__ */ new Date();
4185
+ const nowIso = now.toISOString();
4186
+ const mergedInput = args.input !== void 0 ? args.input : existing.input;
4187
+ const mergedGroundTruth = args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth;
4188
+ const mergedExpectedTrajectory = args.expectedTrajectory !== void 0 ? args.expectedTrajectory : existing.expectedTrajectory;
4189
+ const mergedToolMocks = args.toolMocks !== void 0 ? args.toolMocks : existing.toolMocks;
4190
+ const mergedUnmockedToolPolicy = args.unmockedToolPolicy !== void 0 ? args.unmockedToolPolicy : existing.unmockedToolPolicy;
4191
+ const mergedScorerIds = args.scorerIds !== void 0 ? args.scorerIds ?? void 0 : existing.scorerIds;
4192
+ const mergedRequestContext = args.requestContext !== void 0 ? args.requestContext : existing.requestContext;
4193
+ const mergedMetadata = args.metadata !== void 0 ? args.metadata : existing.metadata;
4194
+ const mergedSource = args.source !== void 0 ? args.source : existing.source;
4195
+ const versionResult = await tx.execute({
4196
+ sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
4197
+ args: [args.datasetId]
4198
+ });
4199
+ const newVersion = Number(versionResult.rows[0].version);
4200
+ await tx.execute({
4201
+ sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = ? WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4202
+ args: [newVersion, args.id]
4203
+ });
4204
+ await tx.execute({
4205
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,?,?,?,?,NULL,0,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4206
+ args: [
4207
+ args.id,
4208
+ args.datasetId,
4209
+ newVersion,
4210
+ existing.externalId ?? null,
4211
+ organizationId,
4212
+ projectId,
4213
+ jsonbArg(mergedInput),
4214
+ jsonbArg(mergedGroundTruth),
4215
+ jsonbArg(mergedExpectedTrajectory),
4216
+ jsonbArg(mergedToolMocks),
4217
+ mergedUnmockedToolPolicy ?? null,
4218
+ jsonbArg(mergedScorerIds),
4219
+ jsonbArg(mergedRequestContext),
4220
+ jsonbArg(mergedMetadata),
4221
+ jsonbArg(mergedSource),
4222
+ existing.createdAt.toISOString(),
4223
+ nowIso
4224
+ ]
4225
+ });
4226
+ await tx.execute({
4227
+ sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, ?, ?)`,
4228
+ args: [
4229
+ versionId,
4230
+ args.datasetId,
4231
+ newVersion,
4232
+ nowIso
4233
+ ]
4234
+ });
4235
+ await tx.commit();
4236
+ return {
4237
+ ...existing,
4238
+ datasetVersion: newVersion,
4239
+ organizationId,
4240
+ projectId,
4241
+ input: mergedInput,
4242
+ groundTruth: mergedGroundTruth,
4243
+ expectedTrajectory: mergedExpectedTrajectory,
4244
+ toolMocks: mergedToolMocks,
4245
+ unmockedToolPolicy: mergedUnmockedToolPolicy,
4246
+ scorerIds: mergedScorerIds,
4247
+ requestContext: mergedRequestContext,
4248
+ metadata: mergedMetadata,
4249
+ source: mergedSource,
4250
+ updatedAt: now
4251
+ };
4252
+ } catch (error) {
4253
+ if (!tx.closed) await tx.rollback().catch((rollbackError) => {
4254
+ throw new AggregateError([error, rollbackError], "Transaction and rollback both failed");
4255
+ });
4256
+ throw error;
4158
4257
  }
4159
4258
  });
4160
- const dataset = await this.getDatasetById({ id: args.datasetId });
4161
- const versionId = crypto.randomUUID();
4162
- const now = /* @__PURE__ */ new Date();
4163
- const nowIso = now.toISOString();
4164
- const mergedInput = args.input !== void 0 ? args.input : existing.input;
4165
- const mergedGroundTruth = args.groundTruth !== void 0 ? args.groundTruth : existing.groundTruth;
4166
- const mergedExpectedTrajectory = args.expectedTrajectory !== void 0 ? args.expectedTrajectory : existing.expectedTrajectory;
4167
- const mergedToolMocks = args.toolMocks !== void 0 ? args.toolMocks : existing.toolMocks;
4168
- const mergedUnmockedToolPolicy = args.unmockedToolPolicy !== void 0 ? args.unmockedToolPolicy : existing.unmockedToolPolicy;
4169
- const mergedScorerIds = args.scorerIds !== void 0 ? args.scorerIds ?? void 0 : existing.scorerIds;
4170
- const mergedRequestContext = args.requestContext !== void 0 ? args.requestContext : existing.requestContext;
4171
- const mergedMetadata = args.metadata !== void 0 ? args.metadata : existing.metadata;
4172
- const mergedSource = args.source !== void 0 ? args.source : existing.source;
4173
- const results = await this.#client.batch([
4174
- {
4175
- sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
4176
- args: [args.datasetId]
4177
- },
4178
- {
4179
- sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4180
- args: [args.datasetId, args.id]
4181
- },
4182
- {
4183
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,(SELECT version FROM ${TABLE_DATASETS} WHERE id = ?),?,(SELECT organizationId FROM ${TABLE_DATASETS} WHERE id = ?),(SELECT projectId FROM ${TABLE_DATASETS} WHERE id = ?),NULL,0,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4184
- args: [
4185
- args.id,
4186
- args.datasetId,
4187
- args.datasetId,
4188
- existing.externalId ?? null,
4189
- args.datasetId,
4190
- args.datasetId,
4191
- jsonbArg(mergedInput),
4192
- jsonbArg(mergedGroundTruth),
4193
- jsonbArg(mergedExpectedTrajectory),
4194
- jsonbArg(mergedToolMocks),
4195
- mergedUnmockedToolPolicy ?? null,
4196
- jsonbArg(mergedScorerIds),
4197
- jsonbArg(mergedRequestContext),
4198
- jsonbArg(mergedMetadata),
4199
- jsonbArg(mergedSource),
4200
- existing.createdAt.toISOString(),
4201
- nowIso
4202
- ]
4203
- },
4204
- {
4205
- sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), ?)`,
4206
- args: [
4207
- versionId,
4208
- args.datasetId,
4209
- args.datasetId,
4210
- nowIso
4211
- ]
4212
- }
4213
- ], "write");
4214
- const newVersion = Number(results[0].rows[0].version);
4215
- return {
4216
- ...existing,
4217
- datasetVersion: newVersion,
4218
- organizationId: dataset?.organizationId ?? null,
4219
- projectId: dataset?.projectId ?? null,
4220
- input: mergedInput,
4221
- groundTruth: mergedGroundTruth,
4222
- expectedTrajectory: mergedExpectedTrajectory,
4223
- toolMocks: mergedToolMocks,
4224
- unmockedToolPolicy: mergedUnmockedToolPolicy,
4225
- scorerIds: mergedScorerIds,
4226
- requestContext: mergedRequestContext,
4227
- metadata: mergedMetadata,
4228
- source: mergedSource,
4229
- updatedAt: now
4230
- };
4231
4259
  } catch (error) {
4232
4260
  if (error instanceof MastraError) throw error;
4233
4261
  throw new MastraError({
@@ -4239,61 +4267,78 @@ var DatasetsLibSQL = class extends DatasetsStorage {
4239
4267
  }
4240
4268
  async _doDeleteItem({ id, datasetId }) {
4241
4269
  try {
4242
- const existing = await this.getItemById({ id });
4243
- if (!existing) return;
4244
- if (existing.datasetId !== datasetId) throw new MastraError({
4245
- id: createStorageErrorId("LIBSQL", "DELETE_ITEM", "DATASET_MISMATCH"),
4246
- domain: ErrorDomain.STORAGE,
4247
- category: ErrorCategory.USER,
4248
- details: {
4249
- itemId: id,
4250
- expectedDatasetId: datasetId,
4251
- actualDatasetId: existing.datasetId
4270
+ await withClientWriteLock(this.#client, async () => {
4271
+ const tx = await this.#client.transaction("write");
4272
+ try {
4273
+ const itemResult = await tx.execute({
4274
+ sql: `SELECT ${buildSelectColumns(TABLE_DATASET_ITEMS)} FROM ${TABLE_DATASET_ITEMS} WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4275
+ args: [id]
4276
+ });
4277
+ const existing = itemResult.rows[0] ? this.transformItemRow(itemResult.rows[0]) : null;
4278
+ if (!existing) {
4279
+ await tx.commit();
4280
+ return;
4281
+ }
4282
+ if (existing.datasetId !== datasetId) throw new MastraError({
4283
+ id: createStorageErrorId("LIBSQL", "DELETE_ITEM", "DATASET_MISMATCH"),
4284
+ domain: ErrorDomain.STORAGE,
4285
+ category: ErrorCategory.USER,
4286
+ details: {
4287
+ itemId: id,
4288
+ expectedDatasetId: datasetId,
4289
+ actualDatasetId: existing.datasetId
4290
+ }
4291
+ });
4292
+ const versionId = crypto.randomUUID();
4293
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4294
+ const dataset = (await tx.execute({
4295
+ sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version, organizationId, projectId`,
4296
+ args: [datasetId]
4297
+ })).rows[0];
4298
+ const newVersion = Number(dataset.version);
4299
+ await tx.execute({
4300
+ sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = ? WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4301
+ args: [newVersion, id]
4302
+ });
4303
+ await tx.execute({
4304
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,?,?,?,?,NULL,1,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4305
+ args: [
4306
+ id,
4307
+ datasetId,
4308
+ newVersion,
4309
+ existing.externalId ?? null,
4310
+ dataset.organizationId ?? null,
4311
+ dataset.projectId ?? null,
4312
+ jsonbArg(existing.input),
4313
+ jsonbArg(existing.groundTruth),
4314
+ jsonbArg(existing.expectedTrajectory),
4315
+ jsonbArg(existing.toolMocks),
4316
+ existing.unmockedToolPolicy ?? null,
4317
+ jsonbArg(existing.scorerIds),
4318
+ jsonbArg(existing.requestContext),
4319
+ jsonbArg(existing.metadata),
4320
+ jsonbArg(existing.source),
4321
+ existing.createdAt.toISOString(),
4322
+ nowIso
4323
+ ]
4324
+ });
4325
+ await tx.execute({
4326
+ sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, ?, ?)`,
4327
+ args: [
4328
+ versionId,
4329
+ datasetId,
4330
+ newVersion,
4331
+ nowIso
4332
+ ]
4333
+ });
4334
+ await tx.commit();
4335
+ } catch (error) {
4336
+ if (!tx.closed) await tx.rollback().catch((rollbackError) => {
4337
+ throw new AggregateError([error, rollbackError], "Transaction and rollback both failed");
4338
+ });
4339
+ throw error;
4252
4340
  }
4253
4341
  });
4254
- const versionId = crypto.randomUUID();
4255
- const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4256
- await this.#client.batch([
4257
- {
4258
- sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
4259
- args: [datasetId]
4260
- },
4261
- {
4262
- sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4263
- args: [datasetId, id]
4264
- },
4265
- {
4266
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,(SELECT version FROM ${TABLE_DATASETS} WHERE id = ?),?,(SELECT organizationId FROM ${TABLE_DATASETS} WHERE id = ?),(SELECT projectId FROM ${TABLE_DATASETS} WHERE id = ?),NULL,1,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4267
- args: [
4268
- id,
4269
- datasetId,
4270
- datasetId,
4271
- existing.externalId ?? null,
4272
- datasetId,
4273
- datasetId,
4274
- jsonbArg(existing.input),
4275
- jsonbArg(existing.groundTruth),
4276
- jsonbArg(existing.expectedTrajectory),
4277
- jsonbArg(existing.toolMocks),
4278
- existing.unmockedToolPolicy ?? null,
4279
- jsonbArg(existing.scorerIds),
4280
- jsonbArg(existing.requestContext),
4281
- jsonbArg(existing.metadata),
4282
- jsonbArg(existing.source),
4283
- existing.createdAt.toISOString(),
4284
- nowIso
4285
- ]
4286
- },
4287
- {
4288
- sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), ?)`,
4289
- args: [
4290
- versionId,
4291
- datasetId,
4292
- datasetId,
4293
- nowIso
4294
- ]
4295
- }
4296
- ], "write");
4297
4342
  } catch (error) {
4298
4343
  if (error instanceof MastraError) throw error;
4299
4344
  throw new MastraError({
@@ -4711,63 +4756,84 @@ var DatasetsLibSQL = class extends DatasetsStorage {
4711
4756
  }
4712
4757
  async _doBatchDeleteItems(input) {
4713
4758
  try {
4714
- const dataset = await this.getDatasetById({ id: input.datasetId });
4715
- if (!dataset) throw new MastraError({
4716
- id: createStorageErrorId("LIBSQL", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
4717
- domain: ErrorDomain.STORAGE,
4718
- category: ErrorCategory.USER,
4719
- details: { datasetId: input.datasetId }
4720
- });
4721
- const currentItems = [];
4722
- for (const itemId of input.itemIds) {
4723
- const item = await this.getItemById({ id: itemId });
4724
- if (item && item.datasetId === input.datasetId) currentItems.push(item);
4725
- }
4726
- if (currentItems.length === 0) return;
4727
- const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4728
- const versionId = crypto.randomUUID();
4729
- const statements = [{
4730
- sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
4731
- args: [input.datasetId]
4732
- }];
4733
- for (const item of currentItems) {
4734
- statements.push({
4735
- sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4736
- args: [input.datasetId, item.id]
4737
- });
4738
- statements.push({
4739
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,(SELECT version FROM ${TABLE_DATASETS} WHERE id = ?),?,?,?,NULL,1,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4740
- args: [
4741
- item.id,
4742
- input.datasetId,
4743
- input.datasetId,
4744
- item.externalId ?? null,
4745
- dataset.organizationId ?? null,
4746
- dataset.projectId ?? null,
4747
- jsonbArg(item.input),
4748
- jsonbArg(item.groundTruth),
4749
- jsonbArg(item.expectedTrajectory),
4750
- jsonbArg(item.toolMocks),
4751
- item.unmockedToolPolicy ?? null,
4752
- jsonbArg(item.scorerIds),
4753
- jsonbArg(item.requestContext),
4754
- jsonbArg(item.metadata),
4755
- jsonbArg(item.source),
4756
- item.createdAt.toISOString(),
4757
- nowIso
4758
- ]
4759
- });
4760
- }
4761
- statements.push({
4762
- sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), ?)`,
4763
- args: [
4764
- versionId,
4765
- input.datasetId,
4766
- input.datasetId,
4767
- nowIso
4768
- ]
4759
+ await withClientWriteLock(this.#client, async () => {
4760
+ const tx = await this.#client.transaction("write");
4761
+ try {
4762
+ const dataset = (await tx.execute({
4763
+ sql: `SELECT organizationId, projectId FROM ${TABLE_DATASETS} WHERE id = ?`,
4764
+ args: [input.datasetId]
4765
+ })).rows[0];
4766
+ if (!dataset) throw new MastraError({
4767
+ id: createStorageErrorId("LIBSQL", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
4768
+ domain: ErrorDomain.STORAGE,
4769
+ category: ErrorCategory.USER,
4770
+ details: { datasetId: input.datasetId }
4771
+ });
4772
+ const currentItems = [];
4773
+ for (const itemId of input.itemIds) {
4774
+ const itemResult = await tx.execute({
4775
+ sql: `SELECT ${buildSelectColumns(TABLE_DATASET_ITEMS)} FROM ${TABLE_DATASET_ITEMS} WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4776
+ args: [itemId]
4777
+ });
4778
+ const item = itemResult.rows[0] ? this.transformItemRow(itemResult.rows[0]) : null;
4779
+ if (item && item.datasetId === input.datasetId) currentItems.push(item);
4780
+ }
4781
+ if (currentItems.length === 0) {
4782
+ await tx.commit();
4783
+ return;
4784
+ }
4785
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4786
+ const versionId = crypto.randomUUID();
4787
+ const statements = [{
4788
+ sql: `UPDATE ${TABLE_DATASETS} SET version = version + 1 WHERE id = ? RETURNING version`,
4789
+ args: [input.datasetId]
4790
+ }];
4791
+ for (const item of currentItems) {
4792
+ statements.push({
4793
+ sql: `UPDATE ${TABLE_DATASET_ITEMS} SET validTo = (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?) WHERE id = ? AND validTo IS NULL AND isDeleted = 0`,
4794
+ args: [input.datasetId, item.id]
4795
+ });
4796
+ statements.push({
4797
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id,datasetId,datasetVersion,externalId,organizationId,projectId,validTo,isDeleted,input,groundTruth,expectedTrajectory,toolMocks,unmockedToolPolicy,scorerIds,requestContext,metadata,source,createdAt,updatedAt) VALUES (?,?,(SELECT version FROM ${TABLE_DATASETS} WHERE id = ?),?,?,?,NULL,1,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,jsonb(?),jsonb(?),jsonb(?),jsonb(?),?,?)`,
4798
+ args: [
4799
+ item.id,
4800
+ input.datasetId,
4801
+ input.datasetId,
4802
+ item.externalId ?? null,
4803
+ dataset.organizationId ?? null,
4804
+ dataset.projectId ?? null,
4805
+ jsonbArg(item.input),
4806
+ jsonbArg(item.groundTruth),
4807
+ jsonbArg(item.expectedTrajectory),
4808
+ jsonbArg(item.toolMocks),
4809
+ item.unmockedToolPolicy ?? null,
4810
+ jsonbArg(item.scorerIds),
4811
+ jsonbArg(item.requestContext),
4812
+ jsonbArg(item.metadata),
4813
+ jsonbArg(item.source),
4814
+ item.createdAt.toISOString(),
4815
+ nowIso
4816
+ ]
4817
+ });
4818
+ }
4819
+ statements.push({
4820
+ sql: `INSERT INTO ${TABLE_DATASET_VERSIONS} (id, datasetId, version, createdAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), ?)`,
4821
+ args: [
4822
+ versionId,
4823
+ input.datasetId,
4824
+ input.datasetId,
4825
+ nowIso
4826
+ ]
4827
+ });
4828
+ for (const statement of statements) await tx.execute(statement);
4829
+ await tx.commit();
4830
+ } catch (error) {
4831
+ if (!tx.closed) await tx.rollback().catch((rollbackError) => {
4832
+ throw new AggregateError([error, rollbackError], "Transaction and rollback both failed");
4833
+ });
4834
+ throw error;
4835
+ }
4769
4836
  });
4770
- await this.#client.batch(statements, "write");
4771
4837
  } catch (error) {
4772
4838
  if (error instanceof MastraError) throw error;
4773
4839
  throw new MastraError({
@@ -8746,8 +8812,9 @@ var MemoryLibSQL = class MemoryLibSQL extends MemoryStorage {
8746
8812
  text: `Thread with id ${newThreadId} already exists`,
8747
8813
  details: { newThreadId }
8748
8814
  });
8815
+ const hydrateMessages = options?.hydrateMessages ?? true;
8749
8816
  try {
8750
- let messageQuery = `SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
8817
+ let messageQuery = `SELECT ${hydrateMessages ? `id, content, role, type, "createdAt", thread_id, "resourceId"` : `id, "createdAt"`}
8751
8818
  FROM "${TABLE_MESSAGES}" WHERE thread_id = ?`;
8752
8819
  const messageParams = [sourceThreadId];
8753
8820
  if (options?.messageFilter?.startDate) {
@@ -8810,7 +8877,23 @@ var MemoryLibSQL = class MemoryLibSQL extends MemoryStorage {
8810
8877
  const targetResourceId = resourceId || sourceThread.resourceId;
8811
8878
  for (const sourceMsg of sourceMessages) {
8812
8879
  const newMessageId = crypto.randomUUID();
8813
- messageIdMap[sourceMsg.id] = newMessageId;
8880
+ const sourceMsgId = sourceMsg.id;
8881
+ messageIdMap[sourceMsgId] = newMessageId;
8882
+ if (!hydrateMessages) {
8883
+ const insertResult = await tx.execute({
8884
+ sql: `INSERT INTO "${TABLE_MESSAGES}" (id, thread_id, content, role, type, "createdAt", "resourceId")
8885
+ SELECT ?, ?, content, role, type, "createdAt", ?
8886
+ FROM "${TABLE_MESSAGES}" WHERE id = ?`,
8887
+ args: [
8888
+ newMessageId,
8889
+ newThreadId,
8890
+ targetResourceId,
8891
+ sourceMsgId
8892
+ ]
8893
+ });
8894
+ if (insertResult.rowsAffected !== 1) throw new Error(`Failed to clone message ${sourceMsgId}: expected 1 row copied but got ${insertResult.rowsAffected}`);
8895
+ continue;
8896
+ }
8814
8897
  const contentStr = sourceMsg.content;
8815
8898
  let parsedContent;
8816
8899
  try {