@mastra/mongodb 0.0.0-vnext-inngest-20250508131921 → 0.0.0-vnext-20251119160359

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 (49) hide show
  1. package/CHANGELOG.md +1501 -2
  2. package/LICENSE.md +11 -42
  3. package/README.md +56 -0
  4. package/dist/index.cjs +2459 -141
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.d.ts +5 -7
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2455 -138
  9. package/dist/index.js.map +1 -0
  10. package/dist/storage/connectors/MongoDBConnector.d.ts +23 -0
  11. package/dist/storage/connectors/MongoDBConnector.d.ts.map +1 -0
  12. package/dist/storage/connectors/base.d.ts +6 -0
  13. package/dist/storage/connectors/base.d.ts.map +1 -0
  14. package/dist/storage/domains/memory/index.d.ts +60 -0
  15. package/dist/storage/domains/memory/index.d.ts.map +1 -0
  16. package/dist/storage/domains/observability/index.d.ts +43 -0
  17. package/dist/storage/domains/observability/index.d.ts.map +1 -0
  18. package/dist/storage/domains/operations/index.d.ts +50 -0
  19. package/dist/storage/domains/operations/index.d.ts.map +1 -0
  20. package/dist/storage/domains/scores/index.d.ts +50 -0
  21. package/dist/storage/domains/scores/index.d.ts.map +1 -0
  22. package/dist/storage/domains/utils.d.ts +8 -0
  23. package/dist/storage/domains/utils.d.ts.map +1 -0
  24. package/dist/storage/domains/workflows/index.d.ts +45 -0
  25. package/dist/storage/domains/workflows/index.d.ts.map +1 -0
  26. package/dist/storage/index.d.ts +198 -0
  27. package/dist/storage/index.d.ts.map +1 -0
  28. package/dist/storage/types.d.ts +13 -0
  29. package/dist/storage/types.d.ts.map +1 -0
  30. package/dist/vector/filter.d.ts +21 -0
  31. package/dist/vector/filter.d.ts.map +1 -0
  32. package/dist/vector/index.d.ts +94 -0
  33. package/dist/vector/index.d.ts.map +1 -0
  34. package/dist/vector/prompt.d.ts +6 -0
  35. package/dist/vector/prompt.d.ts.map +1 -0
  36. package/package.json +39 -16
  37. package/dist/_tsup-dts-rollup.d.cts +0 -96
  38. package/dist/_tsup-dts-rollup.d.ts +0 -96
  39. package/dist/index.d.cts +0 -7
  40. package/docker-compose.yml +0 -8
  41. package/eslint.config.js +0 -6
  42. package/src/index.ts +0 -2
  43. package/src/vector/filter.test.ts +0 -410
  44. package/src/vector/filter.ts +0 -122
  45. package/src/vector/index.test.ts +0 -459
  46. package/src/vector/index.ts +0 -380
  47. package/src/vector/prompt.ts +0 -97
  48. package/tsconfig.json +0 -5
  49. package/vitest.config.ts +0 -11
package/dist/index.js CHANGED
@@ -1,9 +1,17 @@
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, normalizePerPage, calculatePagination, TABLE_THREADS, TABLE_RESOURCES, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, ObservabilityStorage, TABLE_SPANS } from '@mastra/core/storage';
7
+ import { MessageList } from '@mastra/core/agent';
8
+ import { saveScorePayloadSchema } from '@mastra/core/evals';
5
9
 
6
10
  // src/vector/index.ts
11
+
12
+ // package.json
13
+ var package_default = {
14
+ version: "1.0.0-beta.0"};
7
15
  var MongoDBFilterTranslator = class extends BaseFilterTranslator {
8
16
  getSupportedOperators() {
9
17
  return {
@@ -106,37 +114,83 @@ var MongoDBVector = class extends MastraVector {
106
114
  euclidean: "euclidean",
107
115
  dotproduct: "dotProduct"
108
116
  };
109
- constructor({ uri, dbName, options }) {
110
- super();
111
- this.client = new MongoClient(uri, options);
117
+ constructor({ id, uri, dbName, options }) {
118
+ super({ id });
119
+ const client = new MongoClient(uri, {
120
+ ...options,
121
+ driverInfo: {
122
+ name: "mastra-vector",
123
+ version: package_default.version
124
+ }
125
+ });
126
+ this.client = client;
112
127
  this.db = this.client.db(dbName);
113
128
  this.collections = /* @__PURE__ */ new Map();
114
129
  }
115
130
  // Public methods
116
131
  async connect() {
117
- await this.client.connect();
132
+ try {
133
+ await this.client.connect();
134
+ } catch (error) {
135
+ throw new MastraError(
136
+ {
137
+ id: "STORAGE_MONGODB_VECTOR_CONNECT_FAILED",
138
+ domain: ErrorDomain.STORAGE,
139
+ category: ErrorCategory.THIRD_PARTY
140
+ },
141
+ error
142
+ );
143
+ }
118
144
  }
119
145
  async disconnect() {
120
- await this.client.close();
121
- }
122
- async createIndex(params) {
123
- const { indexName, dimension, metric = "cosine" } = params;
124
- if (!Number.isInteger(dimension) || dimension <= 0) {
125
- throw new Error("Dimension must be a positive integer");
126
- }
127
- const mongoMetric = this.mongoMetricMap[metric];
128
- if (!mongoMetric) {
129
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
146
+ try {
147
+ await this.client.close();
148
+ } catch (error) {
149
+ throw new MastraError(
150
+ {
151
+ id: "STORAGE_MONGODB_VECTOR_DISCONNECT_FAILED",
152
+ domain: ErrorDomain.STORAGE,
153
+ category: ErrorCategory.THIRD_PARTY
154
+ },
155
+ error
156
+ );
130
157
  }
131
- const collectionExists = await this.db.listCollections({ name: indexName }).hasNext();
132
- if (!collectionExists) {
133
- await this.db.createCollection(indexName);
158
+ }
159
+ async createIndex({ indexName, dimension, metric = "cosine" }) {
160
+ let mongoMetric;
161
+ try {
162
+ if (!Number.isInteger(dimension) || dimension <= 0) {
163
+ throw new Error("Dimension must be a positive integer");
164
+ }
165
+ mongoMetric = this.mongoMetricMap[metric];
166
+ if (!mongoMetric) {
167
+ throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
168
+ }
169
+ } catch (error) {
170
+ throw new MastraError(
171
+ {
172
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_INVALID_ARGS",
173
+ domain: ErrorDomain.STORAGE,
174
+ category: ErrorCategory.USER,
175
+ details: {
176
+ indexName,
177
+ dimension,
178
+ metric
179
+ }
180
+ },
181
+ error
182
+ );
134
183
  }
135
- const collection = await this.getCollection(indexName);
136
- const indexNameInternal = `${indexName}_vector_index`;
137
- const embeddingField = this.embeddingFieldName;
138
- const numDimensions = dimension;
184
+ let collection;
139
185
  try {
186
+ const collectionExists = await this.db.listCollections({ name: indexName }).hasNext();
187
+ if (!collectionExists) {
188
+ await this.db.createCollection(indexName);
189
+ }
190
+ collection = await this.getCollection(indexName);
191
+ const indexNameInternal = `${indexName}_vector_index`;
192
+ const embeddingField = this.embeddingFieldName;
193
+ const numDimensions = dimension;
140
194
  await collection.createSearchIndex({
141
195
  definition: {
142
196
  fields: [
@@ -145,20 +199,66 @@ var MongoDBVector = class extends MastraVector {
145
199
  path: embeddingField,
146
200
  numDimensions,
147
201
  similarity: mongoMetric
202
+ },
203
+ {
204
+ type: "filter",
205
+ path: "_id"
148
206
  }
149
207
  ]
150
208
  },
151
209
  name: indexNameInternal,
152
210
  type: "vectorSearch"
153
211
  });
212
+ await collection.createSearchIndex({
213
+ definition: {
214
+ mappings: {
215
+ dynamic: true
216
+ }
217
+ },
218
+ name: `${indexName}_search_index`,
219
+ type: "search"
220
+ });
154
221
  } catch (error) {
155
222
  if (error.codeName !== "IndexAlreadyExists") {
156
- throw error;
223
+ throw new MastraError(
224
+ {
225
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED",
226
+ domain: ErrorDomain.STORAGE,
227
+ category: ErrorCategory.THIRD_PARTY
228
+ },
229
+ error
230
+ );
157
231
  }
158
232
  }
159
- await collection.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
233
+ try {
234
+ await collection?.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
235
+ } catch (error) {
236
+ throw new MastraError(
237
+ {
238
+ id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED_STORE_METADATA",
239
+ domain: ErrorDomain.STORAGE,
240
+ category: ErrorCategory.THIRD_PARTY,
241
+ details: {
242
+ indexName
243
+ }
244
+ },
245
+ error
246
+ );
247
+ }
160
248
  }
161
- async waitForIndexReady(indexName, timeoutMs = 6e4, checkIntervalMs = 2e3) {
249
+ /**
250
+ * Waits for the index to be ready.
251
+ *
252
+ * @param {string} indexName - The name of the index to wait for
253
+ * @param {number} timeoutMs - The maximum time in milliseconds to wait for the index to be ready (default: 60000)
254
+ * @param {number} checkIntervalMs - The interval in milliseconds at which to check if the index is ready (default: 2000)
255
+ * @returns A promise that resolves when the index is ready
256
+ */
257
+ async waitForIndexReady({
258
+ indexName,
259
+ timeoutMs = 6e4,
260
+ checkIntervalMs = 2e3
261
+ }) {
162
262
  const collection = await this.getCollection(indexName, true);
163
263
  const indexNameInternal = `${indexName}_vector_index`;
164
264
  const startTime = Date.now();
@@ -173,83 +273,110 @@ var MongoDBVector = class extends MastraVector {
173
273
  }
174
274
  throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
175
275
  }
176
- async upsert(params) {
177
- const { indexName, vectors, metadata, ids, documents } = params;
178
- const collection = await this.getCollection(indexName);
179
- this.collectionForValidation = collection;
180
- const stats = await this.describeIndex(indexName);
181
- await this.validateVectorDimensions(vectors, stats.dimension);
182
- const generatedIds = ids || vectors.map(() => v4());
183
- const operations = vectors.map((vector, idx) => {
184
- const id = generatedIds[idx];
185
- const meta = metadata?.[idx] || {};
186
- const doc = documents?.[idx];
187
- const normalizedMeta = Object.keys(meta).reduce(
188
- (acc, key) => {
189
- acc[key] = meta[key] instanceof Date ? meta[key].toISOString() : meta[key];
190
- return acc;
191
- },
192
- {}
193
- );
194
- const updateDoc = {
195
- [this.embeddingFieldName]: vector,
196
- [this.metadataFieldName]: normalizedMeta
197
- };
198
- if (doc !== void 0) {
199
- updateDoc[this.documentFieldName] = doc;
200
- }
201
- return {
202
- updateOne: {
203
- filter: { _id: id },
204
- // '_id' is a string as per MongoDBDocument interface
205
- update: { $set: updateDoc },
206
- upsert: true
276
+ async upsert({ indexName, vectors, metadata, ids, documents }) {
277
+ try {
278
+ const collection = await this.getCollection(indexName);
279
+ this.collectionForValidation = collection;
280
+ const stats = await this.describeIndex({ indexName });
281
+ await this.validateVectorDimensions(vectors, stats.dimension);
282
+ const generatedIds = ids || vectors.map(() => v4());
283
+ const operations = vectors.map((vector, idx) => {
284
+ const id = generatedIds[idx];
285
+ const meta = metadata?.[idx] || {};
286
+ const doc = documents?.[idx];
287
+ const normalizedMeta = Object.keys(meta).reduce(
288
+ (acc, key) => {
289
+ acc[key] = meta[key] instanceof Date ? meta[key].toISOString() : meta[key];
290
+ return acc;
291
+ },
292
+ {}
293
+ );
294
+ const updateDoc = {
295
+ [this.embeddingFieldName]: vector,
296
+ [this.metadataFieldName]: normalizedMeta
297
+ };
298
+ if (doc !== void 0) {
299
+ updateDoc[this.documentFieldName] = doc;
207
300
  }
208
- };
209
- });
210
- await collection.bulkWrite(operations);
211
- return generatedIds;
301
+ return {
302
+ updateOne: {
303
+ filter: { _id: id },
304
+ // '_id' is a string as per MongoDBDocument interface
305
+ update: { $set: updateDoc },
306
+ upsert: true
307
+ }
308
+ };
309
+ });
310
+ await collection.bulkWrite(operations);
311
+ return generatedIds;
312
+ } catch (error) {
313
+ throw new MastraError(
314
+ {
315
+ id: "STORAGE_MONGODB_VECTOR_UPSERT_FAILED",
316
+ domain: ErrorDomain.STORAGE,
317
+ category: ErrorCategory.THIRD_PARTY,
318
+ details: {
319
+ indexName
320
+ }
321
+ },
322
+ error
323
+ );
324
+ }
212
325
  }
213
- async query(params) {
214
- const { indexName, queryVector, topK = 10, filter, includeVector = false, documentFilter } = params;
215
- const collection = await this.getCollection(indexName, true);
216
- const indexNameInternal = `${indexName}_vector_index`;
217
- const mongoFilter = this.transformFilter(filter);
218
- const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
219
- let combinedFilter = {};
220
- if (Object.keys(mongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
221
- combinedFilter = { $and: [mongoFilter, documentMongoFilter] };
222
- } else if (Object.keys(mongoFilter).length > 0) {
223
- combinedFilter = mongoFilter;
224
- } else if (Object.keys(documentMongoFilter).length > 0) {
225
- combinedFilter = documentMongoFilter;
226
- }
227
- const pipeline = [
228
- {
229
- $vectorSearch: {
230
- index: indexNameInternal,
231
- queryVector,
232
- path: this.embeddingFieldName,
233
- numCandidates: 100,
234
- limit: topK
235
- }
236
- },
237
- // Apply the filter using $match stage
238
- ...Object.keys(combinedFilter).length > 0 ? [{ $match: combinedFilter }] : [],
239
- {
240
- $set: { score: { $meta: "vectorSearchScore" } }
241
- },
242
- {
243
- $project: {
244
- _id: 1,
245
- score: 1,
246
- metadata: `$${this.metadataFieldName}`,
247
- document: `$${this.documentFieldName}`,
248
- ...includeVector && { vector: `$${this.embeddingFieldName}` }
326
+ async query({
327
+ indexName,
328
+ queryVector,
329
+ topK = 10,
330
+ filter,
331
+ includeVector = false,
332
+ documentFilter
333
+ }) {
334
+ try {
335
+ const collection = await this.getCollection(indexName, true);
336
+ const indexNameInternal = `${indexName}_vector_index`;
337
+ const mongoFilter = this.transformFilter(filter);
338
+ const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
339
+ const transformedMongoFilter = this.transformMetadataFilter(mongoFilter);
340
+ let combinedFilter = {};
341
+ if (Object.keys(transformedMongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
342
+ combinedFilter = { $and: [transformedMongoFilter, documentMongoFilter] };
343
+ } else if (Object.keys(transformedMongoFilter).length > 0) {
344
+ combinedFilter = transformedMongoFilter;
345
+ } else if (Object.keys(documentMongoFilter).length > 0) {
346
+ combinedFilter = documentMongoFilter;
347
+ }
348
+ const vectorSearch = {
349
+ index: indexNameInternal,
350
+ queryVector,
351
+ path: this.embeddingFieldName,
352
+ numCandidates: 100,
353
+ limit: topK
354
+ };
355
+ if (Object.keys(combinedFilter).length > 0) {
356
+ const candidateIds = await collection.aggregate([{ $match: combinedFilter }, { $project: { _id: 1 } }]).map((doc) => doc._id).toArray();
357
+ if (candidateIds.length > 0) {
358
+ vectorSearch.filter = { _id: { $in: candidateIds } };
359
+ } else {
360
+ return [];
249
361
  }
250
362
  }
251
- ];
252
- try {
363
+ const pipeline = [
364
+ {
365
+ $vectorSearch: vectorSearch
366
+ },
367
+ {
368
+ $set: { score: { $meta: "vectorSearchScore" } }
369
+ },
370
+ {
371
+ $project: {
372
+ _id: 1,
373
+ score: 1,
374
+ metadata: `$${this.metadataFieldName}`,
375
+ document: `$${this.documentFieldName}`,
376
+ ...includeVector && { vector: `$${this.embeddingFieldName}` }
377
+ }
378
+ }
379
+ ];
253
380
  const results = await collection.aggregate(pipeline).toArray();
254
381
  return results.map((result) => ({
255
382
  id: result._id,
@@ -259,62 +386,161 @@ var MongoDBVector = class extends MastraVector {
259
386
  document: result.document
260
387
  }));
261
388
  } catch (error) {
262
- console.error("Error during vector search:", error);
263
- throw error;
389
+ throw new MastraError(
390
+ {
391
+ id: "STORAGE_MONGODB_VECTOR_QUERY_FAILED",
392
+ domain: ErrorDomain.STORAGE,
393
+ category: ErrorCategory.THIRD_PARTY,
394
+ details: {
395
+ indexName
396
+ }
397
+ },
398
+ error
399
+ );
264
400
  }
265
401
  }
266
402
  async listIndexes() {
267
- const collections = await this.db.listCollections().toArray();
268
- return collections.map((col) => col.name);
403
+ try {
404
+ const collections = await this.db.listCollections().toArray();
405
+ return collections.map((col) => col.name);
406
+ } catch (error) {
407
+ throw new MastraError(
408
+ {
409
+ id: "STORAGE_MONGODB_VECTOR_LIST_INDEXES_FAILED",
410
+ domain: ErrorDomain.STORAGE,
411
+ category: ErrorCategory.THIRD_PARTY
412
+ },
413
+ error
414
+ );
415
+ }
269
416
  }
270
- async describeIndex(indexName) {
271
- const collection = await this.getCollection(indexName, true);
272
- const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
273
- const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
274
- const dimension = metadataDoc?.dimension || 0;
275
- const metric = metadataDoc?.metric || "cosine";
276
- return {
277
- dimension,
278
- count,
279
- metric
280
- };
417
+ /**
418
+ * Retrieves statistics about a vector index.
419
+ *
420
+ * @param {string} indexName - The name of the index to describe
421
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
422
+ */
423
+ async describeIndex({ indexName }) {
424
+ try {
425
+ const collection = await this.getCollection(indexName, true);
426
+ const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
427
+ const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
428
+ const dimension = metadataDoc?.dimension || 0;
429
+ const metric = metadataDoc?.metric || "cosine";
430
+ return {
431
+ dimension,
432
+ count,
433
+ metric
434
+ };
435
+ } catch (error) {
436
+ throw new MastraError(
437
+ {
438
+ id: "STORAGE_MONGODB_VECTOR_DESCRIBE_INDEX_FAILED",
439
+ domain: ErrorDomain.STORAGE,
440
+ category: ErrorCategory.THIRD_PARTY,
441
+ details: {
442
+ indexName
443
+ }
444
+ },
445
+ error
446
+ );
447
+ }
281
448
  }
282
- async deleteIndex(indexName) {
449
+ async deleteIndex({ indexName }) {
283
450
  const collection = await this.getCollection(indexName, false);
284
- if (collection) {
285
- await collection.drop();
286
- this.collections.delete(indexName);
287
- } else {
288
- throw new Error(`Index (Collection) "${indexName}" does not exist`);
451
+ try {
452
+ if (collection) {
453
+ await collection.drop();
454
+ this.collections.delete(indexName);
455
+ } else {
456
+ throw new Error(`Index (Collection) "${indexName}" does not exist`);
457
+ }
458
+ } catch (error) {
459
+ throw new MastraError(
460
+ {
461
+ id: "STORAGE_MONGODB_VECTOR_DELETE_INDEX_FAILED",
462
+ domain: ErrorDomain.STORAGE,
463
+ category: ErrorCategory.THIRD_PARTY,
464
+ details: {
465
+ indexName
466
+ }
467
+ },
468
+ error
469
+ );
289
470
  }
290
471
  }
291
- async updateIndexById(indexName, id, update) {
292
- if (!update.vector && !update.metadata) {
293
- throw new Error("No updates provided");
294
- }
295
- const collection = await this.getCollection(indexName, true);
296
- const updateDoc = {};
297
- if (update.vector) {
298
- updateDoc[this.embeddingFieldName] = update.vector;
299
- }
300
- if (update.metadata) {
301
- const normalizedMeta = Object.keys(update.metadata).reduce(
302
- (acc, key) => {
303
- acc[key] = update.metadata[key] instanceof Date ? update.metadata[key].toISOString() : update.metadata[key];
304
- return acc;
472
+ /**
473
+ * Updates a vector by its ID with the provided vector and/or metadata.
474
+ * @param indexName - The name of the index containing the vector.
475
+ * @param id - The ID of the vector to update.
476
+ * @param update - An object containing the vector and/or metadata to update.
477
+ * @param update.vector - An optional array of numbers representing the new vector.
478
+ * @param update.metadata - An optional record containing the new metadata.
479
+ * @returns A promise that resolves when the update is complete.
480
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
481
+ */
482
+ async updateVector({ indexName, id, update }) {
483
+ try {
484
+ if (!update.vector && !update.metadata) {
485
+ throw new Error("No updates provided");
486
+ }
487
+ const collection = await this.getCollection(indexName, true);
488
+ const updateDoc = {};
489
+ if (update.vector) {
490
+ const stats = await this.describeIndex({ indexName });
491
+ await this.validateVectorDimensions([update.vector], stats.dimension);
492
+ updateDoc[this.embeddingFieldName] = update.vector;
493
+ }
494
+ if (update.metadata) {
495
+ const normalizedMeta = Object.keys(update.metadata).reduce(
496
+ (acc, key) => {
497
+ acc[key] = update.metadata[key] instanceof Date ? update.metadata[key].toISOString() : update.metadata[key];
498
+ return acc;
499
+ },
500
+ {}
501
+ );
502
+ updateDoc[this.metadataFieldName] = normalizedMeta;
503
+ }
504
+ await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
505
+ } catch (error) {
506
+ throw new MastraError(
507
+ {
508
+ id: "STORAGE_MONGODB_VECTOR_UPDATE_VECTOR_FAILED",
509
+ domain: ErrorDomain.STORAGE,
510
+ category: ErrorCategory.THIRD_PARTY,
511
+ details: {
512
+ indexName,
513
+ id
514
+ }
305
515
  },
306
- {}
516
+ error
307
517
  );
308
- updateDoc[this.metadataFieldName] = normalizedMeta;
309
518
  }
310
- await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
311
519
  }
312
- async deleteIndexById(indexName, id) {
520
+ /**
521
+ * Deletes a vector by its ID.
522
+ * @param indexName - The name of the index containing the vector.
523
+ * @param id - The ID of the vector to delete.
524
+ * @returns A promise that resolves when the deletion is complete.
525
+ * @throws Will throw an error if the deletion operation fails.
526
+ */
527
+ async deleteVector({ indexName, id }) {
313
528
  try {
314
529
  const collection = await this.getCollection(indexName, true);
315
530
  await collection.deleteOne({ _id: id });
316
531
  } catch (error) {
317
- throw new Error(`Failed to delete index by id: ${id} for index name: ${indexName}: ${error.message}`);
532
+ throw new MastraError(
533
+ {
534
+ id: "STORAGE_MONGODB_VECTOR_DELETE_VECTOR_FAILED",
535
+ domain: ErrorDomain.STORAGE,
536
+ category: ErrorCategory.THIRD_PARTY,
537
+ details: {
538
+ indexName,
539
+ id
540
+ }
541
+ },
542
+ error
543
+ );
318
544
  }
319
545
  }
320
546
  // Private methods
@@ -354,6 +580,2095 @@ var MongoDBVector = class extends MastraVector {
354
580
  if (!filter) return {};
355
581
  return translator.translate(filter);
356
582
  }
583
+ /**
584
+ * Transform metadata field filters to use MongoDB dot notation.
585
+ * Fields that are stored in the metadata subdocument need to be prefixed with 'metadata.'
586
+ * This handles filters from the Memory system which expects direct field access.
587
+ *
588
+ * @param filter - The filter object to transform
589
+ * @returns Transformed filter with metadata fields properly prefixed
590
+ */
591
+ transformMetadataFilter(filter) {
592
+ if (!filter || typeof filter !== "object") return filter;
593
+ const transformed = {};
594
+ for (const [key, value] of Object.entries(filter)) {
595
+ if (key.startsWith("$")) {
596
+ if (Array.isArray(value)) {
597
+ transformed[key] = value.map((item) => this.transformMetadataFilter(item));
598
+ } else {
599
+ transformed[key] = this.transformMetadataFilter(value);
600
+ }
601
+ } else if (key.startsWith("metadata.")) {
602
+ transformed[key] = value;
603
+ } else if (this.isMetadataField(key)) {
604
+ transformed[`metadata.${key}`] = value;
605
+ } else {
606
+ transformed[key] = value;
607
+ }
608
+ }
609
+ return transformed;
610
+ }
611
+ /**
612
+ * Determine if a field should be treated as a metadata field.
613
+ * Common metadata fields include thread_id, resource_id, message_id, and any field
614
+ * that doesn't start with underscore (MongoDB system fields).
615
+ */
616
+ isMetadataField(key) {
617
+ if (key.startsWith("_")) return false;
618
+ const documentFields = ["_id", this.embeddingFieldName, this.documentFieldName];
619
+ if (documentFields.includes(key)) return false;
620
+ return true;
621
+ }
622
+ };
623
+ var MongoDBConnector = class _MongoDBConnector {
624
+ #client;
625
+ #dbName;
626
+ #handler;
627
+ #isConnected;
628
+ #db;
629
+ constructor(options) {
630
+ this.#client = options.client;
631
+ this.#dbName = options.dbName;
632
+ this.#handler = options.handler;
633
+ this.#isConnected = false;
634
+ }
635
+ static fromDatabaseConfig(config) {
636
+ if (!config.url?.trim().length) {
637
+ throw new Error(
638
+ "MongoDBStore: url must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
639
+ );
640
+ }
641
+ if (!config.dbName?.trim().length) {
642
+ throw new Error(
643
+ "MongoDBStore: dbName must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
644
+ );
645
+ }
646
+ const client = new MongoClient(config.url, {
647
+ ...config.options,
648
+ driverInfo: {
649
+ name: "mastra-storage",
650
+ version: package_default.version
651
+ }
652
+ });
653
+ return new _MongoDBConnector({
654
+ client,
655
+ dbName: config.dbName,
656
+ handler: void 0
657
+ });
658
+ }
659
+ static fromConnectionHandler(handler) {
660
+ return new _MongoDBConnector({
661
+ client: void 0,
662
+ dbName: void 0,
663
+ handler
664
+ });
665
+ }
666
+ async getConnection() {
667
+ if (this.#client) {
668
+ if (this.#isConnected && this.#db) {
669
+ return this.#db;
670
+ }
671
+ await this.#client.connect();
672
+ this.#db = this.#client.db(this.#dbName);
673
+ this.#isConnected = true;
674
+ return this.#db;
675
+ }
676
+ throw new Error("MongoDBStore: client cannot be empty. Check your MongoDBConnector configuration.");
677
+ }
678
+ async getCollection(collectionName) {
679
+ if (this.#handler) {
680
+ return this.#handler.getCollection(collectionName);
681
+ }
682
+ const db = await this.getConnection();
683
+ return db.collection(collectionName);
684
+ }
685
+ async close() {
686
+ if (this.#client) {
687
+ await this.#client.close();
688
+ this.#isConnected = false;
689
+ return;
690
+ }
691
+ if (this.#handler) {
692
+ await this.#handler.close();
693
+ }
694
+ }
695
+ };
696
+
697
+ // src/storage/domains/utils.ts
698
+ function formatDateForMongoDB(date) {
699
+ return typeof date === "string" ? new Date(date) : date;
700
+ }
701
+
702
+ // src/storage/domains/memory/index.ts
703
+ var MemoryStorageMongoDB = class extends MemoryStorage {
704
+ operations;
705
+ constructor({ operations }) {
706
+ super();
707
+ this.operations = operations;
708
+ }
709
+ parseRow(row) {
710
+ let content = row.content;
711
+ if (typeof content === "string") {
712
+ try {
713
+ content = JSON.parse(content);
714
+ } catch {
715
+ }
716
+ }
717
+ const result = {
718
+ id: row.id,
719
+ content,
720
+ role: row.role,
721
+ createdAt: formatDateForMongoDB(row.createdAt),
722
+ threadId: row.thread_id,
723
+ resourceId: row.resourceId
724
+ };
725
+ if (row.type && row.type !== "v2") result.type = row.type;
726
+ return result;
727
+ }
728
+ async _getIncludedMessages({
729
+ threadId,
730
+ include
731
+ }) {
732
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
733
+ if (!include) return null;
734
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
735
+ const includedMessages = [];
736
+ for (const inc of include) {
737
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
738
+ const searchThreadId = inc.threadId || threadId;
739
+ const allMessages = await collection.find({ thread_id: searchThreadId }).sort({ createdAt: 1 }).toArray();
740
+ const targetIndex = allMessages.findIndex((msg) => msg.id === id);
741
+ if (targetIndex === -1) continue;
742
+ const startIndex = Math.max(0, targetIndex - withPreviousMessages);
743
+ const endIndex = Math.min(allMessages.length - 1, targetIndex + withNextMessages);
744
+ for (let i = startIndex; i <= endIndex; i++) {
745
+ includedMessages.push(allMessages[i]);
746
+ }
747
+ }
748
+ const seen = /* @__PURE__ */ new Set();
749
+ const dedupedMessages = includedMessages.filter((msg) => {
750
+ if (seen.has(msg.id)) return false;
751
+ seen.add(msg.id);
752
+ return true;
753
+ });
754
+ return dedupedMessages.map((row) => this.parseRow(row));
755
+ }
756
+ async listMessagesById({ messageIds }) {
757
+ if (messageIds.length === 0) return { messages: [] };
758
+ try {
759
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
760
+ const rawMessages = await collection.find({ id: { $in: messageIds } }).sort({ createdAt: -1 }).toArray();
761
+ const list = new MessageList().add(
762
+ rawMessages.map(this.parseRow),
763
+ "memory"
764
+ );
765
+ return { messages: list.get.all.db() };
766
+ } catch (error) {
767
+ throw new MastraError(
768
+ {
769
+ id: "MONGODB_STORE_LIST_MESSAGES_BY_ID_FAILED",
770
+ domain: ErrorDomain.STORAGE,
771
+ category: ErrorCategory.THIRD_PARTY,
772
+ details: { messageIds: JSON.stringify(messageIds) }
773
+ },
774
+ error
775
+ );
776
+ }
777
+ }
778
+ async listMessages(args) {
779
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
780
+ if (!threadId.trim()) {
781
+ throw new MastraError(
782
+ {
783
+ id: "STORAGE_MONGODB_LIST_MESSAGES_INVALID_THREAD_ID",
784
+ domain: ErrorDomain.STORAGE,
785
+ category: ErrorCategory.THIRD_PARTY,
786
+ details: { threadId }
787
+ },
788
+ new Error("threadId must be a non-empty string")
789
+ );
790
+ }
791
+ if (page < 0) {
792
+ throw new MastraError(
793
+ {
794
+ id: "STORAGE_MONGODB_LIST_MESSAGES_INVALID_PAGE",
795
+ domain: ErrorDomain.STORAGE,
796
+ category: ErrorCategory.USER,
797
+ details: { page }
798
+ },
799
+ new Error("page must be >= 0")
800
+ );
801
+ }
802
+ const perPage = normalizePerPage(perPageInput, 40);
803
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
804
+ try {
805
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
806
+ const sortOrder = direction === "ASC" ? 1 : -1;
807
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
808
+ const query = { thread_id: threadId };
809
+ if (resourceId) {
810
+ query.resourceId = resourceId;
811
+ }
812
+ if (filter?.dateRange?.start) {
813
+ query.createdAt = { ...query.createdAt, $gte: filter.dateRange.start };
814
+ }
815
+ if (filter?.dateRange?.end) {
816
+ query.createdAt = { ...query.createdAt, $lte: filter.dateRange.end };
817
+ }
818
+ const total = await collection.countDocuments(query);
819
+ const messages = [];
820
+ if (perPage !== 0) {
821
+ const sortObj = { [field]: sortOrder };
822
+ let cursor = collection.find(query).sort(sortObj).skip(offset);
823
+ if (perPageInput !== false) {
824
+ cursor = cursor.limit(perPage);
825
+ }
826
+ const dataResult = await cursor.toArray();
827
+ messages.push(...dataResult.map((row) => this.parseRow(row)));
828
+ }
829
+ if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
830
+ return {
831
+ messages: [],
832
+ total: 0,
833
+ page,
834
+ perPage: perPageForResponse,
835
+ hasMore: false
836
+ };
837
+ }
838
+ const messageIds = new Set(messages.map((m) => m.id));
839
+ if (include && include.length > 0) {
840
+ const includeMessages = await this._getIncludedMessages({ threadId, include });
841
+ if (includeMessages) {
842
+ for (const includeMsg of includeMessages) {
843
+ if (!messageIds.has(includeMsg.id)) {
844
+ messages.push(includeMsg);
845
+ messageIds.add(includeMsg.id);
846
+ }
847
+ }
848
+ }
849
+ }
850
+ const list = new MessageList().add(messages, "memory");
851
+ let finalMessages = list.get.all.db();
852
+ finalMessages = finalMessages.sort((a, b) => {
853
+ const isDateField = field === "createdAt" || field === "updatedAt";
854
+ const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
855
+ const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
856
+ if (typeof aValue === "number" && typeof bValue === "number") {
857
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
858
+ }
859
+ return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
860
+ });
861
+ const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
862
+ const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
863
+ const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + perPage < total;
864
+ return {
865
+ messages: finalMessages,
866
+ total,
867
+ page,
868
+ perPage: perPageForResponse,
869
+ hasMore
870
+ };
871
+ } catch (error) {
872
+ const mastraError = new MastraError(
873
+ {
874
+ id: "MONGODB_STORE_LIST_MESSAGES_FAILED",
875
+ domain: ErrorDomain.STORAGE,
876
+ category: ErrorCategory.THIRD_PARTY,
877
+ details: {
878
+ threadId,
879
+ resourceId: resourceId ?? ""
880
+ }
881
+ },
882
+ error
883
+ );
884
+ this.logger?.error?.(mastraError.toString());
885
+ this.logger?.trackException?.(mastraError);
886
+ return {
887
+ messages: [],
888
+ total: 0,
889
+ page,
890
+ perPage: perPageForResponse,
891
+ hasMore: false
892
+ };
893
+ }
894
+ }
895
+ async saveMessages({ messages }) {
896
+ if (messages.length === 0) return { messages: [] };
897
+ try {
898
+ const threadId = messages[0]?.threadId;
899
+ if (!threadId) {
900
+ throw new Error("Thread ID is required");
901
+ }
902
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
903
+ const threadsCollection = await this.operations.getCollection(TABLE_THREADS);
904
+ const messagesToInsert = messages.map((message) => {
905
+ const time = message.createdAt || /* @__PURE__ */ new Date();
906
+ if (!message.threadId) {
907
+ throw new Error(
908
+ "Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred."
909
+ );
910
+ }
911
+ if (!message.resourceId) {
912
+ throw new Error(
913
+ "Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred."
914
+ );
915
+ }
916
+ return {
917
+ updateOne: {
918
+ filter: { id: message.id },
919
+ update: {
920
+ $set: {
921
+ id: message.id,
922
+ thread_id: message.threadId,
923
+ content: typeof message.content === "object" ? JSON.stringify(message.content) : message.content,
924
+ role: message.role,
925
+ type: message.type || "v2",
926
+ createdAt: formatDateForMongoDB(time),
927
+ resourceId: message.resourceId
928
+ }
929
+ },
930
+ upsert: true
931
+ }
932
+ };
933
+ });
934
+ await Promise.all([
935
+ collection.bulkWrite(messagesToInsert),
936
+ threadsCollection.updateOne({ id: threadId }, { $set: { updatedAt: /* @__PURE__ */ new Date() } })
937
+ ]);
938
+ const list = new MessageList().add(messages, "memory");
939
+ return { messages: list.get.all.db() };
940
+ } catch (error) {
941
+ throw new MastraError(
942
+ {
943
+ id: "MONGODB_STORE_SAVE_MESSAGES_FAILED",
944
+ domain: ErrorDomain.STORAGE,
945
+ category: ErrorCategory.THIRD_PARTY
946
+ },
947
+ error
948
+ );
949
+ }
950
+ }
951
+ async updateMessages({
952
+ messages
953
+ }) {
954
+ if (messages.length === 0) {
955
+ return [];
956
+ }
957
+ const messageIds = messages.map((m) => m.id);
958
+ const collection = await this.operations.getCollection(TABLE_MESSAGES);
959
+ const existingMessages = await collection.find({ id: { $in: messageIds } }).toArray();
960
+ const existingMessagesParsed = existingMessages.map((msg) => this.parseRow(msg));
961
+ if (existingMessagesParsed.length === 0) {
962
+ return [];
963
+ }
964
+ const threadIdsToUpdate = /* @__PURE__ */ new Set();
965
+ const bulkOps = [];
966
+ for (const existingMessage of existingMessagesParsed) {
967
+ const updatePayload = messages.find((m) => m.id === existingMessage.id);
968
+ if (!updatePayload) continue;
969
+ const { id, ...fieldsToUpdate } = updatePayload;
970
+ if (Object.keys(fieldsToUpdate).length === 0) continue;
971
+ threadIdsToUpdate.add(existingMessage.threadId);
972
+ if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
973
+ threadIdsToUpdate.add(updatePayload.threadId);
974
+ }
975
+ const updateDoc = {};
976
+ const updatableFields = { ...fieldsToUpdate };
977
+ if (updatableFields.content) {
978
+ const newContent = {
979
+ ...existingMessage.content,
980
+ ...updatableFields.content,
981
+ // Deep merge metadata if it exists on both
982
+ ...existingMessage.content?.metadata && updatableFields.content.metadata ? {
983
+ metadata: {
984
+ ...existingMessage.content.metadata,
985
+ ...updatableFields.content.metadata
986
+ }
987
+ } : {}
988
+ };
989
+ updateDoc.content = JSON.stringify(newContent);
990
+ delete updatableFields.content;
991
+ }
992
+ for (const key in updatableFields) {
993
+ if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
994
+ const dbKey = key === "threadId" ? "thread_id" : key;
995
+ let value = updatableFields[key];
996
+ if (typeof value === "object" && value !== null) {
997
+ value = JSON.stringify(value);
998
+ }
999
+ updateDoc[dbKey] = value;
1000
+ }
1001
+ }
1002
+ if (Object.keys(updateDoc).length > 0) {
1003
+ bulkOps.push({
1004
+ updateOne: {
1005
+ filter: { id },
1006
+ update: { $set: updateDoc }
1007
+ }
1008
+ });
1009
+ }
1010
+ }
1011
+ if (bulkOps.length > 0) {
1012
+ await collection.bulkWrite(bulkOps);
1013
+ }
1014
+ if (threadIdsToUpdate.size > 0) {
1015
+ const threadsCollection = await this.operations.getCollection(TABLE_THREADS);
1016
+ await threadsCollection.updateMany(
1017
+ { id: { $in: Array.from(threadIdsToUpdate) } },
1018
+ { $set: { updatedAt: /* @__PURE__ */ new Date() } }
1019
+ );
1020
+ }
1021
+ const updatedMessages = await collection.find({ id: { $in: messageIds } }).toArray();
1022
+ return updatedMessages.map((row) => this.parseRow(row));
1023
+ }
1024
+ async getResourceById({ resourceId }) {
1025
+ try {
1026
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1027
+ const result = await collection.findOne({ id: resourceId });
1028
+ if (!result) {
1029
+ return null;
1030
+ }
1031
+ return {
1032
+ id: result.id,
1033
+ workingMemory: result.workingMemory || "",
1034
+ metadata: typeof result.metadata === "string" ? safelyParseJSON(result.metadata) : result.metadata,
1035
+ createdAt: formatDateForMongoDB(result.createdAt),
1036
+ updatedAt: formatDateForMongoDB(result.updatedAt)
1037
+ };
1038
+ } catch (error) {
1039
+ throw new MastraError(
1040
+ {
1041
+ id: "STORAGE_MONGODB_STORE_GET_RESOURCE_BY_ID_FAILED",
1042
+ domain: ErrorDomain.STORAGE,
1043
+ category: ErrorCategory.THIRD_PARTY,
1044
+ details: { resourceId }
1045
+ },
1046
+ error
1047
+ );
1048
+ }
1049
+ }
1050
+ async saveResource({ resource }) {
1051
+ try {
1052
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1053
+ await collection.updateOne(
1054
+ { id: resource.id },
1055
+ {
1056
+ $set: {
1057
+ ...resource,
1058
+ metadata: JSON.stringify(resource.metadata)
1059
+ }
1060
+ },
1061
+ { upsert: true }
1062
+ );
1063
+ return resource;
1064
+ } catch (error) {
1065
+ throw new MastraError(
1066
+ {
1067
+ id: "STORAGE_MONGODB_STORE_SAVE_RESOURCE_FAILED",
1068
+ domain: ErrorDomain.STORAGE,
1069
+ category: ErrorCategory.THIRD_PARTY,
1070
+ details: { resourceId: resource.id }
1071
+ },
1072
+ error
1073
+ );
1074
+ }
1075
+ }
1076
+ async updateResource({
1077
+ resourceId,
1078
+ workingMemory,
1079
+ metadata
1080
+ }) {
1081
+ try {
1082
+ const existingResource = await this.getResourceById({ resourceId });
1083
+ if (!existingResource) {
1084
+ const newResource = {
1085
+ id: resourceId,
1086
+ workingMemory: workingMemory || "",
1087
+ metadata: metadata || {},
1088
+ createdAt: /* @__PURE__ */ new Date(),
1089
+ updatedAt: /* @__PURE__ */ new Date()
1090
+ };
1091
+ return this.saveResource({ resource: newResource });
1092
+ }
1093
+ const updatedResource = {
1094
+ ...existingResource,
1095
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
1096
+ metadata: metadata ? { ...existingResource.metadata, ...metadata } : existingResource.metadata,
1097
+ updatedAt: /* @__PURE__ */ new Date()
1098
+ };
1099
+ const collection = await this.operations.getCollection(TABLE_RESOURCES);
1100
+ const updateDoc = { updatedAt: updatedResource.updatedAt };
1101
+ if (workingMemory !== void 0) {
1102
+ updateDoc.workingMemory = workingMemory;
1103
+ }
1104
+ if (metadata) {
1105
+ updateDoc.metadata = JSON.stringify(updatedResource.metadata);
1106
+ }
1107
+ await collection.updateOne({ id: resourceId }, { $set: updateDoc });
1108
+ return updatedResource;
1109
+ } catch (error) {
1110
+ throw new MastraError(
1111
+ {
1112
+ id: "STORAGE_MONGODB_STORE_UPDATE_RESOURCE_FAILED",
1113
+ domain: ErrorDomain.STORAGE,
1114
+ category: ErrorCategory.THIRD_PARTY,
1115
+ details: { resourceId }
1116
+ },
1117
+ error
1118
+ );
1119
+ }
1120
+ }
1121
+ async getThreadById({ threadId }) {
1122
+ try {
1123
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1124
+ const result = await collection.findOne({ id: threadId });
1125
+ if (!result) {
1126
+ return null;
1127
+ }
1128
+ return {
1129
+ ...result,
1130
+ metadata: typeof result.metadata === "string" ? safelyParseJSON(result.metadata) : result.metadata
1131
+ };
1132
+ } catch (error) {
1133
+ throw new MastraError(
1134
+ {
1135
+ id: "STORAGE_MONGODB_STORE_GET_THREAD_BY_ID_FAILED",
1136
+ domain: ErrorDomain.STORAGE,
1137
+ category: ErrorCategory.THIRD_PARTY,
1138
+ details: { threadId }
1139
+ },
1140
+ error
1141
+ );
1142
+ }
1143
+ }
1144
+ async listThreadsByResourceId(args) {
1145
+ try {
1146
+ const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
1147
+ if (page < 0) {
1148
+ throw new MastraError(
1149
+ {
1150
+ id: "STORAGE_MONGODB_LIST_THREADS_BY_RESOURCE_ID_INVALID_PAGE",
1151
+ domain: ErrorDomain.STORAGE,
1152
+ category: ErrorCategory.USER,
1153
+ details: { page }
1154
+ },
1155
+ new Error("page must be >= 0")
1156
+ );
1157
+ }
1158
+ const perPage = normalizePerPage(perPageInput, 100);
1159
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1160
+ const { field, direction } = this.parseOrderBy(orderBy);
1161
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1162
+ const query = { resourceId };
1163
+ const total = await collection.countDocuments(query);
1164
+ if (perPage === 0) {
1165
+ return {
1166
+ threads: [],
1167
+ total,
1168
+ page,
1169
+ perPage: perPageForResponse,
1170
+ hasMore: offset < total
1171
+ };
1172
+ }
1173
+ const sortOrder = direction === "ASC" ? 1 : -1;
1174
+ let cursor = collection.find(query).sort({ [field]: sortOrder }).skip(offset);
1175
+ if (perPageInput !== false) {
1176
+ cursor = cursor.limit(perPage);
1177
+ }
1178
+ const threads = await cursor.toArray();
1179
+ return {
1180
+ threads: threads.map((thread) => ({
1181
+ id: thread.id,
1182
+ title: thread.title,
1183
+ resourceId: thread.resourceId,
1184
+ createdAt: formatDateForMongoDB(thread.createdAt),
1185
+ updatedAt: formatDateForMongoDB(thread.updatedAt),
1186
+ metadata: thread.metadata || {}
1187
+ })),
1188
+ total,
1189
+ page,
1190
+ perPage: perPageForResponse,
1191
+ hasMore: perPageInput === false ? false : offset + perPage < total
1192
+ };
1193
+ } catch (error) {
1194
+ throw new MastraError(
1195
+ {
1196
+ id: "MONGODB_STORE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
1197
+ domain: ErrorDomain.STORAGE,
1198
+ category: ErrorCategory.THIRD_PARTY,
1199
+ details: { resourceId: args.resourceId }
1200
+ },
1201
+ error
1202
+ );
1203
+ }
1204
+ }
1205
+ async saveThread({ thread }) {
1206
+ try {
1207
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1208
+ await collection.updateOne(
1209
+ { id: thread.id },
1210
+ {
1211
+ $set: {
1212
+ ...thread,
1213
+ metadata: thread.metadata
1214
+ }
1215
+ },
1216
+ { upsert: true }
1217
+ );
1218
+ return thread;
1219
+ } catch (error) {
1220
+ throw new MastraError(
1221
+ {
1222
+ id: "STORAGE_MONGODB_STORE_SAVE_THREAD_FAILED",
1223
+ domain: ErrorDomain.STORAGE,
1224
+ category: ErrorCategory.THIRD_PARTY,
1225
+ details: { threadId: thread.id }
1226
+ },
1227
+ error
1228
+ );
1229
+ }
1230
+ }
1231
+ async updateThread({
1232
+ id,
1233
+ title,
1234
+ metadata
1235
+ }) {
1236
+ const thread = await this.getThreadById({ threadId: id });
1237
+ if (!thread) {
1238
+ throw new MastraError({
1239
+ id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_NOT_FOUND",
1240
+ domain: ErrorDomain.STORAGE,
1241
+ category: ErrorCategory.THIRD_PARTY,
1242
+ details: { threadId: id, status: 404 },
1243
+ text: `Thread ${id} not found`
1244
+ });
1245
+ }
1246
+ const updatedThread = {
1247
+ ...thread,
1248
+ title,
1249
+ metadata: {
1250
+ ...thread.metadata,
1251
+ ...metadata
1252
+ }
1253
+ };
1254
+ try {
1255
+ const collection = await this.operations.getCollection(TABLE_THREADS);
1256
+ await collection.updateOne(
1257
+ { id },
1258
+ {
1259
+ $set: {
1260
+ title,
1261
+ metadata: updatedThread.metadata
1262
+ }
1263
+ }
1264
+ );
1265
+ } catch (error) {
1266
+ throw new MastraError(
1267
+ {
1268
+ id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_FAILED",
1269
+ domain: ErrorDomain.STORAGE,
1270
+ category: ErrorCategory.THIRD_PARTY,
1271
+ details: { threadId: id }
1272
+ },
1273
+ error
1274
+ );
1275
+ }
1276
+ return updatedThread;
1277
+ }
1278
+ async deleteThread({ threadId }) {
1279
+ try {
1280
+ const collectionMessages = await this.operations.getCollection(TABLE_MESSAGES);
1281
+ await collectionMessages.deleteMany({ thread_id: threadId });
1282
+ const collectionThreads = await this.operations.getCollection(TABLE_THREADS);
1283
+ await collectionThreads.deleteOne({ id: threadId });
1284
+ } catch (error) {
1285
+ throw new MastraError(
1286
+ {
1287
+ id: "STORAGE_MONGODB_STORE_DELETE_THREAD_FAILED",
1288
+ domain: ErrorDomain.STORAGE,
1289
+ category: ErrorCategory.THIRD_PARTY,
1290
+ details: { threadId }
1291
+ },
1292
+ error
1293
+ );
1294
+ }
1295
+ }
1296
+ };
1297
+ var ObservabilityMongoDB = class extends ObservabilityStorage {
1298
+ operations;
1299
+ constructor({ operations }) {
1300
+ super();
1301
+ this.operations = operations;
1302
+ }
1303
+ get tracingStrategy() {
1304
+ return {
1305
+ preferred: "batch-with-updates",
1306
+ supported: ["batch-with-updates", "insert-only"]
1307
+ };
1308
+ }
1309
+ async createSpan(span) {
1310
+ try {
1311
+ const startedAt = span.startedAt instanceof Date ? span.startedAt.toISOString() : span.startedAt;
1312
+ const endedAt = span.endedAt instanceof Date ? span.endedAt.toISOString() : span.endedAt;
1313
+ const record = {
1314
+ ...span,
1315
+ startedAt,
1316
+ endedAt,
1317
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1318
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1319
+ };
1320
+ return this.operations.insert({ tableName: TABLE_SPANS, record });
1321
+ } catch (error) {
1322
+ throw new MastraError(
1323
+ {
1324
+ id: "MONGODB_STORE_CREATE_SPAN_FAILED",
1325
+ domain: ErrorDomain.STORAGE,
1326
+ category: ErrorCategory.USER,
1327
+ details: {
1328
+ spanId: span.spanId,
1329
+ traceId: span.traceId,
1330
+ spanType: span.spanType,
1331
+ spanName: span.name
1332
+ }
1333
+ },
1334
+ error
1335
+ );
1336
+ }
1337
+ }
1338
+ async getTrace(traceId) {
1339
+ try {
1340
+ const collection = await this.operations.getCollection(TABLE_SPANS);
1341
+ const spans = await collection.find({ traceId }).sort({ startedAt: -1 }).toArray();
1342
+ if (!spans || spans.length === 0) {
1343
+ return null;
1344
+ }
1345
+ return {
1346
+ traceId,
1347
+ spans: spans.map((span) => this.transformSpanFromMongo(span))
1348
+ };
1349
+ } catch (error) {
1350
+ throw new MastraError(
1351
+ {
1352
+ id: "MONGODB_STORE_GET_TRACE_FAILED",
1353
+ domain: ErrorDomain.STORAGE,
1354
+ category: ErrorCategory.USER,
1355
+ details: {
1356
+ traceId
1357
+ }
1358
+ },
1359
+ error
1360
+ );
1361
+ }
1362
+ }
1363
+ async updateSpan({
1364
+ spanId,
1365
+ traceId,
1366
+ updates
1367
+ }) {
1368
+ try {
1369
+ const data = { ...updates };
1370
+ if (data.endedAt instanceof Date) {
1371
+ data.endedAt = data.endedAt.toISOString();
1372
+ }
1373
+ if (data.startedAt instanceof Date) {
1374
+ data.startedAt = data.startedAt.toISOString();
1375
+ }
1376
+ const updateData = {
1377
+ ...data,
1378
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1379
+ };
1380
+ await this.operations.update({
1381
+ tableName: TABLE_SPANS,
1382
+ keys: { spanId, traceId },
1383
+ data: updateData
1384
+ });
1385
+ } catch (error) {
1386
+ throw new MastraError(
1387
+ {
1388
+ id: "MONGODB_STORE_UPDATE_SPAN_FAILED",
1389
+ domain: ErrorDomain.STORAGE,
1390
+ category: ErrorCategory.USER,
1391
+ details: {
1392
+ spanId,
1393
+ traceId
1394
+ }
1395
+ },
1396
+ error
1397
+ );
1398
+ }
1399
+ }
1400
+ async getTracesPaginated({
1401
+ filters,
1402
+ pagination
1403
+ }) {
1404
+ const page = pagination?.page ?? 0;
1405
+ const perPage = pagination?.perPage ?? 10;
1406
+ const { entityId, entityType, ...actualFilters } = filters || {};
1407
+ try {
1408
+ const collection = await this.operations.getCollection(TABLE_SPANS);
1409
+ const mongoFilter = {
1410
+ parentSpanId: null,
1411
+ // Only get root spans for traces
1412
+ ...actualFilters
1413
+ };
1414
+ if (pagination?.dateRange) {
1415
+ const dateFilter = {};
1416
+ if (pagination.dateRange.start) {
1417
+ dateFilter.$gte = pagination.dateRange.start instanceof Date ? pagination.dateRange.start.toISOString() : pagination.dateRange.start;
1418
+ }
1419
+ if (pagination.dateRange.end) {
1420
+ dateFilter.$lte = pagination.dateRange.end instanceof Date ? pagination.dateRange.end.toISOString() : pagination.dateRange.end;
1421
+ }
1422
+ if (Object.keys(dateFilter).length > 0) {
1423
+ mongoFilter.startedAt = dateFilter;
1424
+ }
1425
+ }
1426
+ if (entityId && entityType) {
1427
+ let name = "";
1428
+ if (entityType === "workflow") {
1429
+ name = `workflow run: '${entityId}'`;
1430
+ } else if (entityType === "agent") {
1431
+ name = `agent run: '${entityId}'`;
1432
+ } else {
1433
+ const error = new MastraError({
1434
+ id: "MONGODB_STORE_GET_TRACES_PAGINATED_FAILED",
1435
+ domain: ErrorDomain.STORAGE,
1436
+ category: ErrorCategory.USER,
1437
+ details: {
1438
+ entityType
1439
+ },
1440
+ text: `Cannot filter by entity type: ${entityType}`
1441
+ });
1442
+ throw error;
1443
+ }
1444
+ mongoFilter.name = name;
1445
+ }
1446
+ const count = await collection.countDocuments(mongoFilter);
1447
+ if (count === 0) {
1448
+ return {
1449
+ pagination: {
1450
+ total: 0,
1451
+ page,
1452
+ perPage,
1453
+ hasMore: false
1454
+ },
1455
+ spans: []
1456
+ };
1457
+ }
1458
+ const spans = await collection.find(mongoFilter).sort({ startedAt: -1 }).skip(page * perPage).limit(perPage).toArray();
1459
+ return {
1460
+ pagination: {
1461
+ total: count,
1462
+ page,
1463
+ perPage,
1464
+ hasMore: spans.length === perPage
1465
+ },
1466
+ spans: spans.map((span) => this.transformSpanFromMongo(span))
1467
+ };
1468
+ } catch (error) {
1469
+ throw new MastraError(
1470
+ {
1471
+ id: "MONGODB_STORE_GET_TRACES_PAGINATED_FAILED",
1472
+ domain: ErrorDomain.STORAGE,
1473
+ category: ErrorCategory.USER
1474
+ },
1475
+ error
1476
+ );
1477
+ }
1478
+ }
1479
+ async batchCreateSpans(args) {
1480
+ try {
1481
+ const records = args.records.map((record) => {
1482
+ const startedAt = record.startedAt instanceof Date ? record.startedAt.toISOString() : record.startedAt;
1483
+ const endedAt = record.endedAt instanceof Date ? record.endedAt.toISOString() : record.endedAt;
1484
+ return {
1485
+ ...record,
1486
+ startedAt,
1487
+ endedAt,
1488
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1489
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1490
+ };
1491
+ });
1492
+ return this.operations.batchInsert({
1493
+ tableName: TABLE_SPANS,
1494
+ records
1495
+ });
1496
+ } catch (error) {
1497
+ throw new MastraError(
1498
+ {
1499
+ id: "MONGODB_STORE_BATCH_CREATE_SPANS_FAILED",
1500
+ domain: ErrorDomain.STORAGE,
1501
+ category: ErrorCategory.USER
1502
+ },
1503
+ error
1504
+ );
1505
+ }
1506
+ }
1507
+ async batchUpdateSpans(args) {
1508
+ try {
1509
+ return this.operations.batchUpdate({
1510
+ tableName: TABLE_SPANS,
1511
+ updates: args.records.map((record) => {
1512
+ const data = { ...record.updates };
1513
+ if (data.endedAt instanceof Date) {
1514
+ data.endedAt = data.endedAt.toISOString();
1515
+ }
1516
+ if (data.startedAt instanceof Date) {
1517
+ data.startedAt = data.startedAt.toISOString();
1518
+ }
1519
+ const updateData = {
1520
+ ...data,
1521
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1522
+ };
1523
+ return {
1524
+ keys: { spanId: record.spanId, traceId: record.traceId },
1525
+ data: updateData
1526
+ };
1527
+ })
1528
+ });
1529
+ } catch (error) {
1530
+ throw new MastraError(
1531
+ {
1532
+ id: "MONGODB_STORE_BATCH_UPDATE_SPANS_FAILED",
1533
+ domain: ErrorDomain.STORAGE,
1534
+ category: ErrorCategory.USER
1535
+ },
1536
+ error
1537
+ );
1538
+ }
1539
+ }
1540
+ async batchDeleteTraces(args) {
1541
+ try {
1542
+ const collection = await this.operations.getCollection(TABLE_SPANS);
1543
+ await collection.deleteMany({
1544
+ traceId: { $in: args.traceIds }
1545
+ });
1546
+ } catch (error) {
1547
+ throw new MastraError(
1548
+ {
1549
+ id: "MONGODB_STORE_BATCH_DELETE_TRACES_FAILED",
1550
+ domain: ErrorDomain.STORAGE,
1551
+ category: ErrorCategory.USER
1552
+ },
1553
+ error
1554
+ );
1555
+ }
1556
+ }
1557
+ /**
1558
+ * Transform MongoDB document to SpanRecord format
1559
+ */
1560
+ transformSpanFromMongo(doc) {
1561
+ const { _id, ...span } = doc;
1562
+ if (span.startedAt && typeof span.startedAt === "string") {
1563
+ span.startedAt = span.startedAt;
1564
+ }
1565
+ if (span.endedAt && typeof span.endedAt === "string") {
1566
+ span.endedAt = span.endedAt;
1567
+ }
1568
+ if (span.createdAt && typeof span.createdAt === "string") {
1569
+ span.createdAt = new Date(span.createdAt);
1570
+ }
1571
+ if (span.updatedAt && typeof span.updatedAt === "string") {
1572
+ span.updatedAt = new Date(span.updatedAt);
1573
+ }
1574
+ return span;
1575
+ }
1576
+ };
1577
+ var StoreOperationsMongoDB = class extends StoreOperations {
1578
+ #connector;
1579
+ constructor(config) {
1580
+ super();
1581
+ this.#connector = config.connector;
1582
+ }
1583
+ async getCollection(collectionName) {
1584
+ return this.#connector.getCollection(collectionName);
1585
+ }
1586
+ async hasColumn(_table, _column) {
1587
+ return true;
1588
+ }
1589
+ async createTable() {
1590
+ }
1591
+ async alterTable(_args) {
1592
+ }
1593
+ async clearTable({ tableName }) {
1594
+ try {
1595
+ const collection = await this.getCollection(tableName);
1596
+ await collection.deleteMany({});
1597
+ } catch (error) {
1598
+ const mastraError = new MastraError(
1599
+ {
1600
+ id: "STORAGE_MONGODB_STORE_CLEAR_TABLE_FAILED",
1601
+ domain: ErrorDomain.STORAGE,
1602
+ category: ErrorCategory.THIRD_PARTY,
1603
+ details: { tableName }
1604
+ },
1605
+ error
1606
+ );
1607
+ this.logger.error(mastraError.message);
1608
+ this.logger?.trackException(mastraError);
1609
+ throw mastraError;
1610
+ }
1611
+ }
1612
+ async dropTable({ tableName }) {
1613
+ try {
1614
+ const collection = await this.getCollection(tableName);
1615
+ await collection.drop();
1616
+ } catch (error) {
1617
+ if (error instanceof Error && error.message.includes("ns not found")) {
1618
+ return;
1619
+ }
1620
+ throw new MastraError(
1621
+ {
1622
+ id: "MONGODB_STORE_DROP_TABLE_FAILED",
1623
+ domain: ErrorDomain.STORAGE,
1624
+ category: ErrorCategory.THIRD_PARTY,
1625
+ details: { tableName }
1626
+ },
1627
+ error
1628
+ );
1629
+ }
1630
+ }
1631
+ processJsonbFields(tableName, record) {
1632
+ const schema = TABLE_SCHEMAS[tableName];
1633
+ if (!schema) {
1634
+ return record;
1635
+ }
1636
+ return Object.fromEntries(
1637
+ Object.entries(schema).map(([key, value]) => {
1638
+ if (value.type === "jsonb" && record[key] && typeof record[key] === "string") {
1639
+ return [key, safelyParseJSON(record[key])];
1640
+ }
1641
+ return [key, record[key]];
1642
+ })
1643
+ );
1644
+ }
1645
+ async insert({ tableName, record }) {
1646
+ try {
1647
+ const collection = await this.getCollection(tableName);
1648
+ const recordToInsert = this.processJsonbFields(tableName, record);
1649
+ await collection.insertOne(recordToInsert);
1650
+ } catch (error) {
1651
+ const mastraError = new MastraError(
1652
+ {
1653
+ id: "STORAGE_MONGODB_STORE_INSERT_FAILED",
1654
+ domain: ErrorDomain.STORAGE,
1655
+ category: ErrorCategory.THIRD_PARTY,
1656
+ details: { tableName }
1657
+ },
1658
+ error
1659
+ );
1660
+ this.logger.error(mastraError.message);
1661
+ this.logger?.trackException(mastraError);
1662
+ throw mastraError;
1663
+ }
1664
+ }
1665
+ async batchInsert({ tableName, records }) {
1666
+ if (!records.length) {
1667
+ return;
1668
+ }
1669
+ try {
1670
+ const collection = await this.getCollection(tableName);
1671
+ const processedRecords = records.map((record) => this.processJsonbFields(tableName, record));
1672
+ await collection.insertMany(processedRecords);
1673
+ } catch (error) {
1674
+ throw new MastraError(
1675
+ {
1676
+ id: "STORAGE_MONGODB_STORE_BATCH_INSERT_FAILED",
1677
+ domain: ErrorDomain.STORAGE,
1678
+ category: ErrorCategory.THIRD_PARTY,
1679
+ details: { tableName }
1680
+ },
1681
+ error
1682
+ );
1683
+ }
1684
+ }
1685
+ async load({ tableName, keys }) {
1686
+ this.logger.info(`Loading ${tableName} with keys ${JSON.stringify(keys)}`);
1687
+ try {
1688
+ const collection = await this.getCollection(tableName);
1689
+ return await collection.find(keys).toArray();
1690
+ } catch (error) {
1691
+ throw new MastraError(
1692
+ {
1693
+ id: "STORAGE_MONGODB_STORE_LOAD_FAILED",
1694
+ domain: ErrorDomain.STORAGE,
1695
+ category: ErrorCategory.THIRD_PARTY,
1696
+ details: { tableName }
1697
+ },
1698
+ error
1699
+ );
1700
+ }
1701
+ }
1702
+ async update({
1703
+ tableName,
1704
+ keys,
1705
+ data
1706
+ }) {
1707
+ try {
1708
+ const collection = await this.getCollection(tableName);
1709
+ const processedData = this.processJsonbFields(tableName, data);
1710
+ const cleanData = Object.fromEntries(Object.entries(processedData).filter(([_, value]) => value !== void 0));
1711
+ await collection.updateOne(keys, { $set: cleanData });
1712
+ } catch (error) {
1713
+ throw new MastraError(
1714
+ {
1715
+ id: "STORAGE_MONGODB_STORE_UPDATE_FAILED",
1716
+ domain: ErrorDomain.STORAGE,
1717
+ category: ErrorCategory.THIRD_PARTY,
1718
+ details: { tableName }
1719
+ },
1720
+ error
1721
+ );
1722
+ }
1723
+ }
1724
+ async batchUpdate({
1725
+ tableName,
1726
+ updates
1727
+ }) {
1728
+ if (!updates.length) {
1729
+ return;
1730
+ }
1731
+ try {
1732
+ const collection = await this.getCollection(tableName);
1733
+ const bulkOps = updates.map(({ keys, data }) => {
1734
+ const processedData = this.processJsonbFields(tableName, data);
1735
+ const cleanData = Object.fromEntries(Object.entries(processedData).filter(([_, value]) => value !== void 0));
1736
+ return {
1737
+ updateOne: {
1738
+ filter: keys,
1739
+ update: { $set: cleanData }
1740
+ }
1741
+ };
1742
+ });
1743
+ await collection.bulkWrite(bulkOps);
1744
+ } catch (error) {
1745
+ throw new MastraError(
1746
+ {
1747
+ id: "STORAGE_MONGODB_STORE_BATCH_UPDATE_FAILED",
1748
+ domain: ErrorDomain.STORAGE,
1749
+ category: ErrorCategory.THIRD_PARTY,
1750
+ details: { tableName }
1751
+ },
1752
+ error
1753
+ );
1754
+ }
1755
+ }
1756
+ };
1757
+ function transformScoreRow(row) {
1758
+ let scorerValue = null;
1759
+ if (row.scorer) {
1760
+ try {
1761
+ scorerValue = typeof row.scorer === "string" ? safelyParseJSON(row.scorer) : row.scorer;
1762
+ } catch (e) {
1763
+ console.warn("Failed to parse scorer:", e);
1764
+ }
1765
+ }
1766
+ let preprocessStepResultValue = null;
1767
+ if (row.preprocessStepResult) {
1768
+ try {
1769
+ preprocessStepResultValue = typeof row.preprocessStepResult === "string" ? safelyParseJSON(row.preprocessStepResult) : row.preprocessStepResult;
1770
+ } catch (e) {
1771
+ console.warn("Failed to parse preprocessStepResult:", e);
1772
+ }
1773
+ }
1774
+ let analyzeStepResultValue = null;
1775
+ if (row.analyzeStepResult) {
1776
+ try {
1777
+ analyzeStepResultValue = typeof row.analyzeStepResult === "string" ? safelyParseJSON(row.analyzeStepResult) : row.analyzeStepResult;
1778
+ } catch (e) {
1779
+ console.warn("Failed to parse analyzeStepResult:", e);
1780
+ }
1781
+ }
1782
+ let inputValue = null;
1783
+ if (row.input) {
1784
+ try {
1785
+ inputValue = typeof row.input === "string" ? safelyParseJSON(row.input) : row.input;
1786
+ } catch (e) {
1787
+ console.warn("Failed to parse input:", e);
1788
+ }
1789
+ }
1790
+ let outputValue = null;
1791
+ if (row.output) {
1792
+ try {
1793
+ outputValue = typeof row.output === "string" ? safelyParseJSON(row.output) : row.output;
1794
+ } catch (e) {
1795
+ console.warn("Failed to parse output:", e);
1796
+ }
1797
+ }
1798
+ let entityValue = null;
1799
+ if (row.entity) {
1800
+ try {
1801
+ entityValue = typeof row.entity === "string" ? safelyParseJSON(row.entity) : row.entity;
1802
+ } catch (e) {
1803
+ console.warn("Failed to parse entity:", e);
1804
+ }
1805
+ }
1806
+ let requestContextValue = null;
1807
+ if (row.requestContext) {
1808
+ try {
1809
+ requestContextValue = typeof row.requestContext === "string" ? safelyParseJSON(row.requestContext) : row.requestContext;
1810
+ } catch (e) {
1811
+ console.warn("Failed to parse requestContext:", e);
1812
+ }
1813
+ }
1814
+ let metadataValue = null;
1815
+ if (row.metadata) {
1816
+ try {
1817
+ metadataValue = typeof row.metadata === "string" ? safelyParseJSON(row.metadata) : row.metadata;
1818
+ } catch (e) {
1819
+ console.warn("Failed to parse metadata:", e);
1820
+ }
1821
+ }
1822
+ return {
1823
+ id: row.id,
1824
+ entityId: row.entityId,
1825
+ entityType: row.entityType,
1826
+ scorerId: row.scorerId,
1827
+ traceId: row.traceId,
1828
+ spanId: row.spanId,
1829
+ runId: row.runId,
1830
+ scorer: scorerValue,
1831
+ preprocessStepResult: preprocessStepResultValue,
1832
+ preprocessPrompt: row.preprocessPrompt,
1833
+ analyzeStepResult: analyzeStepResultValue,
1834
+ generateScorePrompt: row.generateScorePrompt,
1835
+ score: row.score,
1836
+ analyzePrompt: row.analyzePrompt,
1837
+ reasonPrompt: row.reasonPrompt,
1838
+ metadata: metadataValue,
1839
+ input: inputValue,
1840
+ output: outputValue,
1841
+ additionalContext: row.additionalContext,
1842
+ requestContext: requestContextValue,
1843
+ entity: entityValue,
1844
+ source: row.source,
1845
+ resourceId: row.resourceId,
1846
+ threadId: row.threadId,
1847
+ createdAt: new Date(row.createdAt),
1848
+ updatedAt: new Date(row.updatedAt)
1849
+ };
1850
+ }
1851
+ var ScoresStorageMongoDB = class extends ScoresStorage {
1852
+ operations;
1853
+ constructor({ operations }) {
1854
+ super();
1855
+ this.operations = operations;
1856
+ }
1857
+ async getScoreById({ id }) {
1858
+ try {
1859
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1860
+ const document = await collection.findOne({ id });
1861
+ if (!document) {
1862
+ return null;
1863
+ }
1864
+ return transformScoreRow(document);
1865
+ } catch (error) {
1866
+ throw new MastraError(
1867
+ {
1868
+ id: "STORAGE_MONGODB_STORE_GET_SCORE_BY_ID_FAILED",
1869
+ domain: ErrorDomain.STORAGE,
1870
+ category: ErrorCategory.THIRD_PARTY,
1871
+ details: { id }
1872
+ },
1873
+ error
1874
+ );
1875
+ }
1876
+ }
1877
+ async saveScore(score) {
1878
+ let validatedScore;
1879
+ try {
1880
+ validatedScore = saveScorePayloadSchema.parse(score);
1881
+ } catch (error) {
1882
+ throw new MastraError(
1883
+ {
1884
+ id: "STORAGE_MONGODB_STORE_SAVE_SCORE_VALIDATION_FAILED",
1885
+ domain: ErrorDomain.STORAGE,
1886
+ category: ErrorCategory.THIRD_PARTY
1887
+ },
1888
+ error
1889
+ );
1890
+ }
1891
+ try {
1892
+ const now = /* @__PURE__ */ new Date();
1893
+ const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1894
+ const scoreData = {
1895
+ id: scoreId,
1896
+ entityId: validatedScore.entityId,
1897
+ entityType: validatedScore.entityType,
1898
+ scorerId: validatedScore.scorerId,
1899
+ traceId: validatedScore.traceId || "",
1900
+ spanId: validatedScore.spanId || "",
1901
+ runId: validatedScore.runId,
1902
+ scorer: typeof validatedScore.scorer === "string" ? safelyParseJSON(validatedScore.scorer) : validatedScore.scorer,
1903
+ preprocessStepResult: typeof validatedScore.preprocessStepResult === "string" ? safelyParseJSON(validatedScore.preprocessStepResult) : validatedScore.preprocessStepResult,
1904
+ analyzeStepResult: typeof validatedScore.analyzeStepResult === "string" ? safelyParseJSON(validatedScore.analyzeStepResult) : validatedScore.analyzeStepResult,
1905
+ score: validatedScore.score,
1906
+ reason: validatedScore.reason,
1907
+ preprocessPrompt: validatedScore.preprocessPrompt,
1908
+ generateScorePrompt: validatedScore.generateScorePrompt,
1909
+ generateReasonPrompt: validatedScore.generateReasonPrompt,
1910
+ analyzePrompt: validatedScore.analyzePrompt,
1911
+ input: typeof validatedScore.input === "string" ? safelyParseJSON(validatedScore.input) : validatedScore.input,
1912
+ output: typeof validatedScore.output === "string" ? safelyParseJSON(validatedScore.output) : validatedScore.output,
1913
+ additionalContext: validatedScore.additionalContext,
1914
+ requestContext: typeof validatedScore.requestContext === "string" ? safelyParseJSON(validatedScore.requestContext) : validatedScore.requestContext,
1915
+ entity: typeof validatedScore.entity === "string" ? safelyParseJSON(validatedScore.entity) : validatedScore.entity,
1916
+ source: validatedScore.source,
1917
+ resourceId: validatedScore.resourceId || "",
1918
+ threadId: validatedScore.threadId || "",
1919
+ createdAt: now,
1920
+ updatedAt: now
1921
+ };
1922
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1923
+ await collection.insertOne(scoreData);
1924
+ const savedScore = {
1925
+ ...score,
1926
+ id: scoreId,
1927
+ createdAt: now,
1928
+ updatedAt: now
1929
+ };
1930
+ return { score: savedScore };
1931
+ } catch (error) {
1932
+ throw new MastraError(
1933
+ {
1934
+ id: "STORAGE_MONGODB_STORE_SAVE_SCORE_FAILED",
1935
+ domain: ErrorDomain.STORAGE,
1936
+ category: ErrorCategory.THIRD_PARTY,
1937
+ details: { scorerId: score.scorerId, runId: score.runId }
1938
+ },
1939
+ error
1940
+ );
1941
+ }
1942
+ }
1943
+ async listScoresByScorerId({
1944
+ scorerId,
1945
+ pagination,
1946
+ entityId,
1947
+ entityType,
1948
+ source
1949
+ }) {
1950
+ try {
1951
+ const { page, perPage: perPageInput } = pagination;
1952
+ const perPage = normalizePerPage(perPageInput, 100);
1953
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1954
+ const query = { scorerId };
1955
+ if (entityId) {
1956
+ query.entityId = entityId;
1957
+ }
1958
+ if (entityType) {
1959
+ query.entityType = entityType;
1960
+ }
1961
+ if (source) {
1962
+ query.source = source;
1963
+ }
1964
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
1965
+ const total = await collection.countDocuments(query);
1966
+ if (total === 0) {
1967
+ return {
1968
+ scores: [],
1969
+ pagination: {
1970
+ total: 0,
1971
+ page,
1972
+ perPage: perPageInput,
1973
+ hasMore: false
1974
+ }
1975
+ };
1976
+ }
1977
+ const end = perPageInput === false ? total : start + perPage;
1978
+ let cursor = collection.find(query).sort({ createdAt: "desc" }).skip(start);
1979
+ if (perPageInput !== false) {
1980
+ cursor = cursor.limit(perPage);
1981
+ }
1982
+ const documents = await cursor.toArray();
1983
+ const scores = documents.map((row) => transformScoreRow(row));
1984
+ return {
1985
+ scores,
1986
+ pagination: {
1987
+ total,
1988
+ page,
1989
+ perPage: perPageForResponse,
1990
+ hasMore: end < total
1991
+ }
1992
+ };
1993
+ } catch (error) {
1994
+ throw new MastraError(
1995
+ {
1996
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_SCORER_ID_FAILED",
1997
+ domain: ErrorDomain.STORAGE,
1998
+ category: ErrorCategory.THIRD_PARTY,
1999
+ details: { scorerId, page: pagination.page, perPage: pagination.perPage }
2000
+ },
2001
+ error
2002
+ );
2003
+ }
2004
+ }
2005
+ async listScoresByRunId({
2006
+ runId,
2007
+ pagination
2008
+ }) {
2009
+ try {
2010
+ const { page, perPage: perPageInput } = pagination;
2011
+ const perPage = normalizePerPage(perPageInput, 100);
2012
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2013
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
2014
+ const total = await collection.countDocuments({ runId });
2015
+ if (total === 0) {
2016
+ return {
2017
+ scores: [],
2018
+ pagination: {
2019
+ total: 0,
2020
+ page,
2021
+ perPage: perPageInput,
2022
+ hasMore: false
2023
+ }
2024
+ };
2025
+ }
2026
+ const end = perPageInput === false ? total : start + perPage;
2027
+ let cursor = collection.find({ runId }).sort({ createdAt: "desc" }).skip(start);
2028
+ if (perPageInput !== false) {
2029
+ cursor = cursor.limit(perPage);
2030
+ }
2031
+ const documents = await cursor.toArray();
2032
+ const scores = documents.map((row) => transformScoreRow(row));
2033
+ return {
2034
+ scores,
2035
+ pagination: {
2036
+ total,
2037
+ page,
2038
+ perPage: perPageForResponse,
2039
+ hasMore: end < total
2040
+ }
2041
+ };
2042
+ } catch (error) {
2043
+ throw new MastraError(
2044
+ {
2045
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_RUN_ID_FAILED",
2046
+ domain: ErrorDomain.STORAGE,
2047
+ category: ErrorCategory.THIRD_PARTY,
2048
+ details: { runId, page: pagination.page, perPage: pagination.perPage }
2049
+ },
2050
+ error
2051
+ );
2052
+ }
2053
+ }
2054
+ async listScoresByEntityId({
2055
+ entityId,
2056
+ entityType,
2057
+ pagination
2058
+ }) {
2059
+ try {
2060
+ const { page, perPage: perPageInput } = pagination;
2061
+ const perPage = normalizePerPage(perPageInput, 100);
2062
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2063
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
2064
+ const total = await collection.countDocuments({ entityId, entityType });
2065
+ if (total === 0) {
2066
+ return {
2067
+ scores: [],
2068
+ pagination: {
2069
+ total: 0,
2070
+ page,
2071
+ perPage: perPageInput,
2072
+ hasMore: false
2073
+ }
2074
+ };
2075
+ }
2076
+ const end = perPageInput === false ? total : start + perPage;
2077
+ let cursor = collection.find({ entityId, entityType }).sort({ createdAt: "desc" }).skip(start);
2078
+ if (perPageInput !== false) {
2079
+ cursor = cursor.limit(perPage);
2080
+ }
2081
+ const documents = await cursor.toArray();
2082
+ const scores = documents.map((row) => transformScoreRow(row));
2083
+ return {
2084
+ scores,
2085
+ pagination: {
2086
+ total,
2087
+ page,
2088
+ perPage: perPageForResponse,
2089
+ hasMore: end < total
2090
+ }
2091
+ };
2092
+ } catch (error) {
2093
+ throw new MastraError(
2094
+ {
2095
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_ENTITY_ID_FAILED",
2096
+ domain: ErrorDomain.STORAGE,
2097
+ category: ErrorCategory.THIRD_PARTY,
2098
+ details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
2099
+ },
2100
+ error
2101
+ );
2102
+ }
2103
+ }
2104
+ async listScoresBySpan({
2105
+ traceId,
2106
+ spanId,
2107
+ pagination
2108
+ }) {
2109
+ try {
2110
+ const { page, perPage: perPageInput } = pagination;
2111
+ const perPage = normalizePerPage(perPageInput, 100);
2112
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2113
+ const query = { traceId, spanId };
2114
+ const collection = await this.operations.getCollection(TABLE_SCORERS);
2115
+ const total = await collection.countDocuments(query);
2116
+ if (total === 0) {
2117
+ return {
2118
+ scores: [],
2119
+ pagination: {
2120
+ total: 0,
2121
+ page,
2122
+ perPage: perPageInput,
2123
+ hasMore: false
2124
+ }
2125
+ };
2126
+ }
2127
+ const end = perPageInput === false ? total : start + perPage;
2128
+ let cursor = collection.find(query).sort({ createdAt: "desc" }).skip(start);
2129
+ if (perPageInput !== false) {
2130
+ cursor = cursor.limit(perPage);
2131
+ }
2132
+ const documents = await cursor.toArray();
2133
+ const scores = documents.map((row) => transformScoreRow(row));
2134
+ return {
2135
+ scores,
2136
+ pagination: {
2137
+ total,
2138
+ page,
2139
+ perPage: perPageForResponse,
2140
+ hasMore: end < total
2141
+ }
2142
+ };
2143
+ } catch (error) {
2144
+ throw new MastraError(
2145
+ {
2146
+ id: "STORAGE_MONGODB_STORE_GET_SCORES_BY_SPAN_FAILED",
2147
+ domain: ErrorDomain.STORAGE,
2148
+ category: ErrorCategory.THIRD_PARTY,
2149
+ details: { traceId, spanId, page: pagination.page, perPage: pagination.perPage }
2150
+ },
2151
+ error
2152
+ );
2153
+ }
2154
+ }
2155
+ };
2156
+ var WorkflowsStorageMongoDB = class extends WorkflowsStorage {
2157
+ operations;
2158
+ constructor({ operations }) {
2159
+ super();
2160
+ this.operations = operations;
2161
+ }
2162
+ updateWorkflowResults({
2163
+ // workflowName,
2164
+ // runId,
2165
+ // stepId,
2166
+ // result,
2167
+ // requestContext,
2168
+ }) {
2169
+ throw new Error("Method not implemented.");
2170
+ }
2171
+ updateWorkflowState({
2172
+ // workflowName,
2173
+ // runId,
2174
+ // opts,
2175
+ }) {
2176
+ throw new Error("Method not implemented.");
2177
+ }
2178
+ async persistWorkflowSnapshot({
2179
+ workflowName,
2180
+ runId,
2181
+ resourceId,
2182
+ snapshot
2183
+ }) {
2184
+ try {
2185
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
2186
+ await collection.updateOne(
2187
+ { workflow_name: workflowName, run_id: runId },
2188
+ {
2189
+ $set: {
2190
+ workflow_name: workflowName,
2191
+ run_id: runId,
2192
+ resourceId,
2193
+ snapshot,
2194
+ createdAt: /* @__PURE__ */ new Date(),
2195
+ updatedAt: /* @__PURE__ */ new Date()
2196
+ }
2197
+ },
2198
+ { upsert: true }
2199
+ );
2200
+ } catch (error) {
2201
+ throw new MastraError(
2202
+ {
2203
+ id: "STORAGE_MONGODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
2204
+ domain: ErrorDomain.STORAGE,
2205
+ category: ErrorCategory.THIRD_PARTY,
2206
+ details: { workflowName, runId }
2207
+ },
2208
+ error
2209
+ );
2210
+ }
2211
+ }
2212
+ async loadWorkflowSnapshot({
2213
+ workflowName,
2214
+ runId
2215
+ }) {
2216
+ try {
2217
+ const result = await this.operations.load({
2218
+ tableName: TABLE_WORKFLOW_SNAPSHOT,
2219
+ keys: {
2220
+ workflow_name: workflowName,
2221
+ run_id: runId
2222
+ }
2223
+ });
2224
+ if (!result?.length) {
2225
+ return null;
2226
+ }
2227
+ return typeof result[0].snapshot === "string" ? safelyParseJSON(result[0].snapshot) : result[0].snapshot;
2228
+ } catch (error) {
2229
+ throw new MastraError(
2230
+ {
2231
+ id: "STORAGE_MONGODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
2232
+ domain: ErrorDomain.STORAGE,
2233
+ category: ErrorCategory.THIRD_PARTY,
2234
+ details: { workflowName, runId }
2235
+ },
2236
+ error
2237
+ );
2238
+ }
2239
+ }
2240
+ async listWorkflowRuns(args) {
2241
+ const options = args || {};
2242
+ try {
2243
+ const query = {};
2244
+ if (options.workflowName) {
2245
+ query["workflow_name"] = options.workflowName;
2246
+ }
2247
+ if (options.status) {
2248
+ query["snapshot.status"] = options.status;
2249
+ }
2250
+ if (options.fromDate) {
2251
+ query["createdAt"] = { $gte: options.fromDate };
2252
+ }
2253
+ if (options.toDate) {
2254
+ if (query["createdAt"]) {
2255
+ query["createdAt"].$lte = options.toDate;
2256
+ } else {
2257
+ query["createdAt"] = { $lte: options.toDate };
2258
+ }
2259
+ }
2260
+ if (options.resourceId) {
2261
+ query["resourceId"] = options.resourceId;
2262
+ }
2263
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
2264
+ let total = 0;
2265
+ let cursor = collection.find(query).sort({ createdAt: -1 });
2266
+ if (options.page !== void 0 && typeof options.perPage === "number") {
2267
+ if (options.page < 0) {
2268
+ throw new MastraError(
2269
+ {
2270
+ id: "STORAGE_MONGODB_INVALID_PAGE",
2271
+ domain: ErrorDomain.STORAGE,
2272
+ category: ErrorCategory.USER,
2273
+ details: { page: options.page }
2274
+ },
2275
+ new Error("page must be >= 0")
2276
+ );
2277
+ }
2278
+ total = await collection.countDocuments(query);
2279
+ const normalizedPerPage = normalizePerPage(options.perPage, Number.MAX_SAFE_INTEGER);
2280
+ if (normalizedPerPage === 0) {
2281
+ return { runs: [], total };
2282
+ }
2283
+ const offset = options.page * normalizedPerPage;
2284
+ cursor = cursor.skip(offset);
2285
+ cursor = cursor.limit(Math.min(normalizedPerPage, 2147483647));
2286
+ }
2287
+ const results = await cursor.toArray();
2288
+ const runs = results.map((row) => this.parseWorkflowRun(row));
2289
+ return {
2290
+ runs,
2291
+ total: total || runs.length
2292
+ };
2293
+ } catch (error) {
2294
+ throw new MastraError(
2295
+ {
2296
+ id: "STORAGE_MONGODB_STORE_LIST_WORKFLOW_RUNS_FAILED",
2297
+ domain: ErrorDomain.STORAGE,
2298
+ category: ErrorCategory.THIRD_PARTY,
2299
+ details: { workflowName: options.workflowName || "unknown" }
2300
+ },
2301
+ error
2302
+ );
2303
+ }
2304
+ }
2305
+ async getWorkflowRunById(args) {
2306
+ try {
2307
+ const query = {};
2308
+ if (args.runId) {
2309
+ query["run_id"] = args.runId;
2310
+ }
2311
+ if (args.workflowName) {
2312
+ query["workflow_name"] = args.workflowName;
2313
+ }
2314
+ const collection = await this.operations.getCollection(TABLE_WORKFLOW_SNAPSHOT);
2315
+ const result = await collection.findOne(query);
2316
+ if (!result) {
2317
+ return null;
2318
+ }
2319
+ return this.parseWorkflowRun(result);
2320
+ } catch (error) {
2321
+ throw new MastraError(
2322
+ {
2323
+ id: "STORAGE_MONGODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2324
+ domain: ErrorDomain.STORAGE,
2325
+ category: ErrorCategory.THIRD_PARTY,
2326
+ details: { runId: args.runId }
2327
+ },
2328
+ error
2329
+ );
2330
+ }
2331
+ }
2332
+ parseWorkflowRun(row) {
2333
+ let parsedSnapshot = row.snapshot;
2334
+ if (typeof parsedSnapshot === "string") {
2335
+ try {
2336
+ parsedSnapshot = typeof row.snapshot === "string" ? safelyParseJSON(row.snapshot) : row.snapshot;
2337
+ } catch (e) {
2338
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
2339
+ }
2340
+ }
2341
+ return {
2342
+ workflowName: row.workflow_name,
2343
+ runId: row.run_id,
2344
+ snapshot: parsedSnapshot,
2345
+ createdAt: new Date(row.createdAt),
2346
+ updatedAt: new Date(row.updatedAt),
2347
+ resourceId: row.resourceId
2348
+ };
2349
+ }
2350
+ };
2351
+
2352
+ // src/storage/index.ts
2353
+ var loadConnector = (config) => {
2354
+ try {
2355
+ if ("connectorHandler" in config) {
2356
+ return MongoDBConnector.fromConnectionHandler(config.connectorHandler);
2357
+ }
2358
+ } catch (error) {
2359
+ throw new MastraError(
2360
+ {
2361
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2362
+ domain: ErrorDomain.STORAGE,
2363
+ category: ErrorCategory.USER,
2364
+ details: { connectionHandler: true }
2365
+ },
2366
+ error
2367
+ );
2368
+ }
2369
+ try {
2370
+ return MongoDBConnector.fromDatabaseConfig({
2371
+ id: config.id,
2372
+ options: config.options,
2373
+ url: config.url,
2374
+ dbName: config.dbName
2375
+ });
2376
+ } catch (error) {
2377
+ throw new MastraError(
2378
+ {
2379
+ id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
2380
+ domain: ErrorDomain.STORAGE,
2381
+ category: ErrorCategory.USER,
2382
+ details: { url: config?.url, dbName: config?.dbName }
2383
+ },
2384
+ error
2385
+ );
2386
+ }
2387
+ };
2388
+ var MongoDBStore = class extends MastraStorage {
2389
+ #connector;
2390
+ stores;
2391
+ get supports() {
2392
+ return {
2393
+ selectByIncludeResourceScope: true,
2394
+ resourceWorkingMemory: true,
2395
+ hasColumn: false,
2396
+ createTable: false,
2397
+ deleteMessages: false,
2398
+ listScoresBySpan: true
2399
+ };
2400
+ }
2401
+ constructor(config) {
2402
+ super({ id: config.id, name: "MongoDBStore" });
2403
+ this.stores = {};
2404
+ this.#connector = loadConnector(config);
2405
+ const operations = new StoreOperationsMongoDB({
2406
+ connector: this.#connector
2407
+ });
2408
+ const memory = new MemoryStorageMongoDB({
2409
+ operations
2410
+ });
2411
+ const scores = new ScoresStorageMongoDB({
2412
+ operations
2413
+ });
2414
+ const workflows = new WorkflowsStorageMongoDB({
2415
+ operations
2416
+ });
2417
+ const observability = new ObservabilityMongoDB({
2418
+ operations
2419
+ });
2420
+ this.stores = {
2421
+ operations,
2422
+ memory,
2423
+ scores,
2424
+ workflows,
2425
+ observability
2426
+ };
2427
+ }
2428
+ async createTable({
2429
+ tableName,
2430
+ schema
2431
+ }) {
2432
+ return this.stores.operations.createTable({ tableName, schema });
2433
+ }
2434
+ async alterTable(_args) {
2435
+ return this.stores.operations.alterTable(_args);
2436
+ }
2437
+ async dropTable({ tableName }) {
2438
+ return this.stores.operations.dropTable({ tableName });
2439
+ }
2440
+ async clearTable({ tableName }) {
2441
+ return this.stores.operations.clearTable({ tableName });
2442
+ }
2443
+ async insert({ tableName, record }) {
2444
+ return this.stores.operations.insert({ tableName, record });
2445
+ }
2446
+ async batchInsert({ tableName, records }) {
2447
+ return this.stores.operations.batchInsert({ tableName, records });
2448
+ }
2449
+ async load({ tableName, keys }) {
2450
+ return this.stores.operations.load({ tableName, keys });
2451
+ }
2452
+ async getThreadById({ threadId }) {
2453
+ return this.stores.memory.getThreadById({ threadId });
2454
+ }
2455
+ async saveThread({ thread }) {
2456
+ return this.stores.memory.saveThread({ thread });
2457
+ }
2458
+ async updateThread({
2459
+ id,
2460
+ title,
2461
+ metadata
2462
+ }) {
2463
+ return this.stores.memory.updateThread({ id, title, metadata });
2464
+ }
2465
+ async deleteThread({ threadId }) {
2466
+ return this.stores.memory.deleteThread({ threadId });
2467
+ }
2468
+ async listMessagesById({ messageIds }) {
2469
+ return this.stores.memory.listMessagesById({ messageIds });
2470
+ }
2471
+ async saveMessages(args) {
2472
+ return this.stores.memory.saveMessages(args);
2473
+ }
2474
+ async updateMessages(_args) {
2475
+ return this.stores.memory.updateMessages(_args);
2476
+ }
2477
+ async listWorkflowRuns(args) {
2478
+ return this.stores.workflows.listWorkflowRuns(args);
2479
+ }
2480
+ async updateWorkflowResults({
2481
+ workflowName,
2482
+ runId,
2483
+ stepId,
2484
+ result,
2485
+ requestContext
2486
+ }) {
2487
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
2488
+ }
2489
+ async updateWorkflowState({
2490
+ workflowName,
2491
+ runId,
2492
+ opts
2493
+ }) {
2494
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
2495
+ }
2496
+ async persistWorkflowSnapshot({
2497
+ workflowName,
2498
+ runId,
2499
+ resourceId,
2500
+ snapshot
2501
+ }) {
2502
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2503
+ }
2504
+ async loadWorkflowSnapshot({
2505
+ workflowName,
2506
+ runId
2507
+ }) {
2508
+ return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2509
+ }
2510
+ async getWorkflowRunById({
2511
+ runId,
2512
+ workflowName
2513
+ }) {
2514
+ return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
2515
+ }
2516
+ async close() {
2517
+ try {
2518
+ await this.#connector.close();
2519
+ } catch (error) {
2520
+ throw new MastraError(
2521
+ {
2522
+ id: "STORAGE_MONGODB_STORE_CLOSE_FAILED",
2523
+ domain: ErrorDomain.STORAGE,
2524
+ category: ErrorCategory.USER
2525
+ },
2526
+ error
2527
+ );
2528
+ }
2529
+ }
2530
+ /**
2531
+ * SCORERS
2532
+ */
2533
+ async getScoreById({ id }) {
2534
+ return this.stores.scores.getScoreById({ id });
2535
+ }
2536
+ async saveScore(score) {
2537
+ return this.stores.scores.saveScore(score);
2538
+ }
2539
+ async listScoresByRunId({
2540
+ runId,
2541
+ pagination
2542
+ }) {
2543
+ return this.stores.scores.listScoresByRunId({ runId, pagination });
2544
+ }
2545
+ async listScoresByEntityId({
2546
+ entityId,
2547
+ entityType,
2548
+ pagination
2549
+ }) {
2550
+ return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
2551
+ }
2552
+ async listScoresByScorerId({
2553
+ scorerId,
2554
+ pagination,
2555
+ entityId,
2556
+ entityType,
2557
+ source
2558
+ }) {
2559
+ return this.stores.scores.listScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
2560
+ }
2561
+ async listScoresBySpan({
2562
+ traceId,
2563
+ spanId,
2564
+ pagination
2565
+ }) {
2566
+ return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
2567
+ }
2568
+ /**
2569
+ * RESOURCES
2570
+ */
2571
+ async getResourceById({ resourceId }) {
2572
+ return this.stores.memory.getResourceById({ resourceId });
2573
+ }
2574
+ async saveResource({ resource }) {
2575
+ return this.stores.memory.saveResource({ resource });
2576
+ }
2577
+ async updateResource({
2578
+ resourceId,
2579
+ workingMemory,
2580
+ metadata
2581
+ }) {
2582
+ return this.stores.memory.updateResource({
2583
+ resourceId,
2584
+ workingMemory,
2585
+ metadata
2586
+ });
2587
+ }
2588
+ /**
2589
+ * Tracing/Observability
2590
+ */
2591
+ async createSpan(span) {
2592
+ if (!this.stores.observability) {
2593
+ throw new MastraError({
2594
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2595
+ domain: ErrorDomain.STORAGE,
2596
+ category: ErrorCategory.SYSTEM,
2597
+ text: "Observability storage is not initialized"
2598
+ });
2599
+ }
2600
+ return this.stores.observability.createSpan(span);
2601
+ }
2602
+ async updateSpan({
2603
+ spanId,
2604
+ traceId,
2605
+ updates
2606
+ }) {
2607
+ if (!this.stores.observability) {
2608
+ throw new MastraError({
2609
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2610
+ domain: ErrorDomain.STORAGE,
2611
+ category: ErrorCategory.SYSTEM,
2612
+ text: "Observability storage is not initialized"
2613
+ });
2614
+ }
2615
+ return this.stores.observability.updateSpan({ spanId, traceId, updates });
2616
+ }
2617
+ async getTrace(traceId) {
2618
+ if (!this.stores.observability) {
2619
+ throw new MastraError({
2620
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2621
+ domain: ErrorDomain.STORAGE,
2622
+ category: ErrorCategory.SYSTEM,
2623
+ text: "Observability storage is not initialized"
2624
+ });
2625
+ }
2626
+ return this.stores.observability.getTrace(traceId);
2627
+ }
2628
+ async getTracesPaginated(args) {
2629
+ if (!this.stores.observability) {
2630
+ throw new MastraError({
2631
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2632
+ domain: ErrorDomain.STORAGE,
2633
+ category: ErrorCategory.SYSTEM,
2634
+ text: "Observability storage is not initialized"
2635
+ });
2636
+ }
2637
+ return this.stores.observability.getTracesPaginated(args);
2638
+ }
2639
+ async batchCreateSpans(args) {
2640
+ if (!this.stores.observability) {
2641
+ throw new MastraError({
2642
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2643
+ domain: ErrorDomain.STORAGE,
2644
+ category: ErrorCategory.SYSTEM,
2645
+ text: "Observability storage is not initialized"
2646
+ });
2647
+ }
2648
+ return this.stores.observability.batchCreateSpans(args);
2649
+ }
2650
+ async batchUpdateSpans(args) {
2651
+ if (!this.stores.observability) {
2652
+ throw new MastraError({
2653
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2654
+ domain: ErrorDomain.STORAGE,
2655
+ category: ErrorCategory.SYSTEM,
2656
+ text: "Observability storage is not initialized"
2657
+ });
2658
+ }
2659
+ return this.stores.observability.batchUpdateSpans(args);
2660
+ }
2661
+ async batchDeleteTraces(args) {
2662
+ if (!this.stores.observability) {
2663
+ throw new MastraError({
2664
+ id: "MONGODB_STORE_OBSERVABILITY_NOT_INITIALIZED",
2665
+ domain: ErrorDomain.STORAGE,
2666
+ category: ErrorCategory.SYSTEM,
2667
+ text: "Observability storage is not initialized"
2668
+ });
2669
+ }
2670
+ return this.stores.observability.batchDeleteTraces(args);
2671
+ }
357
2672
  };
358
2673
 
359
2674
  // src/vector/prompt.ts
@@ -451,4 +2766,6 @@ Example Complex Query:
451
2766
  ]
452
2767
  }`;
453
2768
 
454
- export { MONGODB_PROMPT, MongoDBVector };
2769
+ export { MONGODB_PROMPT, MongoDBStore, MongoDBVector };
2770
+ //# sourceMappingURL=index.js.map
2771
+ //# sourceMappingURL=index.js.map