@mastra/mongodb 1.18.6-alpha.0 → 1.18.6

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
@@ -9,7 +9,7 @@ import { MessageList } from "@mastra/core/agent";
9
9
  import { saveScorePayloadSchema } from "@mastra/core/evals";
10
10
  import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skills";
11
11
  //#region package.json
12
- var version = "1.18.6-alpha.0";
12
+ var version = "1.18.6";
13
13
  //#endregion
14
14
  //#region src/vector/filter.ts
15
15
  /**
@@ -1395,6 +1395,10 @@ var MongoDBConnector = class MongoDBConnector {
1395
1395
  if (this.#handler) return this.#handler.getCollection(collectionName);
1396
1396
  return (await this.getConnection()).collection(collectionName);
1397
1397
  }
1398
+ async collectionExists(collectionName) {
1399
+ if (this.#handler) return true;
1400
+ return (await this.getConnection()).listCollections({ name: collectionName }).hasNext();
1401
+ }
1398
1402
  /**
1399
1403
  * Returns true when the deployment supports multi-document transactions
1400
1404
  * (replica set or sharded cluster). Standalone servers and custom connector
@@ -2791,6 +2795,8 @@ var MongoDBDatasetsStorage = class extends DatasetsStorage {
2791
2795
  };
2792
2796
  }
2793
2797
  transformItemRow(row) {
2798
+ const metadata = (typeof row.metadata === "string" ? safelyParseJSON(row.metadata) : row.metadata) ?? void 0;
2799
+ const emptyValue = metadata?.__purged === true ? null : void 0;
2794
2800
  return {
2795
2801
  id: row.id,
2796
2802
  datasetId: row.datasetId,
@@ -2801,12 +2807,12 @@ var MongoDBDatasetsStorage = class extends DatasetsStorage {
2801
2807
  input: typeof row.input === "string" ? safelyParseJSON(row.input) : row.input,
2802
2808
  groundTruth: typeof row.groundTruth === "string" ? safelyParseJSON(row.groundTruth) : row.groundTruth,
2803
2809
  expectedTrajectory: typeof row.expectedTrajectory === "string" ? safelyParseJSON(row.expectedTrajectory) : row.expectedTrajectory,
2804
- toolMocks: (typeof row.toolMocks === "string" ? safelyParseJSON(row.toolMocks) : row.toolMocks) ?? void 0,
2805
- unmockedToolPolicy: row.unmockedToolPolicy ?? void 0,
2806
- scorerIds: (typeof row.scorerIds === "string" ? safelyParseJSON(row.scorerIds) : row.scorerIds) ?? void 0,
2807
- requestContext: typeof row.requestContext === "string" ? safelyParseJSON(row.requestContext) : row.requestContext,
2808
- metadata: typeof row.metadata === "string" ? safelyParseJSON(row.metadata) : row.metadata,
2809
- source: typeof row.source === "string" ? safelyParseJSON(row.source) : row.source,
2810
+ toolMocks: (typeof row.toolMocks === "string" ? safelyParseJSON(row.toolMocks) : row.toolMocks) ?? emptyValue,
2811
+ unmockedToolPolicy: row.unmockedToolPolicy ?? emptyValue,
2812
+ scorerIds: (typeof row.scorerIds === "string" ? safelyParseJSON(row.scorerIds) : row.scorerIds) ?? emptyValue,
2813
+ requestContext: (typeof row.requestContext === "string" ? safelyParseJSON(row.requestContext) : row.requestContext) ?? emptyValue,
2814
+ metadata,
2815
+ source: (typeof row.source === "string" ? safelyParseJSON(row.source) : row.source) ?? emptyValue,
2810
2816
  createdAt: ensureDate(row.createdAt),
2811
2817
  updatedAt: ensureDate(row.updatedAt)
2812
2818
  };
@@ -3272,6 +3278,79 @@ var MongoDBDatasetsStorage = class extends DatasetsStorage {
3272
3278
  }, error);
3273
3279
  }
3274
3280
  }
3281
+ async _doPurgeItem({ id, datasetId }) {
3282
+ try {
3283
+ if (!await this.#connector.supportsTransactions()) throw new MastraError({
3284
+ id: "MONGODB_DATASET_ITEM_PURGE_REQUIRES_TRANSACTIONS",
3285
+ domain: ErrorDomain.STORAGE,
3286
+ category: ErrorCategory.USER,
3287
+ text: "Dataset item purge requires a MongoDB replica set or sharded deployment with transaction support.",
3288
+ details: {
3289
+ datasetId,
3290
+ itemId: id
3291
+ }
3292
+ });
3293
+ const itemsCollection = await this.getCollection(TABLE_DATASET_ITEMS);
3294
+ const experimentsCollection = await this.getCollection(TABLE_EXPERIMENTS);
3295
+ const experimentResultsCollection = await this.getCollection(TABLE_EXPERIMENT_RESULTS);
3296
+ const experimentCollectionsExist = await this.#connector.collectionExists(TABLE_EXPERIMENTS) && await this.#connector.collectionExists(TABLE_EXPERIMENT_RESULTS);
3297
+ const metadata = {
3298
+ __purged: true,
3299
+ purgedAt: (/* @__PURE__ */ new Date()).toISOString()
3300
+ };
3301
+ await this.#connector.withTransaction(async (session) => {
3302
+ if (!await itemsCollection.findOneAndUpdate({
3303
+ id,
3304
+ datasetId
3305
+ }, { $inc: { purgeBarrierRevision: 1 } }, {
3306
+ projection: { id: 1 },
3307
+ returnDocument: "after",
3308
+ session,
3309
+ sort: { datasetVersion: -1 }
3310
+ })) return;
3311
+ await itemsCollection.updateMany({
3312
+ id,
3313
+ datasetId
3314
+ }, { $set: {
3315
+ input: null,
3316
+ groundTruth: null,
3317
+ expectedTrajectory: null,
3318
+ toolMocks: null,
3319
+ unmockedToolPolicy: null,
3320
+ scorerIds: null,
3321
+ requestContext: null,
3322
+ metadata,
3323
+ source: null
3324
+ } }, { session });
3325
+ if (experimentCollectionsExist) {
3326
+ const experimentIds = await experimentsCollection.find({ datasetId }, {
3327
+ projection: { id: 1 },
3328
+ session
3329
+ }).map((experiment) => experiment.id).toArray();
3330
+ if (experimentIds.length > 0) await experimentResultsCollection.updateMany({
3331
+ itemId: id,
3332
+ experimentId: { $in: experimentIds }
3333
+ }, { $set: {
3334
+ input: null,
3335
+ output: null,
3336
+ groundTruth: null,
3337
+ error: null,
3338
+ toolMockReport: null,
3339
+ tags: null,
3340
+ comment: null,
3341
+ metadata
3342
+ } }, { session });
3343
+ }
3344
+ });
3345
+ } catch (error) {
3346
+ if (error instanceof MastraError) throw error;
3347
+ throw new MastraError({
3348
+ id: createStorageErrorId("MONGODB", "PURGE_ITEM", "FAILED"),
3349
+ domain: ErrorDomain.STORAGE,
3350
+ category: ErrorCategory.THIRD_PARTY
3351
+ }, error);
3352
+ }
3353
+ }
3275
3354
  async _doBatchInsertItems(input) {
3276
3355
  try {
3277
3356
  if (input.items.length === 0) return [];
@@ -3703,7 +3782,7 @@ function transformExperimentResultRow(row) {
3703
3782
  itemDatasetVersion: row.itemDatasetVersion != null ? Number(row.itemDatasetVersion) : null,
3704
3783
  organizationId: row.organizationId ?? null,
3705
3784
  projectId: row.projectId ?? null,
3706
- input: parseJsonField(row.input),
3785
+ input: row.input === null ? null : parseJsonField(row.input),
3707
3786
  output: parseJsonField(row.output) ?? null,
3708
3787
  groundTruth: parseJsonField(row.groundTruth) ?? null,
3709
3788
  metadata: parseJsonField(row.metadata) ?? null,
@@ -3745,6 +3824,27 @@ var MongoDBExperimentsStorage = class MongoDBExperimentsStorage extends Experime
3745
3824
  async getCollection(name) {
3746
3825
  return this.#connector.getCollection(name);
3747
3826
  }
3827
+ async #withPurgeBarrier(experimentId, itemId, fn) {
3828
+ const experiments = await this.getCollection(TABLE_EXPERIMENTS);
3829
+ const items = await this.getCollection(TABLE_DATASET_ITEMS);
3830
+ return this.#connector.withTransaction(async (session) => {
3831
+ const datasetId = (await experiments.findOne({ id: experimentId }, { session }))?.datasetId ?? null;
3832
+ let purgeMetadata = null;
3833
+ if (datasetId) {
3834
+ const item = await items.findOneAndUpdate({
3835
+ id: itemId,
3836
+ datasetId
3837
+ }, { $inc: { purgeBarrierRevision: 1 } }, {
3838
+ projection: { metadata: 1 },
3839
+ returnDocument: "after",
3840
+ session,
3841
+ sort: { datasetVersion: -1 }
3842
+ });
3843
+ purgeMetadata = item?.metadata?.__purged === true ? item.metadata : null;
3844
+ }
3845
+ return fn(session, purgeMetadata);
3846
+ });
3847
+ }
3748
3848
  /**
3749
3849
  * Prune whole experiments older than the `experiments` policy's `maxAge`.
3750
3850
  *
@@ -4080,52 +4180,34 @@ var MongoDBExperimentsStorage = class MongoDBExperimentsStorage extends Experime
4080
4180
  async addExperimentResult(input) {
4081
4181
  const id = input.id ?? randomUUID();
4082
4182
  const now = /* @__PURE__ */ new Date();
4083
- const doc = {
4084
- id,
4085
- experimentId: input.experimentId,
4086
- itemId: input.itemId,
4087
- itemDatasetVersion: input.itemDatasetVersion ?? null,
4088
- organizationId: input.organizationId ?? null,
4089
- projectId: input.projectId ?? null,
4090
- input: input.input,
4091
- output: input.output ?? null,
4092
- groundTruth: input.groundTruth ?? null,
4093
- metadata: input.metadata ?? null,
4094
- error: input.error ?? null,
4095
- startedAt: input.startedAt,
4096
- completedAt: input.completedAt,
4097
- retryCount: input.retryCount,
4098
- attempt: input.attempt ?? 0,
4099
- traceId: input.traceId ?? null,
4100
- status: input.status ?? null,
4101
- tags: input.tags ?? null,
4102
- toolMockReport: input.toolMockReport ?? null,
4103
- createdAt: now
4104
- };
4105
4183
  try {
4106
- await (await this.getCollection(TABLE_EXPERIMENT_RESULTS)).insertOne(doc);
4107
- return {
4108
- id,
4109
- experimentId: input.experimentId,
4110
- itemId: input.itemId,
4111
- itemDatasetVersion: input.itemDatasetVersion ?? null,
4112
- organizationId: input.organizationId ?? null,
4113
- projectId: input.projectId ?? null,
4114
- input: input.input,
4115
- output: input.output ?? null,
4116
- groundTruth: input.groundTruth ?? null,
4117
- metadata: input.metadata ?? null,
4118
- error: input.error ?? null,
4119
- startedAt: input.startedAt,
4120
- completedAt: input.completedAt,
4121
- retryCount: input.retryCount,
4122
- attempt: input.attempt ?? 0,
4123
- traceId: input.traceId ?? null,
4124
- status: input.status ?? null,
4125
- tags: input.tags ?? null,
4126
- toolMockReport: input.toolMockReport ?? null,
4127
- createdAt: now
4128
- };
4184
+ return await this.#withPurgeBarrier(input.experimentId, input.itemId, async (session, marker) => {
4185
+ const collection = await this.getCollection(TABLE_EXPERIMENT_RESULTS);
4186
+ const doc = {
4187
+ id,
4188
+ experimentId: input.experimentId,
4189
+ itemId: input.itemId,
4190
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
4191
+ organizationId: input.organizationId ?? null,
4192
+ projectId: input.projectId ?? null,
4193
+ input: marker ? null : input.input,
4194
+ output: marker ? null : input.output ?? null,
4195
+ groundTruth: marker ? null : input.groundTruth ?? null,
4196
+ metadata: marker ?? input.metadata ?? null,
4197
+ error: marker ? null : input.error ?? null,
4198
+ startedAt: input.startedAt,
4199
+ completedAt: input.completedAt,
4200
+ retryCount: input.retryCount,
4201
+ attempt: input.attempt ?? 0,
4202
+ traceId: input.traceId ?? null,
4203
+ status: input.status ?? null,
4204
+ tags: marker ? null : input.tags ?? null,
4205
+ toolMockReport: marker ? null : input.toolMockReport ?? null,
4206
+ createdAt: now
4207
+ };
4208
+ await collection.insertOne(doc, { session });
4209
+ return transformExperimentResultRow(doc);
4210
+ });
4129
4211
  } catch (error) {
4130
4212
  throw new MastraError({
4131
4213
  id: createStorageErrorId("MONGODB", "ADD_EXPERIMENT_RESULT", "FAILED"),
@@ -4138,37 +4220,41 @@ var MongoDBExperimentsStorage = class MongoDBExperimentsStorage extends Experime
4138
4220
  async upsertExperimentResult(input) {
4139
4221
  const attempt = input.attempt ?? 0;
4140
4222
  try {
4141
- return transformExperimentResultRow(await (await this.getCollection(TABLE_EXPERIMENT_RESULTS)).findOneAndUpdate({
4142
- experimentId: input.experimentId,
4143
- itemId: input.itemId,
4144
- $or: [{ attempt }, ...attempt === 0 ? [{ attempt: null }, { attempt: { $exists: false } }] : []]
4145
- }, {
4146
- $set: {
4147
- itemDatasetVersion: input.itemDatasetVersion ?? null,
4148
- organizationId: input.organizationId ?? null,
4149
- projectId: input.projectId ?? null,
4150
- input: input.input,
4151
- output: input.output ?? null,
4152
- groundTruth: input.groundTruth ?? null,
4153
- metadata: input.metadata ?? null,
4154
- error: input.error ?? null,
4155
- startedAt: input.startedAt,
4156
- completedAt: input.completedAt,
4157
- retryCount: input.retryCount,
4158
- attempt,
4159
- traceId: input.traceId ?? null,
4160
- status: input.status ?? null,
4161
- tags: input.tags ?? null,
4162
- toolMockReport: input.toolMockReport ?? null
4163
- },
4164
- $setOnInsert: {
4165
- id: randomUUID(),
4166
- createdAt: /* @__PURE__ */ new Date()
4167
- }
4168
- }, {
4169
- upsert: true,
4170
- returnDocument: "after"
4171
- }));
4223
+ return await this.#withPurgeBarrier(input.experimentId, input.itemId, async (session, marker) => {
4224
+ return transformExperimentResultRow(await (await this.getCollection(TABLE_EXPERIMENT_RESULTS)).findOneAndUpdate({
4225
+ experimentId: input.experimentId,
4226
+ itemId: input.itemId,
4227
+ $or: [{ attempt }, ...attempt === 0 ? [{ attempt: null }, { attempt: { $exists: false } }] : []]
4228
+ }, {
4229
+ $set: {
4230
+ itemDatasetVersion: input.itemDatasetVersion ?? null,
4231
+ organizationId: input.organizationId ?? null,
4232
+ projectId: input.projectId ?? null,
4233
+ input: marker ? null : input.input,
4234
+ output: marker ? null : input.output ?? null,
4235
+ groundTruth: marker ? null : input.groundTruth ?? null,
4236
+ metadata: marker ?? input.metadata ?? null,
4237
+ error: marker ? null : input.error ?? null,
4238
+ startedAt: input.startedAt,
4239
+ completedAt: input.completedAt,
4240
+ retryCount: input.retryCount,
4241
+ attempt,
4242
+ traceId: input.traceId ?? null,
4243
+ status: input.status ?? null,
4244
+ tags: marker ? null : input.tags ?? null,
4245
+ toolMockReport: marker ? null : input.toolMockReport ?? null,
4246
+ ...marker ? { comment: null } : {}
4247
+ },
4248
+ $setOnInsert: {
4249
+ id: randomUUID(),
4250
+ createdAt: /* @__PURE__ */ new Date()
4251
+ }
4252
+ }, {
4253
+ upsert: true,
4254
+ returnDocument: "after",
4255
+ session
4256
+ }));
4257
+ });
4172
4258
  } catch (error) {
4173
4259
  throw new MastraError({
4174
4260
  id: createStorageErrorId("MONGODB", "UPSERT_EXPERIMENT_RESULT", "FAILED"),
@@ -4197,14 +4283,30 @@ var MongoDBExperimentsStorage = class MongoDBExperimentsStorage extends Experime
4197
4283
  const collection = await this.getCollection(TABLE_EXPERIMENT_RESULTS);
4198
4284
  const filter = { id: input.id };
4199
4285
  if (input.experimentId) filter.experimentId = input.experimentId;
4200
- const result = await collection.findOneAndUpdate(filter, { $set: updateFields }, { returnDocument: "after" });
4201
- if (!result) throw new MastraError({
4286
+ const existing = await collection.findOne(filter);
4287
+ if (!existing) throw new MastraError({
4202
4288
  id: createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
4203
4289
  domain: ErrorDomain.STORAGE,
4204
4290
  category: ErrorCategory.USER,
4205
4291
  details: { resultId: input.id }
4206
4292
  });
4207
- return transformExperimentResultRow(result);
4293
+ return await this.#withPurgeBarrier(existing.experimentId, existing.itemId, async (session, marker) => {
4294
+ if (marker) {
4295
+ updateFields.tags = null;
4296
+ updateFields.comment = null;
4297
+ }
4298
+ const result = await collection.findOneAndUpdate(filter, { $set: updateFields }, {
4299
+ returnDocument: "after",
4300
+ session
4301
+ });
4302
+ if (!result) throw new MastraError({
4303
+ id: createStorageErrorId("MONGODB", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
4304
+ domain: ErrorDomain.STORAGE,
4305
+ category: ErrorCategory.USER,
4306
+ details: { resultId: input.id }
4307
+ });
4308
+ return transformExperimentResultRow(result);
4309
+ });
4208
4310
  } catch (error) {
4209
4311
  if (error instanceof MastraError) throw error;
4210
4312
  throw new MastraError({