@mastra/mongodb 1.11.0 → 1.11.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.cjs CHANGED
@@ -15,7 +15,7 @@ var skills = require('@mastra/core/storage/domains/skills');
15
15
 
16
16
  // package.json
17
17
  var package_default = {
18
- version: "1.11.0"};
18
+ version: "1.11.1-alpha.0"};
19
19
  var MongoDBFilterTranslator = class extends filter.BaseFilterTranslator {
20
20
  getSupportedOperators() {
21
21
  return {
@@ -112,7 +112,6 @@ var MongoDBVector = class extends vector.MastraVector {
112
112
  embeddingFieldName;
113
113
  metadataFieldName = "metadata";
114
114
  documentFieldName = "document";
115
- collectionForValidation = null;
116
115
  mongoMetricMap = {
117
116
  cosine: "cosine",
118
117
  euclidean: "euclidean",
@@ -164,6 +163,17 @@ var MongoDBVector = class extends vector.MastraVector {
164
163
  );
165
164
  }
166
165
  }
166
+ /**
167
+ * Creates a MongoDB collection and the Atlas Search indexes that back a
168
+ * Mastra index with the given name.
169
+ *
170
+ * **Async index lifecycle:** Atlas Search indexes transition through
171
+ * PENDING → BUILDING → READY after this method returns. If you need to
172
+ * `upsert` or `query` immediately after calling `createIndex`, call
173
+ * `waitForIndexReady({ indexName })` first to block until the index is
174
+ * queryable. Skipping that step on a real Atlas cluster may cause
175
+ * "index not found" or "index not ready" errors on subsequent operations.
176
+ */
167
177
  async createIndex({ indexName, dimension, metric = "cosine" }) {
168
178
  let mongoMetric;
169
179
  try {
@@ -211,6 +221,10 @@ var MongoDBVector = class extends vector.MastraVector {
211
221
  {
212
222
  type: "filter",
213
223
  path: "_id"
224
+ },
225
+ {
226
+ type: "filter",
227
+ path: "document"
214
228
  }
215
229
  ]
216
230
  },
@@ -238,21 +252,6 @@ var MongoDBVector = class extends vector.MastraVector {
238
252
  );
239
253
  }
240
254
  }
241
- try {
242
- await collection?.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
243
- } catch (error$1) {
244
- throw new error.MastraError(
245
- {
246
- id: storage.createVectorErrorId("MONGODB", "CREATE_INDEX", "STORE_METADATA_FAILED"),
247
- domain: error.ErrorDomain.STORAGE,
248
- category: error.ErrorCategory.THIRD_PARTY,
249
- details: {
250
- indexName
251
- }
252
- },
253
- error$1
254
- );
255
- }
256
255
  }
257
256
  /**
258
257
  * Waits for the index to be ready.
@@ -281,12 +280,25 @@ var MongoDBVector = class extends vector.MastraVector {
281
280
  }
282
281
  throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
283
282
  }
283
+ /**
284
+ * Inserts or updates vectors in the specified index.
285
+ *
286
+ * @param indexName - Name of the index (MongoDB collection) to write into.
287
+ * @param vectors - Array of embedding vectors. Each must have the same
288
+ * dimension as declared when the index was created.
289
+ * @param metadata - Optional array of metadata objects, one per vector,
290
+ * stored in a nested `metadata` field alongside the embedding.
291
+ * @param ids - Optional string IDs for each vector, used as the MongoDB
292
+ * document `_id`. Auto-generated UUIDs are used when omitted.
293
+ * @param documents - Optional text strings associated with each vector,
294
+ * stored in a `document` field.
295
+ * @returns The IDs of the upserted vectors in input order.
296
+ */
284
297
  async upsert({ indexName, vectors, metadata, ids, documents }) {
285
298
  vector.validateUpsertInput("MONGODB", vectors, metadata, ids);
286
299
  vector.validateVectorValues("MONGODB", vectors);
287
300
  try {
288
301
  const collection = await this.getCollection(indexName);
289
- this.collectionForValidation = collection;
290
302
  const stats = await this.describeIndex({ indexName });
291
303
  await this.validateVectorDimensions(vectors, stats.dimension);
292
304
  const generatedIds = ids || vectors.map(() => uuid.v4());
@@ -333,13 +345,30 @@ var MongoDBVector = class extends vector.MastraVector {
333
345
  );
334
346
  }
335
347
  }
348
+ /**
349
+ * Runs an approximate nearest-neighbor search against the specified index.
350
+ *
351
+ * @param indexName - Name of the index (MongoDB collection) to search.
352
+ * @param queryVector - The query embedding. Must match the index dimension.
353
+ * @param topK - Maximum number of results to return (default: 10).
354
+ * @param filter - Optional metadata filter. Fields are matched against the
355
+ * nested `metadata` subdocument; no `metadata.` prefix is needed.
356
+ * @param includeVector - When true, each result includes the stored embedding
357
+ * in a `vector` field (default: false).
358
+ * @param documentFilter - Optional filter applied to the `document` text
359
+ * field, independent of `filter`.
360
+ * @param numCandidates - HNSW candidate pool size. Higher values improve
361
+ * recall at the cost of latency. Defaults to 20 * topK, capped at 10000.
362
+ * @returns Array of results ordered by descending similarity score.
363
+ */
336
364
  async query({
337
365
  indexName,
338
366
  queryVector,
339
367
  topK = 10,
340
368
  filter,
341
369
  includeVector = false,
342
- documentFilter
370
+ documentFilter,
371
+ numCandidates
343
372
  }) {
344
373
  if (!queryVector) {
345
374
  throw new error.MastraError({
@@ -353,36 +382,21 @@ var MongoDBVector = class extends vector.MastraVector {
353
382
  try {
354
383
  const collection = await this.getCollection(indexName, true);
355
384
  const indexNameInternal = `${indexName}_vector_index`;
356
- const mongoFilter = this.transformFilter(filter);
357
- const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
358
- const transformedMongoFilter = this.transformMetadataFilter(mongoFilter);
359
- let combinedFilter = {};
360
- if (Object.keys(transformedMongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
361
- combinedFilter = { $and: [transformedMongoFilter, documentMongoFilter] };
362
- } else if (Object.keys(transformedMongoFilter).length > 0) {
363
- combinedFilter = transformedMongoFilter;
364
- } else if (Object.keys(documentMongoFilter).length > 0) {
365
- combinedFilter = documentMongoFilter;
366
- }
385
+ const metadataFilter = this.transformMetadataFilter(this.transformFilter(filter));
386
+ const hasMetadataFilter = Object.keys(metadataFilter).length > 0;
367
387
  const vectorSearch = {
368
388
  index: indexNameInternal,
369
389
  queryVector,
370
390
  path: this.embeddingFieldName,
371
- numCandidates: Math.min(1e4, Math.max(100, topK)),
391
+ numCandidates: Math.min(1e4, Math.max(topK, numCandidates ?? topK * 20)),
372
392
  limit: Math.min(1e4, topK)
373
393
  };
374
- if (Object.keys(combinedFilter).length > 0) {
375
- const filterWithExclusion = {
376
- $and: [{ _id: { $ne: "__index_metadata__" } }, combinedFilter]
377
- };
378
- const candidateIds = await collection.aggregate([{ $match: filterWithExclusion }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
379
- if (candidateIds.length > 0) {
380
- vectorSearch.filter = { _id: { $in: candidateIds } };
381
- } else {
382
- return [];
383
- }
384
- } else {
385
- vectorSearch.filter = { _id: { $ne: "__index_metadata__" } };
394
+ if (hasMetadataFilter) {
395
+ const candidateIds = await collection.aggregate([{ $match: metadataFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
396
+ if (candidateIds.length === 0) return [];
397
+ vectorSearch.filter = documentFilter ? { $and: [{ _id: { $in: candidateIds } }, { [this.documentFieldName]: documentFilter }] } : { _id: { $in: candidateIds } };
398
+ } else if (documentFilter) {
399
+ vectorSearch.filter = { [this.documentFieldName]: documentFilter };
386
400
  }
387
401
  const pipeline = [
388
402
  {
@@ -448,23 +462,44 @@ var MongoDBVector = class extends vector.MastraVector {
448
462
  try {
449
463
  const collection = await this.getCollection(indexName, true);
450
464
  const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
451
- const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
452
- const dimension = metadataDoc?.dimension || 0;
453
- const metric = metadataDoc?.metric || "cosine";
454
- return {
455
- dimension,
456
- count,
457
- metric
465
+ const indexNameInternal = `${indexName}_vector_index`;
466
+ const indexInfo = await collection.listSearchIndexes().toArray();
467
+ const indexData = indexInfo.find((idx) => idx.name === indexNameInternal);
468
+ if (!indexData) {
469
+ throw new error.MastraError({
470
+ id: storage.createVectorErrorId("MONGODB", "DESCRIBE_INDEX", "NOT_FOUND"),
471
+ domain: error.ErrorDomain.STORAGE,
472
+ category: error.ErrorCategory.USER,
473
+ details: { indexName },
474
+ text: `Atlas Search index "${indexNameInternal}" does not exist on collection "${indexName}". The collection may predate Mastra or the index may have been dropped externally.`
475
+ });
476
+ }
477
+ const vectorField = indexData.latestDefinition?.fields?.find((f) => f.type === "vector");
478
+ if (!vectorField) {
479
+ throw new error.MastraError({
480
+ id: storage.createVectorErrorId("MONGODB", "DESCRIBE_INDEX", "INVALID"),
481
+ domain: error.ErrorDomain.STORAGE,
482
+ category: error.ErrorCategory.USER,
483
+ details: { indexName },
484
+ text: `Atlas Search index "${indexNameInternal}" exists but has no vector field. The index may have been created outside of Mastra or without vector configuration.`
485
+ });
486
+ }
487
+ const dimension = vectorField.numDimensions;
488
+ const reverseMetricMap = {
489
+ cosine: "cosine",
490
+ euclidean: "euclidean",
491
+ dotProduct: "dotproduct"
458
492
  };
493
+ const metric = reverseMetricMap[vectorField.similarity] ?? "cosine";
494
+ return { dimension, count, metric };
459
495
  } catch (error$1) {
496
+ if (error$1 instanceof error.MastraError) throw error$1;
460
497
  throw new error.MastraError(
461
498
  {
462
499
  id: storage.createVectorErrorId("MONGODB", "DESCRIBE_INDEX", "FAILED"),
463
500
  domain: error.ErrorDomain.STORAGE,
464
501
  category: error.ErrorCategory.THIRD_PARTY,
465
- details: {
466
- indexName
467
- }
502
+ details: { indexName }
468
503
  },
469
504
  error$1
470
505
  );
@@ -671,10 +706,7 @@ var MongoDBVector = class extends vector.MastraVector {
671
706
  text: "Filter produced empty query"
672
707
  });
673
708
  }
674
- const finalFilter = {
675
- $and: [{ _id: { $ne: "__index_metadata__" } }, transformedFilter]
676
- };
677
- await collection.deleteMany(finalFilter);
709
+ await collection.deleteMany(transformedFilter);
678
710
  }
679
711
  } catch (error$1) {
680
712
  if (error$1 instanceof error.MastraError) {
@@ -695,7 +727,26 @@ var MongoDBVector = class extends vector.MastraVector {
695
727
  );
696
728
  }
697
729
  }
698
- // Private methods
730
+ /**
731
+ * Returns the MongoDB Collection that backs the given Mastra index.
732
+ *
733
+ * **Index vs. collection:** In this driver, each Mastra index is stored as a
734
+ * MongoDB collection whose name equals the index name. The Atlas Vector Search
735
+ * index (named `${indexName}_vector_index`) lives on that collection. The two
736
+ * terms are distinct: "index" is the Mastra concept; "collection" is the
737
+ * MongoDB storage primitive that implements it.
738
+ *
739
+ * **Caching:** Collection handles are cached on first successful lookup to
740
+ * avoid redundant `listCollections` round-trips. Only handles for collections
741
+ * that actually exist are cached; a handle for a missing collection is returned
742
+ * without being cached so the next call re-checks existence rather than
743
+ * returning a stale phantom.
744
+ *
745
+ * @param indexName - Mastra index name, which is also the MongoDB collection name.
746
+ * @param throwIfNotExists - When `true` (default), throws if no MongoDB
747
+ * collection exists for this index name. Pass `false` when absence is not an
748
+ * error (e.g., inside `deleteIndex`).
749
+ */
699
750
  async getCollection(indexName, throwIfNotExists = true) {
700
751
  if (this.collections.has(indexName)) {
701
752
  return this.collections.get(indexName);
@@ -703,9 +754,13 @@ var MongoDBVector = class extends vector.MastraVector {
703
754
  const collection = this.db.collection(indexName);
704
755
  const collectionExists = await this.db.listCollections({ name: indexName }).hasNext();
705
756
  if (!collectionExists && throwIfNotExists) {
706
- throw new Error(`Index (Collection) "${indexName}" does not exist`);
757
+ throw new Error(
758
+ `Mastra index "${indexName}" has no backing MongoDB collection. Call createIndex first, or verify the collection was not dropped externally.`
759
+ );
760
+ }
761
+ if (collectionExists) {
762
+ this.collections.set(indexName, collection);
707
763
  }
708
- this.collections.set(indexName, collection);
709
764
  return collection;
710
765
  }
711
766
  async validateVectorDimensions(vectors, dimension) {
@@ -714,7 +769,6 @@ var MongoDBVector = class extends vector.MastraVector {
714
769
  }
715
770
  if (dimension === 0) {
716
771
  dimension = vectors[0] ? vectors[0].length : 0;
717
- await this.setIndexDimension(dimension);
718
772
  }
719
773
  for (let i = 0; i < vectors.length; i++) {
720
774
  let v = vectors[i]?.length;
@@ -723,10 +777,6 @@ var MongoDBVector = class extends vector.MastraVector {
723
777
  }
724
778
  }
725
779
  }
726
- async setIndexDimension(dimension) {
727
- const collection = this.collectionForValidation;
728
- await collection.updateOne({ _id: "__index_metadata__" }, { $set: { dimension } }, { upsert: true });
729
- }
730
780
  transformFilter(filter) {
731
781
  const translator = new MongoDBFilterTranslator();
732
782
  if (!filter) return {};
@@ -756,12 +806,7 @@ var MongoDBVector = class extends vector.MastraVector {
756
806
  transformed[key] = value;
757
807
  }
758
808
  } else if (key.startsWith("metadata.")) {
759
- if (typeof value === "object" && value !== null && !Array.isArray(value)) {
760
- const hasOperator = Object.keys(value).some((k) => k.startsWith("$"));
761
- transformed[key] = hasOperator ? value : value;
762
- } else {
763
- transformed[key] = value;
764
- }
809
+ transformed[key] = value;
765
810
  } else if (this.isMetadataField(key)) {
766
811
  transformed[`metadata.${key}`] = value;
767
812
  } else {
@@ -788,6 +833,7 @@ var MongoDBConnector = class _MongoDBConnector {
788
833
  #handler;
789
834
  #isConnected;
790
835
  #db;
836
+ #supportsTransactions;
791
837
  constructor(options) {
792
838
  this.#client = options.client;
793
839
  this.#dbName = options.dbName;
@@ -844,6 +890,50 @@ var MongoDBConnector = class _MongoDBConnector {
844
890
  const db = await this.getConnection();
845
891
  return db.collection(collectionName);
846
892
  }
893
+ /**
894
+ * Returns true when the deployment supports multi-document transactions
895
+ * (replica set or sharded cluster). Standalone servers and custom connector
896
+ * handlers return false. Probed once and cached.
897
+ */
898
+ async supportsTransactions() {
899
+ if (this.#supportsTransactions !== void 0) {
900
+ return this.#supportsTransactions;
901
+ }
902
+ if (!this.#client) {
903
+ this.#supportsTransactions = false;
904
+ return false;
905
+ }
906
+ try {
907
+ const db = await this.getConnection();
908
+ const hello = await db.admin().command({ hello: 1 });
909
+ this.#supportsTransactions = Boolean(hello.setName) || hello.msg === "isdbgrid";
910
+ return this.#supportsTransactions;
911
+ } catch {
912
+ return false;
913
+ }
914
+ }
915
+ /**
916
+ * Runs `fn` inside a transaction when the deployment supports it, passing the
917
+ * session so callers can scope each operation with `{ session }`. On a
918
+ * standalone server (or custom handler) it degrades to running `fn` directly
919
+ * with an undefined session — best-effort sequential, no atomicity.
920
+ */
921
+ async withTransaction(fn) {
922
+ const supported = await this.supportsTransactions();
923
+ if (!supported || !this.#client) {
924
+ return fn(void 0);
925
+ }
926
+ const session = this.#client.startSession();
927
+ try {
928
+ let result;
929
+ await session.withTransaction(async () => {
930
+ result = await fn(session);
931
+ });
932
+ return result;
933
+ } finally {
934
+ await session.endSession();
935
+ }
936
+ }
847
937
  async close() {
848
938
  if (this.#client) {
849
939
  await this.#client.close();
@@ -1079,16 +1169,23 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends storage.AgentsSto
1079
1169
  createdAt: now,
1080
1170
  updatedAt: now
1081
1171
  };
1082
- await collection.insertOne(this.serializeAgent(newAgent));
1083
1172
  const { id: _id, authorId: _authorId, visibility: _visibility, metadata: _metadata, ...snapshotConfig } = agent;
1084
1173
  const versionId = crypto$1.randomUUID();
1085
- await this.createVersion({
1174
+ const versionDoc = {
1086
1175
  id: versionId,
1087
1176
  agentId: agent.id,
1088
1177
  versionNumber: 1,
1089
- ...snapshotConfig,
1090
1178
  changedFields: Object.keys(snapshotConfig),
1091
- changeMessage: "Initial version"
1179
+ changeMessage: "Initial version",
1180
+ createdAt: /* @__PURE__ */ new Date()
1181
+ };
1182
+ for (const field of SNAPSHOT_FIELDS) {
1183
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
1184
+ }
1185
+ await this.#connector.withTransaction(async (session) => {
1186
+ await collection.insertOne(this.serializeAgent(newAgent), { session });
1187
+ const versionsCol = await this.getCollection(storage.TABLE_AGENT_VERSIONS);
1188
+ await versionsCol.insertOne(versionDoc, { session });
1092
1189
  });
1093
1190
  return newAgent;
1094
1191
  } catch (error$1) {
@@ -1173,9 +1270,12 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends storage.AgentsSto
1173
1270
  }
1174
1271
  async delete(id) {
1175
1272
  try {
1176
- await this.deleteVersionsByParentId(id);
1177
- const collection = await this.getCollection(storage.TABLE_AGENTS);
1178
- await collection.deleteOne({ id });
1273
+ await this.#connector.withTransaction(async (session) => {
1274
+ const versionsCol = await this.getCollection(storage.TABLE_AGENT_VERSIONS);
1275
+ await versionsCol.deleteMany({ agentId: id }, { session });
1276
+ const col = await this.getCollection(storage.TABLE_AGENTS);
1277
+ await col.deleteOne({ id }, { session });
1278
+ });
1179
1279
  } catch (error$1) {
1180
1280
  throw new error.MastraError(
1181
1281
  {
@@ -2241,45 +2341,56 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2241
2341
  const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2242
2342
  const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2243
2343
  const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2244
- const result = await datasetsCollection.findOneAndUpdate(
2245
- { id: args.datasetId },
2246
- { $inc: { version: 1 } },
2247
- { returnDocument: "after" }
2248
- );
2249
- if (!result) {
2250
- throw new error.MastraError({
2251
- id: storage.createStorageErrorId("MONGODB", "ADD_ITEM", "DATASET_NOT_FOUND"),
2252
- domain: error.ErrorDomain.STORAGE,
2253
- category: error.ErrorCategory.USER,
2254
- details: { datasetId: args.datasetId }
2255
- });
2256
- }
2257
- const newVersion = result.version;
2258
- const organizationId = result.organizationId ?? null;
2259
- const projectId = result.projectId ?? null;
2260
- await itemsCollection.insertOne({
2261
- id,
2262
- datasetId: args.datasetId,
2263
- datasetVersion: newVersion,
2264
- organizationId,
2265
- projectId,
2266
- validTo: null,
2267
- isDeleted: false,
2268
- input: args.input,
2269
- groundTruth: args.groundTruth ?? null,
2270
- expectedTrajectory: args.expectedTrajectory ?? null,
2271
- toolMocks: args.toolMocks ?? null,
2272
- requestContext: args.requestContext ?? null,
2273
- metadata: args.metadata ?? null,
2274
- source: args.source ?? null,
2275
- createdAt: now,
2276
- updatedAt: now
2277
- });
2278
- await versionsCollection.insertOne({
2279
- id: versionId,
2280
- datasetId: args.datasetId,
2281
- version: newVersion,
2282
- createdAt: now
2344
+ let newVersion = 0;
2345
+ let organizationId = null;
2346
+ let projectId = null;
2347
+ await this.#connector.withTransaction(async (session) => {
2348
+ const result = await datasetsCollection.findOneAndUpdate(
2349
+ { id: args.datasetId },
2350
+ { $inc: { version: 1 } },
2351
+ { session, returnDocument: "after" }
2352
+ );
2353
+ if (!result) {
2354
+ throw new error.MastraError({
2355
+ id: storage.createStorageErrorId("MONGODB", "ADD_ITEM", "DATASET_NOT_FOUND"),
2356
+ domain: error.ErrorDomain.STORAGE,
2357
+ category: error.ErrorCategory.USER,
2358
+ details: { datasetId: args.datasetId }
2359
+ });
2360
+ }
2361
+ newVersion = result.version;
2362
+ organizationId = result.organizationId ?? null;
2363
+ projectId = result.projectId ?? null;
2364
+ await itemsCollection.insertOne(
2365
+ {
2366
+ id,
2367
+ datasetId: args.datasetId,
2368
+ datasetVersion: newVersion,
2369
+ organizationId,
2370
+ projectId,
2371
+ validTo: null,
2372
+ isDeleted: false,
2373
+ input: args.input,
2374
+ groundTruth: args.groundTruth ?? null,
2375
+ expectedTrajectory: args.expectedTrajectory ?? null,
2376
+ toolMocks: args.toolMocks ?? null,
2377
+ requestContext: args.requestContext ?? null,
2378
+ metadata: args.metadata ?? null,
2379
+ source: args.source ?? null,
2380
+ createdAt: now,
2381
+ updatedAt: now
2382
+ },
2383
+ { session }
2384
+ );
2385
+ await versionsCollection.insertOne(
2386
+ {
2387
+ id: versionId,
2388
+ datasetId: args.datasetId,
2389
+ version: newVersion,
2390
+ createdAt: now
2391
+ },
2392
+ { session }
2393
+ );
2283
2394
  });
2284
2395
  return {
2285
2396
  id,
@@ -2344,49 +2455,61 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2344
2455
  const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2345
2456
  const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2346
2457
  const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2347
- const result = await datasetsCollection.findOneAndUpdate(
2348
- { id: args.datasetId },
2349
- { $inc: { version: 1 } },
2350
- { returnDocument: "after" }
2351
- );
2352
- if (!result) {
2353
- throw new error.MastraError({
2354
- id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "DATASET_NOT_FOUND"),
2355
- domain: error.ErrorDomain.STORAGE,
2356
- category: error.ErrorCategory.USER,
2357
- details: { datasetId: args.datasetId }
2358
- });
2359
- }
2360
- const newVersion = result.version;
2361
- const parentOrganizationId = result.organizationId ?? null;
2362
- const parentProjectId = result.projectId ?? null;
2363
- await itemsCollection.updateOne(
2364
- { id: args.id, validTo: null, isDeleted: false },
2365
- { $set: { validTo: newVersion } }
2366
- );
2367
- await itemsCollection.insertOne({
2368
- id: args.id,
2369
- datasetId: args.datasetId,
2370
- datasetVersion: newVersion,
2371
- organizationId: parentOrganizationId,
2372
- projectId: parentProjectId,
2373
- validTo: null,
2374
- isDeleted: false,
2375
- input: mergedInput,
2376
- groundTruth: mergedGroundTruth,
2377
- expectedTrajectory: mergedExpectedTrajectory ?? null,
2378
- toolMocks: mergedToolMocks ?? null,
2379
- requestContext: mergedRequestContext,
2380
- metadata: mergedMetadata,
2381
- source: mergedSource,
2382
- createdAt: existing.createdAt,
2383
- updatedAt: now
2384
- });
2385
- await versionsCollection.insertOne({
2386
- id: versionId,
2387
- datasetId: args.datasetId,
2388
- version: newVersion,
2389
- createdAt: now
2458
+ let newVersion = 0;
2459
+ let parentOrganizationId = null;
2460
+ let parentProjectId = null;
2461
+ await this.#connector.withTransaction(async (session) => {
2462
+ const result = await datasetsCollection.findOneAndUpdate(
2463
+ { id: args.datasetId },
2464
+ { $inc: { version: 1 } },
2465
+ { session, returnDocument: "after" }
2466
+ );
2467
+ if (!result) {
2468
+ throw new error.MastraError({
2469
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_ITEM", "DATASET_NOT_FOUND"),
2470
+ domain: error.ErrorDomain.STORAGE,
2471
+ category: error.ErrorCategory.USER,
2472
+ details: { datasetId: args.datasetId }
2473
+ });
2474
+ }
2475
+ newVersion = result.version;
2476
+ parentOrganizationId = result.organizationId ?? null;
2477
+ parentProjectId = result.projectId ?? null;
2478
+ await itemsCollection.updateOne(
2479
+ { id: args.id, validTo: null, isDeleted: false },
2480
+ { $set: { validTo: newVersion } },
2481
+ { session }
2482
+ );
2483
+ await itemsCollection.insertOne(
2484
+ {
2485
+ id: args.id,
2486
+ datasetId: args.datasetId,
2487
+ datasetVersion: newVersion,
2488
+ organizationId: parentOrganizationId,
2489
+ projectId: parentProjectId,
2490
+ validTo: null,
2491
+ isDeleted: false,
2492
+ input: mergedInput,
2493
+ groundTruth: mergedGroundTruth,
2494
+ expectedTrajectory: mergedExpectedTrajectory ?? null,
2495
+ toolMocks: mergedToolMocks ?? null,
2496
+ requestContext: mergedRequestContext,
2497
+ metadata: mergedMetadata,
2498
+ source: mergedSource,
2499
+ createdAt: existing.createdAt,
2500
+ updatedAt: now
2501
+ },
2502
+ { session }
2503
+ );
2504
+ await versionsCollection.insertOne(
2505
+ {
2506
+ id: versionId,
2507
+ datasetId: args.datasetId,
2508
+ version: newVersion,
2509
+ createdAt: now
2510
+ },
2511
+ { session }
2512
+ );
2390
2513
  });
2391
2514
  return {
2392
2515
  ...existing,
@@ -2431,46 +2554,58 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2431
2554
  const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2432
2555
  const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2433
2556
  const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2434
- const result = await datasetsCollection.findOneAndUpdate(
2435
- { id: datasetId },
2436
- { $inc: { version: 1 } },
2437
- { returnDocument: "after" }
2438
- );
2439
- if (!result) {
2440
- throw new error.MastraError({
2441
- id: storage.createStorageErrorId("MONGODB", "DELETE_ITEM", "DATASET_NOT_FOUND"),
2442
- domain: error.ErrorDomain.STORAGE,
2443
- category: error.ErrorCategory.USER,
2444
- details: { datasetId }
2445
- });
2446
- }
2447
- const newVersion = result.version;
2448
- const parentOrganizationId = result.organizationId ?? null;
2449
- const parentProjectId = result.projectId ?? null;
2450
- await itemsCollection.updateOne({ id, validTo: null, isDeleted: false }, { $set: { validTo: newVersion } });
2451
- await itemsCollection.insertOne({
2452
- id,
2453
- datasetId,
2454
- datasetVersion: newVersion,
2455
- organizationId: parentOrganizationId,
2456
- projectId: parentProjectId,
2457
- validTo: null,
2458
- isDeleted: true,
2459
- input: existing.input,
2460
- groundTruth: existing.groundTruth,
2461
- expectedTrajectory: existing.expectedTrajectory ?? null,
2462
- toolMocks: existing.toolMocks ?? null,
2463
- requestContext: existing.requestContext,
2464
- metadata: existing.metadata,
2465
- source: existing.source,
2466
- createdAt: existing.createdAt,
2467
- updatedAt: now
2468
- });
2469
- await versionsCollection.insertOne({
2470
- id: versionId,
2471
- datasetId,
2472
- version: newVersion,
2473
- createdAt: now
2557
+ await this.#connector.withTransaction(async (session) => {
2558
+ const result = await datasetsCollection.findOneAndUpdate(
2559
+ { id: datasetId },
2560
+ { $inc: { version: 1 } },
2561
+ { session, returnDocument: "after" }
2562
+ );
2563
+ if (!result) {
2564
+ throw new error.MastraError({
2565
+ id: storage.createStorageErrorId("MONGODB", "DELETE_ITEM", "DATASET_NOT_FOUND"),
2566
+ domain: error.ErrorDomain.STORAGE,
2567
+ category: error.ErrorCategory.USER,
2568
+ details: { datasetId }
2569
+ });
2570
+ }
2571
+ const newVersion = result.version;
2572
+ const parentOrganizationId = result.organizationId ?? null;
2573
+ const parentProjectId = result.projectId ?? null;
2574
+ await itemsCollection.updateOne(
2575
+ { id, validTo: null, isDeleted: false },
2576
+ { $set: { validTo: newVersion } },
2577
+ { session }
2578
+ );
2579
+ await itemsCollection.insertOne(
2580
+ {
2581
+ id,
2582
+ datasetId,
2583
+ datasetVersion: newVersion,
2584
+ organizationId: parentOrganizationId,
2585
+ projectId: parentProjectId,
2586
+ validTo: null,
2587
+ isDeleted: true,
2588
+ input: existing.input,
2589
+ groundTruth: existing.groundTruth,
2590
+ expectedTrajectory: existing.expectedTrajectory ?? null,
2591
+ toolMocks: existing.toolMocks ?? null,
2592
+ requestContext: existing.requestContext,
2593
+ metadata: existing.metadata,
2594
+ source: existing.source,
2595
+ createdAt: existing.createdAt,
2596
+ updatedAt: now
2597
+ },
2598
+ { session }
2599
+ );
2600
+ await versionsCollection.insertOne(
2601
+ {
2602
+ id: versionId,
2603
+ datasetId,
2604
+ version: newVersion,
2605
+ createdAt: now
2606
+ },
2607
+ { session }
2608
+ );
2474
2609
  });
2475
2610
  } catch (error$1) {
2476
2611
  if (error$1 instanceof error.MastraError) throw error$1;
@@ -2508,23 +2643,26 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2508
2643
  const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2509
2644
  const itemsCollection = await this.getCollection(storage.TABLE_DATASET_ITEMS);
2510
2645
  const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2511
- const result = await datasetsCollection.findOneAndUpdate(
2512
- { id: input.datasetId },
2513
- { $inc: { version: 1 } },
2514
- { returnDocument: "after" }
2515
- );
2516
- if (!result) {
2517
- throw new error.MastraError({
2518
- id: storage.createStorageErrorId("MONGODB", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
2519
- domain: error.ErrorDomain.STORAGE,
2520
- category: error.ErrorCategory.USER,
2521
- details: { datasetId: input.datasetId }
2522
- });
2523
- }
2524
- const newVersion = result.version;
2525
- const organizationId = result.organizationId ?? null;
2526
- const projectId = result.projectId ?? null;
2527
- if (itemsWithIds.length > 0) {
2646
+ let newVersion = 0;
2647
+ let organizationId = null;
2648
+ let projectId = null;
2649
+ await this.#connector.withTransaction(async (session) => {
2650
+ const result = await datasetsCollection.findOneAndUpdate(
2651
+ { id: input.datasetId },
2652
+ { $inc: { version: 1 } },
2653
+ { session, returnDocument: "after" }
2654
+ );
2655
+ if (!result) {
2656
+ throw new error.MastraError({
2657
+ id: storage.createStorageErrorId("MONGODB", "BULK_ADD_ITEMS", "DATASET_NOT_FOUND"),
2658
+ domain: error.ErrorDomain.STORAGE,
2659
+ category: error.ErrorCategory.USER,
2660
+ details: { datasetId: input.datasetId }
2661
+ });
2662
+ }
2663
+ newVersion = result.version;
2664
+ organizationId = result.organizationId ?? null;
2665
+ projectId = result.projectId ?? null;
2528
2666
  const docs = itemsWithIds.map(({ generatedId, itemInput }) => ({
2529
2667
  id: generatedId,
2530
2668
  datasetId: input.datasetId,
@@ -2543,13 +2681,16 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2543
2681
  createdAt: now,
2544
2682
  updatedAt: now
2545
2683
  }));
2546
- await itemsCollection.insertMany(docs);
2547
- }
2548
- await versionsCollection.insertOne({
2549
- id: versionId,
2550
- datasetId: input.datasetId,
2551
- version: newVersion,
2552
- createdAt: now
2684
+ await itemsCollection.insertMany(docs, { session });
2685
+ await versionsCollection.insertOne(
2686
+ {
2687
+ id: versionId,
2688
+ datasetId: input.datasetId,
2689
+ version: newVersion,
2690
+ createdAt: now
2691
+ },
2692
+ { session }
2693
+ );
2553
2694
  });
2554
2695
  return itemsWithIds.map(({ generatedId, itemInput }) => ({
2555
2696
  id: generatedId,
@@ -2603,51 +2744,57 @@ var MongoDBDatasetsStorage = class extends storage.DatasetsStorage {
2603
2744
  const versionId = crypto$1.randomUUID();
2604
2745
  const datasetsCollection = await this.getCollection(storage.TABLE_DATASETS);
2605
2746
  const versionsCollection = await this.getCollection(storage.TABLE_DATASET_VERSIONS);
2606
- const result = await datasetsCollection.findOneAndUpdate(
2607
- { id: input.datasetId },
2608
- { $inc: { version: 1 } },
2609
- { returnDocument: "after" }
2610
- );
2611
- if (!result) {
2612
- throw new error.MastraError({
2613
- id: storage.createStorageErrorId("MONGODB", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
2614
- domain: error.ErrorDomain.STORAGE,
2615
- category: error.ErrorCategory.USER,
2616
- details: { datasetId: input.datasetId }
2617
- });
2618
- }
2619
- const newVersion = result.version;
2620
- const parentOrganizationId = result.organizationId ?? null;
2621
- const parentProjectId = result.projectId ?? null;
2622
2747
  const currentIds = currentItems.map((i) => i.id);
2623
- await itemsCollection.updateMany(
2624
- { id: { $in: currentIds }, validTo: null, isDeleted: false },
2625
- { $set: { validTo: newVersion } }
2626
- );
2627
- const tombstones = currentItems.map((item) => ({
2628
- id: item.id,
2629
- datasetId: input.datasetId,
2630
- datasetVersion: newVersion,
2631
- organizationId: parentOrganizationId,
2632
- projectId: parentProjectId,
2633
- validTo: null,
2634
- isDeleted: true,
2635
- input: item.input,
2636
- groundTruth: item.groundTruth,
2637
- expectedTrajectory: item.expectedTrajectory ?? null,
2638
- toolMocks: item.toolMocks ?? null,
2639
- requestContext: item.requestContext,
2640
- metadata: item.metadata,
2641
- source: item.source,
2642
- createdAt: item.createdAt,
2643
- updatedAt: now
2644
- }));
2645
- await itemsCollection.insertMany(tombstones);
2646
- await versionsCollection.insertOne({
2647
- id: versionId,
2648
- datasetId: input.datasetId,
2649
- version: newVersion,
2650
- createdAt: now
2748
+ await this.#connector.withTransaction(async (session) => {
2749
+ const result = await datasetsCollection.findOneAndUpdate(
2750
+ { id: input.datasetId },
2751
+ { $inc: { version: 1 } },
2752
+ { session, returnDocument: "after" }
2753
+ );
2754
+ if (!result) {
2755
+ throw new error.MastraError({
2756
+ id: storage.createStorageErrorId("MONGODB", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
2757
+ domain: error.ErrorDomain.STORAGE,
2758
+ category: error.ErrorCategory.USER,
2759
+ details: { datasetId: input.datasetId }
2760
+ });
2761
+ }
2762
+ const newVersion = result.version;
2763
+ const parentOrganizationId = result.organizationId ?? null;
2764
+ const parentProjectId = result.projectId ?? null;
2765
+ const tombstones = currentItems.map((item) => ({
2766
+ id: item.id,
2767
+ datasetId: input.datasetId,
2768
+ datasetVersion: newVersion,
2769
+ organizationId: parentOrganizationId,
2770
+ projectId: parentProjectId,
2771
+ validTo: null,
2772
+ isDeleted: true,
2773
+ input: item.input,
2774
+ groundTruth: item.groundTruth,
2775
+ expectedTrajectory: item.expectedTrajectory ?? null,
2776
+ toolMocks: item.toolMocks ?? null,
2777
+ requestContext: item.requestContext,
2778
+ metadata: item.metadata,
2779
+ source: item.source,
2780
+ createdAt: item.createdAt,
2781
+ updatedAt: now
2782
+ }));
2783
+ await itemsCollection.updateMany(
2784
+ { id: { $in: currentIds }, validTo: null, isDeleted: false },
2785
+ { $set: { validTo: newVersion } },
2786
+ { session }
2787
+ );
2788
+ await itemsCollection.insertMany(tombstones, { session });
2789
+ await versionsCollection.insertOne(
2790
+ {
2791
+ id: versionId,
2792
+ datasetId: input.datasetId,
2793
+ version: newVersion,
2794
+ createdAt: now
2795
+ },
2796
+ { session }
2797
+ );
2651
2798
  });
2652
2799
  } catch (error$1) {
2653
2800
  if (error$1 instanceof error.MastraError) throw error$1;
@@ -3546,27 +3693,27 @@ var MongoDBMCPClientsStorage = class _MongoDBMCPClientsStorage extends storage.M
3546
3693
  createdAt: now,
3547
3694
  updatedAt: now
3548
3695
  };
3549
- await collection.insertOne(this.serializeMCPClient(newMCPClient));
3550
3696
  const snapshotConfig = {};
3551
3697
  for (const field of SNAPSHOT_FIELDS2) {
3552
- if (mcpClient[field] !== void 0) {
3553
- snapshotConfig[field] = mcpClient[field];
3554
- }
3698
+ if (mcpClient[field] !== void 0) snapshotConfig[field] = mcpClient[field];
3555
3699
  }
3556
3700
  const versionId = crypto$1.randomUUID();
3557
- try {
3558
- await this.createVersion({
3559
- id: versionId,
3560
- mcpClientId: mcpClient.id,
3561
- versionNumber: 1,
3562
- ...snapshotConfig,
3563
- changedFields: Object.keys(snapshotConfig),
3564
- changeMessage: "Initial version"
3565
- });
3566
- } catch (versionError) {
3567
- await collection.deleteOne({ id: mcpClient.id });
3568
- throw versionError;
3701
+ const versionDoc = {
3702
+ id: versionId,
3703
+ mcpClientId: mcpClient.id,
3704
+ versionNumber: 1,
3705
+ changedFields: Object.keys(snapshotConfig),
3706
+ changeMessage: "Initial version",
3707
+ createdAt: /* @__PURE__ */ new Date()
3708
+ };
3709
+ for (const field of SNAPSHOT_FIELDS2) {
3710
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
3569
3711
  }
3712
+ await this.#connector.withTransaction(async (session) => {
3713
+ await collection.insertOne(this.serializeMCPClient(newMCPClient), { session });
3714
+ const versionsCol = await this.getCollection(storage.TABLE_MCP_CLIENT_VERSIONS);
3715
+ await versionsCol.insertOne(versionDoc, { session });
3716
+ });
3570
3717
  return newMCPClient;
3571
3718
  } catch (error$1) {
3572
3719
  if (error$1 instanceof error.MastraError) {
@@ -3646,9 +3793,12 @@ var MongoDBMCPClientsStorage = class _MongoDBMCPClientsStorage extends storage.M
3646
3793
  }
3647
3794
  async delete(id) {
3648
3795
  try {
3649
- await this.deleteVersionsByParentId(id);
3650
- const collection = await this.getCollection(storage.TABLE_MCP_CLIENTS);
3651
- await collection.deleteOne({ id });
3796
+ await this.#connector.withTransaction(async (session) => {
3797
+ const versionsCol = await this.getCollection(storage.TABLE_MCP_CLIENT_VERSIONS);
3798
+ await versionsCol.deleteMany({ mcpClientId: id }, { session });
3799
+ const col = await this.getCollection(storage.TABLE_MCP_CLIENTS);
3800
+ await col.deleteOne({ id }, { session });
3801
+ });
3652
3802
  } catch (error$1) {
3653
3803
  throw new error.MastraError(
3654
3804
  {
@@ -4098,7 +4248,6 @@ var MongoDBMCPServersStorage = class _MongoDBMCPServersStorage extends storage.M
4098
4248
  createdAt: now,
4099
4249
  updatedAt: now
4100
4250
  };
4101
- await collection.insertOne(this.serializeMCPServer(newMCPServer));
4102
4251
  const snapshotConfig = {};
4103
4252
  for (const field of SNAPSHOT_FIELDS3) {
4104
4253
  if (mcpServer[field] !== void 0) {
@@ -4106,19 +4255,22 @@ var MongoDBMCPServersStorage = class _MongoDBMCPServersStorage extends storage.M
4106
4255
  }
4107
4256
  }
4108
4257
  const versionId = crypto$1.randomUUID();
4109
- try {
4110
- await this.createVersion({
4111
- id: versionId,
4112
- mcpServerId: mcpServer.id,
4113
- versionNumber: 1,
4114
- ...snapshotConfig,
4115
- changedFields: Object.keys(snapshotConfig),
4116
- changeMessage: "Initial version"
4117
- });
4118
- } catch (versionError) {
4119
- await collection.deleteOne({ id: mcpServer.id });
4120
- throw versionError;
4258
+ const versionDoc = {
4259
+ id: versionId,
4260
+ mcpServerId: mcpServer.id,
4261
+ versionNumber: 1,
4262
+ changedFields: Object.keys(snapshotConfig),
4263
+ changeMessage: "Initial version",
4264
+ createdAt: /* @__PURE__ */ new Date()
4265
+ };
4266
+ for (const field of SNAPSHOT_FIELDS3) {
4267
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
4121
4268
  }
4269
+ await this.#connector.withTransaction(async (session) => {
4270
+ await collection.insertOne(this.serializeMCPServer(newMCPServer), { session });
4271
+ const versionsCol = await this.getCollection(storage.TABLE_MCP_SERVER_VERSIONS);
4272
+ await versionsCol.insertOne(versionDoc, { session });
4273
+ });
4122
4274
  return newMCPServer;
4123
4275
  } catch (error$1) {
4124
4276
  if (error$1 instanceof error.MastraError) {
@@ -4198,9 +4350,12 @@ var MongoDBMCPServersStorage = class _MongoDBMCPServersStorage extends storage.M
4198
4350
  }
4199
4351
  async delete(id) {
4200
4352
  try {
4201
- await this.deleteVersionsByParentId(id);
4202
- const collection = await this.getCollection(storage.TABLE_MCP_SERVERS);
4203
- await collection.deleteOne({ id });
4353
+ await this.#connector.withTransaction(async (session) => {
4354
+ const versionsCol = await this.getCollection(storage.TABLE_MCP_SERVER_VERSIONS);
4355
+ await versionsCol.deleteMany({ mcpServerId: id }, { session });
4356
+ const col = await this.getCollection(storage.TABLE_MCP_SERVERS);
4357
+ await col.deleteOne({ id }, { session });
4358
+ });
4204
4359
  } catch (error$1) {
4205
4360
  if (error$1 instanceof error.MastraError) throw error$1;
4206
4361
  throw new error.MastraError(
@@ -4556,24 +4711,24 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
4556
4711
  */
4557
4712
  getDefaultIndexDefinitions() {
4558
4713
  return [
4559
- // Threads collection indexes
4714
+ // Threads: point lookups (id) + resource-scoped listing sorted by createdAt or updatedAt.
4715
+ // A single descending compound serves both ASC and DESC sorts, and its resourceId prefix
4716
+ // covers resourceId-only filters. Unfiltered (no resourceId) listing is a rare admin path
4717
+ // left to an in-memory sort rather than carrying standalone single-field sort indexes.
4560
4718
  { collection: storage.TABLE_THREADS, keys: { id: 1 }, options: { unique: true } },
4561
- { collection: storage.TABLE_THREADS, keys: { resourceId: 1 } },
4562
- { collection: storage.TABLE_THREADS, keys: { createdAt: -1 } },
4563
- { collection: storage.TABLE_THREADS, keys: { updatedAt: -1 } },
4564
- // Messages collection indexes
4719
+ { collection: storage.TABLE_THREADS, keys: { resourceId: 1, createdAt: -1 } },
4720
+ { collection: storage.TABLE_THREADS, keys: { resourceId: 1, updatedAt: -1 } },
4721
+ // Messages: point lookups (id) + per-thread retrieval (listMessages) and per-resource
4722
+ // retrieval (listMessagesByResourceId), both sorted by createdAt. The compound prefixes
4723
+ // cover thread_id-only and resourceId-only filters.
4565
4724
  { collection: storage.TABLE_MESSAGES, keys: { id: 1 }, options: { unique: true } },
4566
- { collection: storage.TABLE_MESSAGES, keys: { thread_id: 1 } },
4567
- { collection: storage.TABLE_MESSAGES, keys: { resourceId: 1 } },
4568
- { collection: storage.TABLE_MESSAGES, keys: { createdAt: -1 } },
4569
4725
  { collection: storage.TABLE_MESSAGES, keys: { thread_id: 1, createdAt: 1 } },
4570
- // Resources collection indexes
4726
+ { collection: storage.TABLE_MESSAGES, keys: { resourceId: 1, createdAt: 1 } },
4727
+ // Resources: only ever fetched by id.
4571
4728
  { collection: storage.TABLE_RESOURCES, keys: { id: 1 }, options: { unique: true } },
4572
- { collection: storage.TABLE_RESOURCES, keys: { createdAt: -1 } },
4573
- { collection: storage.TABLE_RESOURCES, keys: { updatedAt: -1 } },
4574
- // Observational Memory collection indexes
4729
+ // Observational Memory: point lookups (id) + latest-generation-per-lookupKey. The compound
4730
+ // prefix covers lookupKey-only filters.
4575
4731
  { collection: OM_TABLE, keys: { id: 1 }, options: { unique: true } },
4576
- { collection: OM_TABLE, keys: { lookupKey: 1 } },
4577
4732
  { collection: OM_TABLE, keys: { lookupKey: 1, generationCount: -1 } }
4578
4733
  ];
4579
4734
  }
@@ -4588,8 +4743,17 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
4588
4743
  try {
4589
4744
  const collection = await this.getCollection(indexDef.collection);
4590
4745
  await collection.createIndex(indexDef.keys, indexDef.options);
4591
- } catch (error) {
4592
- this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
4746
+ } catch (error$1) {
4747
+ throw new error.MastraError(
4748
+ {
4749
+ id: storage.createStorageErrorId("MONGODB", "CREATE_DEFAULT_INDEXES", "FAILED"),
4750
+ domain: error.ErrorDomain.STORAGE,
4751
+ category: error.ErrorCategory.THIRD_PARTY,
4752
+ text: `Failed to create default index on collection "${indexDef.collection}". Set skipDefaultIndexes to manage indexes yourself.`,
4753
+ details: { collection: indexDef.collection }
4754
+ },
4755
+ error$1
4756
+ );
4593
4757
  }
4594
4758
  }
4595
4759
  }
@@ -4610,13 +4774,17 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
4610
4774
  }
4611
4775
  }
4612
4776
  async dangerouslyClearAll() {
4613
- const threadsCollection = await this.getCollection(storage.TABLE_THREADS);
4614
- const messagesCollection = await this.getCollection(storage.TABLE_MESSAGES);
4615
- const resourcesCollection = await this.getCollection(storage.TABLE_RESOURCES);
4777
+ const [threadsCollection, messagesCollection, resourcesCollection, omCollection] = await Promise.all([
4778
+ this.getCollection(storage.TABLE_THREADS),
4779
+ this.getCollection(storage.TABLE_MESSAGES),
4780
+ this.getCollection(storage.TABLE_RESOURCES),
4781
+ this.getCollection(OM_TABLE)
4782
+ ]);
4616
4783
  await Promise.all([
4617
4784
  threadsCollection.deleteMany({}),
4618
4785
  messagesCollection.deleteMany({}),
4619
- resourcesCollection.deleteMany({})
4786
+ resourcesCollection.deleteMany({}),
4787
+ omCollection.deleteMany({})
4620
4788
  ]);
4621
4789
  }
4622
4790
  parseRow(row) {
@@ -4990,10 +5158,14 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
4990
5158
  }
4991
5159
  };
4992
5160
  });
4993
- await Promise.all([
4994
- collection.bulkWrite(messagesToInsert),
4995
- threadsCollection.updateOne({ id: threadId }, { $set: { updatedAt: /* @__PURE__ */ new Date() } })
4996
- ]);
5161
+ const allThreadIds = new Set(messages.map((m) => m.threadId));
5162
+ const now = /* @__PURE__ */ new Date();
5163
+ await this.#connector.withTransaction(async (session) => {
5164
+ await collection.bulkWrite(messagesToInsert, { session });
5165
+ for (const tid of allThreadIds) {
5166
+ await threadsCollection.updateOne({ id: tid }, { $set: { updatedAt: now } }, { session });
5167
+ }
5168
+ });
4997
5169
  const list = new agent.MessageList().add(messages, "memory");
4998
5170
  return { messages: list.get.all.db() };
4999
5171
  } catch (error$1) {
@@ -5112,10 +5284,7 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
5112
5284
  await collection.updateOne(
5113
5285
  { id: resource.id },
5114
5286
  {
5115
- $set: {
5116
- ...resource,
5117
- metadata: JSON.stringify(resource.metadata)
5118
- }
5287
+ $set: { ...resource }
5119
5288
  },
5120
5289
  { upsert: true }
5121
5290
  );
@@ -5161,7 +5330,7 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends storage.MemorySto
5161
5330
  updateDoc.workingMemory = workingMemory;
5162
5331
  }
5163
5332
  if (metadata) {
5164
- updateDoc.metadata = JSON.stringify(updatedResource.metadata);
5333
+ updateDoc.metadata = updatedResource.metadata;
5165
5334
  }
5166
5335
  await collection.updateOne({ id: resourceId }, { $set: updateDoc });
5167
5336
  return updatedResource;
@@ -7406,9 +7575,13 @@ Note: This migration may take some time for large collections.
7406
7575
  });
7407
7576
  if (records.length > 0) {
7408
7577
  const collection = await this.getCollection(storage.TABLE_SPANS);
7409
- await collection.insertMany(records);
7578
+ await collection.insertMany(records, { ordered: false });
7410
7579
  }
7411
7580
  } catch (error$1) {
7581
+ if (error$1 instanceof mongodb.MongoBulkWriteError) {
7582
+ const writeErrors = Array.isArray(error$1.writeErrors) ? error$1.writeErrors : [error$1.writeErrors];
7583
+ if (writeErrors.length > 0 && writeErrors.every((e) => e.code === 11e3)) return;
7584
+ }
7412
7585
  throw new error.MastraError(
7413
7586
  {
7414
7587
  id: storage.createStorageErrorId("MONGODB", "BATCH_CREATE_SPANS", "FAILED"),
@@ -7608,7 +7781,6 @@ var MongoDBPromptBlocksStorage = class _MongoDBPromptBlocksStorage extends stora
7608
7781
  createdAt: now,
7609
7782
  updatedAt: now
7610
7783
  };
7611
- await collection.insertOne(this.serializeBlock(newBlock));
7612
7784
  const snapshotConfig = {};
7613
7785
  for (const field of SNAPSHOT_FIELDS4) {
7614
7786
  if (promptBlock[field] !== void 0) {
@@ -7616,13 +7788,21 @@ var MongoDBPromptBlocksStorage = class _MongoDBPromptBlocksStorage extends stora
7616
7788
  }
7617
7789
  }
7618
7790
  const versionId = crypto$1.randomUUID();
7619
- await this.createVersion({
7791
+ const versionDoc = {
7620
7792
  id: versionId,
7621
7793
  blockId: promptBlock.id,
7622
7794
  versionNumber: 1,
7623
- ...snapshotConfig,
7624
7795
  changedFields: Object.keys(snapshotConfig),
7625
- changeMessage: "Initial version"
7796
+ changeMessage: "Initial version",
7797
+ createdAt: /* @__PURE__ */ new Date()
7798
+ };
7799
+ for (const field of SNAPSHOT_FIELDS4) {
7800
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
7801
+ }
7802
+ await this.#connector.withTransaction(async (session) => {
7803
+ await collection.insertOne(this.serializeBlock(newBlock), { session });
7804
+ const versionsCol = await this.getCollection(storage.TABLE_PROMPT_BLOCK_VERSIONS);
7805
+ await versionsCol.insertOne(versionDoc, { session });
7626
7806
  });
7627
7807
  return newBlock;
7628
7808
  } catch (error$1) {
@@ -7703,9 +7883,12 @@ var MongoDBPromptBlocksStorage = class _MongoDBPromptBlocksStorage extends stora
7703
7883
  }
7704
7884
  async delete(id) {
7705
7885
  try {
7706
- await this.deleteVersionsByParentId(id);
7707
- const collection = await this.getCollection(storage.TABLE_PROMPT_BLOCKS);
7708
- await collection.deleteOne({ id });
7886
+ await this.#connector.withTransaction(async (session) => {
7887
+ const versionsCol = await this.getCollection(storage.TABLE_PROMPT_BLOCK_VERSIONS);
7888
+ await versionsCol.deleteMany({ blockId: id }, { session });
7889
+ const col = await this.getCollection(storage.TABLE_PROMPT_BLOCKS);
7890
+ await col.deleteOne({ id }, { session });
7891
+ });
7709
7892
  } catch (error$1) {
7710
7893
  throw new error.MastraError(
7711
7894
  {
@@ -8225,10 +8408,12 @@ var SchedulesMongoDB = class _SchedulesMongoDB extends storage.SchedulesStorage
8225
8408
  return result.matchedCount > 0;
8226
8409
  }
8227
8410
  async deleteSchedule(id) {
8228
- const triggers = await this.getTriggersCollection();
8229
- await triggers.deleteMany({ schedule_id: id });
8230
- const schedules = await this.getSchedulesCollection();
8231
- await schedules.deleteOne({ id });
8411
+ await this.#connector.withTransaction(async (session) => {
8412
+ const triggers = await this.getTriggersCollection();
8413
+ await triggers.deleteMany({ schedule_id: id }, { session });
8414
+ const schedules = await this.getSchedulesCollection();
8415
+ await schedules.deleteOne({ id }, { session });
8416
+ });
8232
8417
  }
8233
8418
  async recordTrigger(trigger) {
8234
8419
  const collection = await this.getTriggersCollection();
@@ -8375,7 +8560,6 @@ var MongoDBScorerDefinitionsStorage = class _MongoDBScorerDefinitionsStorage ext
8375
8560
  createdAt: now,
8376
8561
  updatedAt: now
8377
8562
  };
8378
- await collection.insertOne(this.serializeScorerDefinition(newScorerDefinition));
8379
8563
  const snapshotConfig = {};
8380
8564
  for (const field of SNAPSHOT_FIELDS5) {
8381
8565
  if (scorerDefinition[field] !== void 0) {
@@ -8383,13 +8567,21 @@ var MongoDBScorerDefinitionsStorage = class _MongoDBScorerDefinitionsStorage ext
8383
8567
  }
8384
8568
  }
8385
8569
  const versionId = crypto$1.randomUUID();
8386
- await this.createVersion({
8570
+ const versionDoc = {
8387
8571
  id: versionId,
8388
8572
  scorerDefinitionId: scorerDefinition.id,
8389
8573
  versionNumber: 1,
8390
- ...snapshotConfig,
8391
8574
  changedFields: Object.keys(snapshotConfig),
8392
- changeMessage: "Initial version"
8575
+ changeMessage: "Initial version",
8576
+ createdAt: /* @__PURE__ */ new Date()
8577
+ };
8578
+ for (const field of SNAPSHOT_FIELDS5) {
8579
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
8580
+ }
8581
+ await this.#connector.withTransaction(async (session) => {
8582
+ await collection.insertOne(this.serializeScorerDefinition(newScorerDefinition), { session });
8583
+ const versionsCol = await this.getCollection(storage.TABLE_SCORER_DEFINITION_VERSIONS);
8584
+ await versionsCol.insertOne(versionDoc, { session });
8393
8585
  });
8394
8586
  return newScorerDefinition;
8395
8587
  } catch (error$1) {
@@ -8470,9 +8662,12 @@ var MongoDBScorerDefinitionsStorage = class _MongoDBScorerDefinitionsStorage ext
8470
8662
  }
8471
8663
  async delete(id) {
8472
8664
  try {
8473
- await this.deleteVersionsByParentId(id);
8474
- const collection = await this.getCollection(storage.TABLE_SCORER_DEFINITIONS);
8475
- await collection.deleteOne({ id });
8665
+ await this.#connector.withTransaction(async (session) => {
8666
+ const versionsCol = await this.getCollection(storage.TABLE_SCORER_DEFINITION_VERSIONS);
8667
+ await versionsCol.deleteMany({ scorerDefinitionId: id }, { session });
8668
+ const col = await this.getCollection(storage.TABLE_SCORER_DEFINITIONS);
8669
+ await col.deleteOne({ id }, { session });
8670
+ });
8476
8671
  } catch (error$1) {
8477
8672
  throw new error.MastraError(
8478
8673
  {
@@ -9294,27 +9489,27 @@ var MongoDBSkillsStorage = class _MongoDBSkillsStorage extends storage.SkillsSto
9294
9489
  createdAt: now,
9295
9490
  updatedAt: now
9296
9491
  };
9297
- await collection.insertOne(this.serializeSkill(newSkill));
9298
9492
  const snapshotConfig = {};
9299
9493
  for (const field of SNAPSHOT_FIELDS6) {
9300
- if (skill[field] !== void 0) {
9301
- snapshotConfig[field] = skill[field];
9302
- }
9494
+ if (skill[field] !== void 0) snapshotConfig[field] = skill[field];
9303
9495
  }
9304
9496
  const versionId = crypto$1.randomUUID();
9305
- try {
9306
- await this.createVersion({
9307
- id: versionId,
9308
- skillId: id,
9309
- versionNumber: 1,
9310
- ...snapshotConfig,
9311
- changedFields: Object.keys(snapshotConfig),
9312
- changeMessage: "Initial version"
9313
- });
9314
- } catch (versionError) {
9315
- await collection.deleteOne({ id });
9316
- throw versionError;
9497
+ const versionDoc = {
9498
+ id: versionId,
9499
+ skillId: id,
9500
+ versionNumber: 1,
9501
+ changedFields: Object.keys(snapshotConfig),
9502
+ changeMessage: "Initial version",
9503
+ createdAt: /* @__PURE__ */ new Date()
9504
+ };
9505
+ for (const field of SNAPSHOT_FIELDS6) {
9506
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
9317
9507
  }
9508
+ await this.#connector.withTransaction(async (session) => {
9509
+ await collection.insertOne(this.serializeSkill(newSkill), { session });
9510
+ const versionsCol = await this.getCollection(storage.TABLE_SKILL_VERSIONS);
9511
+ await versionsCol.insertOne(versionDoc, { session });
9512
+ });
9318
9513
  return newSkill;
9319
9514
  } catch (error$1) {
9320
9515
  if (error$1 instanceof error.MastraError) {
@@ -9360,6 +9555,18 @@ var MongoDBSkillsStorage = class _MongoDBSkillsStorage extends storage.SkillsSto
9360
9555
  configFields[field] = updates[field];
9361
9556
  }
9362
9557
  }
9558
+ if (metadataFields.authorId !== void 0) updateDoc.authorId = metadataFields.authorId;
9559
+ if (metadataFields.visibility !== void 0) updateDoc.visibility = metadataFields.visibility;
9560
+ if (metadataFields.activeVersionId !== void 0) {
9561
+ updateDoc.activeVersionId = metadataFields.activeVersionId;
9562
+ if (metadataFields.status === void 0) {
9563
+ updateDoc.status = "published";
9564
+ }
9565
+ }
9566
+ if (metadataFields.status !== void 0) {
9567
+ updateDoc.status = metadataFields.status;
9568
+ }
9569
+ let newVersionDoc = null;
9363
9570
  if (Object.keys(configFields).length > 0) {
9364
9571
  const latestVersion = await this.getLatestVersion(id);
9365
9572
  if (!latestVersion) {
@@ -9379,29 +9586,28 @@ var MongoDBSkillsStorage = class _MongoDBSkillsStorage extends storage.SkillsSto
9379
9586
  )
9380
9587
  );
9381
9588
  if (changedFields.length > 0) {
9382
- await this.createVersion({
9589
+ const mergedSnapshot = { ...existingSnapshot, ...configFields };
9590
+ newVersionDoc = {
9383
9591
  id: crypto$1.randomUUID(),
9384
9592
  skillId: id,
9385
9593
  versionNumber: latestVersion.versionNumber + 1,
9386
- ...existingSnapshot,
9387
- ...configFields,
9388
9594
  changedFields,
9389
- changeMessage: `Updated: ${changedFields.join(", ")}`
9390
- });
9595
+ changeMessage: `Updated: ${changedFields.join(", ")}`,
9596
+ createdAt: /* @__PURE__ */ new Date()
9597
+ };
9598
+ for (const field of SNAPSHOT_FIELDS6) {
9599
+ if (mergedSnapshot[field] !== void 0) newVersionDoc[field] = mergedSnapshot[field];
9600
+ }
9391
9601
  }
9392
9602
  }
9393
- if (metadataFields.authorId !== void 0) updateDoc.authorId = metadataFields.authorId;
9394
- if (metadataFields.visibility !== void 0) updateDoc.visibility = metadataFields.visibility;
9395
- if (metadataFields.activeVersionId !== void 0) {
9396
- updateDoc.activeVersionId = metadataFields.activeVersionId;
9397
- if (metadataFields.status === void 0) {
9398
- updateDoc.status = "published";
9603
+ await this.#connector.withTransaction(async (session) => {
9604
+ if (newVersionDoc) {
9605
+ const versionsCol = await this.getCollection(storage.TABLE_SKILL_VERSIONS);
9606
+ await versionsCol.insertOne(newVersionDoc, { session });
9399
9607
  }
9400
- }
9401
- if (metadataFields.status !== void 0) {
9402
- updateDoc.status = metadataFields.status;
9403
- }
9404
- await collection.updateOne({ id }, { $set: updateDoc });
9608
+ const col = await this.getCollection(storage.TABLE_SKILLS);
9609
+ await col.updateOne({ id }, { $set: updateDoc }, { session });
9610
+ });
9405
9611
  const updatedSkill = await collection.findOne({ id });
9406
9612
  if (!updatedSkill) {
9407
9613
  throw new error.MastraError({
@@ -9430,9 +9636,12 @@ var MongoDBSkillsStorage = class _MongoDBSkillsStorage extends storage.SkillsSto
9430
9636
  }
9431
9637
  async delete(id) {
9432
9638
  try {
9433
- await this.deleteVersionsByParentId(id);
9434
- const collection = await this.getCollection(storage.TABLE_SKILLS);
9435
- await collection.deleteOne({ id });
9639
+ await this.#connector.withTransaction(async (session) => {
9640
+ const versionsCol = await this.getCollection(storage.TABLE_SKILL_VERSIONS);
9641
+ await versionsCol.deleteMany({ skillId: id }, { session });
9642
+ const col = await this.getCollection(storage.TABLE_SKILLS);
9643
+ await col.deleteOne({ id }, { session });
9644
+ });
9436
9645
  } catch (error$1) {
9437
9646
  throw new error.MastraError(
9438
9647
  {
@@ -9922,16 +10131,10 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends storage.Wor
9922
10131
  try {
9923
10132
  const collection = await this.getCollection(storage.TABLE_WORKFLOW_SNAPSHOT);
9924
10133
  const updatedDoc = await collection.findOneAndUpdate(
9925
- {
9926
- workflow_name: workflowName,
9927
- run_id: runId,
9928
- // Only update if snapshot exists and has context
9929
- "snapshot.context": { $exists: true }
9930
- },
10134
+ { workflow_name: workflowName, run_id: runId },
9931
10135
  [
9932
10136
  {
9933
10137
  $set: {
9934
- // Merge the new options into the existing snapshot
9935
10138
  snapshot: {
9936
10139
  $mergeObjects: ["$snapshot", opts]
9937
10140
  },
@@ -9945,8 +10148,18 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends storage.Wor
9945
10148
  return void 0;
9946
10149
  }
9947
10150
  const snapshot = typeof updatedDoc.snapshot === "string" ? JSON.parse(updatedDoc.snapshot) : updatedDoc.snapshot;
10151
+ if (!snapshot?.context) {
10152
+ throw new error.MastraError({
10153
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
10154
+ domain: error.ErrorDomain.STORAGE,
10155
+ category: error.ErrorCategory.USER,
10156
+ text: `Snapshot not found for runId ${runId}`,
10157
+ details: { workflowName, runId }
10158
+ });
10159
+ }
9948
10160
  return snapshot;
9949
10161
  } catch (error$1) {
10162
+ if (error$1 instanceof error.MastraError) throw error$1;
9950
10163
  throw new error.MastraError(
9951
10164
  {
9952
10165
  id: storage.createStorageErrorId("MONGODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
@@ -10290,27 +10503,27 @@ var MongoDBWorkspacesStorage = class _MongoDBWorkspacesStorage extends storage.W
10290
10503
  createdAt: now,
10291
10504
  updatedAt: now
10292
10505
  };
10293
- await collection.insertOne(this.serializeWorkspace(newWorkspace));
10294
10506
  const snapshotConfig = {};
10295
10507
  for (const field of SNAPSHOT_FIELDS7) {
10296
- if (workspace[field] !== void 0) {
10297
- snapshotConfig[field] = workspace[field];
10298
- }
10508
+ if (workspace[field] !== void 0) snapshotConfig[field] = workspace[field];
10299
10509
  }
10300
10510
  const versionId = crypto$1.randomUUID();
10301
- try {
10302
- await this.createVersion({
10303
- id: versionId,
10304
- workspaceId: id,
10305
- versionNumber: 1,
10306
- ...snapshotConfig,
10307
- changedFields: Object.keys(snapshotConfig),
10308
- changeMessage: "Initial version"
10309
- });
10310
- } catch (versionError) {
10311
- await collection.deleteOne({ id });
10312
- throw versionError;
10511
+ const versionDoc = {
10512
+ id: versionId,
10513
+ workspaceId: id,
10514
+ versionNumber: 1,
10515
+ changedFields: Object.keys(snapshotConfig),
10516
+ changeMessage: "Initial version",
10517
+ createdAt: /* @__PURE__ */ new Date()
10518
+ };
10519
+ for (const field of SNAPSHOT_FIELDS7) {
10520
+ if (snapshotConfig[field] !== void 0) versionDoc[field] = snapshotConfig[field];
10313
10521
  }
10522
+ await this.#connector.withTransaction(async (session) => {
10523
+ await collection.insertOne(this.serializeWorkspace(newWorkspace), { session });
10524
+ const versionsCol = await this.getCollection(storage.TABLE_WORKSPACE_VERSIONS);
10525
+ await versionsCol.insertOne(versionDoc, { session });
10526
+ });
10314
10527
  return newWorkspace;
10315
10528
  } catch (error$1) {
10316
10529
  if (error$1 instanceof error.MastraError) {
@@ -10356,6 +10569,7 @@ var MongoDBWorkspacesStorage = class _MongoDBWorkspacesStorage extends storage.W
10356
10569
  configFields[field] = updates[field];
10357
10570
  }
10358
10571
  }
10572
+ let newVersionDoc = null;
10359
10573
  if (Object.keys(configFields).length > 0) {
10360
10574
  const latestVersion = await this.getLatestVersion(id);
10361
10575
  if (!latestVersion) {
@@ -10368,15 +10582,18 @@ var MongoDBWorkspacesStorage = class _MongoDBWorkspacesStorage extends storage.W
10368
10582
  });
10369
10583
  }
10370
10584
  const existingSnapshot = this.extractSnapshotFields(latestVersion);
10371
- await this.createVersion({
10585
+ const mergedSnapshot = { ...existingSnapshot, ...configFields };
10586
+ newVersionDoc = {
10372
10587
  id: crypto$1.randomUUID(),
10373
10588
  workspaceId: id,
10374
10589
  versionNumber: latestVersion.versionNumber + 1,
10375
- ...existingSnapshot,
10376
- ...configFields,
10377
10590
  changedFields: Object.keys(configFields),
10378
- changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
10379
- });
10591
+ changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`,
10592
+ createdAt: /* @__PURE__ */ new Date()
10593
+ };
10594
+ for (const field of SNAPSHOT_FIELDS7) {
10595
+ if (mergedSnapshot[field] !== void 0) newVersionDoc[field] = mergedSnapshot[field];
10596
+ }
10380
10597
  }
10381
10598
  if (metadataFields.authorId !== void 0) updateDoc.authorId = metadataFields.authorId;
10382
10599
  if (metadataFields.activeVersionId !== void 0) {
@@ -10392,7 +10609,23 @@ var MongoDBWorkspacesStorage = class _MongoDBWorkspacesStorage extends storage.W
10392
10609
  const existingMetadata = existingWorkspace.metadata || {};
10393
10610
  updateDoc.metadata = { ...existingMetadata, ...metadataFields.metadata };
10394
10611
  }
10395
- await collection.updateOne({ id }, { $set: updateDoc });
10612
+ await this.#connector.withTransaction(async (session) => {
10613
+ if (newVersionDoc) {
10614
+ const versionsCol = await this.getCollection(storage.TABLE_WORKSPACE_VERSIONS);
10615
+ await versionsCol.insertOne(newVersionDoc, { session });
10616
+ }
10617
+ const col = await this.getCollection(storage.TABLE_WORKSPACES);
10618
+ const updateResult = await col.updateOne({ id }, { $set: updateDoc }, { session });
10619
+ if (updateResult.matchedCount === 0) {
10620
+ throw new error.MastraError({
10621
+ id: storage.createStorageErrorId("MONGODB", "UPDATE_WORKSPACE", "NOT_FOUND_AFTER_UPDATE"),
10622
+ domain: error.ErrorDomain.STORAGE,
10623
+ category: error.ErrorCategory.SYSTEM,
10624
+ text: `Workspace with id ${id} was deleted during update`,
10625
+ details: { id }
10626
+ });
10627
+ }
10628
+ });
10396
10629
  const updatedWorkspace = await collection.findOne({ id });
10397
10630
  if (!updatedWorkspace) {
10398
10631
  throw new error.MastraError({
@@ -10421,9 +10654,12 @@ var MongoDBWorkspacesStorage = class _MongoDBWorkspacesStorage extends storage.W
10421
10654
  }
10422
10655
  async delete(id) {
10423
10656
  try {
10424
- await this.deleteVersionsByParentId(id);
10425
- const collection = await this.getCollection(storage.TABLE_WORKSPACES);
10426
- await collection.deleteOne({ id });
10657
+ await this.#connector.withTransaction(async (session) => {
10658
+ const versionsCol = await this.getCollection(storage.TABLE_WORKSPACE_VERSIONS);
10659
+ await versionsCol.deleteMany({ workspaceId: id }, { session });
10660
+ const col = await this.getCollection(storage.TABLE_WORKSPACES);
10661
+ await col.deleteOne({ id }, { session });
10662
+ });
10427
10663
  } catch (error$1) {
10428
10664
  throw new error.MastraError(
10429
10665
  {