@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.
@@ -1040,7 +1040,7 @@ function imageSize(input) {
1040
1040
  throw new TypeError(`unsupported file type: ${type}`);
1041
1041
  }
1042
1042
 
1043
- // ../memory/dist/chunk-HB6AYAFD.js
1043
+ // ../memory/dist/chunk-MGHUIRKN.js
1044
1044
  var OM_DEBUG_LOG = process.env.OM_DEBUG ? join(process.cwd(), "om-debug.log") : null;
1045
1045
  function omDebug(msg) {
1046
1046
  if (!OM_DEBUG_LOG) return;
@@ -1223,6 +1223,17 @@ var BufferingCoordinator = class _BufferingCoordinator {
1223
1223
  }
1224
1224
  }
1225
1225
  };
1226
+ function didProviderChange(actorModel, lastModel) {
1227
+ if (actorModel === void 0 || lastModel === void 0) return false;
1228
+ const actorHasSlash = actorModel.includes("/");
1229
+ const lastHasSlash = lastModel.includes("/");
1230
+ if (actorHasSlash && lastHasSlash) {
1231
+ return actorModel !== lastModel;
1232
+ }
1233
+ const actorModelId = actorHasSlash ? actorModel.slice(actorModel.indexOf("/") + 1) : actorModel;
1234
+ const lastModelId = lastHasSlash ? lastModel.slice(lastModel.indexOf("/") + 1) : lastModel;
1235
+ return actorModelId !== lastModelId;
1236
+ }
1226
1237
  function formatRelativeTime(date, currentDate) {
1227
1238
  const diffMs = currentDate.getTime() - date.getTime();
1228
1239
  const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
@@ -1506,7 +1517,9 @@ function createActivationMarker(params) {
1506
1517
  observations: params.observations,
1507
1518
  triggeredBy: params.triggeredBy,
1508
1519
  lastActivityAt: params.lastActivityAt,
1509
- ttlExpiredMs: params.ttlExpiredMs
1520
+ ttlExpiredMs: params.ttlExpiredMs,
1521
+ previousModel: params.previousModel,
1522
+ currentModel: params.currentModel
1510
1523
  }
1511
1524
  };
1512
1525
  }
@@ -2991,6 +3004,7 @@ var ObservationStep = class {
2991
3004
  resourceId,
2992
3005
  checkThreshold: true,
2993
3006
  messages: step0Messages,
3007
+ currentModel: this.turn.actorModelContext,
2994
3008
  writer: this.turn.writer,
2995
3009
  messageList
2996
3010
  });
@@ -3014,6 +3028,8 @@ var ObservationStep = class {
3014
3028
  observationTokens: obsTokens,
3015
3029
  threadId,
3016
3030
  writer: this.turn.writer,
3031
+ messageList,
3032
+ currentModel: this.turn.actorModelContext,
3017
3033
  requestContext: this.turn.requestContext,
3018
3034
  observabilityContext: this.turn.observabilityContext,
3019
3035
  lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
@@ -3180,6 +3196,7 @@ var ObservationStep = class {
3180
3196
  threadId,
3181
3197
  resourceId,
3182
3198
  messages: messageList.get.all.db(),
3199
+ currentModel: this.turn.actorModelContext,
3183
3200
  writer: this.turn.writer,
3184
3201
  messageList
3185
3202
  });
@@ -3191,6 +3208,7 @@ var ObservationStep = class {
3191
3208
  threadId,
3192
3209
  writer: this.turn.writer,
3193
3210
  messageList,
3211
+ currentModel: this.turn.actorModelContext,
3194
3212
  requestContext: this.turn.requestContext,
3195
3213
  observabilityContext: this.turn.observabilityContext,
3196
3214
  lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
@@ -3233,6 +3251,8 @@ var ObservationTurn = class {
3233
3251
  requestContext;
3234
3252
  /** Optional observability context for nested OM spans. */
3235
3253
  observabilityContext;
3254
+ /** Current actor model for this step. Updated by the processor before prepare(). */
3255
+ actorModelContext;
3236
3256
  /** Optional processor-provided hooks for turn/step lifecycle integration. */
3237
3257
  hooks;
3238
3258
  constructor(opts) {
@@ -5091,12 +5111,44 @@ function extractReflectorListItems(content) {
5091
5111
  function validateCompression(reflectedTokens, targetThreshold) {
5092
5112
  return reflectedTokens < targetThreshold;
5093
5113
  }
5114
+ function formatModelContext(provider, modelId) {
5115
+ if (provider && modelId) {
5116
+ return `${provider}/${modelId}`;
5117
+ }
5118
+ return modelId;
5119
+ }
5120
+ function getCurrentModel(model) {
5121
+ return formatModelContext(model?.provider, model?.modelId);
5122
+ }
5123
+ function getLastModelFromMessageList(messageList) {
5124
+ const messages = messageList?.get.all.db();
5125
+ if (!messages) return void 0;
5126
+ for (let i = messages.length - 1; i >= 0; i--) {
5127
+ const message = messages[i];
5128
+ if (!message || message.role !== "assistant" || !message.content || typeof message.content === "string") {
5129
+ continue;
5130
+ }
5131
+ for (let j = message.content.parts.length - 1; j >= 0; j--) {
5132
+ const part = message.content.parts[j];
5133
+ if (part?.type === "step-start" && typeof part.model === "string" && part.model.length > 0) {
5134
+ return part.model;
5135
+ }
5136
+ }
5137
+ const metadata = message.content.metadata;
5138
+ const model = formatModelContext(metadata?.provider, metadata?.modelId);
5139
+ if (model) {
5140
+ return model;
5141
+ }
5142
+ }
5143
+ return void 0;
5144
+ }
5094
5145
  async function withAbortCheck(fn, abortSignal) {
5095
5146
  if (abortSignal?.aborted) throw new Error("The operation was aborted.");
5096
5147
  const result = await fn();
5097
5148
  if (abortSignal?.aborted) throw new Error("The operation was aborted.");
5098
5149
  return result;
5099
5150
  }
5151
+ var EARLY_ACTIVATION_SIZE_FLOOR_RATIO = 0.75;
5100
5152
  var ReflectorRunner = class {
5101
5153
  reflectionConfig;
5102
5154
  observationConfig;
@@ -5421,7 +5473,9 @@ var ReflectorRunner = class {
5421
5473
  }
5422
5474
  /**
5423
5475
  * Try to activate buffered reflection when threshold is reached.
5424
- * Returns true if activation succeeded.
5476
+ * Returns a discriminated result so the caller can distinguish between
5477
+ * "activated", "no buffer present", and "suppressed by overshoot guard"
5478
+ * without re-deriving that state.
5425
5479
  */
5426
5480
  async tryActivateBufferedReflection(record, lockKey, writer, messageList, activationMetadata) {
5427
5481
  const bufferKey = this.buffering.getReflectionBufferKey(lockKey);
@@ -5444,8 +5498,8 @@ var ReflectorRunner = class {
5444
5498
  `[OM:reflect] tryActivateBufferedReflection: freshRecord.id=${freshRecord?.id}, freshBufferedReflection=${freshRecord?.bufferedReflection ? "present (" + freshRecord.bufferedReflection.length + " chars)" : "empty"}, freshObsTokens=${freshRecord?.observationTokenCount}`
5445
5499
  );
5446
5500
  if (!freshRecord?.bufferedReflection) {
5447
- omDebug(`[OM:reflect] tryActivateBufferedReflection: no buffered reflection after re-fetch, returning false`);
5448
- return false;
5501
+ omDebug(`[OM:reflect] tryActivateBufferedReflection: no buffered reflection after re-fetch`);
5502
+ return { status: "no-buffer" };
5449
5503
  }
5450
5504
  const beforeTokens = freshRecord.observationTokenCount ?? 0;
5451
5505
  const reflectedLineCount = freshRecord.reflectedObservationLineCount ?? 0;
@@ -5457,6 +5511,26 @@ var ReflectorRunner = class {
5457
5511
 
5458
5512
  ${unreflectedContent}` : freshRecord.bufferedReflection;
5459
5513
  const combinedTokenCount = this.tokenCounter.countObservations(combinedObservations);
5514
+ if (activationMetadata?.triggeredBy === "ttl" || activationMetadata?.triggeredBy === "provider_change") {
5515
+ const unreflectedTailTokens = unreflectedContent ? this.tokenCounter.countObservations(unreflectedContent) : 0;
5516
+ const bufferedReflectionTokens = freshRecord.bufferedReflectionTokens ?? 0;
5517
+ if (unreflectedTailTokens < bufferedReflectionTokens) {
5518
+ omDebug(
5519
+ `[OM:reflect] tryActivateBufferedReflection: suppressing early ${activationMetadata.triggeredBy} activation \u2014 unreflectedTailTokens=${unreflectedTailTokens} < bufferedReflectionTokens=${bufferedReflectionTokens}; keeping buffer for threshold activation`
5520
+ );
5521
+ return { status: "suppressed", reason: "composition" };
5522
+ }
5523
+ const bufferActivation = this.reflectionConfig.bufferActivation;
5524
+ const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(freshRecord));
5525
+ const regularActivationTarget = reflectThreshold * (1 - bufferActivation);
5526
+ const minCombinedTokens = Math.round(regularActivationTarget * EARLY_ACTIVATION_SIZE_FLOOR_RATIO);
5527
+ if (combinedTokenCount < minCombinedTokens) {
5528
+ omDebug(
5529
+ `[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`
5530
+ );
5531
+ return { status: "suppressed", reason: "size" };
5532
+ }
5533
+ }
5460
5534
  omDebug(
5461
5535
  `[OM:reflect] tryActivateBufferedReflection: activating, beforeTokens=${beforeTokens}, combinedTokenCount=${combinedTokenCount}, reflectedLineCount=${reflectedLineCount}, unreflectedLines=${unreflectedLines.length}`
5462
5536
  );
@@ -5486,6 +5560,8 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5486
5560
  triggeredBy: activationMetadata?.triggeredBy,
5487
5561
  lastActivityAt: activationMetadata?.lastActivityAt,
5488
5562
  ttlExpiredMs: activationMetadata?.ttlExpiredMs,
5563
+ previousModel: activationMetadata?.previousModel,
5564
+ currentModel: activationMetadata?.currentModel,
5489
5565
  config: this.getObservationMarkerConfig(freshRecord)
5490
5566
  });
5491
5567
  void writer.custom(activationMarker).catch(() => {
@@ -5498,7 +5574,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5498
5574
  );
5499
5575
  }
5500
5576
  BufferingCoordinator.reflectionBufferCycleIds.delete(bufferKey);
5501
- return true;
5577
+ return { status: "activated" };
5502
5578
  }
5503
5579
  /**
5504
5580
  * Check if reflection needed and trigger if so.
@@ -5512,6 +5588,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5512
5588
  writer,
5513
5589
  abortSignal,
5514
5590
  messageList,
5591
+ currentModel,
5515
5592
  reflectionHooks,
5516
5593
  requestContext,
5517
5594
  observabilityContext,
@@ -5551,13 +5628,19 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5551
5628
  const activateAfterIdle = this.reflectionConfig.activateAfterIdle;
5552
5629
  const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
5553
5630
  const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
5554
- if (observationTokens < reflectThreshold && !ttlExpired) {
5631
+ const actorModel = getCurrentModel(currentModel);
5632
+ const lastModel = getLastModelFromMessageList(messageList);
5633
+ const providerChanged = this.reflectionConfig.activateOnProviderChange === true && didProviderChange(actorModel, lastModel);
5634
+ if (observationTokens < reflectThreshold && !ttlExpired && !providerChanged) {
5555
5635
  return;
5556
5636
  }
5637
+ const activationTriggeredBy = observationTokens >= reflectThreshold ? "threshold" : providerChanged ? "provider_change" : "ttl";
5557
5638
  const activationMetadata = {
5558
- triggeredBy: ttlExpired ? "ttl" : "threshold",
5559
- lastActivityAt: ttlExpired ? lastActivityAt : void 0,
5560
- ttlExpiredMs: ttlExpired ? ttlExpiredMs : void 0
5639
+ triggeredBy: activationTriggeredBy,
5640
+ lastActivityAt: activationTriggeredBy === "ttl" ? lastActivityAt : void 0,
5641
+ ttlExpiredMs: activationTriggeredBy === "ttl" ? ttlExpiredMs : void 0,
5642
+ previousModel: activationTriggeredBy === "provider_change" ? lastModel : void 0,
5643
+ currentModel: activationTriggeredBy === "provider_change" ? actorModel : void 0
5561
5644
  };
5562
5645
  if (record.isReflecting) {
5563
5646
  if (isOpActiveInProcess(record.id, "reflecting")) {
@@ -5568,14 +5651,20 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
5568
5651
  await this.storage.setReflectingFlag(record.id, false);
5569
5652
  }
5570
5653
  if (this.buffering.isAsyncReflectionEnabled()) {
5571
- const activationSuccess = await this.tryActivateBufferedReflection(
5654
+ const activationResult = await this.tryActivateBufferedReflection(
5572
5655
  record,
5573
5656
  lockKey,
5574
5657
  writer,
5575
5658
  messageList,
5576
5659
  activationMetadata
5577
5660
  );
5578
- if (activationSuccess) {
5661
+ if (activationResult.status === "activated") {
5662
+ return;
5663
+ }
5664
+ if (activationResult.status === "suppressed") {
5665
+ omDebug(
5666
+ `[OM:reflect] skipping sync fallback / re-buffer after suppressed early ${activationMetadata.triggeredBy} activation (reason=${activationResult.reason})`
5667
+ );
5579
5668
  return;
5580
5669
  }
5581
5670
  if (this.reflectionConfig.blockAfter && observationTokens >= this.reflectionConfig.blockAfter) {
@@ -7274,6 +7363,36 @@ function getLastActivityFromMessages(messages) {
7274
7363
  }
7275
7364
  return void 0;
7276
7365
  }
7366
+ function formatModelContext2(provider, modelId) {
7367
+ if (provider && modelId) {
7368
+ return `${provider}/${modelId}`;
7369
+ }
7370
+ return modelId;
7371
+ }
7372
+ function getLastModelFromMessages(messages) {
7373
+ if (!messages) return void 0;
7374
+ for (let i = messages.length - 1; i >= 0; i--) {
7375
+ const message = messages[i];
7376
+ if (!message || message.role !== "assistant" || !message.content || typeof message.content === "string") {
7377
+ continue;
7378
+ }
7379
+ for (let j = message.content.parts.length - 1; j >= 0; j--) {
7380
+ const part = message.content.parts[j];
7381
+ if (part?.type === "step-start" && typeof part.model === "string" && part.model.length > 0) {
7382
+ return part.model;
7383
+ }
7384
+ }
7385
+ const metadata = message.content.metadata;
7386
+ const model = formatModelContext2(metadata?.provider, metadata?.modelId);
7387
+ if (model) {
7388
+ return model;
7389
+ }
7390
+ }
7391
+ return void 0;
7392
+ }
7393
+ function getCurrentModel2(model) {
7394
+ return formatModelContext2(model?.provider, model?.modelId);
7395
+ }
7277
7396
  function parseActivationTTL(value, fieldPath) {
7278
7397
  if (value === void 0) {
7279
7398
  return void 0;
@@ -7450,6 +7569,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
7450
7569
  ),
7451
7570
  bufferActivation: asyncBufferingDisabled ? void 0 : config.observation?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferActivation,
7452
7571
  activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
7572
+ activateOnProviderChange: config.activateOnProviderChange ?? false,
7453
7573
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
7454
7574
  config.observation?.blockAfter ?? (config.observation?.bufferTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens ? 1.2 : void 0),
7455
7575
  config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
@@ -7469,6 +7589,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
7469
7589
  providerOptions: config.reflection?.providerOptions ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.providerOptions,
7470
7590
  bufferActivation: asyncBufferingDisabled ? void 0 : config?.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation,
7471
7591
  activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
7592
+ activateOnProviderChange: config.activateOnProviderChange ?? false,
7472
7593
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
7473
7594
  config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation ? 1.2 : void 0),
7474
7595
  config.reflection?.observationTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens
@@ -9365,6 +9486,8 @@ ${grouped}` : grouped;
9365
9486
  let activationTriggeredBy = "threshold";
9366
9487
  let activationLastActivityAt;
9367
9488
  let activateAfterIdleExpiredMs;
9489
+ let previousModel;
9490
+ let currentModel;
9368
9491
  if (opts.checkThreshold) {
9369
9492
  const thresholdMessages = opts.messages ?? await this.loadMessagesFromStorage(
9370
9493
  threadId,
@@ -9375,7 +9498,14 @@ ${grouped}` : grouped;
9375
9498
  const lastActivityAt = getLastActivityFromMessages(thresholdMessages);
9376
9499
  const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
9377
9500
  const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
9378
- if (ttlExpired) {
9501
+ const actorModel = getCurrentModel2(opts.currentModel);
9502
+ const lastModel = getLastModelFromMessages(thresholdMessages);
9503
+ const providerChanged = this.observationConfig.activateOnProviderChange === true && didProviderChange(actorModel, lastModel);
9504
+ if (providerChanged) {
9505
+ activationTriggeredBy = "provider_change";
9506
+ previousModel = lastModel;
9507
+ currentModel = actorModel;
9508
+ } else if (ttlExpired) {
9379
9509
  activationTriggeredBy = "ttl";
9380
9510
  activationLastActivityAt = lastActivityAt;
9381
9511
  activateAfterIdleExpiredMs = ttlExpiredMs;
@@ -9444,6 +9574,8 @@ ${grouped}` : grouped;
9444
9574
  triggeredBy: activationTriggeredBy,
9445
9575
  lastActivityAt: activationLastActivityAt,
9446
9576
  ttlExpiredMs: activateAfterIdleExpiredMs,
9577
+ previousModel,
9578
+ currentModel,
9447
9579
  config: this.getObservationMarkerConfig()
9448
9580
  });
9449
9581
  void opts.writer.custom(activationMarker).catch(() => {
@@ -9801,6 +9933,7 @@ var ObservationalMemoryProcessor = class {
9801
9933
  const observabilityContext = getOmObservabilityContext(args);
9802
9934
  state.__omObservabilityContext = observabilityContext;
9803
9935
  this.turn.observabilityContext = observabilityContext;
9936
+ this.turn.actorModelContext = actorModelContext;
9804
9937
  {
9805
9938
  const step = this.turn.step(stepNumber);
9806
9939
  let ctx;
@@ -9932,5 +10065,5 @@ function getObservationsAsOf(activeObservations, asOf) {
9932
10065
  }
9933
10066
 
9934
10067
  export { ModelByInputTokens, OBSERVER_SYSTEM_PROMPT, ObservationalMemory, ObservationalMemoryProcessor, TokenCounter, buildObserverPrompt, buildObserverSystemPrompt, combineObservationGroupRanges, deriveObservationGroupProvenance, e, estimateTokenCount, extractCurrentTask, formatMessagesForObserver, formatToolResultForObserver, getObservationsAsOf, hasCurrentTaskSection, injectAnchorIds, optimizeObservationsForContext, parseAnchorId, parseObservationGroups, parseObserverOutput, reconcileObservationGroupsFromReflection, renderObservationGroupsForReflection, resolveToolResultValue, stripEphemeralAnchorIds, stripObservationGroups, truncateStringByTokens, wrapInObservationGroup };
9935
- //# sourceMappingURL=chunk-E5CLWABD.js.map
9936
- //# sourceMappingURL=chunk-E5CLWABD.js.map
10068
+ //# sourceMappingURL=chunk-7ITX6ABS.js.map
10069
+ //# sourceMappingURL=chunk-7ITX6ABS.js.map