@mastra/mongodb 1.0.0 → 1.1.0-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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
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, MastraCompositeStore, TraceStatus, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
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
3
  import { MastraVector, validateUpsertInput, validateVectorValues } from '@mastra/core/vector';
4
4
  import { MongoClient } from 'mongodb';
5
5
  import { v4 } from 'uuid';
@@ -11,7 +11,7 @@ import { saveScorePayloadSchema } from '@mastra/core/evals';
11
11
 
12
12
  // package.json
13
13
  var package_default = {
14
- version: "1.0.0"};
14
+ version: "1.1.0-alpha.1"};
15
15
  var MongoDBFilterTranslator = class extends BaseFilterTranslator {
16
16
  getSupportedOperators() {
17
17
  return {
@@ -892,12 +892,27 @@ function resolveMongoDBConfig(config) {
892
892
  );
893
893
  }
894
894
  }
895
+ var SNAPSHOT_FIELDS = [
896
+ "name",
897
+ "description",
898
+ "instructions",
899
+ "model",
900
+ "tools",
901
+ "defaultOptions",
902
+ "workflows",
903
+ "agents",
904
+ "integrationTools",
905
+ "inputProcessors",
906
+ "outputProcessors",
907
+ "memory",
908
+ "scorers"
909
+ ];
895
910
  var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
896
911
  #connector;
897
912
  #skipDefaultIndexes;
898
913
  #indexes;
899
914
  /** Collections managed by this domain */
900
- static MANAGED_COLLECTIONS = [TABLE_AGENTS];
915
+ static MANAGED_COLLECTIONS = [TABLE_AGENTS, TABLE_AGENT_VERSIONS];
901
916
  constructor(config) {
902
917
  super();
903
918
  this.#connector = resolveMongoDBConfig(config);
@@ -917,7 +932,10 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
917
932
  return [
918
933
  { collection: TABLE_AGENTS, keys: { id: 1 }, options: { unique: true } },
919
934
  { collection: TABLE_AGENTS, keys: { createdAt: -1 } },
920
- { collection: TABLE_AGENTS, keys: { updatedAt: -1 } }
935
+ { collection: TABLE_AGENTS, keys: { updatedAt: -1 } },
936
+ { collection: TABLE_AGENT_VERSIONS, keys: { id: 1 }, options: { unique: true } },
937
+ { collection: TABLE_AGENT_VERSIONS, keys: { agentId: 1, versionNumber: -1 }, options: { unique: true } },
938
+ { collection: TABLE_AGENT_VERSIONS, keys: { agentId: 1, createdAt: -1 } }
921
939
  ];
922
940
  }
923
941
  async createDefaultIndexes() {
@@ -954,8 +972,10 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
954
972
  await this.createCustomIndexes();
955
973
  }
956
974
  async dangerouslyClearAll() {
957
- const collection = await this.getCollection(TABLE_AGENTS);
958
- await collection.deleteMany({});
975
+ const versionsCollection = await this.getCollection(TABLE_AGENT_VERSIONS);
976
+ await versionsCollection.deleteMany({});
977
+ const agentsCollection = await this.getCollection(TABLE_AGENTS);
978
+ await agentsCollection.deleteMany({});
959
979
  }
960
980
  async getAgentById({ id }) {
961
981
  try {
@@ -992,11 +1012,28 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
992
1012
  }
993
1013
  const now = /* @__PURE__ */ new Date();
994
1014
  const newAgent = {
995
- ...agent,
1015
+ id: agent.id,
1016
+ status: "draft",
1017
+ activeVersionId: void 0,
1018
+ authorId: agent.authorId,
1019
+ metadata: agent.metadata,
996
1020
  createdAt: now,
997
1021
  updatedAt: now
998
1022
  };
999
1023
  await collection.insertOne(this.serializeAgent(newAgent));
1024
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = agent;
1025
+ const versionId = crypto.randomUUID();
1026
+ await this.createVersion({
1027
+ id: versionId,
1028
+ agentId: agent.id,
1029
+ versionNumber: 1,
1030
+ ...snapshotConfig,
1031
+ changedFields: Object.keys(snapshotConfig),
1032
+ changeMessage: "Initial version"
1033
+ });
1034
+ newAgent.activeVersionId = versionId;
1035
+ newAgent.status = "published";
1036
+ await collection.updateOne({ id: agent.id }, { $set: { activeVersionId: versionId, status: "published" } });
1000
1037
  return newAgent;
1001
1038
  } catch (error) {
1002
1039
  if (error instanceof MastraError) {
@@ -1029,18 +1066,11 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1029
1066
  const updateDoc = {
1030
1067
  updatedAt: /* @__PURE__ */ new Date()
1031
1068
  };
1032
- if (updates.name !== void 0) updateDoc.name = updates.name;
1033
- if (updates.description !== void 0) updateDoc.description = updates.description;
1034
- if (updates.instructions !== void 0) updateDoc.instructions = updates.instructions;
1035
- if (updates.model !== void 0) updateDoc.model = updates.model;
1036
- if (updates.tools !== void 0) updateDoc.tools = updates.tools;
1037
- if (updates.defaultOptions !== void 0) updateDoc.defaultOptions = updates.defaultOptions;
1038
- if (updates.workflows !== void 0) updateDoc.workflows = updates.workflows;
1039
- if (updates.agents !== void 0) updateDoc.agents = updates.agents;
1040
- if (updates.inputProcessors !== void 0) updateDoc.inputProcessors = updates.inputProcessors;
1041
- if (updates.outputProcessors !== void 0) updateDoc.outputProcessors = updates.outputProcessors;
1042
- if (updates.memory !== void 0) updateDoc.memory = updates.memory;
1043
- if (updates.scorers !== void 0) updateDoc.scorers = updates.scorers;
1069
+ if (updates.authorId !== void 0) updateDoc.authorId = updates.authorId;
1070
+ if (updates.activeVersionId !== void 0) {
1071
+ updateDoc.activeVersionId = updates.activeVersionId;
1072
+ updateDoc.status = "published";
1073
+ }
1044
1074
  if (updates.metadata !== void 0) {
1045
1075
  const existingMetadata = existingAgent.metadata || {};
1046
1076
  updateDoc.metadata = { ...existingMetadata, ...updates.metadata };
@@ -1074,6 +1104,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1074
1104
  }
1075
1105
  async deleteAgent({ id }) {
1076
1106
  try {
1107
+ await this.deleteVersionsByAgentId(id);
1077
1108
  const collection = await this.getCollection(TABLE_AGENTS);
1078
1109
  await collection.deleteOne({ id });
1079
1110
  } catch (error) {
@@ -1144,18 +1175,259 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1144
1175
  );
1145
1176
  }
1146
1177
  }
1178
+ /**
1179
+ * Transforms a raw MongoDB document into a thin StorageAgentType record.
1180
+ * Only returns metadata-level fields (no config/snapshot fields).
1181
+ */
1147
1182
  transformAgent(doc) {
1148
- const { _id, ...agent } = doc;
1183
+ const { _id, ...rest } = doc;
1149
1184
  return {
1150
- ...agent,
1151
- createdAt: agent.createdAt instanceof Date ? agent.createdAt : new Date(agent.createdAt),
1152
- updatedAt: agent.updatedAt instanceof Date ? agent.updatedAt : new Date(agent.updatedAt)
1185
+ id: rest.id,
1186
+ status: rest.status,
1187
+ activeVersionId: rest.activeVersionId,
1188
+ authorId: rest.authorId,
1189
+ metadata: rest.metadata,
1190
+ createdAt: rest.createdAt instanceof Date ? rest.createdAt : new Date(rest.createdAt),
1191
+ updatedAt: rest.updatedAt instanceof Date ? rest.updatedAt : new Date(rest.updatedAt)
1153
1192
  };
1154
1193
  }
1194
+ /**
1195
+ * Serializes a thin StorageAgentType record for MongoDB insertion.
1196
+ * Only persists metadata-level fields.
1197
+ */
1155
1198
  serializeAgent(agent) {
1156
1199
  return {
1157
- ...agent
1200
+ id: agent.id,
1201
+ status: agent.status,
1202
+ activeVersionId: agent.activeVersionId,
1203
+ authorId: agent.authorId,
1204
+ metadata: agent.metadata,
1205
+ createdAt: agent.createdAt,
1206
+ updatedAt: agent.updatedAt
1207
+ };
1208
+ }
1209
+ // ==========================================================================
1210
+ // Agent Version Methods
1211
+ // ==========================================================================
1212
+ async createVersion(input) {
1213
+ try {
1214
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1215
+ const now = /* @__PURE__ */ new Date();
1216
+ const versionDoc = {
1217
+ id: input.id,
1218
+ agentId: input.agentId,
1219
+ versionNumber: input.versionNumber,
1220
+ changedFields: input.changedFields ?? void 0,
1221
+ changeMessage: input.changeMessage ?? void 0,
1222
+ createdAt: now
1223
+ };
1224
+ for (const field of SNAPSHOT_FIELDS) {
1225
+ if (input[field] !== void 0) {
1226
+ versionDoc[field] = input[field];
1227
+ }
1228
+ }
1229
+ await collection.insertOne(versionDoc);
1230
+ return {
1231
+ ...input,
1232
+ createdAt: now
1233
+ };
1234
+ } catch (error) {
1235
+ throw new MastraError(
1236
+ {
1237
+ id: createStorageErrorId("MONGODB", "CREATE_VERSION", "FAILED"),
1238
+ domain: ErrorDomain.STORAGE,
1239
+ category: ErrorCategory.THIRD_PARTY,
1240
+ details: { versionId: input.id, agentId: input.agentId }
1241
+ },
1242
+ error
1243
+ );
1244
+ }
1245
+ }
1246
+ async getVersion(id) {
1247
+ try {
1248
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1249
+ const result = await collection.findOne({ id });
1250
+ if (!result) {
1251
+ return null;
1252
+ }
1253
+ return this.transformVersion(result);
1254
+ } catch (error) {
1255
+ throw new MastraError(
1256
+ {
1257
+ id: createStorageErrorId("MONGODB", "GET_VERSION", "FAILED"),
1258
+ domain: ErrorDomain.STORAGE,
1259
+ category: ErrorCategory.THIRD_PARTY,
1260
+ details: { versionId: id }
1261
+ },
1262
+ error
1263
+ );
1264
+ }
1265
+ }
1266
+ async getVersionByNumber(agentId, versionNumber) {
1267
+ try {
1268
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1269
+ const result = await collection.findOne({ agentId, versionNumber });
1270
+ if (!result) {
1271
+ return null;
1272
+ }
1273
+ return this.transformVersion(result);
1274
+ } catch (error) {
1275
+ throw new MastraError(
1276
+ {
1277
+ id: createStorageErrorId("MONGODB", "GET_VERSION_BY_NUMBER", "FAILED"),
1278
+ domain: ErrorDomain.STORAGE,
1279
+ category: ErrorCategory.THIRD_PARTY,
1280
+ details: { agentId, versionNumber }
1281
+ },
1282
+ error
1283
+ );
1284
+ }
1285
+ }
1286
+ async getLatestVersion(agentId) {
1287
+ try {
1288
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1289
+ const result = await collection.find({ agentId }).sort({ versionNumber: -1 }).limit(1).toArray();
1290
+ if (!result || result.length === 0) {
1291
+ return null;
1292
+ }
1293
+ return this.transformVersion(result[0]);
1294
+ } catch (error) {
1295
+ throw new MastraError(
1296
+ {
1297
+ id: createStorageErrorId("MONGODB", "GET_LATEST_VERSION", "FAILED"),
1298
+ domain: ErrorDomain.STORAGE,
1299
+ category: ErrorCategory.THIRD_PARTY,
1300
+ details: { agentId }
1301
+ },
1302
+ error
1303
+ );
1304
+ }
1305
+ }
1306
+ async listVersions(input) {
1307
+ const { agentId, page = 0, perPage: perPageInput, orderBy } = input;
1308
+ if (page < 0) {
1309
+ throw new MastraError(
1310
+ {
1311
+ id: createStorageErrorId("MONGODB", "LIST_VERSIONS", "INVALID_PAGE"),
1312
+ domain: ErrorDomain.STORAGE,
1313
+ category: ErrorCategory.USER,
1314
+ details: { page }
1315
+ },
1316
+ new Error("page must be >= 0")
1317
+ );
1318
+ }
1319
+ const perPage = normalizePerPage(perPageInput, 20);
1320
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1321
+ try {
1322
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
1323
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1324
+ const total = await collection.countDocuments({ agentId });
1325
+ if (total === 0 || perPage === 0) {
1326
+ return {
1327
+ versions: [],
1328
+ total,
1329
+ page,
1330
+ perPage: perPageForResponse,
1331
+ hasMore: false
1332
+ };
1333
+ }
1334
+ const sortOrder = direction === "ASC" ? 1 : -1;
1335
+ let cursor = collection.find({ agentId }).sort({ [field]: sortOrder }).skip(offset);
1336
+ if (perPageInput !== false) {
1337
+ cursor = cursor.limit(perPage);
1338
+ }
1339
+ const results = await cursor.toArray();
1340
+ const versions = results.map((doc) => this.transformVersion(doc));
1341
+ return {
1342
+ versions,
1343
+ total,
1344
+ page,
1345
+ perPage: perPageForResponse,
1346
+ hasMore: perPageInput !== false && offset + perPage < total
1347
+ };
1348
+ } catch (error) {
1349
+ throw new MastraError(
1350
+ {
1351
+ id: createStorageErrorId("MONGODB", "LIST_VERSIONS", "FAILED"),
1352
+ domain: ErrorDomain.STORAGE,
1353
+ category: ErrorCategory.THIRD_PARTY,
1354
+ details: { agentId }
1355
+ },
1356
+ error
1357
+ );
1358
+ }
1359
+ }
1360
+ async deleteVersion(id) {
1361
+ try {
1362
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1363
+ await collection.deleteOne({ id });
1364
+ } catch (error) {
1365
+ throw new MastraError(
1366
+ {
1367
+ id: createStorageErrorId("MONGODB", "DELETE_VERSION", "FAILED"),
1368
+ domain: ErrorDomain.STORAGE,
1369
+ category: ErrorCategory.THIRD_PARTY,
1370
+ details: { versionId: id }
1371
+ },
1372
+ error
1373
+ );
1374
+ }
1375
+ }
1376
+ async deleteVersionsByAgentId(agentId) {
1377
+ try {
1378
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1379
+ await collection.deleteMany({ agentId });
1380
+ } catch (error) {
1381
+ throw new MastraError(
1382
+ {
1383
+ id: createStorageErrorId("MONGODB", "DELETE_VERSIONS_BY_AGENT_ID", "FAILED"),
1384
+ domain: ErrorDomain.STORAGE,
1385
+ category: ErrorCategory.THIRD_PARTY,
1386
+ details: { agentId }
1387
+ },
1388
+ error
1389
+ );
1390
+ }
1391
+ }
1392
+ async countVersions(agentId) {
1393
+ try {
1394
+ const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1395
+ return await collection.countDocuments({ agentId });
1396
+ } catch (error) {
1397
+ throw new MastraError(
1398
+ {
1399
+ id: createStorageErrorId("MONGODB", "COUNT_VERSIONS", "FAILED"),
1400
+ domain: ErrorDomain.STORAGE,
1401
+ category: ErrorCategory.THIRD_PARTY,
1402
+ details: { agentId }
1403
+ },
1404
+ error
1405
+ );
1406
+ }
1407
+ }
1408
+ // ==========================================================================
1409
+ // Private Helper Methods
1410
+ // ==========================================================================
1411
+ /**
1412
+ * Transforms a raw MongoDB version document into an AgentVersion.
1413
+ * Config fields are returned directly (no nested snapshot object).
1414
+ */
1415
+ transformVersion(doc) {
1416
+ const { _id, ...version } = doc;
1417
+ const result = {
1418
+ id: version.id,
1419
+ agentId: version.agentId,
1420
+ versionNumber: version.versionNumber,
1421
+ changedFields: version.changedFields,
1422
+ changeMessage: version.changeMessage,
1423
+ createdAt: version.createdAt instanceof Date ? version.createdAt : new Date(version.createdAt)
1158
1424
  };
1425
+ for (const field of SNAPSHOT_FIELDS) {
1426
+ if (version[field] !== void 0) {
1427
+ result[field] = version[field];
1428
+ }
1429
+ }
1430
+ return result;
1159
1431
  }
1160
1432
  };
1161
1433
  function formatDateForMongoDB(date) {
@@ -2490,7 +2762,7 @@ Note: This migration may take some time for large collections.
2490
2762
  perPage,
2491
2763
  hasMore: (page + 1) * perPage < count2
2492
2764
  },
2493
- spans: spans2.map((span) => this.transformSpanFromMongo(span))
2765
+ spans: toTraceSpans(spans2.map((span) => this.transformSpanFromMongo(span)))
2494
2766
  };
2495
2767
  }
2496
2768
  const count = await collection.countDocuments(mongoFilter);
@@ -2533,7 +2805,7 @@ Note: This migration may take some time for large collections.
2533
2805
  perPage,
2534
2806
  hasMore: (page + 1) * perPage < count
2535
2807
  },
2536
- spans: spans.map((span) => this.transformSpanFromMongo(span))
2808
+ spans: toTraceSpans(spans.map((span) => this.transformSpanFromMongo(span)))
2537
2809
  };
2538
2810
  } catch (error) {
2539
2811
  throw new MastraError(