@mastra/mongodb 1.2.0-alpha.0 → 1.3.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
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';
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, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, 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';
@@ -12,7 +12,7 @@ import { saveScorePayloadSchema } from '@mastra/core/evals';
12
12
 
13
13
  // package.json
14
14
  var package_default = {
15
- version: "1.2.0-alpha.0"};
15
+ version: "1.3.0-alpha.0"};
16
16
  var MongoDBFilterTranslator = class extends BaseFilterTranslator {
17
17
  getSupportedOperators() {
18
18
  return {
@@ -971,6 +971,42 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
971
971
  async init() {
972
972
  await this.createDefaultIndexes();
973
973
  await this.createCustomIndexes();
974
+ await this.#migrateToolsToJsonbFormat();
975
+ }
976
+ /**
977
+ * Migrates the tools field from string[] format to object format { "tool-key": { "description": "..." } }.
978
+ * This handles the transition from the old format where tools were stored as an array of string keys
979
+ * to the new format where tools can have per-agent description overrides.
980
+ */
981
+ async #migrateToolsToJsonbFormat() {
982
+ try {
983
+ const versionsCollection = await this.getCollection(TABLE_AGENT_VERSIONS);
984
+ const cursor = versionsCollection.find({ tools: { $type: "array" } });
985
+ const updates = [];
986
+ for await (const doc of cursor) {
987
+ if (Array.isArray(doc.tools)) {
988
+ const toolsObject = {};
989
+ for (const toolKey of doc.tools) {
990
+ if (typeof toolKey === "string") {
991
+ toolsObject[toolKey] = {};
992
+ }
993
+ }
994
+ updates.push({ id: doc.id, tools: toolsObject });
995
+ }
996
+ }
997
+ if (updates.length > 0) {
998
+ const bulkOps = updates.map((update) => ({
999
+ updateOne: {
1000
+ filter: { id: update.id },
1001
+ update: { $set: { tools: update.tools } }
1002
+ }
1003
+ }));
1004
+ await versionsCollection.bulkWrite(bulkOps);
1005
+ this.logger?.info?.(`Migrated ${updates.length} agent version tools from array to object format`);
1006
+ }
1007
+ } catch (error) {
1008
+ this.logger?.warn?.("Failed to migrate tools to object format:", error);
1009
+ }
974
1010
  }
975
1011
  async dangerouslyClearAll() {
976
1012
  const versionsCollection = await this.getCollection(TABLE_AGENT_VERSIONS);
@@ -978,7 +1014,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
978
1014
  const agentsCollection = await this.getCollection(TABLE_AGENTS);
979
1015
  await agentsCollection.deleteMany({});
980
1016
  }
981
- async getAgentById({ id }) {
1017
+ async getById(id) {
982
1018
  try {
983
1019
  const collection = await this.getCollection(TABLE_AGENTS);
984
1020
  const result = await collection.findOne({ id });
@@ -998,7 +1034,8 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
998
1034
  );
999
1035
  }
1000
1036
  }
1001
- async createAgent({ agent }) {
1037
+ async create(input) {
1038
+ const { agent } = input;
1002
1039
  try {
1003
1040
  const collection = await this.getCollection(TABLE_AGENTS);
1004
1041
  const existing = await collection.findOne({ id: agent.id });
@@ -1048,7 +1085,8 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1048
1085
  );
1049
1086
  }
1050
1087
  }
1051
- async updateAgent({ id, ...updates }) {
1088
+ async update(input) {
1089
+ const { id, ...updates } = input;
1052
1090
  try {
1053
1091
  const collection = await this.getCollection(TABLE_AGENTS);
1054
1092
  const existingAgent = await collection.findOne({ id });
@@ -1087,14 +1125,17 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1087
1125
  details: { id }
1088
1126
  });
1089
1127
  }
1128
+ const sanitizedConfigFields = Object.fromEntries(
1129
+ Object.entries(configFields).map(([key, value]) => [key, value === null ? void 0 : value])
1130
+ );
1090
1131
  const versionInput = {
1091
1132
  id: randomUUID(),
1092
1133
  agentId: id,
1093
1134
  versionNumber: nextVersionNumber,
1094
1135
  ...this.extractSnapshotFields(latestVersion),
1095
1136
  // Start from latest version
1096
- ...configFields,
1097
- // Apply updates
1137
+ ...sanitizedConfigFields,
1138
+ // Apply updates (null values converted to undefined)
1098
1139
  changedFields: Object.keys(configFields),
1099
1140
  changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
1100
1141
  };
@@ -1135,9 +1176,9 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1135
1176
  );
1136
1177
  }
1137
1178
  }
1138
- async deleteAgent({ id }) {
1179
+ async delete(id) {
1139
1180
  try {
1140
- await this.deleteVersionsByAgentId(id);
1181
+ await this.deleteVersionsByParentId(id);
1141
1182
  const collection = await this.getCollection(TABLE_AGENTS);
1142
1183
  await collection.deleteOne({ id });
1143
1184
  } catch (error) {
@@ -1152,7 +1193,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1152
1193
  );
1153
1194
  }
1154
1195
  }
1155
- async listAgents(args) {
1196
+ async list(args) {
1156
1197
  try {
1157
1198
  const { page = 0, perPage: perPageInput, orderBy } = args || {};
1158
1199
  const { field, direction } = this.parseOrderBy(orderBy);
@@ -1208,123 +1249,6 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1208
1249
  );
1209
1250
  }
1210
1251
  }
1211
- async listAgentsResolved(args) {
1212
- try {
1213
- const { page = 0, perPage: perPageInput, orderBy } = args || {};
1214
- const { field, direction } = this.parseOrderBy(orderBy);
1215
- if (page < 0) {
1216
- throw new MastraError(
1217
- {
1218
- id: createStorageErrorId("MONGODB", "LIST_AGENTS_RESOLVED", "INVALID_PAGE"),
1219
- domain: ErrorDomain.STORAGE,
1220
- category: ErrorCategory.USER,
1221
- details: { page }
1222
- },
1223
- new Error("page must be >= 0")
1224
- );
1225
- }
1226
- const perPage = normalizePerPage(perPageInput, 100);
1227
- const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1228
- const agentsCollection = await this.getCollection(TABLE_AGENTS);
1229
- const total = await agentsCollection.countDocuments({});
1230
- if (total === 0 || perPage === 0) {
1231
- return {
1232
- agents: [],
1233
- total,
1234
- page,
1235
- perPage: perPageForResponse,
1236
- hasMore: false
1237
- };
1238
- }
1239
- const sortOrder = direction === "ASC" ? 1 : -1;
1240
- const pipeline = [
1241
- // Sort agents
1242
- { $sort: { [field]: sortOrder } },
1243
- // Paginate
1244
- { $skip: offset }
1245
- ];
1246
- if (perPageInput !== false) {
1247
- pipeline.push({ $limit: perPage });
1248
- }
1249
- pipeline.push({
1250
- $lookup: {
1251
- from: TABLE_AGENT_VERSIONS,
1252
- localField: "activeVersionId",
1253
- foreignField: "id",
1254
- as: "activeVersion"
1255
- }
1256
- });
1257
- pipeline.push({
1258
- $lookup: {
1259
- from: TABLE_AGENT_VERSIONS,
1260
- let: { agentId: "$id" },
1261
- pipeline: [
1262
- { $match: { $expr: { $eq: ["$agentId", "$$agentId"] } } },
1263
- { $sort: { versionNumber: -1 } },
1264
- { $limit: 1 }
1265
- ],
1266
- as: "latestVersion"
1267
- }
1268
- });
1269
- pipeline.push({
1270
- $addFields: {
1271
- version: {
1272
- $cond: {
1273
- if: { $gt: [{ $size: "$activeVersion" }, 0] },
1274
- then: { $arrayElemAt: ["$activeVersion", 0] },
1275
- else: { $arrayElemAt: ["$latestVersion", 0] }
1276
- }
1277
- }
1278
- }
1279
- });
1280
- pipeline.push({
1281
- $project: {
1282
- activeVersion: 0,
1283
- latestVersion: 0
1284
- }
1285
- });
1286
- const results = await agentsCollection.aggregate(pipeline).toArray();
1287
- const resolvedAgents = results.map((doc) => {
1288
- const agent = this.transformAgent(doc);
1289
- if (doc.version) {
1290
- const version = this.transformVersion(doc.version);
1291
- const {
1292
- id: _versionId,
1293
- agentId: _agentId,
1294
- versionNumber: _versionNumber,
1295
- changedFields: _changedFields,
1296
- changeMessage: _changeMessage,
1297
- createdAt: _createdAt,
1298
- ...snapshotConfig
1299
- } = version;
1300
- return {
1301
- ...agent,
1302
- ...snapshotConfig
1303
- };
1304
- }
1305
- return agent;
1306
- });
1307
- return {
1308
- agents: resolvedAgents,
1309
- total,
1310
- page,
1311
- perPage: perPageForResponse,
1312
- hasMore: perPageInput !== false && offset + perPage < total
1313
- };
1314
- } catch (error) {
1315
- if (error instanceof MastraError) {
1316
- throw error;
1317
- }
1318
- throw new MastraError(
1319
- {
1320
- id: createStorageErrorId("MONGODB", "LIST_AGENTS_RESOLVED", "FAILED"),
1321
- domain: ErrorDomain.STORAGE,
1322
- category: ErrorCategory.THIRD_PARTY
1323
- },
1324
- error
1325
- );
1326
- }
1327
- }
1328
1252
  /**
1329
1253
  * Transforms a raw MongoDB document into a thin StorageAgentType record.
1330
1254
  * Only returns metadata-level fields (no config/snapshot fields).
@@ -1523,7 +1447,7 @@ var MongoDBAgentsStorage = class _MongoDBAgentsStorage extends AgentsStorage {
1523
1447
  );
1524
1448
  }
1525
1449
  }
1526
- async deleteVersionsByAgentId(agentId) {
1450
+ async deleteVersionsByParentId(agentId) {
1527
1451
  try {
1528
1452
  const collection = await this.getCollection(TABLE_AGENT_VERSIONS);
1529
1453
  await collection.deleteMany({ agentId });
@@ -2458,12 +2382,26 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2458
2382
  originType: doc.originType || "initial",
2459
2383
  generationCount: Number(doc.generationCount || 0),
2460
2384
  activeObservations: doc.activeObservations || "",
2385
+ // Handle new chunk-based structure
2386
+ bufferedObservationChunks: doc.bufferedObservationChunks || void 0,
2387
+ // Deprecated fields (for backward compatibility)
2461
2388
  bufferedObservations: doc.activeObservationsPendingUpdate || void 0,
2389
+ bufferedObservationTokens: doc.bufferedObservationTokens ? Number(doc.bufferedObservationTokens) : void 0,
2390
+ bufferedMessageIds: void 0,
2391
+ // Use bufferedObservationChunks instead
2392
+ bufferedReflection: doc.bufferedReflection || void 0,
2393
+ bufferedReflectionTokens: doc.bufferedReflectionTokens ? Number(doc.bufferedReflectionTokens) : void 0,
2394
+ bufferedReflectionInputTokens: doc.bufferedReflectionInputTokens ? Number(doc.bufferedReflectionInputTokens) : void 0,
2395
+ reflectedObservationLineCount: doc.reflectedObservationLineCount ? Number(doc.reflectedObservationLineCount) : void 0,
2462
2396
  totalTokensObserved: Number(doc.totalTokensObserved || 0),
2463
2397
  observationTokenCount: Number(doc.observationTokenCount || 0),
2464
2398
  pendingMessageTokens: Number(doc.pendingMessageTokens || 0),
2465
2399
  isReflecting: Boolean(doc.isReflecting),
2466
2400
  isObserving: Boolean(doc.isObserving),
2401
+ isBufferingObservation: Boolean(doc.isBufferingObservation),
2402
+ isBufferingReflection: Boolean(doc.isBufferingReflection),
2403
+ lastBufferedAtTokens: typeof doc.lastBufferedAtTokens === "number" ? doc.lastBufferedAtTokens : parseInt(String(doc.lastBufferedAtTokens ?? "0"), 10) || 0,
2404
+ lastBufferedAtTime: doc.lastBufferedAtTime ? new Date(doc.lastBufferedAtTime) : null,
2467
2405
  config: doc.config || {},
2468
2406
  metadata: doc.metadata || void 0,
2469
2407
  observedMessageIds: doc.observedMessageIds || void 0,
@@ -2528,6 +2466,10 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2528
2466
  pendingMessageTokens: 0,
2529
2467
  isReflecting: false,
2530
2468
  isObserving: false,
2469
+ isBufferingObservation: false,
2470
+ isBufferingReflection: false,
2471
+ lastBufferedAtTokens: 0,
2472
+ lastBufferedAtTime: null,
2531
2473
  config: input.config,
2532
2474
  observedTimezone: input.observedTimezone
2533
2475
  };
@@ -2550,6 +2492,10 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2550
2492
  observationTokenCount: 0,
2551
2493
  isObserving: false,
2552
2494
  isReflecting: false,
2495
+ isBufferingObservation: false,
2496
+ isBufferingReflection: false,
2497
+ lastBufferedAtTokens: 0,
2498
+ lastBufferedAtTime: null,
2553
2499
  observedTimezone: input.observedTimezone || null,
2554
2500
  createdAt: now,
2555
2501
  updatedAt: now
@@ -2632,6 +2578,10 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2632
2578
  pendingMessageTokens: 0,
2633
2579
  isReflecting: false,
2634
2580
  isObserving: false,
2581
+ isBufferingObservation: false,
2582
+ isBufferingReflection: false,
2583
+ lastBufferedAtTokens: 0,
2584
+ lastBufferedAtTime: null,
2635
2585
  config: input.currentRecord.config,
2636
2586
  metadata: input.currentRecord.metadata,
2637
2587
  observedTimezone: input.currentRecord.observedTimezone
@@ -2655,6 +2605,10 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2655
2605
  observationTokenCount: record.observationTokenCount,
2656
2606
  isObserving: false,
2657
2607
  isReflecting: false,
2608
+ isBufferingObservation: false,
2609
+ isBufferingReflection: false,
2610
+ lastBufferedAtTokens: 0,
2611
+ lastBufferedAtTime: null,
2658
2612
  observedTimezone: record.observedTimezone || null,
2659
2613
  createdAt: now,
2660
2614
  updatedAt: now,
@@ -2729,6 +2683,72 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2729
2683
  );
2730
2684
  }
2731
2685
  }
2686
+ async setBufferingObservationFlag(id, isBuffering, lastBufferedAtTokens) {
2687
+ try {
2688
+ const collection = await this.getCollection(OM_TABLE);
2689
+ const updateDoc = {
2690
+ isBufferingObservation: isBuffering,
2691
+ updatedAt: /* @__PURE__ */ new Date()
2692
+ };
2693
+ if (lastBufferedAtTokens !== void 0) {
2694
+ updateDoc.lastBufferedAtTokens = lastBufferedAtTokens;
2695
+ }
2696
+ const result = await collection.updateOne({ id }, { $set: updateDoc });
2697
+ if (result.matchedCount === 0) {
2698
+ throw new MastraError({
2699
+ id: createStorageErrorId("MONGODB", "SET_BUFFERING_OBSERVATION_FLAG", "NOT_FOUND"),
2700
+ text: `Observational memory record not found: ${id}`,
2701
+ domain: ErrorDomain.STORAGE,
2702
+ category: ErrorCategory.THIRD_PARTY,
2703
+ details: { id, isBuffering, lastBufferedAtTokens: lastBufferedAtTokens ?? null }
2704
+ });
2705
+ }
2706
+ } catch (error) {
2707
+ if (error instanceof MastraError) {
2708
+ throw error;
2709
+ }
2710
+ throw new MastraError(
2711
+ {
2712
+ id: createStorageErrorId("MONGODB", "SET_BUFFERING_OBSERVATION_FLAG", "FAILED"),
2713
+ domain: ErrorDomain.STORAGE,
2714
+ category: ErrorCategory.THIRD_PARTY,
2715
+ details: { id, isBuffering, lastBufferedAtTokens: lastBufferedAtTokens ?? null }
2716
+ },
2717
+ error
2718
+ );
2719
+ }
2720
+ }
2721
+ async setBufferingReflectionFlag(id, isBuffering) {
2722
+ try {
2723
+ const collection = await this.getCollection(OM_TABLE);
2724
+ const result = await collection.updateOne(
2725
+ { id },
2726
+ { $set: { isBufferingReflection: isBuffering, updatedAt: /* @__PURE__ */ new Date() } }
2727
+ );
2728
+ if (result.matchedCount === 0) {
2729
+ throw new MastraError({
2730
+ id: createStorageErrorId("MONGODB", "SET_BUFFERING_REFLECTION_FLAG", "NOT_FOUND"),
2731
+ text: `Observational memory record not found: ${id}`,
2732
+ domain: ErrorDomain.STORAGE,
2733
+ category: ErrorCategory.THIRD_PARTY,
2734
+ details: { id, isBuffering }
2735
+ });
2736
+ }
2737
+ } catch (error) {
2738
+ if (error instanceof MastraError) {
2739
+ throw error;
2740
+ }
2741
+ throw new MastraError(
2742
+ {
2743
+ id: createStorageErrorId("MONGODB", "SET_BUFFERING_REFLECTION_FLAG", "FAILED"),
2744
+ domain: ErrorDomain.STORAGE,
2745
+ category: ErrorCategory.THIRD_PARTY,
2746
+ details: { id, isBuffering }
2747
+ },
2748
+ error
2749
+ );
2750
+ }
2751
+ }
2732
2752
  async clearObservationalMemory(threadId, resourceId) {
2733
2753
  try {
2734
2754
  const lookupKey = this.getOMKey(threadId, resourceId);
@@ -2789,116 +2809,405 @@ var MemoryStorageMongoDB = class _MemoryStorageMongoDB extends MemoryStorage {
2789
2809
  );
2790
2810
  }
2791
2811
  }
2792
- };
2793
- var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStorage {
2794
- #connector;
2795
- #skipDefaultIndexes;
2796
- #indexes;
2797
- /** Collections managed by this domain */
2798
- static MANAGED_COLLECTIONS = [TABLE_SPANS];
2799
- constructor(config) {
2800
- super();
2801
- this.#connector = resolveMongoDBConfig(config);
2802
- this.#skipDefaultIndexes = config.skipDefaultIndexes;
2803
- this.#indexes = config.indexes?.filter(
2804
- (idx) => _ObservabilityMongoDB.MANAGED_COLLECTIONS.includes(idx.collection)
2805
- );
2806
- }
2807
- async getCollection(name) {
2808
- return this.#connector.getCollection(name);
2809
- }
2810
- /**
2811
- * Returns default index definitions for the observability domain collections.
2812
- * These indexes optimize common query patterns for span and trace lookups.
2813
- */
2814
- getDefaultIndexDefinitions() {
2815
- return [
2816
- { collection: TABLE_SPANS, keys: { spanId: 1, traceId: 1 }, options: { unique: true } },
2817
- { collection: TABLE_SPANS, keys: { traceId: 1 } },
2818
- { collection: TABLE_SPANS, keys: { parentSpanId: 1 } },
2819
- { collection: TABLE_SPANS, keys: { startedAt: -1 } },
2820
- { collection: TABLE_SPANS, keys: { spanType: 1 } },
2821
- { collection: TABLE_SPANS, keys: { name: 1 } }
2822
- ];
2823
- }
2824
- async createDefaultIndexes() {
2825
- if (this.#skipDefaultIndexes) {
2826
- return;
2827
- }
2828
- for (const indexDef of this.getDefaultIndexDefinitions()) {
2829
- try {
2830
- const collection = await this.getCollection(indexDef.collection);
2831
- await collection.createIndex(indexDef.keys, indexDef.options);
2832
- } catch (error) {
2833
- this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
2834
- }
2835
- }
2836
- }
2837
- /**
2838
- * Creates custom user-defined indexes for this domain's collections.
2839
- */
2840
- async createCustomIndexes() {
2841
- if (!this.#indexes || this.#indexes.length === 0) {
2842
- return;
2843
- }
2844
- for (const indexDef of this.#indexes) {
2845
- try {
2846
- const collection = await this.getCollection(indexDef.collection);
2847
- await collection.createIndex(indexDef.keys, indexDef.options);
2848
- } catch (error) {
2849
- this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
2812
+ // ============================================
2813
+ // Async Buffering Methods
2814
+ // ============================================
2815
+ async updateBufferedObservations(input) {
2816
+ try {
2817
+ const collection = await this.getCollection(OM_TABLE);
2818
+ const newChunk = {
2819
+ id: `ombuf-${randomUUID()}`,
2820
+ cycleId: input.chunk.cycleId,
2821
+ observations: input.chunk.observations,
2822
+ tokenCount: input.chunk.tokenCount,
2823
+ messageIds: input.chunk.messageIds,
2824
+ messageTokens: input.chunk.messageTokens,
2825
+ lastObservedAt: input.chunk.lastObservedAt,
2826
+ createdAt: /* @__PURE__ */ new Date(),
2827
+ suggestedContinuation: input.chunk.suggestedContinuation,
2828
+ currentTask: input.chunk.currentTask
2829
+ };
2830
+ const $set = { updatedAt: /* @__PURE__ */ new Date() };
2831
+ if (input.lastBufferedAtTime) {
2832
+ $set.lastBufferedAtTime = input.lastBufferedAtTime;
2850
2833
  }
2851
- }
2852
- }
2853
- async init() {
2854
- const uniqueIndexExists = await this.spansUniqueIndexExists();
2855
- if (!uniqueIndexExists) {
2856
- const duplicateInfo = await this.checkForDuplicateSpans();
2857
- if (duplicateInfo.hasDuplicates) {
2858
- const errorMessage = `
2859
- ===========================================================================
2860
- MIGRATION REQUIRED: Duplicate spans detected in ${TABLE_SPANS} collection
2861
- ===========================================================================
2862
-
2863
- Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations.
2864
-
2865
- The spans collection requires a unique index on (traceId, spanId), but your
2866
- database contains duplicate entries that must be resolved first.
2867
-
2868
- To fix this, run the manual migration command:
2869
-
2870
- npx mastra migrate
2871
-
2872
- This command will:
2873
- 1. Remove duplicate spans (keeping the most complete/recent version)
2874
- 2. Add the required unique index
2875
-
2876
- Note: This migration may take some time for large collections.
2877
- ===========================================================================
2878
- `;
2834
+ const result = await collection.updateOne(
2835
+ { id: input.id },
2836
+ {
2837
+ $push: { bufferedObservationChunks: newChunk },
2838
+ $set
2839
+ }
2840
+ );
2841
+ if (result.matchedCount === 0) {
2879
2842
  throw new MastraError({
2880
- id: createStorageErrorId("MONGODB", "MIGRATION_REQUIRED", "DUPLICATE_SPANS"),
2843
+ id: createStorageErrorId("MONGODB", "UPDATE_BUFFERED_OBSERVATIONS", "NOT_FOUND"),
2844
+ text: `Observational memory record not found: ${input.id}`,
2881
2845
  domain: ErrorDomain.STORAGE,
2882
- category: ErrorCategory.USER,
2883
- text: errorMessage
2846
+ category: ErrorCategory.THIRD_PARTY,
2847
+ details: { id: input.id }
2884
2848
  });
2885
2849
  }
2850
+ } catch (error) {
2851
+ if (error instanceof MastraError) {
2852
+ throw error;
2853
+ }
2854
+ throw new MastraError(
2855
+ {
2856
+ id: createStorageErrorId("MONGODB", "UPDATE_BUFFERED_OBSERVATIONS", "FAILED"),
2857
+ domain: ErrorDomain.STORAGE,
2858
+ category: ErrorCategory.THIRD_PARTY,
2859
+ details: { id: input.id }
2860
+ },
2861
+ error
2862
+ );
2886
2863
  }
2887
- await this.createDefaultIndexes();
2888
- await this.createCustomIndexes();
2889
2864
  }
2890
- /**
2891
- * Checks if the unique index on (spanId, traceId) already exists on the spans collection.
2892
- * Used to skip deduplication when the index already exists (migration already complete).
2893
- */
2894
- async spansUniqueIndexExists() {
2865
+ async swapBufferedToActive(input) {
2895
2866
  try {
2896
- const collection = await this.getCollection(TABLE_SPANS);
2897
- const indexes = await collection.indexes();
2898
- return indexes.some((idx) => idx.unique === true && idx.key?.spanId === 1 && idx.key?.traceId === 1);
2899
- } catch {
2900
- return false;
2901
- }
2867
+ const collection = await this.getCollection(OM_TABLE);
2868
+ const doc = await collection.findOne({ id: input.id });
2869
+ if (!doc) {
2870
+ throw new MastraError({
2871
+ id: createStorageErrorId("MONGODB", "SWAP_BUFFERED_TO_ACTIVE", "NOT_FOUND"),
2872
+ text: `Observational memory record not found: ${input.id}`,
2873
+ domain: ErrorDomain.STORAGE,
2874
+ category: ErrorCategory.THIRD_PARTY,
2875
+ details: { id: input.id }
2876
+ });
2877
+ }
2878
+ const chunks = Array.isArray(doc.bufferedObservationChunks) ? doc.bufferedObservationChunks : [];
2879
+ if (chunks.length === 0) {
2880
+ return {
2881
+ chunksActivated: 0,
2882
+ messageTokensActivated: 0,
2883
+ observationTokensActivated: 0,
2884
+ messagesActivated: 0,
2885
+ activatedCycleIds: [],
2886
+ activatedMessageIds: []
2887
+ };
2888
+ }
2889
+ const retentionFloor = input.messageTokensThreshold * (1 - input.activationRatio);
2890
+ const targetMessageTokens = Math.max(0, input.currentPendingTokens - retentionFloor);
2891
+ let cumulativeMessageTokens = 0;
2892
+ let bestBoundary = 0;
2893
+ let bestBoundaryMessageTokens = 0;
2894
+ for (let i = 0; i < chunks.length; i++) {
2895
+ cumulativeMessageTokens += chunks[i].messageTokens ?? 0;
2896
+ const boundary = i + 1;
2897
+ const isUnder = cumulativeMessageTokens <= targetMessageTokens;
2898
+ const bestIsUnder = bestBoundaryMessageTokens <= targetMessageTokens;
2899
+ if (bestBoundary === 0) {
2900
+ bestBoundary = boundary;
2901
+ bestBoundaryMessageTokens = cumulativeMessageTokens;
2902
+ } else if (isUnder && !bestIsUnder) {
2903
+ bestBoundary = boundary;
2904
+ bestBoundaryMessageTokens = cumulativeMessageTokens;
2905
+ } else if (isUnder && bestIsUnder) {
2906
+ if (cumulativeMessageTokens > bestBoundaryMessageTokens) {
2907
+ bestBoundary = boundary;
2908
+ bestBoundaryMessageTokens = cumulativeMessageTokens;
2909
+ }
2910
+ } else if (!isUnder && !bestIsUnder) {
2911
+ if (cumulativeMessageTokens < bestBoundaryMessageTokens) {
2912
+ bestBoundary = boundary;
2913
+ bestBoundaryMessageTokens = cumulativeMessageTokens;
2914
+ }
2915
+ }
2916
+ }
2917
+ const chunksToActivate = bestBoundary === 0 ? 1 : bestBoundary;
2918
+ const activatedChunks = chunks.slice(0, chunksToActivate);
2919
+ const remainingChunks = chunks.slice(chunksToActivate);
2920
+ const activatedContent = activatedChunks.map((c) => c.observations).join("\n\n");
2921
+ const activatedTokens = activatedChunks.reduce((sum, c) => sum + c.tokenCount, 0);
2922
+ const activatedMessageTokens = activatedChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
2923
+ const activatedMessageCount = activatedChunks.reduce((sum, c) => sum + c.messageIds.length, 0);
2924
+ const activatedCycleIds = activatedChunks.map((c) => c.cycleId).filter((id) => !!id);
2925
+ const activatedMessageIds = activatedChunks.flatMap((c) => c.messageIds ?? []);
2926
+ const latestChunk = activatedChunks[activatedChunks.length - 1];
2927
+ const lastObservedAt = input.lastObservedAt ?? (latestChunk?.lastObservedAt ? new Date(latestChunk.lastObservedAt) : /* @__PURE__ */ new Date());
2928
+ const existingActive = doc.activeObservations || "";
2929
+ const existingTokenCount = Number(doc.observationTokenCount || 0);
2930
+ const newActive = existingActive ? `${existingActive}
2931
+
2932
+ ${activatedContent}` : activatedContent;
2933
+ const newTokenCount = existingTokenCount + activatedTokens;
2934
+ const existingPending = Number(doc.pendingMessageTokens || 0);
2935
+ const newPending = Math.max(0, existingPending - activatedMessageTokens);
2936
+ await collection.updateOne(
2937
+ { id: input.id },
2938
+ {
2939
+ $set: {
2940
+ activeObservations: newActive,
2941
+ observationTokenCount: newTokenCount,
2942
+ pendingMessageTokens: newPending,
2943
+ bufferedObservationChunks: remainingChunks.length > 0 ? remainingChunks : null,
2944
+ lastObservedAt,
2945
+ updatedAt: /* @__PURE__ */ new Date()
2946
+ }
2947
+ }
2948
+ );
2949
+ return {
2950
+ chunksActivated: activatedChunks.length,
2951
+ messageTokensActivated: activatedMessageTokens,
2952
+ observationTokensActivated: activatedTokens,
2953
+ messagesActivated: activatedMessageCount,
2954
+ activatedCycleIds,
2955
+ activatedMessageIds,
2956
+ observations: activatedContent,
2957
+ perChunk: activatedChunks.map((c) => ({
2958
+ cycleId: c.cycleId ?? "",
2959
+ messageTokens: c.messageTokens ?? 0,
2960
+ observationTokens: c.tokenCount,
2961
+ messageCount: c.messageIds.length,
2962
+ observations: c.observations
2963
+ }))
2964
+ };
2965
+ } catch (error) {
2966
+ if (error instanceof MastraError) {
2967
+ throw error;
2968
+ }
2969
+ throw new MastraError(
2970
+ {
2971
+ id: createStorageErrorId("MONGODB", "SWAP_BUFFERED_TO_ACTIVE", "FAILED"),
2972
+ domain: ErrorDomain.STORAGE,
2973
+ category: ErrorCategory.THIRD_PARTY,
2974
+ details: { id: input.id }
2975
+ },
2976
+ error
2977
+ );
2978
+ }
2979
+ }
2980
+ async updateBufferedReflection(input) {
2981
+ try {
2982
+ const collection = await this.getCollection(OM_TABLE);
2983
+ const doc = await collection.findOne({ id: input.id });
2984
+ if (!doc) {
2985
+ throw new MastraError({
2986
+ id: createStorageErrorId("MONGODB", "UPDATE_BUFFERED_REFLECTION", "NOT_FOUND"),
2987
+ text: `Observational memory record not found: ${input.id}`,
2988
+ domain: ErrorDomain.STORAGE,
2989
+ category: ErrorCategory.THIRD_PARTY,
2990
+ details: { id: input.id }
2991
+ });
2992
+ }
2993
+ const existingContent = doc.bufferedReflection || "";
2994
+ const existingTokens = Number(doc.bufferedReflectionTokens || 0);
2995
+ const existingInputTokens = Number(doc.bufferedReflectionInputTokens || 0);
2996
+ const newContent = existingContent ? `${existingContent}
2997
+
2998
+ ${input.reflection}` : input.reflection;
2999
+ const newTokens = existingTokens + input.tokenCount;
3000
+ const newInputTokens = existingInputTokens + input.inputTokenCount;
3001
+ const result = await collection.updateOne(
3002
+ { id: input.id },
3003
+ {
3004
+ $set: {
3005
+ bufferedReflection: newContent,
3006
+ bufferedReflectionTokens: newTokens,
3007
+ bufferedReflectionInputTokens: newInputTokens,
3008
+ reflectedObservationLineCount: input.reflectedObservationLineCount,
3009
+ updatedAt: /* @__PURE__ */ new Date()
3010
+ }
3011
+ }
3012
+ );
3013
+ if (result.matchedCount === 0) {
3014
+ throw new MastraError({
3015
+ id: createStorageErrorId("MONGODB", "UPDATE_BUFFERED_REFLECTION", "NOT_FOUND"),
3016
+ text: `Observational memory record not found: ${input.id}`,
3017
+ domain: ErrorDomain.STORAGE,
3018
+ category: ErrorCategory.THIRD_PARTY,
3019
+ details: { id: input.id }
3020
+ });
3021
+ }
3022
+ } catch (error) {
3023
+ if (error instanceof MastraError) {
3024
+ throw error;
3025
+ }
3026
+ throw new MastraError(
3027
+ {
3028
+ id: createStorageErrorId("MONGODB", "UPDATE_BUFFERED_REFLECTION", "FAILED"),
3029
+ domain: ErrorDomain.STORAGE,
3030
+ category: ErrorCategory.THIRD_PARTY,
3031
+ details: { id: input.id }
3032
+ },
3033
+ error
3034
+ );
3035
+ }
3036
+ }
3037
+ async swapBufferedReflectionToActive(input) {
3038
+ try {
3039
+ const collection = await this.getCollection(OM_TABLE);
3040
+ const doc = await collection.findOne({ id: input.currentRecord.id });
3041
+ if (!doc) {
3042
+ throw new MastraError({
3043
+ id: createStorageErrorId("MONGODB", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NOT_FOUND"),
3044
+ text: `Observational memory record not found: ${input.currentRecord.id}`,
3045
+ domain: ErrorDomain.STORAGE,
3046
+ category: ErrorCategory.THIRD_PARTY,
3047
+ details: { id: input.currentRecord.id }
3048
+ });
3049
+ }
3050
+ const bufferedReflection = doc.bufferedReflection || "";
3051
+ const reflectedLineCount = Number(doc.reflectedObservationLineCount || 0);
3052
+ if (!bufferedReflection) {
3053
+ throw new MastraError({
3054
+ id: createStorageErrorId("MONGODB", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "NO_CONTENT"),
3055
+ text: "No buffered reflection to swap",
3056
+ domain: ErrorDomain.STORAGE,
3057
+ category: ErrorCategory.USER,
3058
+ details: { id: input.currentRecord.id }
3059
+ });
3060
+ }
3061
+ const currentObservations = doc.activeObservations || "";
3062
+ const allLines = currentObservations.split("\n");
3063
+ const unreflectedLines = allLines.slice(reflectedLineCount);
3064
+ const unreflectedContent = unreflectedLines.join("\n").trim();
3065
+ const newObservations = unreflectedContent ? `${bufferedReflection}
3066
+
3067
+ ${unreflectedContent}` : bufferedReflection;
3068
+ const newRecord = await this.createReflectionGeneration({
3069
+ currentRecord: input.currentRecord,
3070
+ reflection: newObservations,
3071
+ tokenCount: input.tokenCount
3072
+ });
3073
+ await collection.updateOne(
3074
+ { id: input.currentRecord.id },
3075
+ {
3076
+ $set: {
3077
+ bufferedReflection: null,
3078
+ bufferedReflectionTokens: null,
3079
+ bufferedReflectionInputTokens: null,
3080
+ reflectedObservationLineCount: null,
3081
+ updatedAt: /* @__PURE__ */ new Date()
3082
+ }
3083
+ }
3084
+ );
3085
+ return newRecord;
3086
+ } catch (error) {
3087
+ if (error instanceof MastraError) {
3088
+ throw error;
3089
+ }
3090
+ throw new MastraError(
3091
+ {
3092
+ id: createStorageErrorId("MONGODB", "SWAP_BUFFERED_REFLECTION_TO_ACTIVE", "FAILED"),
3093
+ domain: ErrorDomain.STORAGE,
3094
+ category: ErrorCategory.THIRD_PARTY,
3095
+ details: { id: input.currentRecord.id }
3096
+ },
3097
+ error
3098
+ );
3099
+ }
3100
+ }
3101
+ };
3102
+ var ObservabilityMongoDB = class _ObservabilityMongoDB extends ObservabilityStorage {
3103
+ #connector;
3104
+ #skipDefaultIndexes;
3105
+ #indexes;
3106
+ /** Collections managed by this domain */
3107
+ static MANAGED_COLLECTIONS = [TABLE_SPANS];
3108
+ constructor(config) {
3109
+ super();
3110
+ this.#connector = resolveMongoDBConfig(config);
3111
+ this.#skipDefaultIndexes = config.skipDefaultIndexes;
3112
+ this.#indexes = config.indexes?.filter(
3113
+ (idx) => _ObservabilityMongoDB.MANAGED_COLLECTIONS.includes(idx.collection)
3114
+ );
3115
+ }
3116
+ async getCollection(name) {
3117
+ return this.#connector.getCollection(name);
3118
+ }
3119
+ /**
3120
+ * Returns default index definitions for the observability domain collections.
3121
+ * These indexes optimize common query patterns for span and trace lookups.
3122
+ */
3123
+ getDefaultIndexDefinitions() {
3124
+ return [
3125
+ { collection: TABLE_SPANS, keys: { spanId: 1, traceId: 1 }, options: { unique: true } },
3126
+ { collection: TABLE_SPANS, keys: { traceId: 1 } },
3127
+ { collection: TABLE_SPANS, keys: { parentSpanId: 1 } },
3128
+ { collection: TABLE_SPANS, keys: { startedAt: -1 } },
3129
+ { collection: TABLE_SPANS, keys: { spanType: 1 } },
3130
+ { collection: TABLE_SPANS, keys: { name: 1 } }
3131
+ ];
3132
+ }
3133
+ async createDefaultIndexes() {
3134
+ if (this.#skipDefaultIndexes) {
3135
+ return;
3136
+ }
3137
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
3138
+ try {
3139
+ const collection = await this.getCollection(indexDef.collection);
3140
+ await collection.createIndex(indexDef.keys, indexDef.options);
3141
+ } catch (error) {
3142
+ this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
3143
+ }
3144
+ }
3145
+ }
3146
+ /**
3147
+ * Creates custom user-defined indexes for this domain's collections.
3148
+ */
3149
+ async createCustomIndexes() {
3150
+ if (!this.#indexes || this.#indexes.length === 0) {
3151
+ return;
3152
+ }
3153
+ for (const indexDef of this.#indexes) {
3154
+ try {
3155
+ const collection = await this.getCollection(indexDef.collection);
3156
+ await collection.createIndex(indexDef.keys, indexDef.options);
3157
+ } catch (error) {
3158
+ this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
3159
+ }
3160
+ }
3161
+ }
3162
+ async init() {
3163
+ const uniqueIndexExists = await this.spansUniqueIndexExists();
3164
+ if (!uniqueIndexExists) {
3165
+ const duplicateInfo = await this.checkForDuplicateSpans();
3166
+ if (duplicateInfo.hasDuplicates) {
3167
+ const errorMessage = `
3168
+ ===========================================================================
3169
+ MIGRATION REQUIRED: Duplicate spans detected in ${TABLE_SPANS} collection
3170
+ ===========================================================================
3171
+
3172
+ Found ${duplicateInfo.duplicateCount} duplicate (traceId, spanId) combinations.
3173
+
3174
+ The spans collection requires a unique index on (traceId, spanId), but your
3175
+ database contains duplicate entries that must be resolved first.
3176
+
3177
+ To fix this, run the manual migration command:
3178
+
3179
+ npx mastra migrate
3180
+
3181
+ This command will:
3182
+ 1. Remove duplicate spans (keeping the most complete/recent version)
3183
+ 2. Add the required unique index
3184
+
3185
+ Note: This migration may take some time for large collections.
3186
+ ===========================================================================
3187
+ `;
3188
+ throw new MastraError({
3189
+ id: createStorageErrorId("MONGODB", "MIGRATION_REQUIRED", "DUPLICATE_SPANS"),
3190
+ domain: ErrorDomain.STORAGE,
3191
+ category: ErrorCategory.USER,
3192
+ text: errorMessage
3193
+ });
3194
+ }
3195
+ }
3196
+ await this.createDefaultIndexes();
3197
+ await this.createCustomIndexes();
3198
+ }
3199
+ /**
3200
+ * Checks if the unique index on (spanId, traceId) already exists on the spans collection.
3201
+ * Used to skip deduplication when the index already exists (migration already complete).
3202
+ */
3203
+ async spansUniqueIndexExists() {
3204
+ try {
3205
+ const collection = await this.getCollection(TABLE_SPANS);
3206
+ const indexes = await collection.indexes();
3207
+ return indexes.some((idx) => idx.unique === true && idx.key?.spanId === 1 && idx.key?.traceId === 1);
3208
+ } catch {
3209
+ return false;
3210
+ }
2902
3211
  }
2903
3212
  /**
2904
3213
  * Checks for duplicate (traceId, spanId) combinations in the spans collection.
@@ -3549,6 +3858,1161 @@ Note: This migration may take some time for large collections.
3549
3858
  return span;
3550
3859
  }
3551
3860
  };
3861
+ var SNAPSHOT_FIELDS2 = ["name", "description", "content", "rules"];
3862
+ var MongoDBPromptBlocksStorage = class _MongoDBPromptBlocksStorage extends PromptBlocksStorage {
3863
+ #connector;
3864
+ #skipDefaultIndexes;
3865
+ #indexes;
3866
+ static MANAGED_COLLECTIONS = [TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS];
3867
+ constructor(config) {
3868
+ super();
3869
+ this.#connector = resolveMongoDBConfig(config);
3870
+ this.#skipDefaultIndexes = config.skipDefaultIndexes;
3871
+ this.#indexes = config.indexes?.filter(
3872
+ (idx) => _MongoDBPromptBlocksStorage.MANAGED_COLLECTIONS.includes(idx.collection)
3873
+ );
3874
+ }
3875
+ async getCollection(name) {
3876
+ return this.#connector.getCollection(name);
3877
+ }
3878
+ getDefaultIndexDefinitions() {
3879
+ return [
3880
+ { collection: TABLE_PROMPT_BLOCKS, keys: { id: 1 }, options: { unique: true } },
3881
+ { collection: TABLE_PROMPT_BLOCKS, keys: { createdAt: -1 } },
3882
+ { collection: TABLE_PROMPT_BLOCKS, keys: { updatedAt: -1 } },
3883
+ { collection: TABLE_PROMPT_BLOCKS, keys: { authorId: 1 } },
3884
+ { collection: TABLE_PROMPT_BLOCK_VERSIONS, keys: { id: 1 }, options: { unique: true } },
3885
+ {
3886
+ collection: TABLE_PROMPT_BLOCK_VERSIONS,
3887
+ keys: { blockId: 1, versionNumber: -1 },
3888
+ options: { unique: true }
3889
+ },
3890
+ { collection: TABLE_PROMPT_BLOCK_VERSIONS, keys: { blockId: 1, createdAt: -1 } }
3891
+ ];
3892
+ }
3893
+ async createDefaultIndexes() {
3894
+ if (this.#skipDefaultIndexes) {
3895
+ return;
3896
+ }
3897
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
3898
+ try {
3899
+ const collection = await this.getCollection(indexDef.collection);
3900
+ await collection.createIndex(indexDef.keys, indexDef.options);
3901
+ } catch (error) {
3902
+ this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
3903
+ }
3904
+ }
3905
+ }
3906
+ async createCustomIndexes() {
3907
+ if (!this.#indexes || this.#indexes.length === 0) {
3908
+ return;
3909
+ }
3910
+ for (const indexDef of this.#indexes) {
3911
+ try {
3912
+ const collection = await this.getCollection(indexDef.collection);
3913
+ await collection.createIndex(indexDef.keys, indexDef.options);
3914
+ } catch (error) {
3915
+ this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
3916
+ }
3917
+ }
3918
+ }
3919
+ async init() {
3920
+ await this.createDefaultIndexes();
3921
+ await this.createCustomIndexes();
3922
+ }
3923
+ async dangerouslyClearAll() {
3924
+ const versionsCollection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
3925
+ await versionsCollection.deleteMany({});
3926
+ const blocksCollection = await this.getCollection(TABLE_PROMPT_BLOCKS);
3927
+ await blocksCollection.deleteMany({});
3928
+ }
3929
+ // ==========================================================================
3930
+ // Prompt Block CRUD
3931
+ // ==========================================================================
3932
+ async getById(id) {
3933
+ try {
3934
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCKS);
3935
+ const result = await collection.findOne({ id });
3936
+ if (!result) {
3937
+ return null;
3938
+ }
3939
+ return this.transformBlock(result);
3940
+ } catch (error) {
3941
+ throw new MastraError(
3942
+ {
3943
+ id: createStorageErrorId("MONGODB", "GET_PROMPT_BLOCK_BY_ID", "FAILED"),
3944
+ domain: ErrorDomain.STORAGE,
3945
+ category: ErrorCategory.THIRD_PARTY,
3946
+ details: { id }
3947
+ },
3948
+ error
3949
+ );
3950
+ }
3951
+ }
3952
+ async create(input) {
3953
+ const { promptBlock } = input;
3954
+ try {
3955
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCKS);
3956
+ const existing = await collection.findOne({ id: promptBlock.id });
3957
+ if (existing) {
3958
+ throw new MastraError({
3959
+ id: createStorageErrorId("MONGODB", "CREATE_PROMPT_BLOCK", "ALREADY_EXISTS"),
3960
+ domain: ErrorDomain.STORAGE,
3961
+ category: ErrorCategory.USER,
3962
+ details: { id: promptBlock.id },
3963
+ text: `Prompt block with id ${promptBlock.id} already exists`
3964
+ });
3965
+ }
3966
+ const now = /* @__PURE__ */ new Date();
3967
+ const newBlock = {
3968
+ id: promptBlock.id,
3969
+ status: "draft",
3970
+ activeVersionId: void 0,
3971
+ authorId: promptBlock.authorId,
3972
+ metadata: promptBlock.metadata,
3973
+ createdAt: now,
3974
+ updatedAt: now
3975
+ };
3976
+ await collection.insertOne(this.serializeBlock(newBlock));
3977
+ const snapshotConfig = {};
3978
+ for (const field of SNAPSHOT_FIELDS2) {
3979
+ if (promptBlock[field] !== void 0) {
3980
+ snapshotConfig[field] = promptBlock[field];
3981
+ }
3982
+ }
3983
+ const versionId = randomUUID();
3984
+ await this.createVersion({
3985
+ id: versionId,
3986
+ blockId: promptBlock.id,
3987
+ versionNumber: 1,
3988
+ ...snapshotConfig,
3989
+ changedFields: Object.keys(snapshotConfig),
3990
+ changeMessage: "Initial version"
3991
+ });
3992
+ return newBlock;
3993
+ } catch (error) {
3994
+ if (error instanceof MastraError) {
3995
+ throw error;
3996
+ }
3997
+ throw new MastraError(
3998
+ {
3999
+ id: createStorageErrorId("MONGODB", "CREATE_PROMPT_BLOCK", "FAILED"),
4000
+ domain: ErrorDomain.STORAGE,
4001
+ category: ErrorCategory.THIRD_PARTY,
4002
+ details: { id: promptBlock.id }
4003
+ },
4004
+ error
4005
+ );
4006
+ }
4007
+ }
4008
+ async update(input) {
4009
+ const { id, ...updates } = input;
4010
+ try {
4011
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCKS);
4012
+ const existingBlock = await collection.findOne({ id });
4013
+ if (!existingBlock) {
4014
+ throw new MastraError({
4015
+ id: createStorageErrorId("MONGODB", "UPDATE_PROMPT_BLOCK", "NOT_FOUND"),
4016
+ domain: ErrorDomain.STORAGE,
4017
+ category: ErrorCategory.USER,
4018
+ details: { id },
4019
+ text: `Prompt block with id ${id} not found`
4020
+ });
4021
+ }
4022
+ const updateDoc = {
4023
+ updatedAt: /* @__PURE__ */ new Date()
4024
+ };
4025
+ const metadataFields = {
4026
+ authorId: updates.authorId,
4027
+ activeVersionId: updates.activeVersionId,
4028
+ metadata: updates.metadata,
4029
+ status: updates.status
4030
+ };
4031
+ const configFields = {};
4032
+ for (const field of SNAPSHOT_FIELDS2) {
4033
+ if (updates[field] !== void 0) {
4034
+ configFields[field] = updates[field];
4035
+ }
4036
+ }
4037
+ if (Object.keys(configFields).length > 0) {
4038
+ const latestVersion = await this.getLatestVersion(id);
4039
+ if (!latestVersion) {
4040
+ throw new MastraError({
4041
+ id: createStorageErrorId("MONGODB", "UPDATE_PROMPT_BLOCK", "NO_VERSION"),
4042
+ domain: ErrorDomain.STORAGE,
4043
+ category: ErrorCategory.USER,
4044
+ text: `Cannot update config fields for prompt block ${id} - no versions exist`,
4045
+ details: { id }
4046
+ });
4047
+ }
4048
+ const existingSnapshot = this.extractSnapshotFields(latestVersion);
4049
+ await this.createVersion({
4050
+ id: randomUUID(),
4051
+ blockId: id,
4052
+ versionNumber: latestVersion.versionNumber + 1,
4053
+ ...existingSnapshot,
4054
+ ...configFields,
4055
+ changedFields: Object.keys(configFields),
4056
+ changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
4057
+ });
4058
+ }
4059
+ if (metadataFields.authorId !== void 0) updateDoc.authorId = metadataFields.authorId;
4060
+ if (metadataFields.activeVersionId !== void 0) {
4061
+ updateDoc.activeVersionId = metadataFields.activeVersionId;
4062
+ if (metadataFields.status === void 0) {
4063
+ updateDoc.status = "published";
4064
+ }
4065
+ }
4066
+ if (metadataFields.status !== void 0) {
4067
+ updateDoc.status = metadataFields.status;
4068
+ }
4069
+ if (metadataFields.metadata !== void 0) {
4070
+ const existingMetadata = existingBlock.metadata || {};
4071
+ updateDoc.metadata = { ...existingMetadata, ...metadataFields.metadata };
4072
+ }
4073
+ await collection.updateOne({ id }, { $set: updateDoc });
4074
+ const updatedBlock = await collection.findOne({ id });
4075
+ if (!updatedBlock) {
4076
+ throw new MastraError({
4077
+ id: createStorageErrorId("MONGODB", "UPDATE_PROMPT_BLOCK", "NOT_FOUND_AFTER_UPDATE"),
4078
+ domain: ErrorDomain.STORAGE,
4079
+ category: ErrorCategory.SYSTEM,
4080
+ text: `Prompt block with id ${id} was deleted during update`,
4081
+ details: { id }
4082
+ });
4083
+ }
4084
+ return this.transformBlock(updatedBlock);
4085
+ } catch (error) {
4086
+ if (error instanceof MastraError) {
4087
+ throw error;
4088
+ }
4089
+ throw new MastraError(
4090
+ {
4091
+ id: createStorageErrorId("MONGODB", "UPDATE_PROMPT_BLOCK", "FAILED"),
4092
+ domain: ErrorDomain.STORAGE,
4093
+ category: ErrorCategory.THIRD_PARTY,
4094
+ details: { id }
4095
+ },
4096
+ error
4097
+ );
4098
+ }
4099
+ }
4100
+ async delete(id) {
4101
+ try {
4102
+ await this.deleteVersionsByParentId(id);
4103
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCKS);
4104
+ await collection.deleteOne({ id });
4105
+ } catch (error) {
4106
+ throw new MastraError(
4107
+ {
4108
+ id: createStorageErrorId("MONGODB", "DELETE_PROMPT_BLOCK", "FAILED"),
4109
+ domain: ErrorDomain.STORAGE,
4110
+ category: ErrorCategory.THIRD_PARTY,
4111
+ details: { id }
4112
+ },
4113
+ error
4114
+ );
4115
+ }
4116
+ }
4117
+ async list(args) {
4118
+ try {
4119
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
4120
+ const { field, direction } = this.parseOrderBy(orderBy);
4121
+ if (page < 0) {
4122
+ throw new MastraError(
4123
+ {
4124
+ id: createStorageErrorId("MONGODB", "LIST_PROMPT_BLOCKS", "INVALID_PAGE"),
4125
+ domain: ErrorDomain.STORAGE,
4126
+ category: ErrorCategory.USER,
4127
+ details: { page }
4128
+ },
4129
+ new Error("page must be >= 0")
4130
+ );
4131
+ }
4132
+ const perPage = normalizePerPage(perPageInput, 100);
4133
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
4134
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCKS);
4135
+ const filter = {};
4136
+ if (authorId) {
4137
+ filter.authorId = authorId;
4138
+ }
4139
+ if (metadata) {
4140
+ for (const [key, value] of Object.entries(metadata)) {
4141
+ filter[`metadata.${key}`] = value;
4142
+ }
4143
+ }
4144
+ const total = await collection.countDocuments(filter);
4145
+ if (total === 0 || perPage === 0) {
4146
+ return {
4147
+ promptBlocks: [],
4148
+ total,
4149
+ page,
4150
+ perPage: perPageForResponse,
4151
+ hasMore: false
4152
+ };
4153
+ }
4154
+ const sortOrder = direction === "ASC" ? 1 : -1;
4155
+ let cursor = collection.find(filter).sort({ [field]: sortOrder }).skip(offset);
4156
+ if (perPageInput !== false) {
4157
+ cursor = cursor.limit(perPage);
4158
+ }
4159
+ const results = await cursor.toArray();
4160
+ const promptBlocks = results.map((doc) => this.transformBlock(doc));
4161
+ return {
4162
+ promptBlocks,
4163
+ total,
4164
+ page,
4165
+ perPage: perPageForResponse,
4166
+ hasMore: perPageInput !== false && offset + perPage < total
4167
+ };
4168
+ } catch (error) {
4169
+ if (error instanceof MastraError) {
4170
+ throw error;
4171
+ }
4172
+ throw new MastraError(
4173
+ {
4174
+ id: createStorageErrorId("MONGODB", "LIST_PROMPT_BLOCKS", "FAILED"),
4175
+ domain: ErrorDomain.STORAGE,
4176
+ category: ErrorCategory.THIRD_PARTY
4177
+ },
4178
+ error
4179
+ );
4180
+ }
4181
+ }
4182
+ // ==========================================================================
4183
+ // Prompt Block Version Methods
4184
+ // ==========================================================================
4185
+ async createVersion(input) {
4186
+ try {
4187
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4188
+ const now = /* @__PURE__ */ new Date();
4189
+ const versionDoc = {
4190
+ id: input.id,
4191
+ blockId: input.blockId,
4192
+ versionNumber: input.versionNumber,
4193
+ changedFields: input.changedFields ?? void 0,
4194
+ changeMessage: input.changeMessage ?? void 0,
4195
+ createdAt: now
4196
+ };
4197
+ for (const field of SNAPSHOT_FIELDS2) {
4198
+ if (input[field] !== void 0) {
4199
+ versionDoc[field] = input[field];
4200
+ }
4201
+ }
4202
+ await collection.insertOne(versionDoc);
4203
+ return {
4204
+ ...input,
4205
+ createdAt: now
4206
+ };
4207
+ } catch (error) {
4208
+ throw new MastraError(
4209
+ {
4210
+ id: createStorageErrorId("MONGODB", "CREATE_PROMPT_BLOCK_VERSION", "FAILED"),
4211
+ domain: ErrorDomain.STORAGE,
4212
+ category: ErrorCategory.THIRD_PARTY,
4213
+ details: { versionId: input.id, blockId: input.blockId }
4214
+ },
4215
+ error
4216
+ );
4217
+ }
4218
+ }
4219
+ async getVersion(id) {
4220
+ try {
4221
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4222
+ const result = await collection.findOne({ id });
4223
+ if (!result) {
4224
+ return null;
4225
+ }
4226
+ return this.transformVersion(result);
4227
+ } catch (error) {
4228
+ throw new MastraError(
4229
+ {
4230
+ id: createStorageErrorId("MONGODB", "GET_PROMPT_BLOCK_VERSION", "FAILED"),
4231
+ domain: ErrorDomain.STORAGE,
4232
+ category: ErrorCategory.THIRD_PARTY,
4233
+ details: { versionId: id }
4234
+ },
4235
+ error
4236
+ );
4237
+ }
4238
+ }
4239
+ async getVersionByNumber(blockId, versionNumber) {
4240
+ try {
4241
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4242
+ const result = await collection.findOne({ blockId, versionNumber });
4243
+ if (!result) {
4244
+ return null;
4245
+ }
4246
+ return this.transformVersion(result);
4247
+ } catch (error) {
4248
+ throw new MastraError(
4249
+ {
4250
+ id: createStorageErrorId("MONGODB", "GET_PROMPT_BLOCK_VERSION_BY_NUMBER", "FAILED"),
4251
+ domain: ErrorDomain.STORAGE,
4252
+ category: ErrorCategory.THIRD_PARTY,
4253
+ details: { blockId, versionNumber }
4254
+ },
4255
+ error
4256
+ );
4257
+ }
4258
+ }
4259
+ async getLatestVersion(blockId) {
4260
+ try {
4261
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4262
+ const result = await collection.find({ blockId }).sort({ versionNumber: -1 }).limit(1).toArray();
4263
+ if (!result || result.length === 0) {
4264
+ return null;
4265
+ }
4266
+ return this.transformVersion(result[0]);
4267
+ } catch (error) {
4268
+ throw new MastraError(
4269
+ {
4270
+ id: createStorageErrorId("MONGODB", "GET_LATEST_PROMPT_BLOCK_VERSION", "FAILED"),
4271
+ domain: ErrorDomain.STORAGE,
4272
+ category: ErrorCategory.THIRD_PARTY,
4273
+ details: { blockId }
4274
+ },
4275
+ error
4276
+ );
4277
+ }
4278
+ }
4279
+ async listVersions(input) {
4280
+ const { blockId, page = 0, perPage: perPageInput, orderBy } = input;
4281
+ if (page < 0) {
4282
+ throw new MastraError(
4283
+ {
4284
+ id: createStorageErrorId("MONGODB", "LIST_PROMPT_BLOCK_VERSIONS", "INVALID_PAGE"),
4285
+ domain: ErrorDomain.STORAGE,
4286
+ category: ErrorCategory.USER,
4287
+ details: { page }
4288
+ },
4289
+ new Error("page must be >= 0")
4290
+ );
4291
+ }
4292
+ const perPage = normalizePerPage(perPageInput, 20);
4293
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
4294
+ try {
4295
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
4296
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4297
+ const total = await collection.countDocuments({ blockId });
4298
+ if (total === 0 || perPage === 0) {
4299
+ return {
4300
+ versions: [],
4301
+ total,
4302
+ page,
4303
+ perPage: perPageForResponse,
4304
+ hasMore: false
4305
+ };
4306
+ }
4307
+ const sortOrder = direction === "ASC" ? 1 : -1;
4308
+ let cursor = collection.find({ blockId }).sort({ [field]: sortOrder }).skip(offset);
4309
+ if (perPageInput !== false) {
4310
+ cursor = cursor.limit(perPage);
4311
+ }
4312
+ const results = await cursor.toArray();
4313
+ const versions = results.map((doc) => this.transformVersion(doc));
4314
+ return {
4315
+ versions,
4316
+ total,
4317
+ page,
4318
+ perPage: perPageForResponse,
4319
+ hasMore: perPageInput !== false && offset + perPage < total
4320
+ };
4321
+ } catch (error) {
4322
+ throw new MastraError(
4323
+ {
4324
+ id: createStorageErrorId("MONGODB", "LIST_PROMPT_BLOCK_VERSIONS", "FAILED"),
4325
+ domain: ErrorDomain.STORAGE,
4326
+ category: ErrorCategory.THIRD_PARTY,
4327
+ details: { blockId }
4328
+ },
4329
+ error
4330
+ );
4331
+ }
4332
+ }
4333
+ async deleteVersion(id) {
4334
+ try {
4335
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4336
+ await collection.deleteOne({ id });
4337
+ } catch (error) {
4338
+ throw new MastraError(
4339
+ {
4340
+ id: createStorageErrorId("MONGODB", "DELETE_PROMPT_BLOCK_VERSION", "FAILED"),
4341
+ domain: ErrorDomain.STORAGE,
4342
+ category: ErrorCategory.THIRD_PARTY,
4343
+ details: { versionId: id }
4344
+ },
4345
+ error
4346
+ );
4347
+ }
4348
+ }
4349
+ async deleteVersionsByParentId(blockId) {
4350
+ try {
4351
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4352
+ await collection.deleteMany({ blockId });
4353
+ } catch (error) {
4354
+ throw new MastraError(
4355
+ {
4356
+ id: createStorageErrorId("MONGODB", "DELETE_VERSIONS_BY_BLOCK_ID", "FAILED"),
4357
+ domain: ErrorDomain.STORAGE,
4358
+ category: ErrorCategory.THIRD_PARTY,
4359
+ details: { blockId }
4360
+ },
4361
+ error
4362
+ );
4363
+ }
4364
+ }
4365
+ async countVersions(blockId) {
4366
+ try {
4367
+ const collection = await this.getCollection(TABLE_PROMPT_BLOCK_VERSIONS);
4368
+ return await collection.countDocuments({ blockId });
4369
+ } catch (error) {
4370
+ throw new MastraError(
4371
+ {
4372
+ id: createStorageErrorId("MONGODB", "COUNT_PROMPT_BLOCK_VERSIONS", "FAILED"),
4373
+ domain: ErrorDomain.STORAGE,
4374
+ category: ErrorCategory.THIRD_PARTY,
4375
+ details: { blockId }
4376
+ },
4377
+ error
4378
+ );
4379
+ }
4380
+ }
4381
+ // ==========================================================================
4382
+ // Private Helper Methods
4383
+ // ==========================================================================
4384
+ transformBlock(doc) {
4385
+ const { _id, ...rest } = doc;
4386
+ return {
4387
+ id: rest.id,
4388
+ status: rest.status,
4389
+ activeVersionId: rest.activeVersionId,
4390
+ authorId: rest.authorId,
4391
+ metadata: rest.metadata,
4392
+ createdAt: rest.createdAt instanceof Date ? rest.createdAt : new Date(rest.createdAt),
4393
+ updatedAt: rest.updatedAt instanceof Date ? rest.updatedAt : new Date(rest.updatedAt)
4394
+ };
4395
+ }
4396
+ serializeBlock(block) {
4397
+ return {
4398
+ id: block.id,
4399
+ status: block.status,
4400
+ activeVersionId: block.activeVersionId,
4401
+ authorId: block.authorId,
4402
+ metadata: block.metadata,
4403
+ createdAt: block.createdAt,
4404
+ updatedAt: block.updatedAt
4405
+ };
4406
+ }
4407
+ transformVersion(doc) {
4408
+ const { _id, ...version } = doc;
4409
+ const result = {
4410
+ id: version.id,
4411
+ blockId: version.blockId,
4412
+ versionNumber: version.versionNumber,
4413
+ changedFields: version.changedFields,
4414
+ changeMessage: version.changeMessage,
4415
+ createdAt: version.createdAt instanceof Date ? version.createdAt : new Date(version.createdAt)
4416
+ };
4417
+ for (const field of SNAPSHOT_FIELDS2) {
4418
+ if (version[field] !== void 0) {
4419
+ result[field] = version[field];
4420
+ }
4421
+ }
4422
+ return result;
4423
+ }
4424
+ extractSnapshotFields(version) {
4425
+ const result = {};
4426
+ for (const field of SNAPSHOT_FIELDS2) {
4427
+ if (version[field] !== void 0) {
4428
+ result[field] = version[field];
4429
+ }
4430
+ }
4431
+ return result;
4432
+ }
4433
+ };
4434
+ var SNAPSHOT_FIELDS3 = [
4435
+ "name",
4436
+ "description",
4437
+ "type",
4438
+ "model",
4439
+ "instructions",
4440
+ "scoreRange",
4441
+ "presetConfig",
4442
+ "defaultSampling"
4443
+ ];
4444
+ var MongoDBScorerDefinitionsStorage = class _MongoDBScorerDefinitionsStorage extends ScorerDefinitionsStorage {
4445
+ #connector;
4446
+ #skipDefaultIndexes;
4447
+ #indexes;
4448
+ static MANAGED_COLLECTIONS = [TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS];
4449
+ constructor(config) {
4450
+ super();
4451
+ this.#connector = resolveMongoDBConfig(config);
4452
+ this.#skipDefaultIndexes = config.skipDefaultIndexes;
4453
+ this.#indexes = config.indexes?.filter(
4454
+ (idx) => _MongoDBScorerDefinitionsStorage.MANAGED_COLLECTIONS.includes(idx.collection)
4455
+ );
4456
+ }
4457
+ async getCollection(name) {
4458
+ return this.#connector.getCollection(name);
4459
+ }
4460
+ getDefaultIndexDefinitions() {
4461
+ return [
4462
+ { collection: TABLE_SCORER_DEFINITIONS, keys: { id: 1 }, options: { unique: true } },
4463
+ { collection: TABLE_SCORER_DEFINITIONS, keys: { createdAt: -1 } },
4464
+ { collection: TABLE_SCORER_DEFINITIONS, keys: { updatedAt: -1 } },
4465
+ { collection: TABLE_SCORER_DEFINITIONS, keys: { authorId: 1 } },
4466
+ { collection: TABLE_SCORER_DEFINITION_VERSIONS, keys: { id: 1 }, options: { unique: true } },
4467
+ {
4468
+ collection: TABLE_SCORER_DEFINITION_VERSIONS,
4469
+ keys: { scorerDefinitionId: 1, versionNumber: -1 },
4470
+ options: { unique: true }
4471
+ },
4472
+ { collection: TABLE_SCORER_DEFINITION_VERSIONS, keys: { scorerDefinitionId: 1, createdAt: -1 } }
4473
+ ];
4474
+ }
4475
+ async createDefaultIndexes() {
4476
+ if (this.#skipDefaultIndexes) {
4477
+ return;
4478
+ }
4479
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
4480
+ try {
4481
+ const collection = await this.getCollection(indexDef.collection);
4482
+ await collection.createIndex(indexDef.keys, indexDef.options);
4483
+ } catch (error) {
4484
+ this.logger?.warn?.(`Failed to create index on ${indexDef.collection}:`, error);
4485
+ }
4486
+ }
4487
+ }
4488
+ async createCustomIndexes() {
4489
+ if (!this.#indexes || this.#indexes.length === 0) {
4490
+ return;
4491
+ }
4492
+ for (const indexDef of this.#indexes) {
4493
+ try {
4494
+ const collection = await this.getCollection(indexDef.collection);
4495
+ await collection.createIndex(indexDef.keys, indexDef.options);
4496
+ } catch (error) {
4497
+ this.logger?.warn?.(`Failed to create custom index on ${indexDef.collection}:`, error);
4498
+ }
4499
+ }
4500
+ }
4501
+ async init() {
4502
+ await this.createDefaultIndexes();
4503
+ await this.createCustomIndexes();
4504
+ }
4505
+ async dangerouslyClearAll() {
4506
+ const versionsCollection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4507
+ await versionsCollection.deleteMany({});
4508
+ const scorerDefinitionsCollection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4509
+ await scorerDefinitionsCollection.deleteMany({});
4510
+ }
4511
+ // ==========================================================================
4512
+ // Scorer Definition CRUD
4513
+ // ==========================================================================
4514
+ async getById(id) {
4515
+ try {
4516
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4517
+ const result = await collection.findOne({ id });
4518
+ if (!result) {
4519
+ return null;
4520
+ }
4521
+ return this.transformScorerDefinition(result);
4522
+ } catch (error) {
4523
+ throw new MastraError(
4524
+ {
4525
+ id: createStorageErrorId("MONGODB", "GET_SCORER_DEFINITION_BY_ID", "FAILED"),
4526
+ domain: ErrorDomain.STORAGE,
4527
+ category: ErrorCategory.THIRD_PARTY,
4528
+ details: { id }
4529
+ },
4530
+ error
4531
+ );
4532
+ }
4533
+ }
4534
+ async create(input) {
4535
+ const { scorerDefinition } = input;
4536
+ try {
4537
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4538
+ const existing = await collection.findOne({ id: scorerDefinition.id });
4539
+ if (existing) {
4540
+ throw new MastraError({
4541
+ id: createStorageErrorId("MONGODB", "CREATE_SCORER_DEFINITION", "ALREADY_EXISTS"),
4542
+ domain: ErrorDomain.STORAGE,
4543
+ category: ErrorCategory.USER,
4544
+ details: { id: scorerDefinition.id },
4545
+ text: `Scorer definition with id ${scorerDefinition.id} already exists`
4546
+ });
4547
+ }
4548
+ const now = /* @__PURE__ */ new Date();
4549
+ const newScorerDefinition = {
4550
+ id: scorerDefinition.id,
4551
+ status: "draft",
4552
+ activeVersionId: void 0,
4553
+ authorId: scorerDefinition.authorId,
4554
+ metadata: scorerDefinition.metadata,
4555
+ createdAt: now,
4556
+ updatedAt: now
4557
+ };
4558
+ await collection.insertOne(this.serializeScorerDefinition(newScorerDefinition));
4559
+ const snapshotConfig = {};
4560
+ for (const field of SNAPSHOT_FIELDS3) {
4561
+ if (scorerDefinition[field] !== void 0) {
4562
+ snapshotConfig[field] = scorerDefinition[field];
4563
+ }
4564
+ }
4565
+ const versionId = randomUUID();
4566
+ await this.createVersion({
4567
+ id: versionId,
4568
+ scorerDefinitionId: scorerDefinition.id,
4569
+ versionNumber: 1,
4570
+ ...snapshotConfig,
4571
+ changedFields: Object.keys(snapshotConfig),
4572
+ changeMessage: "Initial version"
4573
+ });
4574
+ return newScorerDefinition;
4575
+ } catch (error) {
4576
+ if (error instanceof MastraError) {
4577
+ throw error;
4578
+ }
4579
+ throw new MastraError(
4580
+ {
4581
+ id: createStorageErrorId("MONGODB", "CREATE_SCORER_DEFINITION", "FAILED"),
4582
+ domain: ErrorDomain.STORAGE,
4583
+ category: ErrorCategory.THIRD_PARTY,
4584
+ details: { id: scorerDefinition.id }
4585
+ },
4586
+ error
4587
+ );
4588
+ }
4589
+ }
4590
+ async update(input) {
4591
+ const { id, ...updates } = input;
4592
+ try {
4593
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4594
+ const existingScorerDefinition = await collection.findOne({ id });
4595
+ if (!existingScorerDefinition) {
4596
+ throw new MastraError({
4597
+ id: createStorageErrorId("MONGODB", "UPDATE_SCORER_DEFINITION", "NOT_FOUND"),
4598
+ domain: ErrorDomain.STORAGE,
4599
+ category: ErrorCategory.USER,
4600
+ details: { id },
4601
+ text: `Scorer definition with id ${id} not found`
4602
+ });
4603
+ }
4604
+ const updateDoc = {
4605
+ updatedAt: /* @__PURE__ */ new Date()
4606
+ };
4607
+ const metadataFields = {
4608
+ authorId: updates.authorId,
4609
+ activeVersionId: updates.activeVersionId,
4610
+ metadata: updates.metadata,
4611
+ status: updates.status
4612
+ };
4613
+ const configFields = {};
4614
+ for (const field of SNAPSHOT_FIELDS3) {
4615
+ if (updates[field] !== void 0) {
4616
+ configFields[field] = updates[field];
4617
+ }
4618
+ }
4619
+ if (Object.keys(configFields).length > 0) {
4620
+ const latestVersion = await this.getLatestVersion(id);
4621
+ if (!latestVersion) {
4622
+ throw new MastraError({
4623
+ id: createStorageErrorId("MONGODB", "UPDATE_SCORER_DEFINITION", "NO_VERSION"),
4624
+ domain: ErrorDomain.STORAGE,
4625
+ category: ErrorCategory.USER,
4626
+ text: `Cannot update config fields for scorer definition ${id} - no versions exist`,
4627
+ details: { id }
4628
+ });
4629
+ }
4630
+ const existingSnapshot = this.extractSnapshotFields(latestVersion);
4631
+ await this.createVersion({
4632
+ id: randomUUID(),
4633
+ scorerDefinitionId: id,
4634
+ versionNumber: latestVersion.versionNumber + 1,
4635
+ ...existingSnapshot,
4636
+ ...configFields,
4637
+ changedFields: Object.keys(configFields),
4638
+ changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
4639
+ });
4640
+ }
4641
+ if (metadataFields.authorId !== void 0) updateDoc.authorId = metadataFields.authorId;
4642
+ if (metadataFields.activeVersionId !== void 0) {
4643
+ updateDoc.activeVersionId = metadataFields.activeVersionId;
4644
+ if (metadataFields.status === void 0) {
4645
+ updateDoc.status = "published";
4646
+ }
4647
+ }
4648
+ if (metadataFields.status !== void 0) {
4649
+ updateDoc.status = metadataFields.status;
4650
+ }
4651
+ if (metadataFields.metadata !== void 0) {
4652
+ const existingMetadata = existingScorerDefinition.metadata || {};
4653
+ updateDoc.metadata = { ...existingMetadata, ...metadataFields.metadata };
4654
+ }
4655
+ await collection.updateOne({ id }, { $set: updateDoc });
4656
+ const updatedScorerDefinition = await collection.findOne({ id });
4657
+ if (!updatedScorerDefinition) {
4658
+ throw new MastraError({
4659
+ id: createStorageErrorId("MONGODB", "UPDATE_SCORER_DEFINITION", "NOT_FOUND_AFTER_UPDATE"),
4660
+ domain: ErrorDomain.STORAGE,
4661
+ category: ErrorCategory.SYSTEM,
4662
+ text: `Scorer definition with id ${id} was deleted during update`,
4663
+ details: { id }
4664
+ });
4665
+ }
4666
+ return this.transformScorerDefinition(updatedScorerDefinition);
4667
+ } catch (error) {
4668
+ if (error instanceof MastraError) {
4669
+ throw error;
4670
+ }
4671
+ throw new MastraError(
4672
+ {
4673
+ id: createStorageErrorId("MONGODB", "UPDATE_SCORER_DEFINITION", "FAILED"),
4674
+ domain: ErrorDomain.STORAGE,
4675
+ category: ErrorCategory.THIRD_PARTY,
4676
+ details: { id }
4677
+ },
4678
+ error
4679
+ );
4680
+ }
4681
+ }
4682
+ async delete(id) {
4683
+ try {
4684
+ await this.deleteVersionsByParentId(id);
4685
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4686
+ await collection.deleteOne({ id });
4687
+ } catch (error) {
4688
+ throw new MastraError(
4689
+ {
4690
+ id: createStorageErrorId("MONGODB", "DELETE_SCORER_DEFINITION", "FAILED"),
4691
+ domain: ErrorDomain.STORAGE,
4692
+ category: ErrorCategory.THIRD_PARTY,
4693
+ details: { id }
4694
+ },
4695
+ error
4696
+ );
4697
+ }
4698
+ }
4699
+ async list(args) {
4700
+ try {
4701
+ const { page = 0, perPage: perPageInput, orderBy, authorId, metadata } = args || {};
4702
+ const { field, direction } = this.parseOrderBy(orderBy);
4703
+ if (page < 0) {
4704
+ throw new MastraError(
4705
+ {
4706
+ id: createStorageErrorId("MONGODB", "LIST_SCORER_DEFINITIONS", "INVALID_PAGE"),
4707
+ domain: ErrorDomain.STORAGE,
4708
+ category: ErrorCategory.USER,
4709
+ details: { page }
4710
+ },
4711
+ new Error("page must be >= 0")
4712
+ );
4713
+ }
4714
+ const perPage = normalizePerPage(perPageInput, 100);
4715
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
4716
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITIONS);
4717
+ const filter = {};
4718
+ if (authorId) {
4719
+ filter.authorId = authorId;
4720
+ }
4721
+ if (metadata) {
4722
+ for (const [key, value] of Object.entries(metadata)) {
4723
+ filter[`metadata.${key}`] = value;
4724
+ }
4725
+ }
4726
+ const total = await collection.countDocuments(filter);
4727
+ if (total === 0 || perPage === 0) {
4728
+ return {
4729
+ scorerDefinitions: [],
4730
+ total,
4731
+ page,
4732
+ perPage: perPageForResponse,
4733
+ hasMore: false
4734
+ };
4735
+ }
4736
+ const sortOrder = direction === "ASC" ? 1 : -1;
4737
+ let cursor = collection.find(filter).sort({ [field]: sortOrder }).skip(offset);
4738
+ if (perPageInput !== false) {
4739
+ cursor = cursor.limit(perPage);
4740
+ }
4741
+ const results = await cursor.toArray();
4742
+ const scorerDefinitions = results.map((doc) => this.transformScorerDefinition(doc));
4743
+ return {
4744
+ scorerDefinitions,
4745
+ total,
4746
+ page,
4747
+ perPage: perPageForResponse,
4748
+ hasMore: perPageInput !== false && offset + perPage < total
4749
+ };
4750
+ } catch (error) {
4751
+ if (error instanceof MastraError) {
4752
+ throw error;
4753
+ }
4754
+ throw new MastraError(
4755
+ {
4756
+ id: createStorageErrorId("MONGODB", "LIST_SCORER_DEFINITIONS", "FAILED"),
4757
+ domain: ErrorDomain.STORAGE,
4758
+ category: ErrorCategory.THIRD_PARTY
4759
+ },
4760
+ error
4761
+ );
4762
+ }
4763
+ }
4764
+ // ==========================================================================
4765
+ // Scorer Definition Version Methods
4766
+ // ==========================================================================
4767
+ async createVersion(input) {
4768
+ try {
4769
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4770
+ const now = /* @__PURE__ */ new Date();
4771
+ const versionDoc = {
4772
+ id: input.id,
4773
+ scorerDefinitionId: input.scorerDefinitionId,
4774
+ versionNumber: input.versionNumber,
4775
+ changedFields: input.changedFields ?? void 0,
4776
+ changeMessage: input.changeMessage ?? void 0,
4777
+ createdAt: now
4778
+ };
4779
+ for (const field of SNAPSHOT_FIELDS3) {
4780
+ if (input[field] !== void 0) {
4781
+ versionDoc[field] = input[field];
4782
+ }
4783
+ }
4784
+ await collection.insertOne(versionDoc);
4785
+ return {
4786
+ ...input,
4787
+ createdAt: now
4788
+ };
4789
+ } catch (error) {
4790
+ throw new MastraError(
4791
+ {
4792
+ id: createStorageErrorId("MONGODB", "CREATE_SCORER_DEFINITION_VERSION", "FAILED"),
4793
+ domain: ErrorDomain.STORAGE,
4794
+ category: ErrorCategory.THIRD_PARTY,
4795
+ details: { versionId: input.id, scorerDefinitionId: input.scorerDefinitionId }
4796
+ },
4797
+ error
4798
+ );
4799
+ }
4800
+ }
4801
+ async getVersion(id) {
4802
+ try {
4803
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4804
+ const result = await collection.findOne({ id });
4805
+ if (!result) {
4806
+ return null;
4807
+ }
4808
+ return this.transformVersion(result);
4809
+ } catch (error) {
4810
+ throw new MastraError(
4811
+ {
4812
+ id: createStorageErrorId("MONGODB", "GET_SCORER_DEFINITION_VERSION", "FAILED"),
4813
+ domain: ErrorDomain.STORAGE,
4814
+ category: ErrorCategory.THIRD_PARTY,
4815
+ details: { versionId: id }
4816
+ },
4817
+ error
4818
+ );
4819
+ }
4820
+ }
4821
+ async getVersionByNumber(scorerDefinitionId, versionNumber) {
4822
+ try {
4823
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4824
+ const result = await collection.findOne({ scorerDefinitionId, versionNumber });
4825
+ if (!result) {
4826
+ return null;
4827
+ }
4828
+ return this.transformVersion(result);
4829
+ } catch (error) {
4830
+ throw new MastraError(
4831
+ {
4832
+ id: createStorageErrorId("MONGODB", "GET_SCORER_DEFINITION_VERSION_BY_NUMBER", "FAILED"),
4833
+ domain: ErrorDomain.STORAGE,
4834
+ category: ErrorCategory.THIRD_PARTY,
4835
+ details: { scorerDefinitionId, versionNumber }
4836
+ },
4837
+ error
4838
+ );
4839
+ }
4840
+ }
4841
+ async getLatestVersion(scorerDefinitionId) {
4842
+ try {
4843
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4844
+ const result = await collection.find({ scorerDefinitionId }).sort({ versionNumber: -1 }).limit(1).toArray();
4845
+ if (!result || result.length === 0) {
4846
+ return null;
4847
+ }
4848
+ return this.transformVersion(result[0]);
4849
+ } catch (error) {
4850
+ throw new MastraError(
4851
+ {
4852
+ id: createStorageErrorId("MONGODB", "GET_LATEST_SCORER_DEFINITION_VERSION", "FAILED"),
4853
+ domain: ErrorDomain.STORAGE,
4854
+ category: ErrorCategory.THIRD_PARTY,
4855
+ details: { scorerDefinitionId }
4856
+ },
4857
+ error
4858
+ );
4859
+ }
4860
+ }
4861
+ async listVersions(input) {
4862
+ const { scorerDefinitionId, page = 0, perPage: perPageInput, orderBy } = input;
4863
+ if (page < 0) {
4864
+ throw new MastraError(
4865
+ {
4866
+ id: createStorageErrorId("MONGODB", "LIST_SCORER_DEFINITION_VERSIONS", "INVALID_PAGE"),
4867
+ domain: ErrorDomain.STORAGE,
4868
+ category: ErrorCategory.USER,
4869
+ details: { page }
4870
+ },
4871
+ new Error("page must be >= 0")
4872
+ );
4873
+ }
4874
+ const perPage = normalizePerPage(perPageInput, 20);
4875
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
4876
+ try {
4877
+ const { field, direction } = this.parseVersionOrderBy(orderBy);
4878
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4879
+ const total = await collection.countDocuments({ scorerDefinitionId });
4880
+ if (total === 0 || perPage === 0) {
4881
+ return {
4882
+ versions: [],
4883
+ total,
4884
+ page,
4885
+ perPage: perPageForResponse,
4886
+ hasMore: false
4887
+ };
4888
+ }
4889
+ const sortOrder = direction === "ASC" ? 1 : -1;
4890
+ let cursor = collection.find({ scorerDefinitionId }).sort({ [field]: sortOrder }).skip(offset);
4891
+ if (perPageInput !== false) {
4892
+ cursor = cursor.limit(perPage);
4893
+ }
4894
+ const results = await cursor.toArray();
4895
+ const versions = results.map((doc) => this.transformVersion(doc));
4896
+ return {
4897
+ versions,
4898
+ total,
4899
+ page,
4900
+ perPage: perPageForResponse,
4901
+ hasMore: perPageInput !== false && offset + perPage < total
4902
+ };
4903
+ } catch (error) {
4904
+ throw new MastraError(
4905
+ {
4906
+ id: createStorageErrorId("MONGODB", "LIST_SCORER_DEFINITION_VERSIONS", "FAILED"),
4907
+ domain: ErrorDomain.STORAGE,
4908
+ category: ErrorCategory.THIRD_PARTY,
4909
+ details: { scorerDefinitionId }
4910
+ },
4911
+ error
4912
+ );
4913
+ }
4914
+ }
4915
+ async deleteVersion(id) {
4916
+ try {
4917
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4918
+ await collection.deleteOne({ id });
4919
+ } catch (error) {
4920
+ throw new MastraError(
4921
+ {
4922
+ id: createStorageErrorId("MONGODB", "DELETE_SCORER_DEFINITION_VERSION", "FAILED"),
4923
+ domain: ErrorDomain.STORAGE,
4924
+ category: ErrorCategory.THIRD_PARTY,
4925
+ details: { versionId: id }
4926
+ },
4927
+ error
4928
+ );
4929
+ }
4930
+ }
4931
+ async deleteVersionsByParentId(scorerDefinitionId) {
4932
+ try {
4933
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4934
+ await collection.deleteMany({ scorerDefinitionId });
4935
+ } catch (error) {
4936
+ throw new MastraError(
4937
+ {
4938
+ id: createStorageErrorId("MONGODB", "DELETE_VERSIONS_BY_SCORER_DEFINITION_ID", "FAILED"),
4939
+ domain: ErrorDomain.STORAGE,
4940
+ category: ErrorCategory.THIRD_PARTY,
4941
+ details: { scorerDefinitionId }
4942
+ },
4943
+ error
4944
+ );
4945
+ }
4946
+ }
4947
+ async countVersions(scorerDefinitionId) {
4948
+ try {
4949
+ const collection = await this.getCollection(TABLE_SCORER_DEFINITION_VERSIONS);
4950
+ return await collection.countDocuments({ scorerDefinitionId });
4951
+ } catch (error) {
4952
+ throw new MastraError(
4953
+ {
4954
+ id: createStorageErrorId("MONGODB", "COUNT_SCORER_DEFINITION_VERSIONS", "FAILED"),
4955
+ domain: ErrorDomain.STORAGE,
4956
+ category: ErrorCategory.THIRD_PARTY,
4957
+ details: { scorerDefinitionId }
4958
+ },
4959
+ error
4960
+ );
4961
+ }
4962
+ }
4963
+ // ==========================================================================
4964
+ // Private Helper Methods
4965
+ // ==========================================================================
4966
+ transformScorerDefinition(doc) {
4967
+ const { _id, ...rest } = doc;
4968
+ return {
4969
+ id: rest.id,
4970
+ status: rest.status,
4971
+ activeVersionId: rest.activeVersionId,
4972
+ authorId: rest.authorId,
4973
+ metadata: rest.metadata,
4974
+ createdAt: rest.createdAt instanceof Date ? rest.createdAt : new Date(rest.createdAt),
4975
+ updatedAt: rest.updatedAt instanceof Date ? rest.updatedAt : new Date(rest.updatedAt)
4976
+ };
4977
+ }
4978
+ serializeScorerDefinition(scorerDefinition) {
4979
+ return {
4980
+ id: scorerDefinition.id,
4981
+ status: scorerDefinition.status,
4982
+ activeVersionId: scorerDefinition.activeVersionId,
4983
+ authorId: scorerDefinition.authorId,
4984
+ metadata: scorerDefinition.metadata,
4985
+ createdAt: scorerDefinition.createdAt,
4986
+ updatedAt: scorerDefinition.updatedAt
4987
+ };
4988
+ }
4989
+ transformVersion(doc) {
4990
+ const { _id, ...version } = doc;
4991
+ const result = {
4992
+ id: version.id,
4993
+ scorerDefinitionId: version.scorerDefinitionId,
4994
+ versionNumber: version.versionNumber,
4995
+ changedFields: version.changedFields,
4996
+ changeMessage: version.changeMessage,
4997
+ createdAt: version.createdAt instanceof Date ? version.createdAt : new Date(version.createdAt)
4998
+ };
4999
+ for (const field of SNAPSHOT_FIELDS3) {
5000
+ if (version[field] !== void 0) {
5001
+ result[field] = version[field];
5002
+ }
5003
+ }
5004
+ return result;
5005
+ }
5006
+ extractSnapshotFields(version) {
5007
+ const result = {};
5008
+ for (const field of SNAPSHOT_FIELDS3) {
5009
+ if (version[field] !== void 0) {
5010
+ result[field] = version[field];
5011
+ }
5012
+ }
5013
+ return result;
5014
+ }
5015
+ };
3552
5016
  function transformScoreRow(row) {
3553
5017
  return transformScoreRow$1(row, {
3554
5018
  convertTimestamps: true
@@ -4213,12 +5677,16 @@ var MongoDBStore = class extends MastraCompositeStore {
4213
5677
  const workflows = new WorkflowsStorageMongoDB(domainConfig);
4214
5678
  const observability = new ObservabilityMongoDB(domainConfig);
4215
5679
  const agents = new MongoDBAgentsStorage(domainConfig);
5680
+ const promptBlocks = new MongoDBPromptBlocksStorage(domainConfig);
5681
+ const scorerDefinitions = new MongoDBScorerDefinitionsStorage(domainConfig);
4216
5682
  this.stores = {
4217
5683
  memory,
4218
5684
  scores,
4219
5685
  workflows,
4220
5686
  observability,
4221
- agents
5687
+ agents,
5688
+ promptBlocks,
5689
+ scorerDefinitions
4222
5690
  };
4223
5691
  }
4224
5692
  /**
@@ -4337,6 +5805,6 @@ Example Complex Query:
4337
5805
  ]
4338
5806
  }`;
4339
5807
 
4340
- export { MONGODB_PROMPT, MemoryStorageMongoDB, MongoDBAgentsStorage, MongoDBStore, MongoDBVector, ObservabilityMongoDB, ScoresStorageMongoDB, WorkflowsStorageMongoDB };
5808
+ export { MONGODB_PROMPT, MemoryStorageMongoDB, MongoDBAgentsStorage, MongoDBPromptBlocksStorage, MongoDBScorerDefinitionsStorage, MongoDBStore, MongoDBVector, ObservabilityMongoDB, ScoresStorageMongoDB, WorkflowsStorageMongoDB };
4341
5809
  //# sourceMappingURL=index.js.map
4342
5810
  //# sourceMappingURL=index.js.map