@mastra/mongodb 1.0.0-beta.9 → 1.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1095 -0
- package/README.md +18 -0
- package/dist/docs/README.md +34 -0
- package/dist/docs/SKILL.md +35 -0
- package/dist/docs/SOURCE_MAP.json +6 -0
- package/dist/docs/memory/01-working-memory.md +411 -0
- package/dist/docs/rag/01-vector-databases.md +643 -0
- package/dist/docs/rag/02-retrieval.md +548 -0
- package/dist/docs/storage/01-reference.md +243 -0
- package/dist/docs/vectors/01-reference.md +201 -0
- package/dist/index.cjs +526 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +528 -54
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/agents/index.d.ts +11 -1
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +2 -2
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +48 -5
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/types.d.ts +14 -2
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/vector/index.d.ts +17 -6
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +14 -13
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
|
-
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, createStorageErrorId, normalizePerPage, calculatePagination, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, safelyParseJSON, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT,
|
|
3
|
-
import { MastraVector } from '@mastra/core/vector';
|
|
2
|
+
import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, safelyParseJSON, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, ScoresStorage, TABLE_SCORERS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MastraCompositeStore, TraceStatus, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
|
|
3
|
+
import { MastraVector, validateUpsertInput, validateVectorValues } from '@mastra/core/vector';
|
|
4
4
|
import { MongoClient } from 'mongodb';
|
|
5
5
|
import { v4 } from 'uuid';
|
|
6
6
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
@@ -11,7 +11,7 @@ import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
|
11
11
|
|
|
12
12
|
// package.json
|
|
13
13
|
var package_default = {
|
|
14
|
-
version: "1.
|
|
14
|
+
version: "1.1.0-alpha.0"};
|
|
15
15
|
var MongoDBFilterTranslator = class extends BaseFilterTranslator {
|
|
16
16
|
getSupportedOperators() {
|
|
17
17
|
return {
|
|
@@ -105,7 +105,7 @@ var MongoDBVector = class extends MastraVector {
|
|
|
105
105
|
client;
|
|
106
106
|
db;
|
|
107
107
|
collections;
|
|
108
|
-
embeddingFieldName
|
|
108
|
+
embeddingFieldName;
|
|
109
109
|
metadataFieldName = "metadata";
|
|
110
110
|
documentFieldName = "document";
|
|
111
111
|
collectionForValidation = null;
|
|
@@ -114,8 +114,11 @@ var MongoDBVector = class extends MastraVector {
|
|
|
114
114
|
euclidean: "euclidean",
|
|
115
115
|
dotproduct: "dotProduct"
|
|
116
116
|
};
|
|
117
|
-
constructor({ id, uri, dbName, options }) {
|
|
117
|
+
constructor({ id, uri, dbName, options, embeddingFieldPath }) {
|
|
118
118
|
super({ id });
|
|
119
|
+
if (!uri) {
|
|
120
|
+
throw new Error('MongoDBVector requires a connection string. Provide "uri" in the constructor options.');
|
|
121
|
+
}
|
|
119
122
|
const client = new MongoClient(uri, {
|
|
120
123
|
...options,
|
|
121
124
|
driverInfo: {
|
|
@@ -126,6 +129,7 @@ var MongoDBVector = class extends MastraVector {
|
|
|
126
129
|
this.client = client;
|
|
127
130
|
this.db = this.client.db(dbName);
|
|
128
131
|
this.collections = /* @__PURE__ */ new Map();
|
|
132
|
+
this.embeddingFieldName = embeddingFieldPath ?? "embedding";
|
|
129
133
|
}
|
|
130
134
|
// Public methods
|
|
131
135
|
async connect() {
|
|
@@ -274,6 +278,8 @@ var MongoDBVector = class extends MastraVector {
|
|
|
274
278
|
throw new Error(`Index "${indexNameInternal}" did not become ready within timeout`);
|
|
275
279
|
}
|
|
276
280
|
async upsert({ indexName, vectors, metadata, ids, documents }) {
|
|
281
|
+
validateUpsertInput("MONGODB", vectors, metadata, ids);
|
|
282
|
+
validateVectorValues("MONGODB", vectors);
|
|
277
283
|
try {
|
|
278
284
|
const collection = await this.getCollection(indexName);
|
|
279
285
|
this.collectionForValidation = collection;
|
|
@@ -349,8 +355,8 @@ var MongoDBVector = class extends MastraVector {
|
|
|
349
355
|
index: indexNameInternal,
|
|
350
356
|
queryVector,
|
|
351
357
|
path: this.embeddingFieldName,
|
|
352
|
-
numCandidates: 100,
|
|
353
|
-
limit: topK
|
|
358
|
+
numCandidates: Math.min(1e4, Math.max(100, topK)),
|
|
359
|
+
limit: Math.min(1e4, topK)
|
|
354
360
|
};
|
|
355
361
|
if (Object.keys(combinedFilter).length > 0) {
|
|
356
362
|
const filterWithExclusion = {
|
|
@@ -857,11 +863,21 @@ function resolveMongoDBConfig(config) {
|
|
|
857
863
|
);
|
|
858
864
|
}
|
|
859
865
|
}
|
|
866
|
+
const connectionString = config.uri ?? config.url;
|
|
867
|
+
if (!connectionString) {
|
|
868
|
+
throw new MastraError({
|
|
869
|
+
id: createStorageErrorId("MONGODB", "CONSTRUCTOR", "MISSING_URI"),
|
|
870
|
+
domain: ErrorDomain.STORAGE,
|
|
871
|
+
category: ErrorCategory.USER,
|
|
872
|
+
details: { dbName: config?.dbName },
|
|
873
|
+
text: 'MongoDBStore requires a connection string. Provide "uri" (recommended) or "url" in the constructor options.'
|
|
874
|
+
});
|
|
875
|
+
}
|
|
860
876
|
try {
|
|
861
877
|
return MongoDBConnector.fromDatabaseConfig({
|
|
862
878
|
id: "id" in config ? config.id : "domain",
|
|
863
879
|
options: config.options,
|
|
864
|
-
url:
|
|
880
|
+
url: connectionString,
|
|
865
881
|
dbName: config.dbName
|
|
866
882
|
});
|
|
867
883
|
} catch (error) {
|
|
@@ -870,7 +886,7 @@ function resolveMongoDBConfig(config) {
|
|
|
870
886
|
id: createStorageErrorId("MONGODB", "CONSTRUCTOR", "FAILED"),
|
|
871
887
|
domain: ErrorDomain.STORAGE,
|
|
872
888
|
category: ErrorCategory.USER,
|
|
873
|
-
details: { url: config?.url, dbName: config?.dbName }
|
|
889
|
+
details: { uri: config?.uri ?? "", url: config?.url ?? "", dbName: config?.dbName ?? "" }
|
|
874
890
|
},
|
|
875
891
|
error
|
|
876
892
|
);
|
|
@@ -881,7 +897,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
881
897
|
#skipDefaultIndexes;
|
|
882
898
|
#indexes;
|
|
883
899
|
/** Collections managed by this domain */
|
|
884
|
-
static MANAGED_COLLECTIONS = [TABLE_AGENTS];
|
|
900
|
+
static MANAGED_COLLECTIONS = [TABLE_AGENTS, TABLE_AGENT_VERSIONS];
|
|
885
901
|
constructor(config) {
|
|
886
902
|
super();
|
|
887
903
|
this.#connector = resolveMongoDBConfig(config);
|
|
@@ -901,7 +917,10 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
901
917
|
return [
|
|
902
918
|
{ collection: TABLE_AGENTS, keys: { id: 1 }, options: { unique: true } },
|
|
903
919
|
{ collection: TABLE_AGENTS, keys: { createdAt: -1 } },
|
|
904
|
-
{ collection: TABLE_AGENTS, keys: { updatedAt: -1 } }
|
|
920
|
+
{ collection: TABLE_AGENTS, keys: { updatedAt: -1 } },
|
|
921
|
+
{ collection: TABLE_AGENT_VERSIONS, keys: { id: 1 }, options: { unique: true } },
|
|
922
|
+
{ collection: TABLE_AGENT_VERSIONS, keys: { agentId: 1, versionNumber: -1 }, options: { unique: true } },
|
|
923
|
+
{ collection: TABLE_AGENT_VERSIONS, keys: { agentId: 1, createdAt: -1 } }
|
|
905
924
|
];
|
|
906
925
|
}
|
|
907
926
|
async createDefaultIndexes() {
|
|
@@ -938,8 +957,10 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
938
957
|
await this.createCustomIndexes();
|
|
939
958
|
}
|
|
940
959
|
async dangerouslyClearAll() {
|
|
941
|
-
const
|
|
942
|
-
await
|
|
960
|
+
const versionsCollection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
961
|
+
await versionsCollection.deleteMany({});
|
|
962
|
+
const agentsCollection = await this.getCollection(TABLE_AGENTS);
|
|
963
|
+
await agentsCollection.deleteMany({});
|
|
943
964
|
}
|
|
944
965
|
async getAgentById({ id }) {
|
|
945
966
|
try {
|
|
@@ -1025,6 +1046,9 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
1025
1046
|
if (updates.outputProcessors !== void 0) updateDoc.outputProcessors = updates.outputProcessors;
|
|
1026
1047
|
if (updates.memory !== void 0) updateDoc.memory = updates.memory;
|
|
1027
1048
|
if (updates.scorers !== void 0) updateDoc.scorers = updates.scorers;
|
|
1049
|
+
if (updates.integrationTools !== void 0) updateDoc.integrationTools = updates.integrationTools;
|
|
1050
|
+
if (updates.ownerId !== void 0) updateDoc.ownerId = updates.ownerId;
|
|
1051
|
+
if (updates.activeVersionId !== void 0) updateDoc.activeVersionId = updates.activeVersionId;
|
|
1028
1052
|
if (updates.metadata !== void 0) {
|
|
1029
1053
|
const existingMetadata = existingAgent.metadata || {};
|
|
1030
1054
|
updateDoc.metadata = { ...existingMetadata, ...updates.metadata };
|
|
@@ -1058,6 +1082,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
1058
1082
|
}
|
|
1059
1083
|
async deleteAgent({ id }) {
|
|
1060
1084
|
try {
|
|
1085
|
+
await this.deleteVersionsByAgentId(id);
|
|
1061
1086
|
const collection = await this.getCollection(TABLE_AGENTS);
|
|
1062
1087
|
await collection.deleteOne({ id });
|
|
1063
1088
|
} catch (error) {
|
|
@@ -1141,6 +1166,212 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
|
|
|
1141
1166
|
...agent
|
|
1142
1167
|
};
|
|
1143
1168
|
}
|
|
1169
|
+
// ==========================================================================
|
|
1170
|
+
// Agent Version Methods
|
|
1171
|
+
// ==========================================================================
|
|
1172
|
+
async createVersion(input) {
|
|
1173
|
+
try {
|
|
1174
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1175
|
+
const now = /* @__PURE__ */ new Date();
|
|
1176
|
+
const versionDoc = {
|
|
1177
|
+
id: input.id,
|
|
1178
|
+
agentId: input.agentId,
|
|
1179
|
+
versionNumber: input.versionNumber,
|
|
1180
|
+
name: input.name ?? void 0,
|
|
1181
|
+
snapshot: input.snapshot,
|
|
1182
|
+
changedFields: input.changedFields ?? void 0,
|
|
1183
|
+
changeMessage: input.changeMessage ?? void 0,
|
|
1184
|
+
createdAt: now
|
|
1185
|
+
};
|
|
1186
|
+
await collection.insertOne(versionDoc);
|
|
1187
|
+
return {
|
|
1188
|
+
...input,
|
|
1189
|
+
createdAt: now
|
|
1190
|
+
};
|
|
1191
|
+
} catch (error) {
|
|
1192
|
+
throw new MastraError(
|
|
1193
|
+
{
|
|
1194
|
+
id: createStorageErrorId("MONGODB", "CREATE_VERSION", "FAILED"),
|
|
1195
|
+
domain: ErrorDomain.STORAGE,
|
|
1196
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1197
|
+
details: { versionId: input.id, agentId: input.agentId }
|
|
1198
|
+
},
|
|
1199
|
+
error
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
async getVersion(id) {
|
|
1204
|
+
try {
|
|
1205
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1206
|
+
const result = await collection.findOne({ id });
|
|
1207
|
+
if (!result) {
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
return this.transformVersion(result);
|
|
1211
|
+
} catch (error) {
|
|
1212
|
+
throw new MastraError(
|
|
1213
|
+
{
|
|
1214
|
+
id: createStorageErrorId("MONGODB", "GET_VERSION", "FAILED"),
|
|
1215
|
+
domain: ErrorDomain.STORAGE,
|
|
1216
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1217
|
+
details: { versionId: id }
|
|
1218
|
+
},
|
|
1219
|
+
error
|
|
1220
|
+
);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
async getVersionByNumber(agentId, versionNumber) {
|
|
1224
|
+
try {
|
|
1225
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1226
|
+
const result = await collection.findOne({ agentId, versionNumber });
|
|
1227
|
+
if (!result) {
|
|
1228
|
+
return null;
|
|
1229
|
+
}
|
|
1230
|
+
return this.transformVersion(result);
|
|
1231
|
+
} catch (error) {
|
|
1232
|
+
throw new MastraError(
|
|
1233
|
+
{
|
|
1234
|
+
id: createStorageErrorId("MONGODB", "GET_VERSION_BY_NUMBER", "FAILED"),
|
|
1235
|
+
domain: ErrorDomain.STORAGE,
|
|
1236
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1237
|
+
details: { agentId, versionNumber }
|
|
1238
|
+
},
|
|
1239
|
+
error
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
async getLatestVersion(agentId) {
|
|
1244
|
+
try {
|
|
1245
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1246
|
+
const result = await collection.find({ agentId }).sort({ versionNumber: -1 }).limit(1).toArray();
|
|
1247
|
+
if (!result || result.length === 0) {
|
|
1248
|
+
return null;
|
|
1249
|
+
}
|
|
1250
|
+
return this.transformVersion(result[0]);
|
|
1251
|
+
} catch (error) {
|
|
1252
|
+
throw new MastraError(
|
|
1253
|
+
{
|
|
1254
|
+
id: createStorageErrorId("MONGODB", "GET_LATEST_VERSION", "FAILED"),
|
|
1255
|
+
domain: ErrorDomain.STORAGE,
|
|
1256
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1257
|
+
details: { agentId }
|
|
1258
|
+
},
|
|
1259
|
+
error
|
|
1260
|
+
);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
async listVersions(input) {
|
|
1264
|
+
const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
|
|
1265
|
+
if (page < 0) {
|
|
1266
|
+
throw new MastraError(
|
|
1267
|
+
{
|
|
1268
|
+
id: createStorageErrorId("MONGODB", "LIST_VERSIONS", "INVALID_PAGE"),
|
|
1269
|
+
domain: ErrorDomain.STORAGE,
|
|
1270
|
+
category: ErrorCategory.USER,
|
|
1271
|
+
details: { page }
|
|
1272
|
+
},
|
|
1273
|
+
new Error("page must be >= 0")
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
const perPage = normalizePerPage(perPageInput, 20);
|
|
1277
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1278
|
+
try {
|
|
1279
|
+
const { field, direction } = this.parseVersionOrderBy(orderBy);
|
|
1280
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1281
|
+
const total = await collection.countDocuments({ agentId });
|
|
1282
|
+
if (total === 0 || perPage === 0) {
|
|
1283
|
+
return {
|
|
1284
|
+
versions: [],
|
|
1285
|
+
total,
|
|
1286
|
+
page,
|
|
1287
|
+
perPage: perPageForResponse,
|
|
1288
|
+
hasMore: false
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
const sortOrder = direction === "ASC" ? 1 : -1;
|
|
1292
|
+
let cursor = collection.find({ agentId }).sort({ [field]: sortOrder }).skip(offset);
|
|
1293
|
+
if (perPageInput !== false) {
|
|
1294
|
+
cursor = cursor.limit(perPage);
|
|
1295
|
+
}
|
|
1296
|
+
const results = await cursor.toArray();
|
|
1297
|
+
const versions = results.map((doc) => this.transformVersion(doc));
|
|
1298
|
+
return {
|
|
1299
|
+
versions,
|
|
1300
|
+
total,
|
|
1301
|
+
page,
|
|
1302
|
+
perPage: perPageForResponse,
|
|
1303
|
+
hasMore: perPageInput !== false && offset + perPage < total
|
|
1304
|
+
};
|
|
1305
|
+
} catch (error) {
|
|
1306
|
+
throw new MastraError(
|
|
1307
|
+
{
|
|
1308
|
+
id: createStorageErrorId("MONGODB", "LIST_VERSIONS", "FAILED"),
|
|
1309
|
+
domain: ErrorDomain.STORAGE,
|
|
1310
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1311
|
+
details: { agentId }
|
|
1312
|
+
},
|
|
1313
|
+
error
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
async deleteVersion(id) {
|
|
1318
|
+
try {
|
|
1319
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1320
|
+
await collection.deleteOne({ id });
|
|
1321
|
+
} catch (error) {
|
|
1322
|
+
throw new MastraError(
|
|
1323
|
+
{
|
|
1324
|
+
id: createStorageErrorId("MONGODB", "DELETE_VERSION", "FAILED"),
|
|
1325
|
+
domain: ErrorDomain.STORAGE,
|
|
1326
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1327
|
+
details: { versionId: id }
|
|
1328
|
+
},
|
|
1329
|
+
error
|
|
1330
|
+
);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
async deleteVersionsByAgentId(agentId) {
|
|
1334
|
+
try {
|
|
1335
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1336
|
+
await collection.deleteMany({ agentId });
|
|
1337
|
+
} catch (error) {
|
|
1338
|
+
throw new MastraError(
|
|
1339
|
+
{
|
|
1340
|
+
id: createStorageErrorId("MONGODB", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
|
|
1341
|
+
domain: ErrorDomain.STORAGE,
|
|
1342
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1343
|
+
details: { agentId }
|
|
1344
|
+
},
|
|
1345
|
+
error
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
async countVersions(agentId) {
|
|
1350
|
+
try {
|
|
1351
|
+
const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
|
|
1352
|
+
return await collection.countDocuments({ agentId });
|
|
1353
|
+
} catch (error) {
|
|
1354
|
+
throw new MastraError(
|
|
1355
|
+
{
|
|
1356
|
+
id: createStorageErrorId("MONGODB", "COUNT_VERSIONS", "FAILED"),
|
|
1357
|
+
domain: ErrorDomain.STORAGE,
|
|
1358
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1359
|
+
details: { agentId }
|
|
1360
|
+
},
|
|
1361
|
+
error
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
// ==========================================================================
|
|
1366
|
+
// Private Helper Methods
|
|
1367
|
+
// ==========================================================================
|
|
1368
|
+
transformVersion(doc) {
|
|
1369
|
+
const { _id, ...version } = doc;
|
|
1370
|
+
return {
|
|
1371
|
+
...version,
|
|
1372
|
+
createdAt: version.createdAt instanceof Date ? version.createdAt : new Date(version.createdAt)
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1144
1375
|
};
|
|
1145
1376
|
function formatDateForMongoDB(date) {
|
|
1146
1377
|
return typeof date === "string" ? new Date(date) : date;
|
|
@@ -1335,10 +1566,12 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
|
|
|
1335
1566
|
query.resourceId = resourceId;
|
|
1336
1567
|
}
|
|
1337
1568
|
if (filter?.dateRange?.start) {
|
|
1338
|
-
|
|
1569
|
+
const startOp = filter.dateRange.startExclusive ? "$gt" : "$gte";
|
|
1570
|
+
query.createdAt = { ...query.createdAt, [startOp]: formatDateForMongoDB(filter.dateRange.start) };
|
|
1339
1571
|
}
|
|
1340
1572
|
if (filter?.dateRange?.end) {
|
|
1341
|
-
|
|
1573
|
+
const endOp = filter.dateRange.endExclusive ? "$lt" : "$lte";
|
|
1574
|
+
query.createdAt = { ...query.createdAt, [endOp]: formatDateForMongoDB(filter.dateRange.end) };
|
|
1342
1575
|
}
|
|
1343
1576
|
const total = await collection.countDocuments(query);
|
|
1344
1577
|
const messages = [];
|
|
@@ -1669,25 +1902,48 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
|
|
|
1669
1902
|
);
|
|
1670
1903
|
}
|
|
1671
1904
|
}
|
|
1672
|
-
async
|
|
1905
|
+
async listThreads(args) {
|
|
1906
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
1907
|
+
try {
|
|
1908
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
1909
|
+
} catch (error) {
|
|
1910
|
+
throw new MastraError(
|
|
1911
|
+
{
|
|
1912
|
+
id: createStorageErrorId("MONGODB", "LIST_THREADS", "INVALID_PAGE"),
|
|
1913
|
+
domain: ErrorDomain.STORAGE,
|
|
1914
|
+
category: ErrorCategory.USER,
|
|
1915
|
+
details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
|
|
1916
|
+
},
|
|
1917
|
+
error instanceof Error ? error : new Error("Invalid pagination parameters")
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
1921
|
+
try {
|
|
1922
|
+
this.validateMetadataKeys(filter?.metadata);
|
|
1923
|
+
} catch (error) {
|
|
1924
|
+
throw new MastraError(
|
|
1925
|
+
{
|
|
1926
|
+
id: createStorageErrorId("MONGODB", "LIST_THREADS", "INVALID_METADATA_KEY"),
|
|
1927
|
+
domain: ErrorDomain.STORAGE,
|
|
1928
|
+
category: ErrorCategory.USER,
|
|
1929
|
+
details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
|
|
1930
|
+
},
|
|
1931
|
+
error instanceof Error ? error : new Error("Invalid metadata key")
|
|
1932
|
+
);
|
|
1933
|
+
}
|
|
1673
1934
|
try {
|
|
1674
|
-
const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
|
|
1675
|
-
if (page < 0) {
|
|
1676
|
-
throw new MastraError(
|
|
1677
|
-
{
|
|
1678
|
-
id: createStorageErrorId("MONGODB", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
|
|
1679
|
-
domain: ErrorDomain.STORAGE,
|
|
1680
|
-
category: ErrorCategory.USER,
|
|
1681
|
-
details: { page }
|
|
1682
|
-
},
|
|
1683
|
-
new Error("page must be >= 0")
|
|
1684
|
-
);
|
|
1685
|
-
}
|
|
1686
|
-
const perPage = normalizePerPage(perPageInput, 100);
|
|
1687
1935
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
1688
1936
|
const { field, direction } = this.parseOrderBy(orderBy);
|
|
1689
1937
|
const collection = await this.getCollection(TABLE_THREADS);
|
|
1690
|
-
const query = {
|
|
1938
|
+
const query = {};
|
|
1939
|
+
if (filter?.resourceId) {
|
|
1940
|
+
query.resourceId = filter.resourceId;
|
|
1941
|
+
}
|
|
1942
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
1943
|
+
for (const [key, value] of Object.entries(filter.metadata)) {
|
|
1944
|
+
query[`metadata.${key}`] = value;
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1691
1947
|
const total = await collection.countDocuments(query);
|
|
1692
1948
|
if (perPage === 0) {
|
|
1693
1949
|
return {
|
|
@@ -1721,10 +1977,13 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
|
|
|
1721
1977
|
} catch (error) {
|
|
1722
1978
|
throw new MastraError(
|
|
1723
1979
|
{
|
|
1724
|
-
id: createStorageErrorId("MONGODB", "
|
|
1980
|
+
id: createStorageErrorId("MONGODB", "LIST_THREADS", "FAILED"),
|
|
1725
1981
|
domain: ErrorDomain.STORAGE,
|
|
1726
1982
|
category: ErrorCategory.THIRD_PARTY,
|
|
1727
|
-
details: {
|
|
1983
|
+
details: {
|
|
1984
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
1985
|
+
hasMetadataFilter: !!filter?.metadata
|
|
1986
|
+
}
|
|
1728
1987
|
},
|
|
1729
1988
|
error
|
|
1730
1989
|
);
|
|
@@ -1906,9 +2165,221 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
1906
2165
|
}
|
|
1907
2166
|
}
|
|
1908
2167
|
async init() {
|
|
2168
|
+
const uniqueIndexExists = await this.spansUniqueIndexExists();
|
|
2169
|
+
if (!uniqueIndexExists) {
|
|
2170
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
2171
|
+
if (duplicateInfo.hasDuplicates) {
|
|
2172
|
+
const errorMessage = `
|
|
2173
|
+
===========================================================================
|
|
2174
|
+
MIGRATION REQUIRED: Duplicate spans detected in ${TABLE_SPANS} collection
|
|
2175
|
+
===========================================================================
|
|
2176
|
+
|
|
2177
|
+
Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations.
|
|
2178
|
+
|
|
2179
|
+
The spans collection requires a unique index on (traceId, spanId), but your
|
|
2180
|
+
database contains duplicate entries that must be resolved first.
|
|
2181
|
+
|
|
2182
|
+
To fix this, run the manual migration command:
|
|
2183
|
+
|
|
2184
|
+
npx mastra migrate
|
|
2185
|
+
|
|
2186
|
+
This command will:
|
|
2187
|
+
1. Remove duplicate spans (keeping the most complete/recent version)
|
|
2188
|
+
2. Add the required unique index
|
|
2189
|
+
|
|
2190
|
+
Note: This migration may take some time for large collections.
|
|
2191
|
+
===========================================================================
|
|
2192
|
+
`;
|
|
2193
|
+
throw new MastraError({
|
|
2194
|
+
id: createStorageErrorId("MONGODB", "MIGRATION_REQUIRED", "DUPLICATE_SPANS"),
|
|
2195
|
+
domain: ErrorDomain.STORAGE,
|
|
2196
|
+
category: ErrorCategory.USER,
|
|
2197
|
+
text: errorMessage
|
|
2198
|
+
});
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
1909
2201
|
await this.createDefaultIndexes();
|
|
1910
2202
|
await this.createCustomIndexes();
|
|
1911
2203
|
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Checks if the unique index on (spanId, traceId) already exists on the spans collection.
|
|
2206
|
+
* Used to skip deduplication when the index already exists (migration already complete).
|
|
2207
|
+
*/
|
|
2208
|
+
async spansUniqueIndexExists() {
|
|
2209
|
+
try {
|
|
2210
|
+
const collection = await this.getCollection(TABLE_SPANS);
|
|
2211
|
+
const indexes = await collection.indexes();
|
|
2212
|
+
return indexes.some((idx) => idx.unique === true && idx.key?.spanId === 1 && idx.key?.traceId === 1);
|
|
2213
|
+
} catch {
|
|
2214
|
+
return false;
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Checks for duplicate (traceId, spanId) combinations in the spans collection.
|
|
2219
|
+
* Returns information about duplicates for logging/CLI purposes.
|
|
2220
|
+
*/
|
|
2221
|
+
async checkForDuplicateSpans() {
|
|
2222
|
+
try {
|
|
2223
|
+
const collection = await this.getCollection(TABLE_SPANS);
|
|
2224
|
+
const result = await collection.aggregate([
|
|
2225
|
+
{
|
|
2226
|
+
$group: {
|
|
2227
|
+
_id: { traceId: "$traceId", spanId: "$spanId" },
|
|
2228
|
+
count: { $sum: 1 }
|
|
2229
|
+
}
|
|
2230
|
+
},
|
|
2231
|
+
{ $match: { count: { $gt: 1 } } },
|
|
2232
|
+
{ $count: "duplicateCount" }
|
|
2233
|
+
]).toArray();
|
|
2234
|
+
const duplicateCount = result[0]?.duplicateCount ?? 0;
|
|
2235
|
+
return {
|
|
2236
|
+
hasDuplicates: duplicateCount > 0,
|
|
2237
|
+
duplicateCount
|
|
2238
|
+
};
|
|
2239
|
+
} catch (error) {
|
|
2240
|
+
this.logger?.debug?.(`Could not check for duplicates: ${error}`);
|
|
2241
|
+
return { hasDuplicates: false, duplicateCount: 0 };
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Manually run the spans migration to deduplicate and add the unique index.
|
|
2246
|
+
* This is intended to be called from the CLI when duplicates are detected.
|
|
2247
|
+
*
|
|
2248
|
+
* @returns Migration result with status and details
|
|
2249
|
+
*/
|
|
2250
|
+
async migrateSpans() {
|
|
2251
|
+
const indexExists = await this.spansUniqueIndexExists();
|
|
2252
|
+
if (indexExists) {
|
|
2253
|
+
return {
|
|
2254
|
+
success: true,
|
|
2255
|
+
alreadyMigrated: true,
|
|
2256
|
+
duplicatesRemoved: 0,
|
|
2257
|
+
message: `Migration already complete. Unique index exists on ${TABLE_SPANS} collection.`
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2260
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
2261
|
+
if (duplicateInfo.hasDuplicates) {
|
|
2262
|
+
this.logger?.info?.(
|
|
2263
|
+
`Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations. Starting deduplication...`
|
|
2264
|
+
);
|
|
2265
|
+
await this.deduplicateSpans();
|
|
2266
|
+
} else {
|
|
2267
|
+
this.logger?.info?.(`No duplicate spans found.`);
|
|
2268
|
+
}
|
|
2269
|
+
await this.createDefaultIndexes();
|
|
2270
|
+
await this.createCustomIndexes();
|
|
2271
|
+
return {
|
|
2272
|
+
success: true,
|
|
2273
|
+
alreadyMigrated: false,
|
|
2274
|
+
duplicatesRemoved: duplicateInfo.duplicateCount,
|
|
2275
|
+
message: duplicateInfo.hasDuplicates ? `Migration complete. Removed duplicates and added unique index to ${TABLE_SPANS} collection.` : `Migration complete. Added unique index to ${TABLE_SPANS} collection.`
|
|
2276
|
+
};
|
|
2277
|
+
}
|
|
2278
|
+
/**
|
|
2279
|
+
* Check migration status for the spans collection.
|
|
2280
|
+
* Returns information about whether migration is needed.
|
|
2281
|
+
*/
|
|
2282
|
+
async checkSpansMigrationStatus() {
|
|
2283
|
+
const indexExists = await this.spansUniqueIndexExists();
|
|
2284
|
+
if (indexExists) {
|
|
2285
|
+
return {
|
|
2286
|
+
needsMigration: false,
|
|
2287
|
+
hasDuplicates: false,
|
|
2288
|
+
duplicateCount: 0,
|
|
2289
|
+
constraintExists: true,
|
|
2290
|
+
tableName: TABLE_SPANS
|
|
2291
|
+
};
|
|
2292
|
+
}
|
|
2293
|
+
const duplicateInfo = await this.checkForDuplicateSpans();
|
|
2294
|
+
return {
|
|
2295
|
+
needsMigration: true,
|
|
2296
|
+
hasDuplicates: duplicateInfo.hasDuplicates,
|
|
2297
|
+
duplicateCount: duplicateInfo.duplicateCount,
|
|
2298
|
+
constraintExists: false,
|
|
2299
|
+
tableName: TABLE_SPANS
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* Deduplicates spans with the same (traceId, spanId) combination.
|
|
2304
|
+
* This is needed for databases that existed before the unique constraint was added.
|
|
2305
|
+
*
|
|
2306
|
+
* Priority for keeping spans:
|
|
2307
|
+
* 1. Completed spans (endedAt IS NOT NULL) over incomplete spans
|
|
2308
|
+
* 2. Most recent updatedAt
|
|
2309
|
+
* 3. Most recent createdAt (as tiebreaker)
|
|
2310
|
+
*
|
|
2311
|
+
* Note: This prioritizes migration completion over perfect data preservation.
|
|
2312
|
+
* Old trace data may be lost, which is acceptable for this use case.
|
|
2313
|
+
*/
|
|
2314
|
+
async deduplicateSpans() {
|
|
2315
|
+
try {
|
|
2316
|
+
const collection = await this.getCollection(TABLE_SPANS);
|
|
2317
|
+
const duplicateCheck = await collection.aggregate([
|
|
2318
|
+
{
|
|
2319
|
+
$group: {
|
|
2320
|
+
_id: { traceId: "$traceId", spanId: "$spanId" },
|
|
2321
|
+
count: { $sum: 1 }
|
|
2322
|
+
}
|
|
2323
|
+
},
|
|
2324
|
+
{ $match: { count: { $gt: 1 } } },
|
|
2325
|
+
{ $limit: 1 }
|
|
2326
|
+
]).toArray();
|
|
2327
|
+
if (duplicateCheck.length === 0) {
|
|
2328
|
+
this.logger?.debug?.("No duplicate spans found");
|
|
2329
|
+
return;
|
|
2330
|
+
}
|
|
2331
|
+
this.logger?.info?.("Duplicate spans detected, starting deduplication...");
|
|
2332
|
+
const idsToDelete = await collection.aggregate([
|
|
2333
|
+
// Sort by priority (affects which document $first picks within each group)
|
|
2334
|
+
{
|
|
2335
|
+
$sort: {
|
|
2336
|
+
// Completed spans first (endedAt exists and is not null)
|
|
2337
|
+
endedAt: -1,
|
|
2338
|
+
updatedAt: -1,
|
|
2339
|
+
createdAt: -1
|
|
2340
|
+
}
|
|
2341
|
+
},
|
|
2342
|
+
// Group by (traceId, spanId), keeping the first (best) _id and all _ids
|
|
2343
|
+
{
|
|
2344
|
+
$group: {
|
|
2345
|
+
_id: { traceId: "$traceId", spanId: "$spanId" },
|
|
2346
|
+
keepId: { $first: "$_id" },
|
|
2347
|
+
// The best one to keep (after sort)
|
|
2348
|
+
allIds: { $push: "$_id" },
|
|
2349
|
+
// All ObjectIds (just 12 bytes each, not full docs)
|
|
2350
|
+
count: { $sum: 1 }
|
|
2351
|
+
}
|
|
2352
|
+
},
|
|
2353
|
+
// Only consider groups with duplicates
|
|
2354
|
+
{ $match: { count: { $gt: 1 } } },
|
|
2355
|
+
// Get IDs to delete (allIds minus keepId)
|
|
2356
|
+
{
|
|
2357
|
+
$project: {
|
|
2358
|
+
idsToDelete: {
|
|
2359
|
+
$filter: {
|
|
2360
|
+
input: "$allIds",
|
|
2361
|
+
cond: { $ne: ["$$this", "$keepId"] }
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
},
|
|
2366
|
+
// Unwind to get flat list of IDs
|
|
2367
|
+
{ $unwind: "$idsToDelete" },
|
|
2368
|
+
// Just output the ID
|
|
2369
|
+
{ $project: { _id: "$idsToDelete" } }
|
|
2370
|
+
]).toArray();
|
|
2371
|
+
if (idsToDelete.length === 0) {
|
|
2372
|
+
this.logger?.debug?.("No duplicates to delete after aggregation");
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2375
|
+
const deleteResult = await collection.deleteMany({
|
|
2376
|
+
_id: { $in: idsToDelete.map((d) => d._id) }
|
|
2377
|
+
});
|
|
2378
|
+
this.logger?.info?.(`Deduplication complete: removed ${deleteResult.deletedCount} duplicate spans`);
|
|
2379
|
+
} catch (error) {
|
|
2380
|
+
this.logger?.warn?.("Failed to deduplicate spans:", error);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
1912
2383
|
async dangerouslyClearAll() {
|
|
1913
2384
|
const collection = await this.getCollection(TABLE_SPANS);
|
|
1914
2385
|
await collection.deleteMany({});
|
|
@@ -2189,7 +2660,7 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
2189
2660
|
// No children with errors
|
|
2190
2661
|
}
|
|
2191
2662
|
];
|
|
2192
|
-
const countResult = await collection.aggregate([...pipeline, { $count: "total" }]).toArray();
|
|
2663
|
+
const countResult = await collection.aggregate([...pipeline, { $count: "total" }], { allowDiskUse: true }).toArray();
|
|
2193
2664
|
const count2 = countResult[0]?.total || 0;
|
|
2194
2665
|
if (count2 === 0) {
|
|
2195
2666
|
return {
|
|
@@ -2226,7 +2697,7 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
2226
2697
|
{ $project: { _errorSpans: 0 } }
|
|
2227
2698
|
];
|
|
2228
2699
|
}
|
|
2229
|
-
const spans2 = await collection.aggregate(aggregationPipeline).toArray();
|
|
2700
|
+
const spans2 = await collection.aggregate(aggregationPipeline, { allowDiskUse: true }).toArray();
|
|
2230
2701
|
return {
|
|
2231
2702
|
pagination: {
|
|
2232
2703
|
total: count2,
|
|
@@ -2234,7 +2705,7 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
2234
2705
|
perPage,
|
|
2235
2706
|
hasMore: (page + 1) * perPage < count2
|
|
2236
2707
|
},
|
|
2237
|
-
spans: spans2.map((span) => this.transformSpanFromMongo(span))
|
|
2708
|
+
spans: toTraceSpans(spans2.map((span) => this.transformSpanFromMongo(span)))
|
|
2238
2709
|
};
|
|
2239
2710
|
}
|
|
2240
2711
|
const count = await collection.countDocuments(mongoFilter);
|
|
@@ -2252,18 +2723,21 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
2252
2723
|
let spans;
|
|
2253
2724
|
if (sortField === "endedAt") {
|
|
2254
2725
|
const nullSortValue = sortDirection === -1 ? 0 : 1;
|
|
2255
|
-
spans = await collection.aggregate(
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2726
|
+
spans = await collection.aggregate(
|
|
2727
|
+
[
|
|
2728
|
+
{ $match: mongoFilter },
|
|
2729
|
+
{
|
|
2730
|
+
$addFields: {
|
|
2731
|
+
_endedAtNull: { $cond: [{ $eq: ["$endedAt", null] }, nullSortValue, sortDirection === -1 ? 1 : 0] }
|
|
2732
|
+
}
|
|
2733
|
+
},
|
|
2734
|
+
{ $sort: { _endedAtNull: 1, [sortField]: sortDirection } },
|
|
2735
|
+
{ $skip: page * perPage },
|
|
2736
|
+
{ $limit: perPage },
|
|
2737
|
+
{ $project: { _endedAtNull: 0 } }
|
|
2738
|
+
],
|
|
2739
|
+
{ allowDiskUse: true }
|
|
2740
|
+
).toArray();
|
|
2267
2741
|
} else {
|
|
2268
2742
|
spans = await collection.find(mongoFilter).sort({ [sortField]: sortDirection }).skip(page * perPage).limit(perPage).toArray();
|
|
2269
2743
|
}
|
|
@@ -2274,7 +2748,7 @@ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStor
|
|
|
2274
2748
|
perPage,
|
|
2275
2749
|
hasMore: (page + 1) * perPage < count
|
|
2276
2750
|
},
|
|
2277
|
-
spans: spans.map((span) => this.transformSpanFromMongo(span))
|
|
2751
|
+
spans: toTraceSpans(spans.map((span) => this.transformSpanFromMongo(span)))
|
|
2278
2752
|
};
|
|
2279
2753
|
} catch (error) {
|
|
2280
2754
|
throw new MastraError(
|
|
@@ -2579,7 +3053,7 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
2579
3053
|
};
|
|
2580
3054
|
}
|
|
2581
3055
|
const end = perPageInput === false ? total : start + perPage;
|
|
2582
|
-
let cursor = collection.find(query).sort({ createdAt:
|
|
3056
|
+
let cursor = collection.find(query).sort({ createdAt: -1 }).skip(start);
|
|
2583
3057
|
if (perPageInput !== false) {
|
|
2584
3058
|
cursor = cursor.limit(perPage);
|
|
2585
3059
|
}
|
|
@@ -2628,7 +3102,7 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
2628
3102
|
};
|
|
2629
3103
|
}
|
|
2630
3104
|
const end = perPageInput === false ? total : start + perPage;
|
|
2631
|
-
let cursor = collection.find({ runId }).sort({ createdAt:
|
|
3105
|
+
let cursor = collection.find({ runId }).sort({ createdAt: -1 }).skip(start);
|
|
2632
3106
|
if (perPageInput !== false) {
|
|
2633
3107
|
cursor = cursor.limit(perPage);
|
|
2634
3108
|
}
|
|
@@ -2678,7 +3152,7 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
2678
3152
|
};
|
|
2679
3153
|
}
|
|
2680
3154
|
const end = perPageInput === false ? total : start + perPage;
|
|
2681
|
-
let cursor = collection.find({ entityId, entityType }).sort({ createdAt:
|
|
3155
|
+
let cursor = collection.find({ entityId, entityType }).sort({ createdAt: -1 }).skip(start);
|
|
2682
3156
|
if (perPageInput !== false) {
|
|
2683
3157
|
cursor = cursor.limit(perPage);
|
|
2684
3158
|
}
|
|
@@ -2729,7 +3203,7 @@ var ScoresStorageMongoDB = class _ScoresStorageMongoDB extends ScoresStorage {
|
|
|
2729
3203
|
};
|
|
2730
3204
|
}
|
|
2731
3205
|
const end = perPageInput === false ? total : start + perPage;
|
|
2732
|
-
let cursor = collection.find(query).sort({ createdAt:
|
|
3206
|
+
let cursor = collection.find(query).sort({ createdAt: -1 }).skip(start);
|
|
2733
3207
|
if (perPageInput !== false) {
|
|
2734
3208
|
cursor = cursor.limit(perPage);
|
|
2735
3209
|
}
|
|
@@ -3022,7 +3496,7 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends WorkflowsSt
|
|
|
3022
3496
|
try {
|
|
3023
3497
|
parsedSnapshot = typeof row.snapshot === "string" ? safelyParseJSON(row.snapshot) : row.snapshot;
|
|
3024
3498
|
} catch (e) {
|
|
3025
|
-
|
|
3499
|
+
this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
3026
3500
|
}
|
|
3027
3501
|
}
|
|
3028
3502
|
return {
|
|
@@ -3037,7 +3511,7 @@ var WorkflowsStorageMongoDB = class _WorkflowsStorageMongoDB extends WorkflowsSt
|
|
|
3037
3511
|
};
|
|
3038
3512
|
|
|
3039
3513
|
// src/storage/index.ts
|
|
3040
|
-
var MongoDBStore = class extends
|
|
3514
|
+
var MongoDBStore = class extends MastraCompositeStore {
|
|
3041
3515
|
#connector;
|
|
3042
3516
|
stores;
|
|
3043
3517
|
constructor(config) {
|