@mastra/mongodb 0.0.0-working-memory-per-user-20250620163010 → 0.0.0-zod-v4-compat-part-2-20250822105954

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +251 -3
  2. package/LICENSE.md +11 -42
  3. package/dist/index.cjs +1846 -505
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.ts +5 -7
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +1815 -474
  8. package/dist/index.js.map +1 -0
  9. package/dist/storage/MongoDBConnector.d.ts +23 -0
  10. package/dist/storage/MongoDBConnector.d.ts.map +1 -0
  11. package/dist/storage/connectors/MongoDBConnector.d.ts +23 -0
  12. package/dist/storage/connectors/MongoDBConnector.d.ts.map +1 -0
  13. package/dist/storage/connectors/base.d.ts +6 -0
  14. package/dist/storage/connectors/base.d.ts.map +1 -0
  15. package/dist/storage/domains/legacy-evals/index.d.ts +18 -0
  16. package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
  17. package/dist/storage/domains/memory/index.d.ts +80 -0
  18. package/dist/storage/domains/memory/index.d.ts.map +1 -0
  19. package/dist/storage/domains/operations/index.d.ts +38 -0
  20. package/dist/storage/domains/operations/index.d.ts.map +1 -0
  21. package/dist/storage/domains/scores/index.d.ts +41 -0
  22. package/dist/storage/domains/scores/index.d.ts.map +1 -0
  23. package/dist/storage/domains/traces/index.d.ts +18 -0
  24. package/dist/storage/domains/traces/index.d.ts.map +1 -0
  25. package/dist/storage/domains/utils.d.ts +8 -0
  26. package/dist/storage/domains/utils.d.ts.map +1 -0
  27. package/dist/storage/domains/workflows/index.d.ts +33 -0
  28. package/dist/storage/domains/workflows/index.d.ts.map +1 -0
  29. package/dist/storage/index.d.ts +178 -0
  30. package/dist/storage/index.d.ts.map +1 -0
  31. package/dist/storage/types.d.ts +11 -0
  32. package/dist/storage/types.d.ts.map +1 -0
  33. package/dist/vector/filter.d.ts +21 -0
  34. package/dist/vector/filter.d.ts.map +1 -0
  35. package/dist/vector/index.d.ts +78 -0
  36. package/dist/vector/index.d.ts.map +1 -0
  37. package/dist/vector/prompt.d.ts +6 -0
  38. package/dist/vector/prompt.d.ts.map +1 -0
  39. package/docker-compose.yaml +1 -1
  40. package/package.json +10 -10
  41. package/src/index.ts +1 -0
  42. package/src/storage/MongoDBConnector.ts +93 -0
  43. package/src/storage/connectors/MongoDBConnector.ts +93 -0
  44. package/src/storage/connectors/base.ts +7 -0
  45. package/src/storage/domains/legacy-evals/index.ts +193 -0
  46. package/src/storage/domains/memory/index.ts +741 -0
  47. package/src/storage/domains/operations/index.ts +155 -0
  48. package/src/storage/domains/scores/index.ts +379 -0
  49. package/src/storage/domains/traces/index.ts +142 -0
  50. package/src/storage/domains/utils.ts +43 -0
  51. package/src/storage/domains/workflows/index.ts +196 -0
  52. package/src/storage/index.test.ts +27 -989
  53. package/src/storage/index.ts +241 -605
  54. package/src/storage/types.ts +14 -0
  55. package/src/vector/filter.test.ts +40 -30
  56. package/src/vector/filter.ts +25 -4
  57. package/src/vector/index.test.ts +48 -3
  58. package/src/vector/index.ts +301 -131
  59. package/tsconfig.build.json +9 -0
  60. package/tsconfig.json +1 -1
  61. package/tsup.config.ts +22 -0
  62. package/dist/_tsup-dts-rollup.d.cts +0 -274
  63. package/dist/_tsup-dts-rollup.d.ts +0 -274
  64. package/dist/index.d.cts +0 -7
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import { MongoClient } from 'mongodb';
3
4
  import { v4 } from 'uuid';
4
5
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
6
+ import { MastraStorage, StoreOperations, TABLE_SCHEMAS, safelyParseJSON, MemoryStorage, TABLE_MESSAGES, resolveMessageLimit, TABLE_THREADS, TABLE_RESOURCES, TracesStorage, TABLE_TRACES, LegacyEvalsStorage, TABLE_EVALS, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT } from '@mastra/core/storage';
5
7
  import { MessageList } from '@mastra/core/agent';
6
- import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS } from '@mastra/core/storage';
7
8
 
8
9
  // src/vector/index.ts
9
10
  var MongoDBFilterTranslator = class extends BaseFilterTranslator {
@@ -116,28 +117,68 @@ var MongoDBVector = class extends MastraVector {
116
117
  }
117
118
  // Public methods
118
119
  async connect() {
119
- await this.client.connect();
120
+ try {
121
+ await this.client.connect();
122
+ } catch (error) {
123
+ throw new MastraError(
124
+ {
125
+ id: "STORAGE_MONGODB_VECTOR_CONNECT_FAILED",
126
+ domain: ErrorDomain.STORAGE,
127
+ category: ErrorCategory.THIRD_PARTY
128
+ },
129
+ error
130
+ );
131
+ }
120
132
  }
121
133
  async disconnect() {
122
- await this.client.close();
134
+ try {
135
+ await this.client.close();
136
+ } catch (error) {
137
+ throw new MastraError(
138
+ {
139
+ id: "STORAGE_MONGODB_VECTOR_DISCONNECT_FAILED",
140
+ domain: ErrorDomain.STORAGE,
141
+ category: ErrorCategory.THIRD_PARTY
142
+ },
143
+ error
144
+ );
145
+ }
123
146
  }
124
147
  async createIndex({ indexName, dimension, metric = "cosine" }) {
125
- if (!Number.isInteger(dimension) || dimension <= 0) {
126
- throw new Error("Dimension must be a positive integer");
127
- }
128
- const mongoMetric = this.mongoMetricMap[metric];
129
- if (!mongoMetric) {
130
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
131
- }
132
- const collectionExists = await this.db.listCollections({ name: indexName }).hasNext();
133
- if (!collectionExists) {
134
- await this.db.createCollection(indexName);
148
+ let mongoMetric;
149
+ try {
150
+ if (!Number.isInteger(dimension) || dimension <= 0) {
151
+ throw new Error("Dimension must be a positive integer");
152
+ }
153
+ mongoMetric = this.mongoMetricMap[metric];
154
+ if (!mongoMetric) {
155
+ throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
156
+ }
157
+ } catch (error) {
158
+ throw new MastraError(
159
+ {
160
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_INVALID_ARGS",
161
+ domain: ErrorDomain.STORAGE,
162
+ category: ErrorCategory.USER,
163
+ details: {
164
+ indexName,
165
+ dimension,
166
+ metric
167
+ }
168
+ },
169
+ error
170
+ );
135
171
  }
136
- const collection = await this.getCollection(indexName);
137
- const indexNameInternal = `${indexName}_vector_index`;
138
- const embeddingField = this.embeddingFieldName;
139
- const numDimensions = dimension;
172
+ let collection;
140
173
  try {
174
+ const collectionExists = await this.db.listCollections({ name: indexName }).hasNext();
175
+ if (!collectionExists) {
176
+ await this.db.createCollection(indexName);
177
+ }
178
+ collection = await this.getCollection(indexName);
179
+ const indexNameInternal = `${indexName}_vector_index`;
180
+ const embeddingField = this.embeddingFieldName;
181
+ const numDimensions = dimension;
141
182
  await collection.createSearchIndex({
142
183
  definition: {
143
184
  fields: [
@@ -146,18 +187,52 @@ var MongoDBVector = class extends MastraVector {
146
187
  path: embeddingField,
147
188
  numDimensions,
148
189
  similarity: mongoMetric
190
+ },
191
+ {
192
+ type: "filter",
193
+ path: "_id"
149
194
  }
150
195
  ]
151
196
  },
152
197
  name: indexNameInternal,
153
198
  type: "vectorSearch"
154
199
  });
200
+ await collection.createSearchIndex({
201
+ definition: {
202
+ mappings: {
203
+ dynamic: true
204
+ }
205
+ },
206
+ name: `${indexName}_search_index`,
207
+ type: "search"
208
+ });
155
209
  } catch (error) {
156
210
  if (error.codeName !== "IndexAlreadyExists") {
157
- throw error;
211
+ throw new MastraError(
212
+ {
213
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED",
214
+ domain: ErrorDomain.STORAGE,
215
+ category: ErrorCategory.THIRD_PARTY
216
+ },
217
+ error
218
+ );
158
219
  }
159
220
  }
160
- await collection.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
221
+ try {
222
+ await collection?.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
223
+ } catch (error) {
224
+ throw new MastraError(
225
+ {
226
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED_STORE_METADATA",
227
+ domain: ErrorDomain.STORAGE,
228
+ category: ErrorCategory.THIRD_PARTY,
229
+ details: {
230
+ indexName
231
+ }
232
+ },
233
+ error
234
+ );
235
+ }
161
236
  }
162
237
  /**
163
238
  * Waits for the index to be ready.
@@ -187,40 +262,54 @@ var MongoDBVector = class extends MastraVector {
187
262
  throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
188
263
  }
189
264
  async upsert({ indexName, vectors, metadata, ids, documents }) {
190
- const collection = await this.getCollection(indexName);
191
- this.collectionForValidation = collection;
192
- const stats = await this.describeIndex({ indexName });
193
- await this.validateVectorDimensions(vectors, stats.dimension);
194
- const generatedIds = ids || vectors.map(() => v4());
195
- const operations = vectors.map((vector, idx) => {
196
- const id = generatedIds[idx];
197
- const meta = metadata?.[idx] || {};
198
- const doc = documents?.[idx];
199
- const normalizedMeta = Object.keys(meta).reduce(
200
- (acc, key) => {
201
- acc[key] = meta[key] instanceof Date ? meta[key].toISOString() : meta[key];
202
- return acc;
265
+ try {
266
+ const collection = await this.getCollection(indexName);
267
+ this.collectionForValidation = collection;
268
+ const stats = await this.describeIndex({ indexName });
269
+ await this.validateVectorDimensions(vectors, stats.dimension);
270
+ const generatedIds = ids || vectors.map(() => v4());
271
+ const operations = vectors.map((vector, idx) => {
272
+ const id = generatedIds[idx];
273
+ const meta = metadata?.[idx] || {};
274
+ const doc = documents?.[idx];
275
+ const normalizedMeta = Object.keys(meta).reduce(
276
+ (acc, key) => {
277
+ acc[key] = meta[key] instanceof Date ? meta[key].toISOString() : meta[key];
278
+ return acc;
279
+ },
280
+ {}
281
+ );
282
+ const updateDoc = {
283
+ [this.embeddingFieldName]: vector,
284
+ [this.metadataFieldName]: normalizedMeta
285
+ };
286
+ if (doc !== void 0) {
287
+ updateDoc[this.documentFieldName] = doc;
288
+ }
289
+ return {
290
+ updateOne: {
291
+ filter: { _id: id },
292
+ // '_id' is a string as per MongoDBDocument interface
293
+ update: { $set: updateDoc },
294
+ upsert: true
295
+ }
296
+ };
297
+ });
298
+ await collection.bulkWrite(operations);
299
+ return generatedIds;
300
+ } catch (error) {
301
+ throw new MastraError(
302
+ {
303
+ id: "STORAGE_MONGODB_VECTOR_UPSERT_FAILED",
304
+ domain: ErrorDomain.STORAGE,
305
+ category: ErrorCategory.THIRD_PARTY,
306
+ details: {
307
+ indexName
308
+ }
203
309
  },
204
- {}
310
+ error
205
311
  );
206
- const updateDoc = {
207
- [this.embeddingFieldName]: vector,
208
- [this.metadataFieldName]: normalizedMeta
209
- };
210
- if (doc !== void 0) {
211
- updateDoc[this.documentFieldName] = doc;
212
- }
213
- return {
214
- updateOne: {
215
- filter: { _id: id },
216
- // '_id' is a string as per MongoDBDocument interface
217
- update: { $set: updateDoc },
218
- upsert: true
219
- }
220
- };
221
- });
222
- await collection.bulkWrite(operations);
223
- return generatedIds;
312
+ }
224
313
  }
225
314
  async query({
226
315
  indexName,
@@ -230,44 +319,49 @@ var MongoDBVector = class extends MastraVector {
230
319
  includeVector = false,
231
320
  documentFilter
232
321
  }) {
233
- const collection = await this.getCollection(indexName, true);
234
- const indexNameInternal = `${indexName}_vector_index`;
235
- const mongoFilter = this.transformFilter(filter);
236
- const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
237
- let combinedFilter = {};
238
- if (Object.keys(mongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
239
- combinedFilter = { $and: [mongoFilter, documentMongoFilter] };
240
- } else if (Object.keys(mongoFilter).length > 0) {
241
- combinedFilter = mongoFilter;
242
- } else if (Object.keys(documentMongoFilter).length > 0) {
243
- combinedFilter = documentMongoFilter;
244
- }
245
- const pipeline = [
246
- {
247
- $vectorSearch: {
248
- index: indexNameInternal,
249
- queryVector,
250
- path: this.embeddingFieldName,
251
- numCandidates: 100,
252
- limit: topK
253
- }
254
- },
255
- // Apply the filter using $match stage
256
- ...Object.keys(combinedFilter).length > 0 ? [{ $match: combinedFilter }] : [],
257
- {
258
- $set: { score: { $meta: "vectorSearchScore" } }
259
- },
260
- {
261
- $project: {
262
- _id: 1,
263
- score: 1,
264
- metadata: `$${this.metadataFieldName}`,
265
- document: `$${this.documentFieldName}`,
266
- ...includeVector && { vector: `$${this.embeddingFieldName}` }
322
+ try {
323
+ const collection = await this.getCollection(indexName, true);
324
+ const indexNameInternal = `${indexName}_vector_index`;
325
+ const mongoFilter = this.transformFilter(filter);
326
+ const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
327
+ let combinedFilter = {};
328
+ if (Object.keys(mongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
329
+ combinedFilter = { $and: [mongoFilter, documentMongoFilter] };
330
+ } else if (Object.keys(mongoFilter).length > 0) {
331
+ combinedFilter = mongoFilter;
332
+ } else if (Object.keys(documentMongoFilter).length > 0) {
333
+ combinedFilter = documentMongoFilter;
334
+ }
335
+ const vectorSearch = {
336
+ index: indexNameInternal,
337
+ queryVector,
338
+ path: this.embeddingFieldName,
339
+ numCandidates: 100,
340
+ limit: topK
341
+ };
342
+ if (Object.keys(combinedFilter).length > 0) {
343
+ const candidateIds = await collection.aggregate([{ $match: combinedFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
344
+ if (candidateIds.length > 0) {
345
+ vectorSearch.filter = { _id: { $in: candidateIds } };
267
346
  }
268
347
  }
269
- ];
270
- try {
348
+ const pipeline = [
349
+ {
350
+ $vectorSearch: vectorSearch
351
+ },
352
+ {
353
+ $set: { score: { $meta: "vectorSearchScore" } }
354
+ },
355
+ {
356
+ $project: {
357
+ _id: 1,
358
+ score: 1,
359
+ metadata: `$${this.metadataFieldName}`,
360
+ document: `$${this.documentFieldName}`,
361
+ ...includeVector && { vector: `$${this.embeddingFieldName}` }
362
+ }
363
+ }
364
+ ];
271
365
  const results = await collection.aggregate(pipeline).toArray();
272
366
  return results.map((result) => ({
273
367
  id: result._id,
@@ -277,13 +371,33 @@ var MongoDBVector = class extends MastraVector {
277
371
  document: result.document
278
372
  }));
279
373
  } catch (error) {
280
- console.error("Error during vector search:", error);
281
- throw error;
374
+ throw new MastraError(
375
+ {
376
+ id: "STORAGE_MONGODB_VECTOR_QUERY_FAILED",
377
+ domain: ErrorDomain.STORAGE,
378
+ category: ErrorCategory.THIRD_PARTY,
379
+ details: {
380
+ indexName
381
+ }
382
+ },
383
+ error
384
+ );
282
385
  }
283
386
  }
284
387
  async listIndexes() {
285
- const collections = await this.db.listCollections().toArray();
286
- return collections.map((col) => col.name);
388
+ try {
389
+ const collections = await this.db.listCollections().toArray();
390
+ return collections.map((col) => col.name);
391
+ } catch (error) {
392
+ throw new MastraError(
393
+ {
394
+ id: "STORAGE_MONGODB_VECTOR_LIST_INDEXES_FAILED",
395
+ domain: ErrorDomain.STORAGE,
396
+ category: ErrorCategory.THIRD_PARTY
397
+ },
398
+ error
399
+ );
400
+ }
287
401
  }
288
402
  /**
289
403
  * Retrieves statistics about a vector index.
@@ -292,24 +406,52 @@ var MongoDBVector = class extends MastraVector {
292
406
  * @returns A promise that resolves to the index statistics including dimension, count and metric
293
407
  */
294
408
  async describeIndex({ indexName }) {
295
- const collection = await this.getCollection(indexName, true);
296
- const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
297
- const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
298
- const dimension = metadataDoc?.dimension || 0;
299
- const metric = metadataDoc?.metric || "cosine";
300
- return {
301
- dimension,
302
- count,
303
- metric
304
- };
409
+ try {
410
+ const collection = await this.getCollection(indexName, true);
411
+ const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
412
+ const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
413
+ const dimension = metadataDoc?.dimension || 0;
414
+ const metric = metadataDoc?.metric || "cosine";
415
+ return {
416
+ dimension,
417
+ count,
418
+ metric
419
+ };
420
+ } catch (error) {
421
+ throw new MastraError(
422
+ {
423
+ id: "STORAGE_MONGODB_VECTOR_DESCRIBE_INDEX_FAILED",
424
+ domain: ErrorDomain.STORAGE,
425
+ category: ErrorCategory.THIRD_PARTY,
426
+ details: {
427
+ indexName
428
+ }
429
+ },
430
+ error
431
+ );
432
+ }
305
433
  }
306
434
  async deleteIndex({ indexName }) {
307
435
  const collection = await this.getCollection(indexName, false);
308
- if (collection) {
309
- await collection.drop();
310
- this.collections.delete(indexName);
311
- } else {
312
- throw new Error(`Index (Collection) "${indexName}" does not exist`);
436
+ try {
437
+ if (collection) {
438
+ await collection.drop();
439
+ this.collections.delete(indexName);
440
+ } else {
441
+ throw new Error(`Index (Collection) "${indexName}" does not exist`);
442
+ }
443
+ } catch (error) {
444
+ throw new MastraError(
445
+ {
446
+ id: "STORAGE_MONGODB_VECTOR_DELETE_INDEX_FAILED",
447
+ domain: ErrorDomain.STORAGE,
448
+ category: ErrorCategory.THIRD_PARTY,
449
+ details: {
450
+ indexName
451
+ }
452
+ },
453
+ error
454
+ );
313
455
  }
314
456
  }
315
457
  /**
@@ -346,7 +488,18 @@ var MongoDBVector = class extends MastraVector {
346
488
  }
347
489
  await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
348
490
  } catch (error) {
349
- throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
491
+ throw new MastraError(
492
+ {
493
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_VECTOR_FAILED",
494
+ domain: ErrorDomain.STORAGE,
495
+ category: ErrorCategory.THIRD_PARTY,
496
+ details: {
497
+ indexName,
498
+ id
499
+ }
500
+ },
501
+ error
502
+ );
350
503
  }
351
504
  }
352
505
  /**
@@ -361,7 +514,18 @@ var MongoDBVector = class extends MastraVector {
361
514
  const collection = await this.getCollection(indexName, true);
362
515
  await collection.deleteOne({ _id: id });
363
516
  } catch (error) {
364
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
517
+ throw new MastraError(
518
+ {
519
+ id: "STORAGE_MONGODB_VECTOR_DELETE_VECTOR_FAILED",
520
+ domain: ErrorDomain.STORAGE,
521
+ category: ErrorCategory.THIRD_PARTY,
522
+ details: {
523
+ indexName,
524
+ id
525
+ }
526
+ },
527
+ error
528
+ );
365
529
  }
366
530
  }
367
531
  // Private methods
@@ -402,21 +566,19 @@ var MongoDBVector = class extends MastraVector {
402
566
  return translator.translate(filter);
403
567
  }
404
568
  };
405
- function safelyParseJSON(jsonString) {
406
- try {
407
- return JSON.parse(jsonString);
408
- } catch {
409
- return {};
410
- }
411
- }
412
- var MongoDBStore = class extends MastraStorage {
413
- #isConnected = false;
569
+ var MongoDBConnector = class _MongoDBConnector {
414
570
  #client;
415
- #db;
416
571
  #dbName;
417
- constructor(config) {
418
- super({ name: "MongoDBStore" });
572
+ #handler;
573
+ #isConnected;
574
+ #db;
575
+ constructor(options) {
576
+ this.#client = options.client;
577
+ this.#dbName = options.dbName;
578
+ this.#handler = options.handler;
419
579
  this.#isConnected = false;
580
+ }
581
+ static fromDatabaseConfig(config) {
420
582
  if (!config.url?.trim().length) {
421
583
  throw new Error(
422
584
  "MongoDBStore: url must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
@@ -427,133 +589,722 @@ var MongoDBStore = class extends MastraStorage {
427
589
  "MongoDBStore: dbName must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
428
590
  );
429
591
  }
430
- this.#dbName = config.dbName;
431
- this.#client = new MongoClient(config.url, config.options);
592
+ return new _MongoDBConnector({
593
+ client: new MongoClient(config.url, config.options),
594
+ dbName: config.dbName,
595
+ handler: void 0
596
+ });
597
+ }
598
+ static fromConnectionHandler(handler) {
599
+ return new _MongoDBConnector({
600
+ client: void 0,
601
+ dbName: void 0,
602
+ handler
603
+ });
432
604
  }
433
605
  async getConnection() {
434
- if (this.#isConnected) {
606
+ if (this.#client) {
607
+ if (this.#isConnected && this.#db) {
608
+ return this.#db;
609
+ }
610
+ await this.#client.connect();
611
+ this.#db = this.#client.db(this.#dbName);
612
+ this.#isConnected = true;
435
613
  return this.#db;
436
614
  }
437
- await this.#client.connect();
438
- this.#db = this.#client.db(this.#dbName);
439
- this.#isConnected = true;
440
- return this.#db;
615
+ throw new Error("MongoDBStore: client cannot be empty. Check your MongoDBConnector configuration.");
441
616
  }
442
617
  async getCollection(collectionName) {
618
+ if (this.#handler) {
619
+ return this.#handler.getCollection(collectionName);
620
+ }
443
621
  const db = await this.getConnection();
444
622
  return db.collection(collectionName);
445
623
  }
446
- async createTable() {
447
- }
448
- /**
449
- * No-op: This backend is schemaless and does not require schema changes.
450
- * @param tableName Name of the table
451
- * @param schema Schema of the table
452
- * @param ifNotExists Array of column names to add if they don't exist
453
- */
454
- async alterTable(_args) {
624
+ async close() {
625
+ if (this.#client) {
626
+ await this.#client.close();
627
+ this.#isConnected = false;
628
+ return;
629
+ }
630
+ if (this.#handler) {
631
+ await this.#handler.close();
632
+ }
455
633
  }
456
- async clearTable({ tableName }) {
634
+ };
635
+ function transformEvalRow(row) {
636
+ let testInfoValue = null;
637
+ if (row.test_info) {
457
638
  try {
458
- const collection = await this.getCollection(tableName);
459
- await collection.deleteMany({});
460
- } catch (error) {
461
- if (error instanceof Error) {
462
- this.logger.error(error.message);
463
- }
639
+ testInfoValue = typeof row.test_info === "string" ? safelyParseJSON(row.test_info) : row.test_info;
640
+ } catch (e) {
641
+ console.warn("Failed to parse test_info:", e);
464
642
  }
465
643
  }
466
- async insert({ tableName, record }) {
644
+ let resultValue;
645
+ try {
646
+ resultValue = typeof row.result === "string" ? safelyParseJSON(row.result) : row.result;
647
+ } catch (e) {
648
+ console.warn("Failed to parse result:", e);
649
+ throw new Error("Invalid result format");
650
+ }
651
+ return {
652
+ agentName: row.agent_name,
653
+ input: row.input,
654
+ output: row.output,
655
+ result: resultValue,
656
+ metricName: row.metric_name,
657
+ instructions: row.instructions,
658
+ testInfo: testInfoValue,
659
+ globalRunId: row.global_run_id,
660
+ runId: row.run_id,
661
+ createdAt: row.createdAt
662
+ };
663
+ }
664
+ var LegacyEvalsMongoDB = class extends LegacyEvalsStorage {
665
+ operations;
666
+ constructor({ operations }) {
667
+ super();
668
+ this.operations = operations;
669
+ }
670
+ /** @deprecated use getEvals instead */
671
+ async getEvalsByAgentName(agentName, type) {
467
672
  try {
468
- const collection = await this.getCollection(tableName);
469
- await collection.insertOne(record);
673
+ const query = {
674
+ agent_name: agentName
675
+ };
676
+ if (type === "test") {
677
+ query["test_info"] = { $ne: null };
678
+ }
679
+ if (type === "live") {
680
+ query["test_info"] = null;
681
+ }
682
+ const collection = await this.operations.getCollection(TABLE_EVALS);
683
+ const documents = await collection.find(query).sort({ created_at: "desc" }).toArray();
684
+ const result = documents.map((row) => transformEvalRow(row));
685
+ return result.filter((row) => {
686
+ if (type === "live") {
687
+ return !Boolean(row.testInfo?.testPath);
688
+ }
689
+ if (type === "test") {
690
+ return row.testInfo?.testPath !== null;
691
+ }
692
+ return true;
693
+ });
470
694
  } catch (error) {
471
- this.logger.error(`Error upserting into table ${tableName}: ${error}`);
472
- throw error;
695
+ if (error instanceof Error && error.message.includes("no such table")) {
696
+ return [];
697
+ }
698
+ throw new MastraError(
699
+ {
700
+ id: "STORAGE_MONGODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
701
+ domain: ErrorDomain.STORAGE,
702
+ category: ErrorCategory.THIRD_PARTY,
703
+ details: { agentName }
704
+ },
705
+ error
706
+ );
473
707
  }
474
708
  }
475
- async batchInsert({ tableName, records }) {
476
- if (!records.length) {
477
- return;
709
+ async getEvals(options = {}) {
710
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
711
+ const fromDate = dateRange?.start;
712
+ const toDate = dateRange?.end;
713
+ const currentOffset = page * perPage;
714
+ const query = {};
715
+ if (agentName) {
716
+ query["agent_name"] = agentName;
478
717
  }
479
- try {
480
- const collection = await this.getCollection(tableName);
481
- await collection.insertMany(records);
482
- } catch (error) {
483
- this.logger.error(`Error upserting into table ${tableName}: ${error}`);
484
- throw error;
718
+ if (type === "test") {
719
+ query["test_info"] = { $ne: null };
720
+ } else if (type === "live") {
721
+ query["test_info"] = null;
485
722
  }
486
- }
487
- async load({ tableName, keys }) {
488
- this.logger.info(`Loading ${tableName} with keys ${JSON.stringify(keys)}`);
489
- try {
490
- const collection = await this.getCollection(tableName);
491
- return await collection.find(keys).toArray();
492
- } catch (error) {
493
- this.logger.error(`Error loading ${tableName} with keys ${JSON.stringify(keys)}: ${error}`);
494
- throw error;
723
+ if (fromDate || toDate) {
724
+ query["createdAt"] = {};
725
+ if (fromDate) {
726
+ query["createdAt"]["$gte"] = fromDate;
727
+ }
728
+ if (toDate) {
729
+ query["createdAt"]["$lte"] = toDate;
730
+ }
495
731
  }
496
- }
497
- async getThreadById({ threadId }) {
498
732
  try {
499
- const collection = await this.getCollection(TABLE_THREADS);
500
- const result = await collection.findOne({ id: threadId });
501
- if (!result) {
502
- return null;
733
+ const collection = await this.operations.getCollection(TABLE_EVALS);
734
+ let total = 0;
735
+ if (page === 0 || perPage < 1e3) {
736
+ total = await collection.countDocuments(query);
737
+ }
738
+ if (total === 0) {
739
+ return {
740
+ evals: [],
741
+ total: 0,
742
+ page,
743
+ perPage,
744
+ hasMore: false
745
+ };
503
746
  }
747
+ const documents = await collection.find(query).sort({ created_at: "desc" }).skip(currentOffset).limit(perPage).toArray();
748
+ const evals = documents.map((row) => transformEvalRow(row));
749
+ const filteredEvals = evals.filter((row) => {
750
+ if (type === "live") {
751
+ return !Boolean(row.testInfo?.testPath);
752
+ }
753
+ if (type === "test") {
754
+ return row.testInfo?.testPath !== null;
755
+ }
756
+ return true;
757
+ });
758
+ const hasMore = currentOffset + filteredEvals.length < total;
504
759
  return {
505
- ...result,
506
- metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
760
+ evals: filteredEvals,
761
+ total,
762
+ page,
763
+ perPage,
764
+ hasMore
507
765
  };
508
766
  } catch (error) {
509
- this.logger.error(`Error loading thread with ID ${threadId}: ${error}`);
510
- throw error;
511
- }
512
- }
513
- async getThreadsByResourceId({ resourceId }) {
514
- try {
515
- const collection = await this.getCollection(TABLE_THREADS);
516
- const results = await collection.find({ resourceId }).toArray();
517
- if (!results.length) {
518
- return [];
519
- }
520
- return results.map((result) => ({
521
- ...result,
522
- metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
523
- }));
524
- } catch (error) {
525
- this.logger.error(`Error loading threads by resourceId ${resourceId}: ${error}`);
526
- throw error;
527
- }
528
- }
529
- async saveThread({ thread }) {
530
- try {
531
- const collection = await this.getCollection(TABLE_THREADS);
532
- await collection.updateOne(
533
- { id: thread.id },
767
+ throw new MastraError(
534
768
  {
535
- $set: {
536
- ...thread,
537
- metadata: JSON.stringify(thread.metadata)
769
+ id: "STORAGE_MONGODB_STORE_GET_EVALS_FAILED",
770
+ domain: ErrorDomain.STORAGE,
771
+ category: ErrorCategory.THIRD_PARTY,
772
+ details: {
773
+ agentName: agentName || "all",
774
+ type: type || "all",
775
+ page,
776
+ perPage
538
777
  }
539
778
  },
540
- { upsert: true }
779
+ error
541
780
  );
542
- return thread;
543
- } catch (error) {
544
- this.logger.error(`Error saving thread ${thread.id}: ${error}`);
545
- throw error;
546
781
  }
547
782
  }
548
- async updateThread({
549
- id,
550
- title,
551
- metadata
552
- }) {
553
- const thread = await this.getThreadById({ threadId: id });
554
- if (!thread) {
555
- throw new Error(`Thread ${id} not found`);
556
- }
783
+ };
784
+
785
+ // src/storage/domains/utils.ts
786
+ function formatDateForMongoDB(date) {
787
+ return typeof date === "string" ? new Date(date) : date;
788
+ }
789
+
790
+ // src/storage/domains/memory/index.ts
791
+ var MemoryStorageMongoDB = class extends MemoryStorage {
792
+ operations;
793
+ constructor({ operations }) {
794
+ super();
795
+ this.operations = operations;
796
+ }
797
+ parseRow(row) {
798
+ let content = row.content;
799
+ if (typeof content === "string") {
800
+ try {
801
+ content = JSON.parse(content);
802
+ } catch {
803
+ }
804
+ }
805
+ const result = {
806
+ id: row.id,
807
+ content,
808
+ role: row.role,
809
+ createdAt: formatDateForMongoDB(row.createdAt),
810
+ threadId: row.thread_id,
811
+ resourceId: row.resourceId
812
+ };
813
+ if (row.type && row.type !== "v2") result.type = row.type;
814
+ return result;
815
+ }
816
+ async _getIncludedMessages({
817
+ threadId,
818
+ selectBy
819
+ }) {
820
+ const include = selectBy?.include;
821
+ if (!include) return null;
822
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
823
+ const includedMessages = [];
824
+ for (const inc of include) {
825
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
826
+ const searchThreadId = inc.threadId || threadId;
827
+ const allMessages = await collection.find({ thread_id: searchThreadId }).sort({ createdAt: 1 }).toArray();
828
+ const targetIndex = allMessages.findIndex((msg) => msg.id === id);
829
+ if (targetIndex === -1) continue;
830
+ const startIndex = Math.max(0, targetIndex - withPreviousMessages);
831
+ const endIndex = Math.min(allMessages.length - 1, targetIndex + withNextMessages);
832
+ for (let i = startIndex; i <= endIndex; i++) {
833
+ includedMessages.push(allMessages[i]);
834
+ }
835
+ }
836
+ const seen = /* @__PURE__ */ new Set();
837
+ const dedupedMessages = includedMessages.filter((msg) => {
838
+ if (seen.has(msg.id)) return false;
839
+ seen.add(msg.id);
840
+ return true;
841
+ });
842
+ return dedupedMessages.map((row) => this.parseRow(row));
843
+ }
844
+ async getMessages({
845
+ threadId,
846
+ selectBy,
847
+ format
848
+ }) {
849
+ try {
850
+ const messages = [];
851
+ const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
852
+ if (selectBy?.include?.length) {
853
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
854
+ if (includeMessages) {
855
+ messages.push(...includeMessages);
856
+ }
857
+ }
858
+ const excludeIds = messages.map((m) => m.id);
859
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
860
+ const query = { thread_id: threadId };
861
+ if (excludeIds.length > 0) {
862
+ query.id = { $nin: excludeIds };
863
+ }
864
+ if (limit > 0) {
865
+ const remainingMessages = await collection.find(query).sort({ createdAt: -1 }).limit(limit).toArray();
866
+ messages.push(...remainingMessages.map((row) => this.parseRow(row)));
867
+ }
868
+ messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
869
+ const list = new MessageList().add(messages, "memory");
870
+ if (format === "v2") return list.get.all.v2();
871
+ return list.get.all.v1();
872
+ } catch (error) {
873
+ throw new MastraError(
874
+ {
875
+ id: "MONGODB_STORE_GET_MESSAGES_FAILED",
876
+ domain: ErrorDomain.STORAGE,
877
+ category: ErrorCategory.THIRD_PARTY,
878
+ details: { threadId }
879
+ },
880
+ error
881
+ );
882
+ }
883
+ }
884
+ async getMessagesPaginated(args) {
885
+ const { threadId, format, selectBy } = args;
886
+ const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
887
+ const perPage = perPageInput !== void 0 ? perPageInput : resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
888
+ const fromDate = dateRange?.start;
889
+ const toDate = dateRange?.end;
890
+ const messages = [];
891
+ if (selectBy?.include?.length) {
892
+ try {
893
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
894
+ if (includeMessages) {
895
+ messages.push(...includeMessages);
896
+ }
897
+ } catch (error) {
898
+ throw new MastraError(
899
+ {
900
+ id: "MONGODB_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED",
901
+ domain: ErrorDomain.STORAGE,
902
+ category: ErrorCategory.THIRD_PARTY,
903
+ details: { threadId }
904
+ },
905
+ error
906
+ );
907
+ }
908
+ }
909
+ try {
910
+ const currentOffset = page * perPage;
911
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
912
+ const query = { thread_id: threadId };
913
+ if (fromDate) {
914
+ query.createdAt = { ...query.createdAt, $gte: fromDate };
915
+ }
916
+ if (toDate) {
917
+ query.createdAt = { ...query.createdAt, $lte: toDate };
918
+ }
919
+ const total = await collection.countDocuments(query);
920
+ if (total === 0 && messages.length === 0) {
921
+ return {
922
+ messages: [],
923
+ total: 0,
924
+ page,
925
+ perPage,
926
+ hasMore: false
927
+ };
928
+ }
929
+ const excludeIds = messages.map((m) => m.id);
930
+ if (excludeIds.length > 0) {
931
+ query.id = { $nin: excludeIds };
932
+ }
933
+ const dataResult = await collection.find(query).sort({ createdAt: -1 }).skip(currentOffset).limit(perPage).toArray();
934
+ messages.push(...dataResult.map((row) => this.parseRow(row)));
935
+ const messagesToReturn = format === "v1" ? new MessageList().add(messages, "memory").get.all.v1() : new MessageList().add(messages, "memory").get.all.v2();
936
+ return {
937
+ messages: messagesToReturn,
938
+ total,
939
+ page,
940
+ perPage,
941
+ hasMore: (page + 1) * perPage < total
942
+ };
943
+ } catch (error) {
944
+ const mastraError = new MastraError(
945
+ {
946
+ id: "MONGODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
947
+ domain: ErrorDomain.STORAGE,
948
+ category: ErrorCategory.THIRD_PARTY,
949
+ details: { threadId }
950
+ },
951
+ error
952
+ );
953
+ this.logger?.trackException?.(mastraError);
954
+ this.logger?.error?.(mastraError.toString());
955
+ return { messages: [], total: 0, page, perPage, hasMore: false };
956
+ }
957
+ }
958
+ async saveMessages({
959
+ messages,
960
+ format
961
+ }) {
962
+ if (messages.length === 0) return messages;
963
+ try {
964
+ const threadId = messages[0]?.threadId;
965
+ if (!threadId) {
966
+ throw new Error("Thread ID is required");
967
+ }
968
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
969
+ const threadsCollection = await this.operations.getCollection(TABLE_THREADS);
970
+ const messagesToInsert = messages.map((message) => {
971
+ const time = message.createdAt || /* @__PURE__ */ new Date();
972
+ if (!message.threadId) {
973
+ throw new Error(
974
+ "Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred."
975
+ );
976
+ }
977
+ if (!message.resourceId) {
978
+ throw new Error(
979
+ "Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred."
980
+ );
981
+ }
982
+ return {
983
+ updateOne: {
984
+ filter: { id: message.id },
985
+ update: {
986
+ $set: {
987
+ id: message.id,
988
+ thread_id: message.threadId,
989
+ content: typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
990
+ role: message.role,
991
+ type: message.type || "v2",
992
+ createdAt: formatDateForMongoDB(time),
993
+ resourceId: message.resourceId
994
+ }
995
+ },
996
+ upsert: true
997
+ }
998
+ };
999
+ });
1000
+ await Promise.all([
1001
+ collection.bulkWrite(messagesToInsert),
1002
+ threadsCollection.updateOne({ id: threadId }, { $set: { updatedAt: /* @__PURE__ */ new Date() } })
1003
+ ]);
1004
+ const list = new MessageList().add(messages, "memory");
1005
+ if (format === "v2") return list.get.all.v2();
1006
+ return list.get.all.v1();
1007
+ } catch (error) {
1008
+ throw new MastraError(
1009
+ {
1010
+ id: "MONGODB_STORE_SAVE_MESSAGES_FAILED",
1011
+ domain: ErrorDomain.STORAGE,
1012
+ category: ErrorCategory.THIRD_PARTY
1013
+ },
1014
+ error
1015
+ );
1016
+ }
1017
+ }
1018
+ async updateMessages({
1019
+ messages
1020
+ }) {
1021
+ if (messages.length === 0) {
1022
+ return [];
1023
+ }
1024
+ const messageIds = messages.map((m) => m.id);
1025
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
1026
+ const existingMessages = await collection.find({ id: { $in: messageIds } }).toArray();
1027
+ const existingMessagesParsed = existingMessages.map((msg) => this.parseRow(msg));
1028
+ if (existingMessagesParsed.length === 0) {
1029
+ return [];
1030
+ }
1031
+ const threadIdsToUpdate = /* @__PURE__ */ new Set();
1032
+ const bulkOps = [];
1033
+ for (const existingMessage of existingMessagesParsed) {
1034
+ const updatePayload = messages.find((m) => m.id === existingMessage.id);
1035
+ if (!updatePayload) continue;
1036
+ const { id, ...fieldsToUpdate } = updatePayload;
1037
+ if (Object.keys(fieldsToUpdate).length === 0) continue;
1038
+ threadIdsToUpdate.add(existingMessage.threadId);
1039
+ if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
1040
+ threadIdsToUpdate.add(updatePayload.threadId);
1041
+ }
1042
+ const updateDoc = {};
1043
+ const updatableFields = { ...fieldsToUpdate };
1044
+ if (updatableFields.content) {
1045
+ const newContent = {
1046
+ ...existingMessage.content,
1047
+ ...updatableFields.content,
1048
+ // Deep merge metadata if it exists on both
1049
+ ...existingMessage.content?.metadata && updatableFields.content.metadata ? {
1050
+ metadata: {
1051
+ ...existingMessage.content.metadata,
1052
+ ...updatableFields.content.metadata
1053
+ }
1054
+ } : {}
1055
+ };
1056
+ updateDoc.content = JSON.stringify(newContent);
1057
+ delete updatableFields.content;
1058
+ }
1059
+ for (const key in updatableFields) {
1060
+ if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
1061
+ const dbKey = key === "threadId" ? "thread_id" : key;
1062
+ let value = updatableFields[key];
1063
+ if (typeof value === "object" && value !== null) {
1064
+ value = JSON.stringify(value);
1065
+ }
1066
+ updateDoc[dbKey] = value;
1067
+ }
1068
+ }
1069
+ if (Object.keys(updateDoc).length > 0) {
1070
+ bulkOps.push({
1071
+ updateOne: {
1072
+ filter: { id },
1073
+ update: { $set: updateDoc }
1074
+ }
1075
+ });
1076
+ }
1077
+ }
1078
+ if (bulkOps.length > 0) {
1079
+ await collection.bulkWrite(bulkOps);
1080
+ }
1081
+ if (threadIdsToUpdate.size > 0) {
1082
+ const threadsCollection = await this.operations.getCollection(TABLE_THREADS);
1083
+ await threadsCollection.updateMany(
1084
+ { id: { $in: Array.from(threadIdsToUpdate) } },
1085
+ { $set: { updatedAt: /* @__PURE__ */ new Date() } }
1086
+ );
1087
+ }
1088
+ const updatedMessages = await collection.find({ id: { $in: messageIds } }).toArray();
1089
+ return updatedMessages.map((row) => this.parseRow(row));
1090
+ }
1091
+ async getResourceById({ resourceId }) {
1092
+ try {
1093
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1094
+ const result = await collection.findOne({ id: resourceId });
1095
+ if (!result) {
1096
+ return null;
1097
+ }
1098
+ return {
1099
+ id: result.id,
1100
+ workingMemory: result.workingMemory || "",
1101
+ metadata: typeof result.metadata === "string" ? safelyParseJSON(result.metadata) : result.metadata,
1102
+ createdAt: formatDateForMongoDB(result.createdAt),
1103
+ updatedAt: formatDateForMongoDB(result.updatedAt)
1104
+ };
1105
+ } catch (error) {
1106
+ throw new MastraError(
1107
+ {
1108
+ id: "STORAGE_MONGODB_STORE_GET_RESOURCE_BY_ID_FAILED",
1109
+ domain: ErrorDomain.STORAGE,
1110
+ category: ErrorCategory.THIRD_PARTY,
1111
+ details: { resourceId }
1112
+ },
1113
+ error
1114
+ );
1115
+ }
1116
+ }
1117
+ async saveResource({ resource }) {
1118
+ try {
1119
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1120
+ await collection.updateOne(
1121
+ { id: resource.id },
1122
+ {
1123
+ $set: {
1124
+ ...resource,
1125
+ metadata: JSON.stringify(resource.metadata)
1126
+ }
1127
+ },
1128
+ { upsert: true }
1129
+ );
1130
+ return resource;
1131
+ } catch (error) {
1132
+ throw new MastraError(
1133
+ {
1134
+ id: "STORAGE_MONGODB_STORE_SAVE_RESOURCE_FAILED",
1135
+ domain: ErrorDomain.STORAGE,
1136
+ category: ErrorCategory.THIRD_PARTY,
1137
+ details: { resourceId: resource.id }
1138
+ },
1139
+ error
1140
+ );
1141
+ }
1142
+ }
1143
+ async updateResource({
1144
+ resourceId,
1145
+ workingMemory,
1146
+ metadata
1147
+ }) {
1148
+ try {
1149
+ const existingResource = await this.getResourceById({ resourceId });
1150
+ if (!existingResource) {
1151
+ const newResource = {
1152
+ id: resourceId,
1153
+ workingMemory: workingMemory || "",
1154
+ metadata: metadata || {},
1155
+ createdAt: /* @__PURE__ */ new Date(),
1156
+ updatedAt: /* @__PURE__ */ new Date()
1157
+ };
1158
+ return this.saveResource({ resource: newResource });
1159
+ }
1160
+ const updatedResource = {
1161
+ ...existingResource,
1162
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
1163
+ metadata: metadata ? { ...existingResource.metadata, ...metadata } : existingResource.metadata,
1164
+ updatedAt: /* @__PURE__ */ new Date()
1165
+ };
1166
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1167
+ const updateDoc = { updatedAt: updatedResource.updatedAt };
1168
+ if (workingMemory !== void 0) {
1169
+ updateDoc.workingMemory = workingMemory;
1170
+ }
1171
+ if (metadata) {
1172
+ updateDoc.metadata = JSON.stringify(updatedResource.metadata);
1173
+ }
1174
+ await collection.updateOne({ id: resourceId }, { $set: updateDoc });
1175
+ return updatedResource;
1176
+ } catch (error) {
1177
+ throw new MastraError(
1178
+ {
1179
+ id: "STORAGE_MONGODB_STORE_UPDATE_RESOURCE_FAILED",
1180
+ domain: ErrorDomain.STORAGE,
1181
+ category: ErrorCategory.THIRD_PARTY,
1182
+ details: { resourceId }
1183
+ },
1184
+ error
1185
+ );
1186
+ }
1187
+ }
1188
+ async getThreadById({ threadId }) {
1189
+ try {
1190
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1191
+ const result = await collection.findOne({ id: threadId });
1192
+ if (!result) {
1193
+ return null;
1194
+ }
1195
+ return {
1196
+ ...result,
1197
+ metadata: typeof result.metadata === "string" ? safelyParseJSON(result.metadata) : result.metadata
1198
+ };
1199
+ } catch (error) {
1200
+ throw new MastraError(
1201
+ {
1202
+ id: "STORAGE_MONGODB_STORE_GET_THREAD_BY_ID_FAILED",
1203
+ domain: ErrorDomain.STORAGE,
1204
+ category: ErrorCategory.THIRD_PARTY,
1205
+ details: { threadId }
1206
+ },
1207
+ error
1208
+ );
1209
+ }
1210
+ }
1211
+ async getThreadsByResourceId({ resourceId }) {
1212
+ try {
1213
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1214
+ const results = await collection.find({ resourceId }).sort({ updatedAt: -1 }).toArray();
1215
+ if (!results.length) {
1216
+ return [];
1217
+ }
1218
+ return results.map((result) => ({
1219
+ ...result,
1220
+ metadata: typeof result.metadata === "string" ? safelyParseJSON(result.metadata) : result.metadata
1221
+ }));
1222
+ } catch (error) {
1223
+ throw new MastraError(
1224
+ {
1225
+ id: "STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1226
+ domain: ErrorDomain.STORAGE,
1227
+ category: ErrorCategory.THIRD_PARTY,
1228
+ details: { resourceId }
1229
+ },
1230
+ error
1231
+ );
1232
+ }
1233
+ }
1234
+ async getThreadsByResourceIdPaginated(args) {
1235
+ try {
1236
+ const { resourceId, page, perPage } = args;
1237
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1238
+ const query = { resourceId };
1239
+ const total = await collection.countDocuments(query);
1240
+ const threads = await collection.find(query).sort({ updatedAt: -1 }).skip(page * perPage).limit(perPage).toArray();
1241
+ return {
1242
+ threads: threads.map((thread) => ({
1243
+ id: thread.id,
1244
+ title: thread.title,
1245
+ resourceId: thread.resourceId,
1246
+ createdAt: formatDateForMongoDB(thread.createdAt),
1247
+ updatedAt: formatDateForMongoDB(thread.updatedAt),
1248
+ metadata: thread.metadata || {}
1249
+ })),
1250
+ total,
1251
+ page,
1252
+ perPage,
1253
+ hasMore: (page + 1) * perPage < total
1254
+ };
1255
+ } catch (error) {
1256
+ throw new MastraError(
1257
+ {
1258
+ id: "MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1259
+ domain: ErrorDomain.STORAGE,
1260
+ category: ErrorCategory.THIRD_PARTY,
1261
+ details: { resourceId: args.resourceId }
1262
+ },
1263
+ error
1264
+ );
1265
+ }
1266
+ }
1267
+ async saveThread({ thread }) {
1268
+ try {
1269
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1270
+ await collection.updateOne(
1271
+ { id: thread.id },
1272
+ {
1273
+ $set: {
1274
+ ...thread,
1275
+ metadata: thread.metadata
1276
+ }
1277
+ },
1278
+ { upsert: true }
1279
+ );
1280
+ return thread;
1281
+ } catch (error) {
1282
+ throw new MastraError(
1283
+ {
1284
+ id: "STORAGE_MONGODB_STORE_SAVE_THREAD_FAILED",
1285
+ domain: ErrorDomain.STORAGE,
1286
+ category: ErrorCategory.THIRD_PARTY,
1287
+ details: { threadId: thread.id }
1288
+ },
1289
+ error
1290
+ );
1291
+ }
1292
+ }
1293
+ async updateThread({
1294
+ id,
1295
+ title,
1296
+ metadata
1297
+ }) {
1298
+ const thread = await this.getThreadById({ threadId: id });
1299
+ if (!thread) {
1300
+ throw new MastraError({
1301
+ id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_NOT_FOUND",
1302
+ domain: ErrorDomain.STORAGE,
1303
+ category: ErrorCategory.THIRD_PARTY,
1304
+ details: { threadId: id, status: 404 },
1305
+ text: `Thread ${id} not found`
1306
+ });
1307
+ }
557
1308
  const updatedThread = {
558
1309
  ...thread,
559
1310
  title,
@@ -563,185 +1314,523 @@ var MongoDBStore = class extends MastraStorage {
563
1314
  }
564
1315
  };
565
1316
  try {
566
- const collection = await this.getCollection(TABLE_THREADS);
1317
+ const collection = await this.operations.getCollection(TABLE_THREADS);
567
1318
  await collection.updateOne(
568
1319
  { id },
569
1320
  {
570
1321
  $set: {
571
1322
  title,
572
- metadata: JSON.stringify(updatedThread.metadata)
1323
+ metadata: updatedThread.metadata
573
1324
  }
574
1325
  }
575
1326
  );
576
1327
  } catch (error) {
577
- this.logger.error(`Error updating thread ${id}:) ${error}`);
578
- throw error;
1328
+ throw new MastraError(
1329
+ {
1330
+ id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_FAILED",
1331
+ domain: ErrorDomain.STORAGE,
1332
+ category: ErrorCategory.THIRD_PARTY,
1333
+ details: { threadId: id }
1334
+ },
1335
+ error
1336
+ );
579
1337
  }
580
1338
  return updatedThread;
581
1339
  }
582
1340
  async deleteThread({ threadId }) {
583
1341
  try {
584
- const collectionMessages = await this.getCollection(TABLE_MESSAGES);
1342
+ const collectionMessages = await this.operations.getCollection(TABLE_MESSAGES);
585
1343
  await collectionMessages.deleteMany({ thread_id: threadId });
586
- const collectionThreads = await this.getCollection(TABLE_THREADS);
1344
+ const collectionThreads = await this.operations.getCollection(TABLE_THREADS);
587
1345
  await collectionThreads.deleteOne({ id: threadId });
588
1346
  } catch (error) {
589
- this.logger.error(`Error deleting thread ${threadId}: ${error}`);
590
- throw error;
1347
+ throw new MastraError(
1348
+ {
1349
+ id: "STORAGE_MONGODB_STORE_DELETE_THREAD_FAILED",
1350
+ domain: ErrorDomain.STORAGE,
1351
+ category: ErrorCategory.THIRD_PARTY,
1352
+ details: { threadId }
1353
+ },
1354
+ error
1355
+ );
1356
+ }
1357
+ }
1358
+ };
1359
+ var StoreOperationsMongoDB = class extends StoreOperations {
1360
+ #connector;
1361
+ constructor(config) {
1362
+ super();
1363
+ this.#connector = config.connector;
1364
+ }
1365
+ async getCollection(collectionName) {
1366
+ return this.#connector.getCollection(collectionName);
1367
+ }
1368
+ async hasColumn(_table, _column) {
1369
+ return true;
1370
+ }
1371
+ async createTable() {
1372
+ }
1373
+ async alterTable(_args) {
1374
+ }
1375
+ async clearTable({ tableName }) {
1376
+ try {
1377
+ const collection = await this.getCollection(tableName);
1378
+ await collection.deleteMany({});
1379
+ } catch (error) {
1380
+ if (error instanceof Error) {
1381
+ const matstraError = new MastraError(
1382
+ {
1383
+ id: "STORAGE_MONGODB_STORE_CLEAR_TABLE_FAILED",
1384
+ domain: ErrorDomain.STORAGE,
1385
+ category: ErrorCategory.THIRD_PARTY,
1386
+ details: { tableName }
1387
+ },
1388
+ error
1389
+ );
1390
+ this.logger.error(matstraError.message);
1391
+ this.logger?.trackException(matstraError);
1392
+ }
1393
+ }
1394
+ }
1395
+ async dropTable({ tableName }) {
1396
+ try {
1397
+ const collection = await this.getCollection(tableName);
1398
+ await collection.drop();
1399
+ } catch (error) {
1400
+ if (error instanceof Error && error.message.includes("ns not found")) {
1401
+ return;
1402
+ }
1403
+ throw new MastraError(
1404
+ {
1405
+ id: "MONGODB_STORE_DROP_TABLE_FAILED",
1406
+ domain: ErrorDomain.STORAGE,
1407
+ category: ErrorCategory.THIRD_PARTY,
1408
+ details: { tableName }
1409
+ },
1410
+ error
1411
+ );
1412
+ }
1413
+ }
1414
+ processJsonbFields(tableName, record) {
1415
+ const schema = TABLE_SCHEMAS[tableName];
1416
+ return Object.fromEntries(
1417
+ Object.entries(schema).map(([key, value]) => {
1418
+ if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1419
+ return [key, safelyParseJSON(record[key])];
1420
+ }
1421
+ return [key, record[key]];
1422
+ })
1423
+ );
1424
+ }
1425
+ async insert({ tableName, record }) {
1426
+ try {
1427
+ const collection = await this.getCollection(tableName);
1428
+ const recordToInsert = this.processJsonbFields(tableName, record);
1429
+ await collection.insertOne(recordToInsert);
1430
+ } catch (error) {
1431
+ if (error instanceof Error) {
1432
+ const matstraError = new MastraError(
1433
+ {
1434
+ id: "STORAGE_MONGODB_STORE_INSERT_FAILED",
1435
+ domain: ErrorDomain.STORAGE,
1436
+ category: ErrorCategory.THIRD_PARTY,
1437
+ details: { tableName }
1438
+ },
1439
+ error
1440
+ );
1441
+ this.logger.error(matstraError.message);
1442
+ this.logger?.trackException(matstraError);
1443
+ }
1444
+ }
1445
+ }
1446
+ async batchInsert({ tableName, records }) {
1447
+ if (!records.length) {
1448
+ return;
1449
+ }
1450
+ try {
1451
+ const collection = await this.getCollection(tableName);
1452
+ const processedRecords = records.map((record) => this.processJsonbFields(tableName, record));
1453
+ await collection.insertMany(processedRecords);
1454
+ } catch (error) {
1455
+ throw new MastraError(
1456
+ {
1457
+ id: "STORAGE_MONGODB_STORE_BATCH_INSERT_FAILED",
1458
+ domain: ErrorDomain.STORAGE,
1459
+ category: ErrorCategory.THIRD_PARTY,
1460
+ details: { tableName }
1461
+ },
1462
+ error
1463
+ );
1464
+ }
1465
+ }
1466
+ async load({ tableName, keys }) {
1467
+ this.logger.info(`Loading ${tableName} with keys ${JSON.stringify(keys)}`);
1468
+ try {
1469
+ const collection = await this.getCollection(tableName);
1470
+ return await collection.find(keys).toArray();
1471
+ } catch (error) {
1472
+ throw new MastraError(
1473
+ {
1474
+ id: "STORAGE_MONGODB_STORE_LOAD_FAILED",
1475
+ domain: ErrorDomain.STORAGE,
1476
+ category: ErrorCategory.THIRD_PARTY,
1477
+ details: { tableName }
1478
+ },
1479
+ error
1480
+ );
1481
+ }
1482
+ }
1483
+ };
1484
+ function transformScoreRow(row) {
1485
+ let scorerValue = null;
1486
+ if (row.scorer) {
1487
+ try {
1488
+ scorerValue = typeof row.scorer === "string" ? safelyParseJSON(row.scorer) : row.scorer;
1489
+ } catch (e) {
1490
+ console.warn("Failed to parse scorer:", e);
1491
+ }
1492
+ }
1493
+ let extractStepResultValue = null;
1494
+ if (row.extractStepResult) {
1495
+ try {
1496
+ extractStepResultValue = typeof row.extractStepResult === "string" ? safelyParseJSON(row.extractStepResult) : row.extractStepResult;
1497
+ } catch (e) {
1498
+ console.warn("Failed to parse extractStepResult:", e);
1499
+ }
1500
+ }
1501
+ let analyzeStepResultValue = null;
1502
+ if (row.analyzeStepResult) {
1503
+ try {
1504
+ analyzeStepResultValue = typeof row.analyzeStepResult === "string" ? safelyParseJSON(row.analyzeStepResult) : row.analyzeStepResult;
1505
+ } catch (e) {
1506
+ console.warn("Failed to parse analyzeStepResult:", e);
1507
+ }
1508
+ }
1509
+ let inputValue = null;
1510
+ if (row.input) {
1511
+ try {
1512
+ inputValue = typeof row.input === "string" ? safelyParseJSON(row.input) : row.input;
1513
+ } catch (e) {
1514
+ console.warn("Failed to parse input:", e);
1515
+ }
1516
+ }
1517
+ let outputValue = null;
1518
+ if (row.output) {
1519
+ try {
1520
+ outputValue = typeof row.output === "string" ? safelyParseJSON(row.output) : row.output;
1521
+ } catch (e) {
1522
+ console.warn("Failed to parse output:", e);
1523
+ }
1524
+ }
1525
+ let entityValue = null;
1526
+ if (row.entity) {
1527
+ try {
1528
+ entityValue = typeof row.entity === "string" ? safelyParseJSON(row.entity) : row.entity;
1529
+ } catch (e) {
1530
+ console.warn("Failed to parse entity:", e);
1531
+ }
1532
+ }
1533
+ let runtimeContextValue = null;
1534
+ if (row.runtimeContext) {
1535
+ try {
1536
+ runtimeContextValue = typeof row.runtimeContext === "string" ? safelyParseJSON(row.runtimeContext) : row.runtimeContext;
1537
+ } catch (e) {
1538
+ console.warn("Failed to parse runtimeContext:", e);
1539
+ }
1540
+ }
1541
+ return {
1542
+ id: row.id,
1543
+ entityId: row.entityId,
1544
+ entityType: row.entityType,
1545
+ scorerId: row.scorerId,
1546
+ traceId: row.traceId,
1547
+ runId: row.runId,
1548
+ scorer: scorerValue,
1549
+ extractStepResult: extractStepResultValue,
1550
+ analyzeStepResult: analyzeStepResultValue,
1551
+ score: row.score,
1552
+ reason: row.reason,
1553
+ extractPrompt: row.extractPrompt,
1554
+ analyzePrompt: row.analyzePrompt,
1555
+ reasonPrompt: row.reasonPrompt,
1556
+ input: inputValue,
1557
+ output: outputValue,
1558
+ additionalContext: row.additionalContext,
1559
+ runtimeContext: runtimeContextValue,
1560
+ entity: entityValue,
1561
+ source: row.source,
1562
+ resourceId: row.resourceId,
1563
+ threadId: row.threadId,
1564
+ createdAt: new Date(row.createdAt),
1565
+ updatedAt: new Date(row.updatedAt)
1566
+ };
1567
+ }
1568
+ var ScoresStorageMongoDB = class extends ScoresStorage {
1569
+ operations;
1570
+ constructor({ operations }) {
1571
+ super();
1572
+ this.operations = operations;
1573
+ }
1574
+ async getScoreById({ id }) {
1575
+ try {
1576
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1577
+ const document = await collection.findOne({ id });
1578
+ if (!document) {
1579
+ return null;
1580
+ }
1581
+ return transformScoreRow(document);
1582
+ } catch (error) {
1583
+ throw new MastraError(
1584
+ {
1585
+ id: "STORAGE_MONGODB_STORE_GET_SCORE_BY_ID_FAILED",
1586
+ domain: ErrorDomain.STORAGE,
1587
+ category: ErrorCategory.THIRD_PARTY,
1588
+ details: { id }
1589
+ },
1590
+ error
1591
+ );
1592
+ }
1593
+ }
1594
+ async saveScore(score) {
1595
+ try {
1596
+ const now = /* @__PURE__ */ new Date();
1597
+ const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1598
+ const scoreData = {
1599
+ id: scoreId,
1600
+ entityId: score.entityId,
1601
+ entityType: score.entityType,
1602
+ scorerId: score.scorerId,
1603
+ traceId: score.traceId || "",
1604
+ runId: score.runId,
1605
+ scorer: typeof score.scorer === "string" ? safelyParseJSON(score.scorer) : score.scorer,
1606
+ extractStepResult: typeof score.extractStepResult === "string" ? safelyParseJSON(score.extractStepResult) : score.extractStepResult,
1607
+ analyzeStepResult: typeof score.analyzeStepResult === "string" ? safelyParseJSON(score.analyzeStepResult) : score.analyzeStepResult,
1608
+ score: score.score,
1609
+ reason: score.reason,
1610
+ extractPrompt: score.extractPrompt,
1611
+ analyzePrompt: score.analyzePrompt,
1612
+ reasonPrompt: score.reasonPrompt,
1613
+ input: typeof score.input === "string" ? safelyParseJSON(score.input) : score.input,
1614
+ output: typeof score.output === "string" ? safelyParseJSON(score.output) : score.output,
1615
+ additionalContext: score.additionalContext,
1616
+ runtimeContext: typeof score.runtimeContext === "string" ? safelyParseJSON(score.runtimeContext) : score.runtimeContext,
1617
+ entity: typeof score.entity === "string" ? safelyParseJSON(score.entity) : score.entity,
1618
+ source: score.source,
1619
+ resourceId: score.resourceId || "",
1620
+ threadId: score.threadId || "",
1621
+ createdAt: now,
1622
+ updatedAt: now
1623
+ };
1624
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1625
+ await collection.insertOne(scoreData);
1626
+ const savedScore = {
1627
+ ...score,
1628
+ id: scoreId,
1629
+ createdAt: now,
1630
+ updatedAt: now
1631
+ };
1632
+ return { score: savedScore };
1633
+ } catch (error) {
1634
+ throw new MastraError(
1635
+ {
1636
+ id: "STORAGE_MONGODB_STORE_SAVE_SCORE_FAILED",
1637
+ domain: ErrorDomain.STORAGE,
1638
+ category: ErrorCategory.THIRD_PARTY,
1639
+ details: { scorerId: score.scorerId, runId: score.runId }
1640
+ },
1641
+ error
1642
+ );
1643
+ }
1644
+ }
1645
+ async getScoresByScorerId({
1646
+ scorerId,
1647
+ pagination,
1648
+ entityId,
1649
+ entityType
1650
+ }) {
1651
+ try {
1652
+ const query = { scorerId };
1653
+ if (entityId) {
1654
+ query.entityId = entityId;
1655
+ }
1656
+ if (entityType) {
1657
+ query.entityType = entityType;
1658
+ }
1659
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1660
+ const total = await collection.countDocuments(query);
1661
+ const currentOffset = pagination.page * pagination.perPage;
1662
+ if (total === 0) {
1663
+ return {
1664
+ scores: [],
1665
+ pagination: {
1666
+ total: 0,
1667
+ page: pagination.page,
1668
+ perPage: pagination.perPage,
1669
+ hasMore: false
1670
+ }
1671
+ };
1672
+ }
1673
+ const documents = await collection.find(query).sort({ createdAt: "desc" }).skip(currentOffset).limit(pagination.perPage).toArray();
1674
+ const scores = documents.map((row) => transformScoreRow(row));
1675
+ const hasMore = currentOffset + scores.length < total;
1676
+ return {
1677
+ scores,
1678
+ pagination: {
1679
+ total,
1680
+ page: pagination.page,
1681
+ perPage: pagination.perPage,
1682
+ hasMore
1683
+ }
1684
+ };
1685
+ } catch (error) {
1686
+ throw new MastraError(
1687
+ {
1688
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_SCORER_ID_FAILED",
1689
+ domain: ErrorDomain.STORAGE,
1690
+ category: ErrorCategory.THIRD_PARTY,
1691
+ details: { scorerId, page: pagination.page, perPage: pagination.perPage }
1692
+ },
1693
+ error
1694
+ );
591
1695
  }
592
1696
  }
593
- async getMessages({
594
- threadId,
595
- selectBy,
596
- format
1697
+ async getScoresByRunId({
1698
+ runId,
1699
+ pagination
597
1700
  }) {
598
1701
  try {
599
- const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
600
- const include = selectBy?.include || [];
601
- let messages = [];
602
- let allMessages = [];
603
- const collection = await this.getCollection(TABLE_MESSAGES);
604
- allMessages = (await collection.find({ thread_id: threadId }).sort({ createdAt: -1 }).toArray()).map(
605
- (row) => this.parseRow(row)
606
- );
607
- if (include.length) {
608
- const idToIndex = /* @__PURE__ */ new Map();
609
- allMessages.forEach((msg, idx) => {
610
- idToIndex.set(msg.id, idx);
611
- });
612
- const selectedIndexes = /* @__PURE__ */ new Set();
613
- for (const inc of include) {
614
- const idx = idToIndex.get(inc.id);
615
- if (idx === void 0) continue;
616
- for (let i = 1; i <= (inc.withPreviousMessages || 0); i++) {
617
- if (idx + i < allMessages.length) selectedIndexes.add(idx + i);
618
- }
619
- selectedIndexes.add(idx);
620
- for (let i = 1; i <= (inc.withNextMessages || 0); i++) {
621
- if (idx - i >= 0) selectedIndexes.add(idx - i);
1702
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1703
+ const total = await collection.countDocuments({ runId });
1704
+ const currentOffset = pagination.page * pagination.perPage;
1705
+ if (total === 0) {
1706
+ return {
1707
+ scores: [],
1708
+ pagination: {
1709
+ total: 0,
1710
+ page: pagination.page,
1711
+ perPage: pagination.perPage,
1712
+ hasMore: false
622
1713
  }
623
- }
624
- messages.push(
625
- ...Array.from(selectedIndexes).map((i) => allMessages[i]).filter((m) => !!m)
626
- );
1714
+ };
627
1715
  }
628
- const excludeIds = new Set(messages.map((m) => m.id));
629
- for (const msg of allMessages) {
630
- if (messages.length >= limit) break;
631
- if (!excludeIds.has(msg.id)) {
632
- messages.push(msg);
1716
+ const documents = await collection.find({ runId }).sort({ createdAt: "desc" }).skip(currentOffset).limit(pagination.perPage).toArray();
1717
+ const scores = documents.map((row) => transformScoreRow(row));
1718
+ const hasMore = currentOffset + scores.length < total;
1719
+ return {
1720
+ scores,
1721
+ pagination: {
1722
+ total,
1723
+ page: pagination.page,
1724
+ perPage: pagination.perPage,
1725
+ hasMore
633
1726
  }
634
- }
635
- messages.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
636
- const list = new MessageList().add(messages.slice(0, limit), "memory");
637
- if (format === `v2`) return list.get.all.v2();
638
- return list.get.all.v1();
1727
+ };
639
1728
  } catch (error) {
640
- this.logger.error("Error getting messages:", error);
641
- throw error;
1729
+ throw new MastraError(
1730
+ {
1731
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_RUN_ID_FAILED",
1732
+ domain: ErrorDomain.STORAGE,
1733
+ category: ErrorCategory.THIRD_PARTY,
1734
+ details: { runId, page: pagination.page, perPage: pagination.perPage }
1735
+ },
1736
+ error
1737
+ );
642
1738
  }
643
1739
  }
644
- async saveMessages({
645
- messages,
646
- format
1740
+ async getScoresByEntityId({
1741
+ entityId,
1742
+ entityType,
1743
+ pagination
647
1744
  }) {
648
- if (!messages.length) {
649
- return messages;
650
- }
651
- const threadId = messages[0]?.threadId;
652
- if (!threadId) {
653
- this.logger.error("Thread ID is required to save messages");
654
- throw new Error("Thread ID is required");
655
- }
656
1745
  try {
657
- const messagesToInsert = messages.map((message) => {
658
- const time = message.createdAt || /* @__PURE__ */ new Date();
1746
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1747
+ const total = await collection.countDocuments({ entityId, entityType });
1748
+ const currentOffset = pagination.page * pagination.perPage;
1749
+ if (total === 0) {
659
1750
  return {
660
- id: message.id,
661
- thread_id: threadId,
662
- content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
663
- role: message.role,
664
- type: message.type,
665
- resourceId: message.resourceId,
666
- createdAt: time instanceof Date ? time.toISOString() : time
1751
+ scores: [],
1752
+ pagination: {
1753
+ total: 0,
1754
+ page: pagination.page,
1755
+ perPage: pagination.perPage,
1756
+ hasMore: false
1757
+ }
667
1758
  };
668
- });
669
- const collection = await this.getCollection(TABLE_MESSAGES);
670
- const threadsCollection = await this.getCollection(TABLE_THREADS);
671
- await Promise.all([
672
- collection.insertMany(messagesToInsert),
673
- threadsCollection.updateOne({ id: threadId }, { $set: { updatedAt: /* @__PURE__ */ new Date() } })
674
- ]);
675
- const list = new MessageList().add(messages, "memory");
676
- if (format === `v2`) return list.get.all.v2();
677
- return list.get.all.v1();
1759
+ }
1760
+ const documents = await collection.find({ entityId, entityType }).sort({ createdAt: "desc" }).skip(currentOffset).limit(pagination.perPage).toArray();
1761
+ const scores = documents.map((row) => transformScoreRow(row));
1762
+ const hasMore = currentOffset + scores.length < total;
1763
+ return {
1764
+ scores,
1765
+ pagination: {
1766
+ total,
1767
+ page: pagination.page,
1768
+ perPage: pagination.perPage,
1769
+ hasMore
1770
+ }
1771
+ };
678
1772
  } catch (error) {
679
- this.logger.error("Failed to save messages in database: " + error?.message);
680
- throw error;
681
- }
682
- }
683
- async getTraces({
684
- name,
685
- scope,
686
- page,
687
- perPage,
688
- attributes,
689
- filters
690
- } = {
691
- page: 0,
692
- perPage: 100
693
- }) {
694
- const limit = perPage;
695
- const offset = page * perPage;
1773
+ throw new MastraError(
1774
+ {
1775
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_ENTITY_ID_FAILED",
1776
+ domain: ErrorDomain.STORAGE,
1777
+ category: ErrorCategory.THIRD_PARTY,
1778
+ details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
1779
+ },
1780
+ error
1781
+ );
1782
+ }
1783
+ }
1784
+ };
1785
+ var TracesStorageMongoDB = class extends TracesStorage {
1786
+ operations;
1787
+ constructor({ operations }) {
1788
+ super();
1789
+ this.operations = operations;
1790
+ }
1791
+ async getTraces(args) {
1792
+ if (args.fromDate || args.toDate) {
1793
+ args.dateRange = {
1794
+ start: args.fromDate,
1795
+ end: args.toDate
1796
+ };
1797
+ }
1798
+ try {
1799
+ const result = await this.getTracesPaginated(args);
1800
+ return result.traces;
1801
+ } catch (error) {
1802
+ throw new MastraError(
1803
+ {
1804
+ id: "STORAGE_MONGODB_STORE_GET_TRACES_FAILED",
1805
+ domain: ErrorDomain.STORAGE,
1806
+ category: ErrorCategory.THIRD_PARTY
1807
+ },
1808
+ error
1809
+ );
1810
+ }
1811
+ }
1812
+ async getTracesPaginated(args) {
1813
+ const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
1814
+ const fromDate = dateRange?.start;
1815
+ const toDate = dateRange?.end;
1816
+ const currentOffset = page * perPage;
696
1817
  const query = {};
697
1818
  if (name) {
698
- query["name"] = `%${name}%`;
1819
+ query["name"] = new RegExp(name);
699
1820
  }
700
1821
  if (scope) {
701
1822
  query["scope"] = scope;
702
1823
  }
703
1824
  if (attributes) {
704
- Object.keys(attributes).forEach((key) => {
705
- query[`attributes.${key}`] = attributes[key];
706
- });
1825
+ query["$and"] = Object.entries(attributes).map(([key, value]) => ({
1826
+ [`attributes.${key}`]: value
1827
+ }));
707
1828
  }
708
1829
  if (filters) {
709
1830
  Object.entries(filters).forEach(([key, value]) => {
710
1831
  query[key] = value;
711
1832
  });
712
1833
  }
713
- const collection = await this.getCollection(TABLE_TRACES);
714
- const result = await collection.find(query, {
715
- sort: { startTime: -1 }
716
- }).limit(limit).skip(offset).toArray();
717
- return result.map((row) => ({
718
- id: row.id,
719
- parentSpanId: row.parentSpanId,
720
- traceId: row.traceId,
721
- name: row.name,
722
- scope: row.scope,
723
- kind: row.kind,
724
- status: safelyParseJSON(row.status),
725
- events: safelyParseJSON(row.events),
726
- links: safelyParseJSON(row.links),
727
- attributes: safelyParseJSON(row.attributes),
728
- startTime: row.startTime,
729
- endTime: row.endTime,
730
- other: safelyParseJSON(row.other),
731
- createdAt: row.createdAt
732
- }));
733
- }
734
- async getWorkflowRuns({
735
- workflowName,
736
- fromDate,
737
- toDate,
738
- limit,
739
- offset
740
- } = {}) {
741
- const query = {};
742
- if (workflowName) {
743
- query["workflow_name"] = workflowName;
744
- }
745
1834
  if (fromDate || toDate) {
746
1835
  query["createdAt"] = {};
747
1836
  if (fromDate) {
@@ -751,93 +1840,99 @@ var MongoDBStore = class extends MastraStorage {
751
1840
  query["createdAt"]["$lte"] = toDate;
752
1841
  }
753
1842
  }
754
- const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
755
- let total = 0;
756
- if (limit !== void 0 && offset !== void 0) {
757
- total = await collection.countDocuments(query);
758
- }
759
- const request = collection.find(query).sort({ createdAt: "desc" });
760
- if (limit) {
761
- request.limit(limit);
762
- }
763
- if (offset) {
764
- request.skip(offset);
765
- }
766
- const result = await request.toArray();
767
- const runs = result.map((row) => {
768
- let parsedSnapshot = row.snapshot;
769
- if (typeof parsedSnapshot === "string") {
770
- try {
771
- parsedSnapshot = JSON.parse(row.snapshot);
772
- } catch (e) {
773
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
774
- }
1843
+ try {
1844
+ const collection = await this.operations.getCollection(TABLE_TRACES);
1845
+ const total = await collection.countDocuments(query);
1846
+ if (total === 0) {
1847
+ return {
1848
+ traces: [],
1849
+ total: 0,
1850
+ page,
1851
+ perPage,
1852
+ hasMore: false
1853
+ };
775
1854
  }
1855
+ const result = await collection.find(query, {
1856
+ sort: { startTime: -1 }
1857
+ }).limit(perPage).skip(currentOffset).toArray();
1858
+ const traces = result.map((row) => ({
1859
+ id: row.id,
1860
+ parentSpanId: row.parentSpanId,
1861
+ traceId: row.traceId,
1862
+ name: row.name,
1863
+ scope: row.scope,
1864
+ kind: row.kind,
1865
+ status: safelyParseJSON(row.status),
1866
+ events: safelyParseJSON(row.events),
1867
+ links: safelyParseJSON(row.links),
1868
+ attributes: safelyParseJSON(row.attributes),
1869
+ startTime: row.startTime,
1870
+ endTime: row.endTime,
1871
+ other: safelyParseJSON(row.other),
1872
+ createdAt: row.createdAt
1873
+ }));
776
1874
  return {
777
- workflowName: row.workflow_name,
778
- runId: row.run_id,
779
- snapshot: parsedSnapshot,
780
- createdAt: new Date(row.createdAt),
781
- updatedAt: new Date(row.updatedAt)
1875
+ traces,
1876
+ total,
1877
+ page,
1878
+ perPage,
1879
+ hasMore: currentOffset + traces.length < total
782
1880
  };
783
- });
784
- return { runs, total: total || runs.length };
785
- }
786
- async getEvalsByAgentName(agentName, type) {
787
- try {
788
- const query = {
789
- agent_name: agentName
790
- };
791
- if (type === "test") {
792
- query["test_info"] = { $ne: null };
793
- }
794
- if (type === "live") {
795
- query["test_info"] = null;
796
- }
797
- const collection = await this.getCollection(TABLE_EVALS);
798
- const documents = await collection.find(query).sort({ created_at: "desc" }).toArray();
799
- const result = documents.map((row) => this.transformEvalRow(row));
800
- return result.filter((row) => {
801
- if (type === "live") {
802
- return !Boolean(row.testInfo?.testPath);
803
- }
804
- if (type === "test") {
805
- return row.testInfo?.testPath !== null;
806
- }
807
- return true;
808
- });
809
1881
  } catch (error) {
810
- if (error instanceof Error && error.message.includes("no such table")) {
811
- return [];
812
- }
813
- this.logger.error("Failed to get evals for the specified agent: " + error?.message);
814
- throw error;
1882
+ throw new MastraError(
1883
+ {
1884
+ id: "STORAGE_MONGODB_STORE_GET_TRACES_PAGINATED_FAILED",
1885
+ domain: ErrorDomain.STORAGE,
1886
+ category: ErrorCategory.THIRD_PARTY
1887
+ },
1888
+ error
1889
+ );
815
1890
  }
816
1891
  }
1892
+ async batchTraceInsert({ records }) {
1893
+ this.logger.debug("Batch inserting traces", { count: records.length });
1894
+ await this.operations.batchInsert({
1895
+ tableName: TABLE_TRACES,
1896
+ records
1897
+ });
1898
+ }
1899
+ };
1900
+ var WorkflowsStorageMongoDB = class extends WorkflowsStorage {
1901
+ operations;
1902
+ constructor({ operations }) {
1903
+ super();
1904
+ this.operations = operations;
1905
+ }
817
1906
  async persistWorkflowSnapshot({
818
1907
  workflowName,
819
1908
  runId,
820
1909
  snapshot
821
1910
  }) {
822
1911
  try {
823
- const now = (/* @__PURE__ */ new Date()).toISOString();
824
- const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
1912
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
825
1913
  await collection.updateOne(
826
1914
  { workflow_name: workflowName, run_id: runId },
827
1915
  {
828
1916
  $set: {
829
- snapshot: JSON.stringify(snapshot),
830
- updatedAt: now
831
- },
832
- $setOnInsert: {
833
- createdAt: now
1917
+ workflow_name: workflowName,
1918
+ run_id: runId,
1919
+ snapshot,
1920
+ createdAt: /* @__PURE__ */ new Date(),
1921
+ updatedAt: /* @__PURE__ */ new Date()
834
1922
  }
835
1923
  },
836
1924
  { upsert: true }
837
1925
  );
838
1926
  } catch (error) {
839
- this.logger.error(`Error persisting workflow snapshot: ${error}`);
840
- throw error;
1927
+ throw new MastraError(
1928
+ {
1929
+ id: "STORAGE_MONGODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1930
+ domain: ErrorDomain.STORAGE,
1931
+ category: ErrorCategory.THIRD_PARTY,
1932
+ details: { workflowName, runId }
1933
+ },
1934
+ error
1935
+ );
841
1936
  }
842
1937
  }
843
1938
  async loadWorkflowSnapshot({
@@ -845,7 +1940,7 @@ var MongoDBStore = class extends MastraStorage {
845
1940
  runId
846
1941
  }) {
847
1942
  try {
848
- const result = await this.load({
1943
+ const result = await this.operations.load({
849
1944
  tableName: TABLE_WORKFLOW_SNAPSHOT,
850
1945
  keys: {
851
1946
  workflow_name: workflowName,
@@ -855,40 +1950,98 @@ var MongoDBStore = class extends MastraStorage {
855
1950
  if (!result?.length) {
856
1951
  return null;
857
1952
  }
858
- return JSON.parse(result[0].snapshot);
1953
+ return typeof result[0].snapshot === "string" ? safelyParseJSON(result[0].snapshot) : result[0].snapshot;
859
1954
  } catch (error) {
860
- console.error("Error loading workflow snapshot:", error);
861
- throw error;
1955
+ throw new MastraError(
1956
+ {
1957
+ id: "STORAGE_MONGODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1958
+ domain: ErrorDomain.STORAGE,
1959
+ category: ErrorCategory.THIRD_PARTY,
1960
+ details: { workflowName, runId }
1961
+ },
1962
+ error
1963
+ );
862
1964
  }
863
1965
  }
864
- async getWorkflowRunById({
865
- runId,
866
- workflowName
867
- }) {
1966
+ async getWorkflowRuns(args) {
1967
+ const options = args || {};
1968
+ try {
1969
+ const query = {};
1970
+ if (options.workflowName) {
1971
+ query["workflow_name"] = options.workflowName;
1972
+ }
1973
+ if (options.fromDate) {
1974
+ query["createdAt"] = { $gte: options.fromDate };
1975
+ }
1976
+ if (options.toDate) {
1977
+ if (query["createdAt"]) {
1978
+ query["createdAt"].$lte = options.toDate;
1979
+ } else {
1980
+ query["createdAt"] = { $lte: options.toDate };
1981
+ }
1982
+ }
1983
+ if (options.resourceId) {
1984
+ query["resourceId"] = options.resourceId;
1985
+ }
1986
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
1987
+ const total = await collection.countDocuments(query);
1988
+ let cursor = collection.find(query).sort({ createdAt: -1 });
1989
+ if (options.offset) {
1990
+ cursor = cursor.skip(options.offset);
1991
+ }
1992
+ if (options.limit) {
1993
+ cursor = cursor.limit(options.limit);
1994
+ }
1995
+ const results = await cursor.toArray();
1996
+ const runs = results.map((row) => this.parseWorkflowRun(row));
1997
+ return {
1998
+ runs,
1999
+ total
2000
+ };
2001
+ } catch (error) {
2002
+ throw new MastraError(
2003
+ {
2004
+ id: "STORAGE_MONGODB_STORE_GET_WORKFLOW_RUNS_FAILED",
2005
+ domain: ErrorDomain.STORAGE,
2006
+ category: ErrorCategory.THIRD_PARTY,
2007
+ details: { workflowName: options.workflowName || "unknown" }
2008
+ },
2009
+ error
2010
+ );
2011
+ }
2012
+ }
2013
+ async getWorkflowRunById(args) {
868
2014
  try {
869
2015
  const query = {};
870
- if (runId) {
871
- query["run_id"] = runId;
2016
+ if (args.runId) {
2017
+ query["run_id"] = args.runId;
872
2018
  }
873
- if (workflowName) {
874
- query["workflow_name"] = workflowName;
2019
+ if (args.workflowName) {
2020
+ query["workflow_name"] = args.workflowName;
875
2021
  }
876
- const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
2022
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
877
2023
  const result = await collection.findOne(query);
878
2024
  if (!result) {
879
2025
  return null;
880
2026
  }
881
2027
  return this.parseWorkflowRun(result);
882
2028
  } catch (error) {
883
- console.error("Error getting workflow run by ID:", error);
884
- throw error;
2029
+ throw new MastraError(
2030
+ {
2031
+ id: "STORAGE_MONGODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2032
+ domain: ErrorDomain.STORAGE,
2033
+ category: ErrorCategory.THIRD_PARTY,
2034
+ details: { runId: args.runId }
2035
+ },
2036
+ error
2037
+ );
885
2038
  }
886
2039
  }
887
2040
  parseWorkflowRun(row) {
888
2041
  let parsedSnapshot = row.snapshot;
889
2042
  if (typeof parsedSnapshot === "string") {
890
2043
  try {
891
- parsedSnapshot = JSON.parse(row.snapshot);
2044
+ parsedSnapshot = typeof row.snapshot === "string" ? safelyParseJSON(row.snapshot) : row.snapshot;
892
2045
  } catch (e) {
893
2046
  console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
894
2047
  }
@@ -897,64 +2050,250 @@ var MongoDBStore = class extends MastraStorage {
897
2050
  workflowName: row.workflow_name,
898
2051
  runId: row.run_id,
899
2052
  snapshot: parsedSnapshot,
900
- createdAt: row.createdAt,
901
- updatedAt: row.updatedAt,
2053
+ createdAt: new Date(row.createdAt),
2054
+ updatedAt: new Date(row.updatedAt),
902
2055
  resourceId: row.resourceId
903
2056
  };
904
2057
  }
905
- parseRow(row) {
906
- let content = row.content;
907
- try {
908
- content = JSON.parse(row.content);
909
- } catch {
2058
+ };
2059
+
2060
+ // src/storage/index.ts
2061
+ var loadConnector = (config) => {
2062
+ try {
2063
+ if ("connectorHandler" in config) {
2064
+ return MongoDBConnector.fromConnectionHandler(config.connectorHandler);
910
2065
  }
2066
+ } catch (error) {
2067
+ throw new MastraError(
2068
+ {
2069
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2070
+ domain: ErrorDomain.STORAGE,
2071
+ category: ErrorCategory.USER,
2072
+ details: { connectionHandler: true }
2073
+ },
2074
+ error
2075
+ );
2076
+ }
2077
+ try {
2078
+ return MongoDBConnector.fromDatabaseConfig({
2079
+ options: config.options,
2080
+ url: config.url,
2081
+ dbName: config.dbName
2082
+ });
2083
+ } catch (error) {
2084
+ throw new MastraError(
2085
+ {
2086
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2087
+ domain: ErrorDomain.STORAGE,
2088
+ category: ErrorCategory.USER,
2089
+ details: { url: config?.url, dbName: config?.dbName }
2090
+ },
2091
+ error
2092
+ );
2093
+ }
2094
+ };
2095
+ var MongoDBStore = class extends MastraStorage {
2096
+ #connector;
2097
+ stores;
2098
+ get supports() {
911
2099
  return {
912
- id: row.id,
913
- content,
914
- role: row.role,
915
- type: row.type,
916
- createdAt: new Date(row.createdAt),
917
- threadId: row.thread_id,
918
- resourceId: row.resourceId
2100
+ selectByIncludeResourceScope: true,
2101
+ resourceWorkingMemory: true,
2102
+ hasColumn: false,
2103
+ createTable: false,
2104
+ deleteMessages: false
919
2105
  };
920
2106
  }
921
- transformEvalRow(row) {
922
- let testInfoValue = null;
923
- if (row.test_info) {
924
- try {
925
- testInfoValue = typeof row.test_info === "string" ? JSON.parse(row.test_info) : row.test_info;
926
- } catch (e) {
927
- console.warn("Failed to parse test_info:", e);
928
- }
929
- }
930
- return {
931
- input: row.input,
932
- output: row.output,
933
- result: row.result,
934
- agentName: row.agent_name,
935
- metricName: row.metric_name,
936
- instructions: row.instructions,
937
- testInfo: testInfoValue,
938
- globalRunId: row.global_run_id,
939
- runId: row.run_id,
940
- createdAt: row.created_at
2107
+ constructor(config) {
2108
+ super({ name: "MongoDBStore" });
2109
+ this.stores = {};
2110
+ this.#connector = loadConnector(config);
2111
+ const operations = new StoreOperationsMongoDB({
2112
+ connector: this.#connector
2113
+ });
2114
+ const memory = new MemoryStorageMongoDB({
2115
+ operations
2116
+ });
2117
+ const traces = new TracesStorageMongoDB({
2118
+ operations
2119
+ });
2120
+ const legacyEvals = new LegacyEvalsMongoDB({
2121
+ operations
2122
+ });
2123
+ const scores = new ScoresStorageMongoDB({
2124
+ operations
2125
+ });
2126
+ const workflows = new WorkflowsStorageMongoDB({
2127
+ operations
2128
+ });
2129
+ this.stores = {
2130
+ operations,
2131
+ memory,
2132
+ traces,
2133
+ legacyEvals,
2134
+ scores,
2135
+ workflows
941
2136
  };
942
2137
  }
943
- async getTracesPaginated(_args) {
944
- throw new Error("Method not implemented.");
2138
+ async createTable({
2139
+ tableName,
2140
+ schema
2141
+ }) {
2142
+ return this.stores.operations.createTable({ tableName, schema });
2143
+ }
2144
+ async alterTable(_args) {
2145
+ return this.stores.operations.alterTable(_args);
2146
+ }
2147
+ async dropTable({ tableName }) {
2148
+ return this.stores.operations.dropTable({ tableName });
2149
+ }
2150
+ async clearTable({ tableName }) {
2151
+ return this.stores.operations.clearTable({ tableName });
2152
+ }
2153
+ async insert({ tableName, record }) {
2154
+ return this.stores.operations.insert({ tableName, record });
2155
+ }
2156
+ async batchInsert({ tableName, records }) {
2157
+ return this.stores.operations.batchInsert({ tableName, records });
2158
+ }
2159
+ async load({ tableName, keys }) {
2160
+ return this.stores.operations.load({ tableName, keys });
2161
+ }
2162
+ async getThreadById({ threadId }) {
2163
+ return this.stores.memory.getThreadById({ threadId });
2164
+ }
2165
+ async getThreadsByResourceId({ resourceId }) {
2166
+ return this.stores.memory.getThreadsByResourceId({ resourceId });
2167
+ }
2168
+ async saveThread({ thread }) {
2169
+ return this.stores.memory.saveThread({ thread });
2170
+ }
2171
+ async updateThread({
2172
+ id,
2173
+ title,
2174
+ metadata
2175
+ }) {
2176
+ return this.stores.memory.updateThread({ id, title, metadata });
2177
+ }
2178
+ async deleteThread({ threadId }) {
2179
+ return this.stores.memory.deleteThread({ threadId });
2180
+ }
2181
+ async getMessages({
2182
+ threadId,
2183
+ selectBy,
2184
+ format
2185
+ }) {
2186
+ return this.stores.memory.getMessages({ threadId, selectBy, format });
2187
+ }
2188
+ async saveMessages(args) {
2189
+ return this.stores.memory.saveMessages(args);
945
2190
  }
946
2191
  async getThreadsByResourceIdPaginated(_args) {
947
- throw new Error("Method not implemented.");
2192
+ return this.stores.memory.getThreadsByResourceIdPaginated(_args);
948
2193
  }
949
2194
  async getMessagesPaginated(_args) {
950
- throw new Error("Method not implemented.");
2195
+ return this.stores.memory.getMessagesPaginated(_args);
2196
+ }
2197
+ async updateMessages(_args) {
2198
+ return this.stores.memory.updateMessages(_args);
2199
+ }
2200
+ async getTraces(args) {
2201
+ return this.stores.traces.getTraces(args);
2202
+ }
2203
+ async getTracesPaginated(args) {
2204
+ return this.stores.traces.getTracesPaginated(args);
2205
+ }
2206
+ async getWorkflowRuns(args) {
2207
+ return this.stores.workflows.getWorkflowRuns(args);
2208
+ }
2209
+ async getEvals(options = {}) {
2210
+ return this.stores.legacyEvals.getEvals(options);
2211
+ }
2212
+ async getEvalsByAgentName(agentName, type) {
2213
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
2214
+ }
2215
+ async persistWorkflowSnapshot({
2216
+ workflowName,
2217
+ runId,
2218
+ snapshot
2219
+ }) {
2220
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2221
+ }
2222
+ async loadWorkflowSnapshot({
2223
+ workflowName,
2224
+ runId
2225
+ }) {
2226
+ return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2227
+ }
2228
+ async getWorkflowRunById({
2229
+ runId,
2230
+ workflowName
2231
+ }) {
2232
+ return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
951
2233
  }
952
2234
  async close() {
953
- await this.#client.close();
2235
+ try {
2236
+ await this.#connector.close();
2237
+ } catch (error) {
2238
+ throw new MastraError(
2239
+ {
2240
+ id: "STORAGE_MONGODB_STORE_CLOSE_FAILED",
2241
+ domain: ErrorDomain.STORAGE,
2242
+ category: ErrorCategory.USER
2243
+ },
2244
+ error
2245
+ );
2246
+ }
954
2247
  }
955
- async updateMessages(_args) {
956
- this.logger.error("updateMessages is not yet implemented in MongoDBStore");
957
- throw new Error("Method not implemented");
2248
+ /**
2249
+ * SCORERS
2250
+ */
2251
+ async getScoreById({ id }) {
2252
+ return this.stores.scores.getScoreById({ id });
2253
+ }
2254
+ async saveScore(score) {
2255
+ return this.stores.scores.saveScore(score);
2256
+ }
2257
+ async getScoresByRunId({
2258
+ runId,
2259
+ pagination
2260
+ }) {
2261
+ return this.stores.scores.getScoresByRunId({ runId, pagination });
2262
+ }
2263
+ async getScoresByEntityId({
2264
+ entityId,
2265
+ entityType,
2266
+ pagination
2267
+ }) {
2268
+ return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
2269
+ }
2270
+ async getScoresByScorerId({
2271
+ scorerId,
2272
+ pagination,
2273
+ entityId,
2274
+ entityType
2275
+ }) {
2276
+ return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType });
2277
+ }
2278
+ /**
2279
+ * RESOURCES
2280
+ */
2281
+ async getResourceById({ resourceId }) {
2282
+ return this.stores.memory.getResourceById({ resourceId });
2283
+ }
2284
+ async saveResource({ resource }) {
2285
+ return this.stores.memory.saveResource({ resource });
2286
+ }
2287
+ async updateResource({
2288
+ resourceId,
2289
+ workingMemory,
2290
+ metadata
2291
+ }) {
2292
+ return this.stores.memory.updateResource({
2293
+ resourceId,
2294
+ workingMemory,
2295
+ metadata
2296
+ });
958
2297
  }
959
2298
  };
960
2299
 
@@ -1054,3 +2393,5 @@ Example Complex Query:
1054
2393
  }`;
1055
2394
 
1056
2395
  export { MONGODB_PROMPT, MongoDBStore, MongoDBVector };
2396
+ //# sourceMappingURL=index.js.map
2397
+ //# sourceMappingURL=index.js.map