@mastra/mongodb 0.11.1-alpha.0 → 0.11.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +14 -0
- package/dist/index.cjs +537 -220
- package/dist/index.js +516 -199
- package/package.json +4 -4
- package/src/storage/index.ts +272 -100
- package/src/vector/index.ts +270 -125
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
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';
|
|
@@ -116,28 +117,68 @@ var MongoDBVector = class extends MastraVector {
|
|
|
116
117
|
}
|
|
117
118
|
// Public methods
|
|
118
119
|
async connect() {
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
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: [
|
|
@@ -154,10 +195,31 @@ var MongoDBVector = class extends MastraVector {
|
|
|
154
195
|
});
|
|
155
196
|
} catch (error) {
|
|
156
197
|
if (error.codeName !== "IndexAlreadyExists") {
|
|
157
|
-
throw
|
|
198
|
+
throw new MastraError(
|
|
199
|
+
{
|
|
200
|
+
id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED",
|
|
201
|
+
domain: ErrorDomain.STORAGE,
|
|
202
|
+
category: ErrorCategory.THIRD_PARTY
|
|
203
|
+
},
|
|
204
|
+
error
|
|
205
|
+
);
|
|
158
206
|
}
|
|
159
207
|
}
|
|
160
|
-
|
|
208
|
+
try {
|
|
209
|
+
await collection?.updateOne({ _id: "__index_metadata__" }, { $set: { dimension, metric } }, { upsert: true });
|
|
210
|
+
} catch (error) {
|
|
211
|
+
throw new MastraError(
|
|
212
|
+
{
|
|
213
|
+
id: "STORAGE_MONGODB_VECTOR_CREATE_INDEX_FAILED_STORE_METADATA",
|
|
214
|
+
domain: ErrorDomain.STORAGE,
|
|
215
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
216
|
+
details: {
|
|
217
|
+
indexName
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
error
|
|
221
|
+
);
|
|
222
|
+
}
|
|
161
223
|
}
|
|
162
224
|
/**
|
|
163
225
|
* Waits for the index to be ready.
|
|
@@ -187,40 +249,54 @@ var MongoDBVector = class extends MastraVector {
|
|
|
187
249
|
throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
|
|
188
250
|
}
|
|
189
251
|
async upsert({ indexName, vectors, metadata, ids, documents }) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
acc
|
|
202
|
-
|
|
252
|
+
try {
|
|
253
|
+
const collection = await this.getCollection(indexName);
|
|
254
|
+
this.collectionForValidation = collection;
|
|
255
|
+
const stats = await this.describeIndex({ indexName });
|
|
256
|
+
await this.validateVectorDimensions(vectors, stats.dimension);
|
|
257
|
+
const generatedIds = ids || vectors.map(() => v4());
|
|
258
|
+
const operations = vectors.map((vector, idx) => {
|
|
259
|
+
const id = generatedIds[idx];
|
|
260
|
+
const meta = metadata?.[idx] || {};
|
|
261
|
+
const doc = documents?.[idx];
|
|
262
|
+
const normalizedMeta = Object.keys(meta).reduce(
|
|
263
|
+
(acc, key) => {
|
|
264
|
+
acc[key] = meta[key] instanceof Date ? meta[key].toISOString() : meta[key];
|
|
265
|
+
return acc;
|
|
266
|
+
},
|
|
267
|
+
{}
|
|
268
|
+
);
|
|
269
|
+
const updateDoc = {
|
|
270
|
+
[this.embeddingFieldName]: vector,
|
|
271
|
+
[this.metadataFieldName]: normalizedMeta
|
|
272
|
+
};
|
|
273
|
+
if (doc !== void 0) {
|
|
274
|
+
updateDoc[this.documentFieldName] = doc;
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
updateOne: {
|
|
278
|
+
filter: { _id: id },
|
|
279
|
+
// '_id' is a string as per MongoDBDocument interface
|
|
280
|
+
update: { $set: updateDoc },
|
|
281
|
+
upsert: true
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
});
|
|
285
|
+
await collection.bulkWrite(operations);
|
|
286
|
+
return generatedIds;
|
|
287
|
+
} catch (error) {
|
|
288
|
+
throw new MastraError(
|
|
289
|
+
{
|
|
290
|
+
id: "STORAGE_MONGODB_VECTOR_UPSERT_FAILED",
|
|
291
|
+
domain: ErrorDomain.STORAGE,
|
|
292
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
293
|
+
details: {
|
|
294
|
+
indexName
|
|
295
|
+
}
|
|
203
296
|
},
|
|
204
|
-
|
|
297
|
+
error
|
|
205
298
|
);
|
|
206
|
-
|
|
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;
|
|
299
|
+
}
|
|
224
300
|
}
|
|
225
301
|
async query({
|
|
226
302
|
indexName,
|
|
@@ -230,44 +306,44 @@ var MongoDBVector = class extends MastraVector {
|
|
|
230
306
|
includeVector = false,
|
|
231
307
|
documentFilter
|
|
232
308
|
}) {
|
|
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}` }
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
];
|
|
270
309
|
try {
|
|
310
|
+
const collection = await this.getCollection(indexName, true);
|
|
311
|
+
const indexNameInternal = `${indexName}_vector_index`;
|
|
312
|
+
const mongoFilter = this.transformFilter(filter);
|
|
313
|
+
const documentMongoFilter = documentFilter ? { [this.documentFieldName]: documentFilter } : {};
|
|
314
|
+
let combinedFilter = {};
|
|
315
|
+
if (Object.keys(mongoFilter).length > 0 && Object.keys(documentMongoFilter).length > 0) {
|
|
316
|
+
combinedFilter = { $and: [mongoFilter, documentMongoFilter] };
|
|
317
|
+
} else if (Object.keys(mongoFilter).length > 0) {
|
|
318
|
+
combinedFilter = mongoFilter;
|
|
319
|
+
} else if (Object.keys(documentMongoFilter).length > 0) {
|
|
320
|
+
combinedFilter = documentMongoFilter;
|
|
321
|
+
}
|
|
322
|
+
const pipeline = [
|
|
323
|
+
{
|
|
324
|
+
$vectorSearch: {
|
|
325
|
+
index: indexNameInternal,
|
|
326
|
+
queryVector,
|
|
327
|
+
path: this.embeddingFieldName,
|
|
328
|
+
numCandidates: 100,
|
|
329
|
+
limit: topK
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
// Apply the filter using $match stage
|
|
333
|
+
...Object.keys(combinedFilter).length > 0 ? [{ $match: combinedFilter }] : [],
|
|
334
|
+
{
|
|
335
|
+
$set: { score: { $meta: "vectorSearchScore" } }
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
$project: {
|
|
339
|
+
_id: 1,
|
|
340
|
+
score: 1,
|
|
341
|
+
metadata: `$${this.metadataFieldName}`,
|
|
342
|
+
document: `$${this.documentFieldName}`,
|
|
343
|
+
...includeVector && { vector: `$${this.embeddingFieldName}` }
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
];
|
|
271
347
|
const results = await collection.aggregate(pipeline).toArray();
|
|
272
348
|
return results.map((result) => ({
|
|
273
349
|
id: result._id,
|
|
@@ -277,13 +353,33 @@ var MongoDBVector = class extends MastraVector {
|
|
|
277
353
|
document: result.document
|
|
278
354
|
}));
|
|
279
355
|
} catch (error) {
|
|
280
|
-
|
|
281
|
-
|
|
356
|
+
throw new MastraError(
|
|
357
|
+
{
|
|
358
|
+
id: "STORAGE_MONGODB_VECTOR_QUERY_FAILED",
|
|
359
|
+
domain: ErrorDomain.STORAGE,
|
|
360
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
361
|
+
details: {
|
|
362
|
+
indexName
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
error
|
|
366
|
+
);
|
|
282
367
|
}
|
|
283
368
|
}
|
|
284
369
|
async listIndexes() {
|
|
285
|
-
|
|
286
|
-
|
|
370
|
+
try {
|
|
371
|
+
const collections = await this.db.listCollections().toArray();
|
|
372
|
+
return collections.map((col) => col.name);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
throw new MastraError(
|
|
375
|
+
{
|
|
376
|
+
id: "STORAGE_MONGODB_VECTOR_LIST_INDEXES_FAILED",
|
|
377
|
+
domain: ErrorDomain.STORAGE,
|
|
378
|
+
category: ErrorCategory.THIRD_PARTY
|
|
379
|
+
},
|
|
380
|
+
error
|
|
381
|
+
);
|
|
382
|
+
}
|
|
287
383
|
}
|
|
288
384
|
/**
|
|
289
385
|
* Retrieves statistics about a vector index.
|
|
@@ -292,24 +388,52 @@ var MongoDBVector = class extends MastraVector {
|
|
|
292
388
|
* @returns A promise that resolves to the index statistics including dimension, count and metric
|
|
293
389
|
*/
|
|
294
390
|
async describeIndex({ indexName }) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
391
|
+
try {
|
|
392
|
+
const collection = await this.getCollection(indexName, true);
|
|
393
|
+
const count = await collection.countDocuments({ _id: { $ne: "__index_metadata__" } });
|
|
394
|
+
const metadataDoc = await collection.findOne({ _id: "__index_metadata__" });
|
|
395
|
+
const dimension = metadataDoc?.dimension || 0;
|
|
396
|
+
const metric = metadataDoc?.metric || "cosine";
|
|
397
|
+
return {
|
|
398
|
+
dimension,
|
|
399
|
+
count,
|
|
400
|
+
metric
|
|
401
|
+
};
|
|
402
|
+
} catch (error) {
|
|
403
|
+
throw new MastraError(
|
|
404
|
+
{
|
|
405
|
+
id: "STORAGE_MONGODB_VECTOR_DESCRIBE_INDEX_FAILED",
|
|
406
|
+
domain: ErrorDomain.STORAGE,
|
|
407
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
408
|
+
details: {
|
|
409
|
+
indexName
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
error
|
|
413
|
+
);
|
|
414
|
+
}
|
|
305
415
|
}
|
|
306
416
|
async deleteIndex({ indexName }) {
|
|
307
417
|
const collection = await this.getCollection(indexName, false);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
418
|
+
try {
|
|
419
|
+
if (collection) {
|
|
420
|
+
await collection.drop();
|
|
421
|
+
this.collections.delete(indexName);
|
|
422
|
+
} else {
|
|
423
|
+
throw new Error(`Index (Collection) "${indexName}" does not exist`);
|
|
424
|
+
}
|
|
425
|
+
} catch (error) {
|
|
426
|
+
throw new MastraError(
|
|
427
|
+
{
|
|
428
|
+
id: "STORAGE_MONGODB_VECTOR_DELETE_INDEX_FAILED",
|
|
429
|
+
domain: ErrorDomain.STORAGE,
|
|
430
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
431
|
+
details: {
|
|
432
|
+
indexName
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
error
|
|
436
|
+
);
|
|
313
437
|
}
|
|
314
438
|
}
|
|
315
439
|
/**
|
|
@@ -346,7 +470,18 @@ var MongoDBVector = class extends MastraVector {
|
|
|
346
470
|
}
|
|
347
471
|
await collection.findOneAndUpdate({ _id: id }, { $set: updateDoc });
|
|
348
472
|
} catch (error) {
|
|
349
|
-
throw new
|
|
473
|
+
throw new MastraError(
|
|
474
|
+
{
|
|
475
|
+
id: "STORAGE_MONGODB_VECTOR_UPDATE_VECTOR_FAILED",
|
|
476
|
+
domain: ErrorDomain.STORAGE,
|
|
477
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
478
|
+
details: {
|
|
479
|
+
indexName,
|
|
480
|
+
id
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
error
|
|
484
|
+
);
|
|
350
485
|
}
|
|
351
486
|
}
|
|
352
487
|
/**
|
|
@@ -361,7 +496,18 @@ var MongoDBVector = class extends MastraVector {
|
|
|
361
496
|
const collection = await this.getCollection(indexName, true);
|
|
362
497
|
await collection.deleteOne({ _id: id });
|
|
363
498
|
} catch (error) {
|
|
364
|
-
throw new
|
|
499
|
+
throw new MastraError(
|
|
500
|
+
{
|
|
501
|
+
id: "STORAGE_MONGODB_VECTOR_DELETE_VECTOR_FAILED",
|
|
502
|
+
domain: ErrorDomain.STORAGE,
|
|
503
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
504
|
+
details: {
|
|
505
|
+
indexName,
|
|
506
|
+
id
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
error
|
|
510
|
+
);
|
|
365
511
|
}
|
|
366
512
|
}
|
|
367
513
|
// Private methods
|
|
@@ -417,14 +563,26 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
417
563
|
constructor(config) {
|
|
418
564
|
super({ name: "MongoDBStore" });
|
|
419
565
|
this.#isConnected = false;
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
566
|
+
try {
|
|
567
|
+
if (!config.url?.trim().length) {
|
|
568
|
+
throw new Error(
|
|
569
|
+
"MongoDBStore: url must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
if (!config.dbName?.trim().length) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
"MongoDBStore: dbName must be provided and cannot be empty. Passing an empty string may cause fallback to local MongoDB defaults."
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
} catch (error) {
|
|
578
|
+
throw new MastraError(
|
|
579
|
+
{
|
|
580
|
+
id: "STORAGE_MONGODB_STORE_CONSTRUCTOR_FAILED",
|
|
581
|
+
domain: ErrorDomain.STORAGE,
|
|
582
|
+
category: ErrorCategory.USER,
|
|
583
|
+
details: { url: config.url, dbName: config.dbName }
|
|
584
|
+
},
|
|
585
|
+
error
|
|
428
586
|
);
|
|
429
587
|
}
|
|
430
588
|
this.#dbName = config.dbName;
|
|
@@ -459,7 +617,17 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
459
617
|
await collection.deleteMany({});
|
|
460
618
|
} catch (error) {
|
|
461
619
|
if (error instanceof Error) {
|
|
462
|
-
|
|
620
|
+
const matstraError = new MastraError(
|
|
621
|
+
{
|
|
622
|
+
id: "STORAGE_MONGODB_STORE_CLEAR_TABLE_FAILED",
|
|
623
|
+
domain: ErrorDomain.STORAGE,
|
|
624
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
625
|
+
details: { tableName }
|
|
626
|
+
},
|
|
627
|
+
error
|
|
628
|
+
);
|
|
629
|
+
this.logger.error(matstraError.message);
|
|
630
|
+
this.logger?.trackException(matstraError);
|
|
463
631
|
}
|
|
464
632
|
}
|
|
465
633
|
}
|
|
@@ -468,8 +636,19 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
468
636
|
const collection = await this.getCollection(tableName);
|
|
469
637
|
await collection.insertOne(record);
|
|
470
638
|
} catch (error) {
|
|
471
|
-
|
|
472
|
-
|
|
639
|
+
if (error instanceof Error) {
|
|
640
|
+
const matstraError = new MastraError(
|
|
641
|
+
{
|
|
642
|
+
id: "STORAGE_MONGODB_STORE_INSERT_FAILED",
|
|
643
|
+
domain: ErrorDomain.STORAGE,
|
|
644
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
645
|
+
details: { tableName }
|
|
646
|
+
},
|
|
647
|
+
error
|
|
648
|
+
);
|
|
649
|
+
this.logger.error(matstraError.message);
|
|
650
|
+
this.logger?.trackException(matstraError);
|
|
651
|
+
}
|
|
473
652
|
}
|
|
474
653
|
}
|
|
475
654
|
async batchInsert({ tableName, records }) {
|
|
@@ -480,8 +659,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
480
659
|
const collection = await this.getCollection(tableName);
|
|
481
660
|
await collection.insertMany(records);
|
|
482
661
|
} catch (error) {
|
|
483
|
-
|
|
484
|
-
|
|
662
|
+
throw new MastraError(
|
|
663
|
+
{
|
|
664
|
+
id: "STORAGE_MONGODB_STORE_BATCH_INSERT_FAILED",
|
|
665
|
+
domain: ErrorDomain.STORAGE,
|
|
666
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
667
|
+
details: { tableName }
|
|
668
|
+
},
|
|
669
|
+
error
|
|
670
|
+
);
|
|
485
671
|
}
|
|
486
672
|
}
|
|
487
673
|
async load({ tableName, keys }) {
|
|
@@ -490,8 +676,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
490
676
|
const collection = await this.getCollection(tableName);
|
|
491
677
|
return await collection.find(keys).toArray();
|
|
492
678
|
} catch (error) {
|
|
493
|
-
|
|
494
|
-
|
|
679
|
+
throw new MastraError(
|
|
680
|
+
{
|
|
681
|
+
id: "STORAGE_MONGODB_STORE_LOAD_FAILED",
|
|
682
|
+
domain: ErrorDomain.STORAGE,
|
|
683
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
684
|
+
details: { tableName }
|
|
685
|
+
},
|
|
686
|
+
error
|
|
687
|
+
);
|
|
495
688
|
}
|
|
496
689
|
}
|
|
497
690
|
async getThreadById({ threadId }) {
|
|
@@ -506,8 +699,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
506
699
|
metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
|
|
507
700
|
};
|
|
508
701
|
} catch (error) {
|
|
509
|
-
|
|
510
|
-
|
|
702
|
+
throw new MastraError(
|
|
703
|
+
{
|
|
704
|
+
id: "STORAGE_MONGODB_STORE_GET_THREAD_BY_ID_FAILED",
|
|
705
|
+
domain: ErrorDomain.STORAGE,
|
|
706
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
707
|
+
details: { threadId }
|
|
708
|
+
},
|
|
709
|
+
error
|
|
710
|
+
);
|
|
511
711
|
}
|
|
512
712
|
}
|
|
513
713
|
async getThreadsByResourceId({ resourceId }) {
|
|
@@ -522,8 +722,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
522
722
|
metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
|
|
523
723
|
}));
|
|
524
724
|
} catch (error) {
|
|
525
|
-
|
|
526
|
-
|
|
725
|
+
throw new MastraError(
|
|
726
|
+
{
|
|
727
|
+
id: "STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
|
|
728
|
+
domain: ErrorDomain.STORAGE,
|
|
729
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
730
|
+
details: { resourceId }
|
|
731
|
+
},
|
|
732
|
+
error
|
|
733
|
+
);
|
|
527
734
|
}
|
|
528
735
|
}
|
|
529
736
|
async saveThread({ thread }) {
|
|
@@ -541,8 +748,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
541
748
|
);
|
|
542
749
|
return thread;
|
|
543
750
|
} catch (error) {
|
|
544
|
-
|
|
545
|
-
|
|
751
|
+
throw new MastraError(
|
|
752
|
+
{
|
|
753
|
+
id: "STORAGE_MONGODB_STORE_SAVE_THREAD_FAILED",
|
|
754
|
+
domain: ErrorDomain.STORAGE,
|
|
755
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
756
|
+
details: { threadId: thread.id }
|
|
757
|
+
},
|
|
758
|
+
error
|
|
759
|
+
);
|
|
546
760
|
}
|
|
547
761
|
}
|
|
548
762
|
async updateThread({
|
|
@@ -552,7 +766,13 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
552
766
|
}) {
|
|
553
767
|
const thread = await this.getThreadById({ threadId: id });
|
|
554
768
|
if (!thread) {
|
|
555
|
-
throw new
|
|
769
|
+
throw new MastraError({
|
|
770
|
+
id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_NOT_FOUND",
|
|
771
|
+
domain: ErrorDomain.STORAGE,
|
|
772
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
773
|
+
details: { threadId: id },
|
|
774
|
+
text: `Thread ${id} not found`
|
|
775
|
+
});
|
|
556
776
|
}
|
|
557
777
|
const updatedThread = {
|
|
558
778
|
...thread,
|
|
@@ -574,8 +794,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
574
794
|
}
|
|
575
795
|
);
|
|
576
796
|
} catch (error) {
|
|
577
|
-
|
|
578
|
-
|
|
797
|
+
throw new MastraError(
|
|
798
|
+
{
|
|
799
|
+
id: "STORAGE_MONGODB_STORE_UPDATE_THREAD_FAILED",
|
|
800
|
+
domain: ErrorDomain.STORAGE,
|
|
801
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
802
|
+
details: { threadId: id }
|
|
803
|
+
},
|
|
804
|
+
error
|
|
805
|
+
);
|
|
579
806
|
}
|
|
580
807
|
return updatedThread;
|
|
581
808
|
}
|
|
@@ -586,8 +813,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
586
813
|
const collectionThreads = await this.getCollection(TABLE_THREADS);
|
|
587
814
|
await collectionThreads.deleteOne({ id: threadId });
|
|
588
815
|
} catch (error) {
|
|
589
|
-
|
|
590
|
-
|
|
816
|
+
throw new MastraError(
|
|
817
|
+
{
|
|
818
|
+
id: "STORAGE_MONGODB_STORE_DELETE_THREAD_FAILED",
|
|
819
|
+
domain: ErrorDomain.STORAGE,
|
|
820
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
821
|
+
details: { threadId }
|
|
822
|
+
},
|
|
823
|
+
error
|
|
824
|
+
);
|
|
591
825
|
}
|
|
592
826
|
}
|
|
593
827
|
async getMessages({
|
|
@@ -596,7 +830,7 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
596
830
|
format
|
|
597
831
|
}) {
|
|
598
832
|
try {
|
|
599
|
-
const limit =
|
|
833
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
600
834
|
const include = selectBy?.include || [];
|
|
601
835
|
let messages = [];
|
|
602
836
|
let allMessages = [];
|
|
@@ -637,8 +871,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
637
871
|
if (format === `v2`) return list.get.all.v2();
|
|
638
872
|
return list.get.all.v1();
|
|
639
873
|
} catch (error) {
|
|
640
|
-
|
|
641
|
-
|
|
874
|
+
throw new MastraError(
|
|
875
|
+
{
|
|
876
|
+
id: "STORAGE_MONGODB_STORE_GET_MESSAGES_FAILED",
|
|
877
|
+
domain: ErrorDomain.STORAGE,
|
|
878
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
879
|
+
details: { threadId }
|
|
880
|
+
},
|
|
881
|
+
error
|
|
882
|
+
);
|
|
642
883
|
}
|
|
643
884
|
}
|
|
644
885
|
async saveMessages({
|
|
@@ -710,26 +951,37 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
710
951
|
query[key] = value;
|
|
711
952
|
});
|
|
712
953
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
954
|
+
try {
|
|
955
|
+
const collection = await this.getCollection(TABLE_TRACES);
|
|
956
|
+
const result = await collection.find(query, {
|
|
957
|
+
sort: { startTime: -1 }
|
|
958
|
+
}).limit(limit).skip(offset).toArray();
|
|
959
|
+
return result.map((row) => ({
|
|
960
|
+
id: row.id,
|
|
961
|
+
parentSpanId: row.parentSpanId,
|
|
962
|
+
traceId: row.traceId,
|
|
963
|
+
name: row.name,
|
|
964
|
+
scope: row.scope,
|
|
965
|
+
kind: row.kind,
|
|
966
|
+
status: safelyParseJSON(row.status),
|
|
967
|
+
events: safelyParseJSON(row.events),
|
|
968
|
+
links: safelyParseJSON(row.links),
|
|
969
|
+
attributes: safelyParseJSON(row.attributes),
|
|
970
|
+
startTime: row.startTime,
|
|
971
|
+
endTime: row.endTime,
|
|
972
|
+
other: safelyParseJSON(row.other),
|
|
973
|
+
createdAt: row.createdAt
|
|
974
|
+
}));
|
|
975
|
+
} catch (error) {
|
|
976
|
+
throw new MastraError(
|
|
977
|
+
{
|
|
978
|
+
id: "STORAGE_MONGODB_STORE_GET_TRACES_FAILED",
|
|
979
|
+
domain: ErrorDomain.STORAGE,
|
|
980
|
+
category: ErrorCategory.THIRD_PARTY
|
|
981
|
+
},
|
|
982
|
+
error
|
|
983
|
+
);
|
|
984
|
+
}
|
|
733
985
|
}
|
|
734
986
|
async getWorkflowRuns({
|
|
735
987
|
workflowName,
|
|
@@ -751,37 +1003,48 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
751
1003
|
query["createdAt"]["$lte"] = toDate;
|
|
752
1004
|
}
|
|
753
1005
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
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
|
-
}
|
|
1006
|
+
try {
|
|
1007
|
+
const collection = await this.getCollection(TABLE_WORKFLOW_SNAPSHOT);
|
|
1008
|
+
let total = 0;
|
|
1009
|
+
if (limit !== void 0 && offset !== void 0) {
|
|
1010
|
+
total = await collection.countDocuments(query);
|
|
775
1011
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
|
|
1012
|
+
const request = collection.find(query).sort({ createdAt: "desc" });
|
|
1013
|
+
if (limit) {
|
|
1014
|
+
request.limit(limit);
|
|
1015
|
+
}
|
|
1016
|
+
if (offset) {
|
|
1017
|
+
request.skip(offset);
|
|
1018
|
+
}
|
|
1019
|
+
const result = await request.toArray();
|
|
1020
|
+
const runs = result.map((row) => {
|
|
1021
|
+
let parsedSnapshot = row.snapshot;
|
|
1022
|
+
if (typeof parsedSnapshot === "string") {
|
|
1023
|
+
try {
|
|
1024
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1025
|
+
} catch (e) {
|
|
1026
|
+
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
return {
|
|
1030
|
+
workflowName: row.workflow_name,
|
|
1031
|
+
runId: row.run_id,
|
|
1032
|
+
snapshot: parsedSnapshot,
|
|
1033
|
+
createdAt: new Date(row.createdAt),
|
|
1034
|
+
updatedAt: new Date(row.updatedAt)
|
|
1035
|
+
};
|
|
1036
|
+
});
|
|
1037
|
+
return { runs, total: total || runs.length };
|
|
1038
|
+
} catch (error) {
|
|
1039
|
+
throw new MastraError(
|
|
1040
|
+
{
|
|
1041
|
+
id: "STORAGE_MONGODB_STORE_GET_WORKFLOW_RUNS_FAILED",
|
|
1042
|
+
domain: ErrorDomain.STORAGE,
|
|
1043
|
+
category: ErrorCategory.THIRD_PARTY
|
|
1044
|
+
},
|
|
1045
|
+
error
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
785
1048
|
}
|
|
786
1049
|
async getEvalsByAgentName(agentName, type) {
|
|
787
1050
|
try {
|
|
@@ -810,8 +1073,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
810
1073
|
if (error instanceof Error && error.message.includes("no such table")) {
|
|
811
1074
|
return [];
|
|
812
1075
|
}
|
|
813
|
-
|
|
814
|
-
|
|
1076
|
+
throw new MastraError(
|
|
1077
|
+
{
|
|
1078
|
+
id: "STORAGE_MONGODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
|
|
1079
|
+
domain: ErrorDomain.STORAGE,
|
|
1080
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1081
|
+
details: { agentName }
|
|
1082
|
+
},
|
|
1083
|
+
error
|
|
1084
|
+
);
|
|
815
1085
|
}
|
|
816
1086
|
}
|
|
817
1087
|
async persistWorkflowSnapshot({
|
|
@@ -836,8 +1106,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
836
1106
|
{ upsert: true }
|
|
837
1107
|
);
|
|
838
1108
|
} catch (error) {
|
|
839
|
-
|
|
840
|
-
|
|
1109
|
+
throw new MastraError(
|
|
1110
|
+
{
|
|
1111
|
+
id: "STORAGE_MONGODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
|
|
1112
|
+
domain: ErrorDomain.STORAGE,
|
|
1113
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1114
|
+
details: { workflowName, runId }
|
|
1115
|
+
},
|
|
1116
|
+
error
|
|
1117
|
+
);
|
|
841
1118
|
}
|
|
842
1119
|
}
|
|
843
1120
|
async loadWorkflowSnapshot({
|
|
@@ -857,8 +1134,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
857
1134
|
}
|
|
858
1135
|
return JSON.parse(result[0].snapshot);
|
|
859
1136
|
} catch (error) {
|
|
860
|
-
|
|
861
|
-
|
|
1137
|
+
throw new MastraError(
|
|
1138
|
+
{
|
|
1139
|
+
id: "STORAGE_MONGODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
|
|
1140
|
+
domain: ErrorDomain.STORAGE,
|
|
1141
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1142
|
+
details: { workflowName, runId }
|
|
1143
|
+
},
|
|
1144
|
+
error
|
|
1145
|
+
);
|
|
862
1146
|
}
|
|
863
1147
|
}
|
|
864
1148
|
async getWorkflowRunById({
|
|
@@ -880,8 +1164,15 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
880
1164
|
}
|
|
881
1165
|
return this.parseWorkflowRun(result);
|
|
882
1166
|
} catch (error) {
|
|
883
|
-
|
|
884
|
-
|
|
1167
|
+
throw new MastraError(
|
|
1168
|
+
{
|
|
1169
|
+
id: "STORAGE_MONGODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
|
|
1170
|
+
domain: ErrorDomain.STORAGE,
|
|
1171
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1172
|
+
details: { runId }
|
|
1173
|
+
},
|
|
1174
|
+
error
|
|
1175
|
+
);
|
|
885
1176
|
}
|
|
886
1177
|
}
|
|
887
1178
|
parseWorkflowRun(row) {
|
|
@@ -941,16 +1232,42 @@ var MongoDBStore = class extends MastraStorage {
|
|
|
941
1232
|
};
|
|
942
1233
|
}
|
|
943
1234
|
async getTracesPaginated(_args) {
|
|
944
|
-
throw new
|
|
1235
|
+
throw new MastraError({
|
|
1236
|
+
id: "STORAGE_MONGODB_STORE_GET_TRACES_PAGINATED_FAILED",
|
|
1237
|
+
domain: ErrorDomain.STORAGE,
|
|
1238
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1239
|
+
text: "Method not implemented."
|
|
1240
|
+
});
|
|
945
1241
|
}
|
|
946
1242
|
async getThreadsByResourceIdPaginated(_args) {
|
|
947
|
-
throw new
|
|
1243
|
+
throw new MastraError({
|
|
1244
|
+
id: "STORAGE_MONGODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
|
|
1245
|
+
domain: ErrorDomain.STORAGE,
|
|
1246
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1247
|
+
text: "Method not implemented."
|
|
1248
|
+
});
|
|
948
1249
|
}
|
|
949
1250
|
async getMessagesPaginated(_args) {
|
|
950
|
-
throw new
|
|
1251
|
+
throw new MastraError({
|
|
1252
|
+
id: "STORAGE_MONGODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
|
|
1253
|
+
domain: ErrorDomain.STORAGE,
|
|
1254
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1255
|
+
text: "Method not implemented."
|
|
1256
|
+
});
|
|
951
1257
|
}
|
|
952
1258
|
async close() {
|
|
953
|
-
|
|
1259
|
+
try {
|
|
1260
|
+
await this.#client.close();
|
|
1261
|
+
} catch (error) {
|
|
1262
|
+
throw new MastraError(
|
|
1263
|
+
{
|
|
1264
|
+
id: "STORAGE_MONGODB_STORE_CLOSE_FAILED",
|
|
1265
|
+
domain: ErrorDomain.STORAGE,
|
|
1266
|
+
category: ErrorCategory.USER
|
|
1267
|
+
},
|
|
1268
|
+
error
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
954
1271
|
}
|
|
955
1272
|
async updateMessages(_args) {
|
|
956
1273
|
this.logger.error("updateMessages is not yet implemented in MongoDBStore");
|