@mastra/server 1.26.0-alpha.3 → 1.26.0-alpha.8

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.
@@ -1042,7 +1042,7 @@ function imageSize(input) {
1042
1042
  throw new TypeError(`unsupported file type: ${type}`);
1043
1043
  }
1044
1044
 
1045
- // ../memory/dist/chunk-HB6AYAFD.js
1045
+ // ../memory/dist/chunk-MGHUIRKN.js
1046
1046
  var OM_DEBUG_LOG = process.env.OM_DEBUG ? path.join(process.cwd(), "om-debug.log") : null;
1047
1047
  function omDebug(msg) {
1048
1048
  if (!OM_DEBUG_LOG) return;
@@ -1225,6 +1225,17 @@ var BufferingCoordinator = class _BufferingCoordinator {
1225
1225
  }
1226
1226
  }
1227
1227
  };
1228
+ function didProviderChange(actorModel, lastModel) {
1229
+ if (actorModel === void 0 || lastModel === void 0) return false;
1230
+ const actorHasSlash = actorModel.includes("/");
1231
+ const lastHasSlash = lastModel.includes("/");
1232
+ if (actorHasSlash && lastHasSlash) {
1233
+ return actorModel !== lastModel;
1234
+ }
1235
+ const actorModelId = actorHasSlash ? actorModel.slice(actorModel.indexOf("/") + 1) : actorModel;
1236
+ const lastModelId = lastHasSlash ? lastModel.slice(lastModel.indexOf("/") + 1) : lastModel;
1237
+ return actorModelId !== lastModelId;
1238
+ }
1228
1239
  function formatRelativeTime(date, currentDate) {
1229
1240
  const diffMs = currentDate.getTime() - date.getTime();
1230
1241
  const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
@@ -1508,7 +1519,9 @@ function createActivationMarker(params) {
1508
1519
  observations: params.observations,
1509
1520
  triggeredBy: params.triggeredBy,
1510
1521
  lastActivityAt: params.lastActivityAt,
1511
- ttlExpiredMs: params.ttlExpiredMs
1522
+ ttlExpiredMs: params.ttlExpiredMs,
1523
+ previousModel: params.previousModel,
1524
+ currentModel: params.currentModel
1512
1525
  }
1513
1526
  };
1514
1527
  }
@@ -2993,6 +3006,7 @@ var ObservationStep = class {
2993
3006
  resourceId,
2994
3007
  checkThreshold: true,
2995
3008
  messages: step0Messages,
3009
+ currentModel: this.turn.actorModelContext,
2996
3010
  writer: this.turn.writer,
2997
3011
  messageList
2998
3012
  });
@@ -3016,6 +3030,8 @@ var ObservationStep = class {
3016
3030
  observationTokens: obsTokens,
3017
3031
  threadId,
3018
3032
  writer: this.turn.writer,
3033
+ messageList,
3034
+ currentModel: this.turn.actorModelContext,
3019
3035
  requestContext: this.turn.requestContext,
3020
3036
  observabilityContext: this.turn.observabilityContext,
3021
3037
  lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
@@ -3182,6 +3198,7 @@ var ObservationStep = class {
3182
3198
  threadId,
3183
3199
  resourceId,
3184
3200
  messages: messageList.get.all.db(),
3201
+ currentModel: this.turn.actorModelContext,
3185
3202
  writer: this.turn.writer,
3186
3203
  messageList
3187
3204
  });
@@ -3193,6 +3210,7 @@ var ObservationStep = class {
3193
3210
  threadId,
3194
3211
  writer: this.turn.writer,
3195
3212
  messageList,
3213
+ currentModel: this.turn.actorModelContext,
3196
3214
  requestContext: this.turn.requestContext,
3197
3215
  observabilityContext: this.turn.observabilityContext,
3198
3216
  lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
@@ -3235,6 +3253,8 @@ var ObservationTurn = class {
3235
3253
  requestContext;
3236
3254
  /** Optional observability context for nested OM spans. */
3237
3255
  observabilityContext;
3256
+ /** Current actor model for this step. Updated by the processor before prepare(). */
3257
+ actorModelContext;
3238
3258
  /** Optional processor-provided hooks for turn/step lifecycle integration. */
3239
3259
  hooks;
3240
3260
  constructor(opts) {
@@ -5093,12 +5113,44 @@ function extractReflectorListItems(content) {
5093
5113
  function validateCompression(reflectedTokens, targetThreshold) {
5094
5114
  return reflectedTokens < targetThreshold;
5095
5115
  }
5116
+ function formatModelContext(provider, modelId) {
5117
+ if (provider && modelId) {
5118
+ return `${provider}/${modelId}`;
5119
+ }
5120
+ return modelId;
5121
+ }
5122
+ function getCurrentModel(model) {
5123
+ return formatModelContext(model?.provider, model?.modelId);
5124
+ }
5125
+ function getLastModelFromMessageList(messageList) {
5126
+ const messages = messageList?.get.all.db();
5127
+ if (!messages) return void 0;
5128
+ for (let i = messages.length - 1; i >= 0; i--) {
5129
+ const message = messages[i];
5130
+ if (!message || message.role !== "assistant" || !message.content || typeof message.content === "string") {
5131
+ continue;
5132
+ }
5133
+ for (let j = message.content.parts.length - 1; j >= 0; j--) {
5134
+ const part = message.content.parts[j];
5135
+ if (part?.type === "step-start" && typeof part.model === "string" && part.model.length > 0) {
5136
+ return part.model;
5137
+ }
5138
+ }
5139
+ const metadata = message.content.metadata;
5140
+ const model = formatModelContext(metadata?.provider, metadata?.modelId);
5141
+ if (model) {
5142
+ return model;
5143
+ }
5144
+ }
5145
+ return void 0;
5146
+ }
5096
5147
  async function withAbortCheck(fn, abortSignal) {
5097
5148
  if (abortSignal?.aborted) throw new Error("The operation was aborted.");
5098
5149
  const result = await fn();
5099
5150
  if (abortSignal?.aborted) throw new Error("The operation was aborted.");
5100
5151
  return result;
5101
5152
  }
5153
+ var EARLY_ACTIVATION_SIZE_FLOOR_RATIO = 0.75;
5102
5154
  var ReflectorRunner = class {
5103
5155
  reflectionConfig;
5104
5156
  observationConfig;
@@ -5423,7 +5475,9 @@ var ReflectorRunner = class {
5423
5475
  }
5424
5476
  /**
5425
5477
  * Try to activate buffered reflection when threshold is reached.
5426
- * Returns true if activation succeeded.
5478
+ * Returns a discriminated result so the caller can distinguish between
5479
+ * "activated", "no buffer present", and "suppressed by overshoot guard"
5480
+ * without re-deriving that state.
5427
5481
  */
5428
5482
  async tryActivateBufferedReflection(record, lockKey, writer, messageList, activationMetadata) {
5429
5483
  const bufferKey = this.buffering.getReflectionBufferKey(lockKey);
@@ -5446,8 +5500,8 @@ var ReflectorRunner = class {
5446
5500
  `[OM:reflect] tryActivateBufferedReflection: freshRecord.id=${freshRecord?.id}, freshBufferedReflection=${freshRecord?.bufferedReflection ? "present (" + freshRecord.bufferedReflection.length + " chars)" : "empty"}, freshObsTokens=${freshRecord?.observationTokenCount}`
5447
5501
  );
5448
5502
  if (!freshRecord?.bufferedReflection) {
5449
- omDebug(`[OM:reflect] tryActivateBufferedReflection: no buffered reflection after re-fetch, returning false`);
5450
- return false;
5503
+ omDebug(`[OM:reflect] tryActivateBufferedReflection: no buffered reflection after re-fetch`);
5504
+ return { status: "no-buffer" };
5451
5505
  }
5452
5506
  const beforeTokens = freshRecord.observationTokenCount ?? 0;
5453
5507
  const reflectedLineCount = freshRecord.reflectedObservationLineCount ?? 0;
@@ -5459,6 +5513,26 @@ var ReflectorRunner = class {
5459
5513
 
5460
5514
  ${unreflectedContent}` : freshRecord.bufferedReflection;
5461
5515
  const combinedTokenCount = this.tokenCounter.countObservations(combinedObservations);
5516
+ if (activationMetadata?.triggeredBy === "ttl" || activationMetadata?.triggeredBy === "provider_change") {
5517
+ const unreflectedTailTokens = unreflectedContent ? this.tokenCounter.countObservations(unreflectedContent) : 0;
5518
+ const bufferedReflectionTokens = freshRecord.bufferedReflectionTokens ?? 0;
5519
+ if (unreflectedTailTokens < bufferedReflectionTokens) {
5520
+ omDebug(
5521
+ `[OM:reflect] tryActivateBufferedReflection: suppressing early ${activationMetadata.triggeredBy} activation \u2014 unreflectedTailTokens=${unreflectedTailTokens} < bufferedReflectionTokens=${bufferedReflectionTokens}; keeping buffer for threshold activation`
5522
+ );
5523
+ return { status: "suppressed", reason: "composition" };
5524
+ }
5525
+ const bufferActivation = this.reflectionConfig.bufferActivation;
5526
+ const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(freshRecord));
5527
+ const regularActivationTarget = reflectThreshold * (1 - bufferActivation);
5528
+ const minCombinedTokens = Math.round(regularActivationTarget * EARLY_ACTIVATION_SIZE_FLOOR_RATIO);
5529
+ if (combinedTokenCount < minCombinedTokens) {
5530
+ omDebug(
5531
+ `[OM:reflect] tryActivateBufferedReflection: suppressing early ${activationMetadata.triggeredBy} activation \u2014 combinedTokenCount=${combinedTokenCount} < minCombinedTokens=${minCombinedTokens} (${EARLY_ACTIVATION_SIZE_FLOOR_RATIO * 100}% of regular activation target ${Math.round(regularActivationTarget)}, threshold=${reflectThreshold}, bufferActivation=${bufferActivation}); keeping buffer for threshold activation`
5532
+ );
5533
+ return { status: "suppressed", reason: "size" };
5534
+ }
5535
+ }
5462
5536
  omDebug(
5463
5537
  `[OM:reflect] tryActivateBufferedReflection: activating, beforeTokens=${beforeTokens}, combinedTokenCount=${combinedTokenCount}, reflectedLineCount=${reflectedLineCount}, unreflectedLines=${unreflectedLines.length}`
5464
5538
  );
@@ -5488,6 +5562,8 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5488
5562
  triggeredBy: activationMetadata?.triggeredBy,
5489
5563
  lastActivityAt: activationMetadata?.lastActivityAt,
5490
5564
  ttlExpiredMs: activationMetadata?.ttlExpiredMs,
5565
+ previousModel: activationMetadata?.previousModel,
5566
+ currentModel: activationMetadata?.currentModel,
5491
5567
  config: this.getObservationMarkerConfig(freshRecord)
5492
5568
  });
5493
5569
  void writer.custom(activationMarker).catch(() => {
@@ -5500,7 +5576,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5500
5576
  );
5501
5577
  }
5502
5578
  BufferingCoordinator.reflectionBufferCycleIds.delete(bufferKey);
5503
- return true;
5579
+ return { status: "activated" };
5504
5580
  }
5505
5581
  /**
5506
5582
  * Check if reflection needed and trigger if so.
@@ -5514,6 +5590,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5514
5590
  writer,
5515
5591
  abortSignal,
5516
5592
  messageList,
5593
+ currentModel,
5517
5594
  reflectionHooks,
5518
5595
  requestContext,
5519
5596
  observabilityContext,
@@ -5553,13 +5630,19 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5553
5630
  const activateAfterIdle = this.reflectionConfig.activateAfterIdle;
5554
5631
  const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
5555
5632
  const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
5556
- if (observationTokens < reflectThreshold && !ttlExpired) {
5633
+ const actorModel = getCurrentModel(currentModel);
5634
+ const lastModel = getLastModelFromMessageList(messageList);
5635
+ const providerChanged = this.reflectionConfig.activateOnProviderChange === true && didProviderChange(actorModel, lastModel);
5636
+ if (observationTokens < reflectThreshold && !ttlExpired && !providerChanged) {
5557
5637
  return;
5558
5638
  }
5639
+ const activationTriggeredBy = observationTokens >= reflectThreshold ? "threshold" : providerChanged ? "provider_change" : "ttl";
5559
5640
  const activationMetadata = {
5560
- triggeredBy: ttlExpired ? "ttl" : "threshold",
5561
- lastActivityAt: ttlExpired ? lastActivityAt : void 0,
5562
- ttlExpiredMs: ttlExpired ? ttlExpiredMs : void 0
5641
+ triggeredBy: activationTriggeredBy,
5642
+ lastActivityAt: activationTriggeredBy === "ttl" ? lastActivityAt : void 0,
5643
+ ttlExpiredMs: activationTriggeredBy === "ttl" ? ttlExpiredMs : void 0,
5644
+ previousModel: activationTriggeredBy === "provider_change" ? lastModel : void 0,
5645
+ currentModel: activationTriggeredBy === "provider_change" ? actorModel : void 0
5563
5646
  };
5564
5647
  if (record.isReflecting) {
5565
5648
  if (isOpActiveInProcess(record.id, "reflecting")) {
@@ -5570,14 +5653,20 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5570
5653
  await this.storage.setReflectingFlag(record.id, false);
5571
5654
  }
5572
5655
  if (this.buffering.isAsyncReflectionEnabled()) {
5573
- const activationSuccess = await this.tryActivateBufferedReflection(
5656
+ const activationResult = await this.tryActivateBufferedReflection(
5574
5657
  record,
5575
5658
  lockKey,
5576
5659
  writer,
5577
5660
  messageList,
5578
5661
  activationMetadata
5579
5662
  );
5580
- if (activationSuccess) {
5663
+ if (activationResult.status === "activated") {
5664
+ return;
5665
+ }
5666
+ if (activationResult.status === "suppressed") {
5667
+ omDebug(
5668
+ `[OM:reflect] skipping sync fallback / re-buffer after suppressed early ${activationMetadata.triggeredBy} activation (reason=${activationResult.reason})`
5669
+ );
5581
5670
  return;
5582
5671
  }
5583
5672
  if (this.reflectionConfig.blockAfter && observationTokens >= this.reflectionConfig.blockAfter) {
@@ -7276,6 +7365,36 @@ function getLastActivityFromMessages(messages) {
7276
7365
  }
7277
7366
  return void 0;
7278
7367
  }
7368
+ function formatModelContext2(provider, modelId) {
7369
+ if (provider && modelId) {
7370
+ return `${provider}/${modelId}`;
7371
+ }
7372
+ return modelId;
7373
+ }
7374
+ function getLastModelFromMessages(messages) {
7375
+ if (!messages) return void 0;
7376
+ for (let i = messages.length - 1; i >= 0; i--) {
7377
+ const message = messages[i];
7378
+ if (!message || message.role !== "assistant" || !message.content || typeof message.content === "string") {
7379
+ continue;
7380
+ }
7381
+ for (let j = message.content.parts.length - 1; j >= 0; j--) {
7382
+ const part = message.content.parts[j];
7383
+ if (part?.type === "step-start" && typeof part.model === "string" && part.model.length > 0) {
7384
+ return part.model;
7385
+ }
7386
+ }
7387
+ const metadata = message.content.metadata;
7388
+ const model = formatModelContext2(metadata?.provider, metadata?.modelId);
7389
+ if (model) {
7390
+ return model;
7391
+ }
7392
+ }
7393
+ return void 0;
7394
+ }
7395
+ function getCurrentModel2(model) {
7396
+ return formatModelContext2(model?.provider, model?.modelId);
7397
+ }
7279
7398
  function parseActivationTTL(value, fieldPath) {
7280
7399
  if (value === void 0) {
7281
7400
  return void 0;
@@ -7452,6 +7571,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
7452
7571
  ),
7453
7572
  bufferActivation: asyncBufferingDisabled ? void 0 : config.observation?.bufferActivation ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferActivation,
7454
7573
  activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
7574
+ activateOnProviderChange: config.activateOnProviderChange ?? false,
7455
7575
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
7456
7576
  config.observation?.blockAfter ?? (config.observation?.bufferTokens ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens ? 1.2 : void 0),
7457
7577
  config.observation?.messageTokens ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
@@ -7471,6 +7591,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
7471
7591
  providerOptions: config.reflection?.providerOptions ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.providerOptions,
7472
7592
  bufferActivation: asyncBufferingDisabled ? void 0 : config?.reflection?.bufferActivation ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation,
7473
7593
  activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
7594
+ activateOnProviderChange: config.activateOnProviderChange ?? false,
7474
7595
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
7475
7596
  config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation ? 1.2 : void 0),
7476
7597
  config.reflection?.observationTokens ?? chunk3D55EABW_cjs.OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens
@@ -9367,6 +9488,8 @@ ${grouped}` : grouped;
9367
9488
  let activationTriggeredBy = "threshold";
9368
9489
  let activationLastActivityAt;
9369
9490
  let activateAfterIdleExpiredMs;
9491
+ let previousModel;
9492
+ let currentModel;
9370
9493
  if (opts.checkThreshold) {
9371
9494
  const thresholdMessages = opts.messages ?? await this.loadMessagesFromStorage(
9372
9495
  threadId,
@@ -9377,7 +9500,14 @@ ${grouped}` : grouped;
9377
9500
  const lastActivityAt = getLastActivityFromMessages(thresholdMessages);
9378
9501
  const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
9379
9502
  const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
9380
- if (ttlExpired) {
9503
+ const actorModel = getCurrentModel2(opts.currentModel);
9504
+ const lastModel = getLastModelFromMessages(thresholdMessages);
9505
+ const providerChanged = this.observationConfig.activateOnProviderChange === true && didProviderChange(actorModel, lastModel);
9506
+ if (providerChanged) {
9507
+ activationTriggeredBy = "provider_change";
9508
+ previousModel = lastModel;
9509
+ currentModel = actorModel;
9510
+ } else if (ttlExpired) {
9381
9511
  activationTriggeredBy = "ttl";
9382
9512
  activationLastActivityAt = lastActivityAt;
9383
9513
  activateAfterIdleExpiredMs = ttlExpiredMs;
@@ -9446,6 +9576,8 @@ ${grouped}` : grouped;
9446
9576
  triggeredBy: activationTriggeredBy,
9447
9577
  lastActivityAt: activationLastActivityAt,
9448
9578
  ttlExpiredMs: activateAfterIdleExpiredMs,
9579
+ previousModel,
9580
+ currentModel,
9449
9581
  config: this.getObservationMarkerConfig()
9450
9582
  });
9451
9583
  void opts.writer.custom(activationMarker).catch(() => {
@@ -9803,6 +9935,7 @@ var ObservationalMemoryProcessor = class {
9803
9935
  const observabilityContext = getOmObservabilityContext(args);
9804
9936
  state.__omObservabilityContext = observabilityContext;
9805
9937
  this.turn.observabilityContext = observabilityContext;
9938
+ this.turn.actorModelContext = actorModelContext;
9806
9939
  {
9807
9940
  const step = this.turn.step(stepNumber);
9808
9941
  let ctx;
@@ -9961,5 +10094,5 @@ exports.stripEphemeralAnchorIds = stripEphemeralAnchorIds;
9961
10094
  exports.stripObservationGroups = stripObservationGroups;
9962
10095
  exports.truncateStringByTokens = truncateStringByTokens;
9963
10096
  exports.wrapInObservationGroup = wrapInObservationGroup;
9964
- //# sourceMappingURL=chunk-6BU7KZ4V.cjs.map
9965
- //# sourceMappingURL=chunk-6BU7KZ4V.cjs.map
10097
+ //# sourceMappingURL=chunk-EOIQWP5O.cjs.map
10098
+ //# sourceMappingURL=chunk-EOIQWP5O.cjs.map