@mastra/server 1.62.0-alpha.2 → 1.62.0-alpha.7

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.
@@ -4693,7 +4693,7 @@ function splitLines(text) {
4693
4693
  return result;
4694
4694
  }
4695
4695
  //#endregion
4696
- //#region ../memory/dist/src-aTfbkxBl.js
4696
+ //#region ../memory/dist/src-kLYHhPqh.js
4697
4697
  var __defProp$3 = Object.defineProperty;
4698
4698
  var __exportAll = (all, no_symbols) => {
4699
4699
  let target = {};
@@ -23480,6 +23480,12 @@ function extractListItemsOnly(content) {
23480
23480
  */
23481
23481
  const MAX_OBSERVATION_LINE_CHARS = 1e4;
23482
23482
  /**
23483
+ * Minimum trimmed line length considered by the duplicate-line degenerate
23484
+ * check. Short lines (blank lines, separators, terse bullets) legitimately
23485
+ * repeat; long identical lines almost never do.
23486
+ */
23487
+ const MIN_DUPLICATE_LINE_CHARS = 24;
23488
+ /**
23483
23489
  * Truncate individual observation lines that exceed the maximum length.
23484
23490
  */
23485
23491
  function sanitizeObservationLines(observations) {
@@ -23517,6 +23523,18 @@ function detectDegenerateRepetition(text) {
23517
23523
  if (totalWindows > 5 && duplicateWindows / totalWindows > .4) return true;
23518
23524
  const lines = text.split("\n");
23519
23525
  for (const line of lines) if (line.length > 5e4) return true;
23526
+ const seenLines = /* @__PURE__ */ new Map();
23527
+ let duplicateLines = 0;
23528
+ let totalCountedLines = 0;
23529
+ for (const line of lines) {
23530
+ const trimmed = line.trim();
23531
+ if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
23532
+ totalCountedLines++;
23533
+ const count = (seenLines.get(trimmed) ?? 0) + 1;
23534
+ seenLines.set(trimmed, count);
23535
+ if (count > 1) duplicateLines++;
23536
+ }
23537
+ if (totalCountedLines >= 20 && duplicateLines / totalCountedLines > .5) return true;
23520
23538
  return false;
23521
23539
  }
23522
23540
  /**
@@ -23551,12 +23569,26 @@ function describeDegenerateOutput(text, snippetChars = 400) {
23551
23569
  topWindow = window;
23552
23570
  }
23553
23571
  let longestLine = 0;
23554
- for (const line of text.split("\n")) if (line.length > longestLine) longestLine = line.length;
23572
+ const seenLines = /* @__PURE__ */ new Map();
23573
+ let duplicateLines = 0;
23574
+ let totalCountedLines = 0;
23575
+ for (const line of text.split("\n")) {
23576
+ if (line.length > longestLine) longestLine = line.length;
23577
+ const trimmed = line.trim();
23578
+ if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
23579
+ totalCountedLines++;
23580
+ const count = (seenLines.get(trimmed) ?? 0) + 1;
23581
+ seenLines.set(trimmed, count);
23582
+ if (count > 1) duplicateLines++;
23583
+ }
23555
23584
  const duplicateRatio = totalWindows > 0 ? (duplicateWindows / totalWindows).toFixed(2) : "n/a";
23585
+ const duplicateLineRatio = totalCountedLines > 0 ? (duplicateLines / totalCountedLines).toFixed(2) : "n/a";
23556
23586
  const parts = [
23557
23587
  `length=${text.length}`,
23558
23588
  `sampledWindows=${totalWindows}`,
23559
23589
  `duplicateRatio=${duplicateRatio}`,
23590
+ `duplicateLineRatio=${duplicateLineRatio}`,
23591
+ `countedLines=${totalCountedLines}`,
23560
23592
  `longestLine=${longestLine}`,
23561
23593
  `topWindowCount=${topCount}`
23562
23594
  ];
@@ -23824,7 +23856,19 @@ async function withOmTracingSpan({ phase, model, inputTokens, requestContext, ob
23824
23856
  });
23825
23857
  const childObservabilityContext = (0, _mastra_core_observability.createObservabilityContext)({ currentSpan: span });
23826
23858
  if (!span) return callback(childObservabilityContext);
23827
- return span.executeInContext(() => callback(childObservabilityContext));
23859
+ return span.executeInContext(async () => {
23860
+ try {
23861
+ const result = await callback(childObservabilityContext);
23862
+ span.end();
23863
+ return result;
23864
+ } catch (error) {
23865
+ span.error({
23866
+ error,
23867
+ endSpan: true
23868
+ });
23869
+ throw error;
23870
+ }
23871
+ });
23828
23872
  }
23829
23873
  function filterObserverExtractors(extractors, skipContinuationHints) {
23830
23874
  const configuredExtractors = extractors ?? [];
@@ -28917,10 +28961,11 @@ ObservationStrategy.create = ((om, opts) => {
28917
28961
  if (deps.scope === "resource" && opts.resourceId) return new ResourceScopedObservationStrategy(deps, opts);
28918
28962
  return new SyncObservationStrategy(deps, opts);
28919
28963
  });
28920
- async function loadMemoryContextMessages({ memory, messageList, threadId, resourceId }) {
28964
+ async function loadMemoryContextMessages({ memory, messageList, threadId, resourceId, runState }) {
28921
28965
  const ctx = await memory.getContext({
28922
28966
  threadId,
28923
- resourceId
28967
+ resourceId,
28968
+ runState
28924
28969
  });
28925
28970
  for (const msg of ctx.messages) if (msg.role !== "system") messageList.add(msg, "memory");
28926
28971
  return ctx;
@@ -29374,10 +29419,11 @@ var ObservationTurn = class {
29374
29419
  * If a MemoryContextProvider is passed, loads historical messages and adds
29375
29420
  * them to the MessageList. Without a provider, only fetches/caches the record.
29376
29421
  */
29377
- async start(memory) {
29422
+ async start(memory, runState) {
29378
29423
  if (this._started) throw new Error("Turn already started");
29379
29424
  this._started = true;
29380
29425
  this._record = await this.om.getOrCreateRecord(this.threadId, this.resourceId);
29426
+ runState?.set(`observational-memory:record:${this.threadId}:${this.resourceId ?? ""}`, this._record);
29381
29427
  this._generationCountAtStart = this._record.generationCount;
29382
29428
  this.memory = memory;
29383
29429
  if (memory) {
@@ -29385,7 +29431,8 @@ var ObservationTurn = class {
29385
29431
  memory,
29386
29432
  messageList: this.messageList,
29387
29433
  threadId: this.threadId,
29388
- resourceId: this.resourceId
29434
+ resourceId: this.resourceId,
29435
+ runState
29389
29436
  });
29390
29437
  this._context = {
29391
29438
  messages: ctx.messages,
@@ -29943,8 +29990,6 @@ var ReflectorRunner = class {
29943
29990
  };
29944
29991
  let reflectedTokens = 0;
29945
29992
  let attemptNumber = 0;
29946
- /** Observations from the previous attempt, used to detect a no-progress ladder. */
29947
- let previousObservations;
29948
29993
  while (currentLevel <= maxLevel) {
29949
29994
  attemptNumber++;
29950
29995
  const isRetry = attemptNumber > 1;
@@ -30018,11 +30063,6 @@ var ReflectorRunner = class {
30018
30063
  omDebug(`[OM:callReflector] degenerate output persists at maxLevel=${maxLevel}, breaking`);
30019
30064
  break;
30020
30065
  }
30021
- if (!parsed.degenerate && previousObservations !== void 0 && parsed.observations === previousObservations) {
30022
- omDebug(`[OM:callReflector] attempt #${attemptNumber} returned output identical to the previous attempt; escalating cannot help, stopping the ladder`);
30023
- break;
30024
- }
30025
- previousObservations = parsed.observations;
30026
30066
  if (streamContext?.writer) {
30027
30067
  const failedMarker = createObservationFailedMarker({
30028
30068
  cycleId: streamContext.cycleId,
@@ -30106,52 +30146,51 @@ var ReflectorRunner = class {
30106
30146
  this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
30107
30147
  omError("[OM] Failed to set buffering reflection flag", err);
30108
30148
  });
30109
- reflectionHooks?.onReflectionStart?.();
30110
- const asyncOp = this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal).then((outcome) => {
30149
+ const asyncOp = (async () => {
30150
+ let outcome;
30151
+ let reflectionError;
30111
30152
  try {
30112
- reflectionHooks?.onReflectionEnd?.({
30113
- usage: outcome?.usage,
30114
- ...outcome?.providerMetadata ? { providerMetadata: outcome.providerMetadata } : {}
30115
- });
30116
- } catch (hookError) {
30117
- omError("[OM] onReflectionEnd hook failed after async buffered reflection", hookError);
30118
- }
30119
- }, async (error) => {
30120
- if (writer) try {
30121
- const failedMarker = createBufferingFailedMarker({
30122
- cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
30123
- operationType: "reflection",
30124
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
30125
- tokensAttempted: observationTokens,
30126
- error: error instanceof Error ? error.message : String(error),
30127
- recordId: record.id,
30128
- threadId: record.threadId ?? ""
30129
- });
30130
- writer.custom({
30131
- ...failedMarker,
30132
- transient: true
30133
- }).catch(() => {});
30134
- await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
30135
- } catch (markerError) {
30136
- omError("[OM] Failed to persist buffering-failed marker after async buffered reflection failure", markerError);
30137
- }
30138
- omError("[OM] Async buffered reflection failed", error);
30139
- try {
30140
- reflectionHooks?.onReflectionEnd?.({
30141
- usage: void 0,
30142
- error: error instanceof Error ? error : new Error(String(error))
30153
+ await reflectionHooks?.onReflectionStart?.();
30154
+ outcome = await this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal);
30155
+ } catch (error) {
30156
+ reflectionError = error instanceof Error ? error : new Error(String(error));
30157
+ if (writer) try {
30158
+ const failedMarker = createBufferingFailedMarker({
30159
+ cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
30160
+ operationType: "reflection",
30161
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
30162
+ tokensAttempted: observationTokens,
30163
+ error: reflectionError.message,
30164
+ recordId: record.id,
30165
+ threadId: record.threadId ?? ""
30166
+ });
30167
+ writer.custom({
30168
+ ...failedMarker,
30169
+ transient: true
30170
+ }).catch(() => {});
30171
+ await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
30172
+ } catch (markerError) {
30173
+ omError("[OM] Failed to persist buffering-failed marker after async buffered reflection failure", markerError);
30174
+ }
30175
+ omError("[OM] Async buffered reflection failed", error);
30176
+ BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
30177
+ } finally {
30178
+ try {
30179
+ await reflectionHooks?.onReflectionEnd?.({
30180
+ usage: outcome?.usage,
30181
+ error: reflectionError,
30182
+ ...outcome?.providerMetadata ? { providerMetadata: outcome.providerMetadata } : {}
30183
+ });
30184
+ } catch (hookError) {
30185
+ omError("[OM] onReflectionEnd hook failed after async buffered reflection", hookError);
30186
+ }
30187
+ BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
30188
+ unregisterOp(record.id, "bufferingReflection");
30189
+ this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
30190
+ omError("[OM] Failed to clear buffering reflection flag", err);
30143
30191
  });
30144
- } catch (hookError) {
30145
- omError("[OM] onReflectionEnd hook failed after async buffered reflection failure", hookError);
30146
30192
  }
30147
- BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
30148
- }).finally(() => {
30149
- BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
30150
- unregisterOp(record.id, "bufferingReflection");
30151
- this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
30152
- omError("[OM] Failed to clear buffering reflection flag", err);
30153
- });
30154
- });
30193
+ })();
30155
30194
  BufferingCoordinator.asyncBufferingOps.set(bufferKey, asyncOp);
30156
30195
  }
30157
30196
  /**
@@ -30452,8 +30491,15 @@ var ReflectorRunner = class {
30452
30491
  let reflectionUsage;
30453
30492
  let reflectionProviderMetadata;
30454
30493
  let reflectionError;
30455
- reflectionHooks?.onReflectionStart?.();
30494
+ let lifecycleError;
30456
30495
  try {
30496
+ try {
30497
+ await reflectionHooks?.onReflectionStart?.();
30498
+ } catch (error) {
30499
+ lifecycleError = error;
30500
+ reflectionError = error instanceof Error ? error : new Error(String(error));
30501
+ throw error;
30502
+ }
30457
30503
  const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
30458
30504
  const reflectResult = await this.call(record.activeObservations, void 0, streamContext, reflectThreshold, abortSignal, void 0, compressionStartLevel, requestContext, priorExtractedValues, observabilityContext, void 0, mainAgent, sendSignal);
30459
30505
  reflectionUsage = reflectResult.usage;
@@ -30523,18 +30569,27 @@ var ReflectorRunner = class {
30523
30569
  await this.persistMarkerToStorage(failedMarker, threadId, record.resourceId ?? void 0);
30524
30570
  }
30525
30571
  reflectionError = error instanceof Error ? error : new Error(String(error));
30526
- if (abortSignal?.aborted) throw error;
30572
+ if (lifecycleError !== void 0 || abortSignal?.aborted) throw error;
30527
30573
  omError("[OM] Reflection failed", error);
30528
30574
  } finally {
30529
- await this.storage.setReflectingFlag(record.id, false);
30530
30575
  try {
30531
- reflectionHooks?.onReflectionEnd?.({
30576
+ await this.storage.setReflectingFlag(record.id, false);
30577
+ } finally {
30578
+ unregisterOp(record.id, "reflecting");
30579
+ }
30580
+ let endHookError;
30581
+ try {
30582
+ await reflectionHooks?.onReflectionEnd?.({
30532
30583
  usage: reflectionUsage,
30533
30584
  error: reflectionError,
30534
30585
  ...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
30535
30586
  });
30536
- } finally {
30537
- unregisterOp(record.id, "reflecting");
30587
+ } catch (error) {
30588
+ endHookError = error;
30589
+ }
30590
+ if (endHookError !== void 0) {
30591
+ if (lifecycleError === void 0 && !abortSignal?.aborted) throw endHookError;
30592
+ omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
30538
30593
  }
30539
30594
  }
30540
30595
  }
@@ -30991,6 +31046,8 @@ var ObservationalMemory = class ObservationalMemory {
30991
31046
  onIndexObservations;
30992
31047
  /** Config-level lifecycle hooks fired for every observation/reflection cycle. */
30993
31048
  hooks;
31049
+ /** Execution policy for config-level hooks on manual and turn-synchronous cycles. */
31050
+ hookExecution;
30994
31051
  /** Observer agent runner — handles LLM calls for extracting observations. */
30995
31052
  observer;
30996
31053
  /** Reflector agent runner — handles LLM calls for compressing observations. */
@@ -31097,6 +31154,7 @@ var ObservationalMemory = class ObservationalMemory {
31097
31154
  this.retrievalSearch = typeof config.retrieval === "object" && Boolean(config.retrieval.vector);
31098
31155
  this.onIndexObservations = config.onIndexObservations;
31099
31156
  this.hooks = config.hooks;
31157
+ this.hookExecution = config.hookExecution ?? "non-blocking";
31100
31158
  this.mastra = config.mastra;
31101
31159
  this.memory = config.memory;
31102
31160
  this.curationCadence = config.curationCadence;
@@ -32889,57 +32947,54 @@ ${formattedMessages}
32889
32947
  };
32890
32948
  }
32891
32949
  /**
32892
- * Compose the config-level hooks with optional per-call hooks into a single
32893
- * `ObserveHooks` object, binding call context onto the config-level
32894
- * callbacks. Config-level hooks are guarded so a throwing consumer hook can
32895
- * never fail an observation/reflection cycle; per-call hooks keep their
32896
- * existing payloads and propagation semantics. Returns undefined when
32897
- * neither is configured, so call sites stay zero-cost.
32898
- *
32899
- * Used internally by every pipeline path (manual observe/reflect,
32900
- * turn-engine sync observation, async buffering); public only so the
32901
- * observation turn engine can thread config-level reflection hooks into
32902
- * reflector calls.
32950
+ * Compose config-level hooks with optional per-call hooks and bind context to
32951
+ * config-level callbacks. The configured policy applies unless a background
32952
+ * path explicitly requests non-blocking invocation.
32903
32953
  *
32904
32954
  * @internal
32905
32955
  */
32906
- composeHooks(callHooks, context) {
32956
+ composeHooks(callHooks, context, execution = "configured") {
32907
32957
  const configHooks = this.hooks;
32908
32958
  if (!configHooks) return callHooks;
32909
32959
  if (!callHooks && !Object.keys(configHooks).length) return void 0;
32910
- const fireConfigHook = (name, arg) => {
32960
+ const shouldAwaitConfig = execution === "configured" && this.hookExecution === "await";
32961
+ const invokeConfigHook = async (name, arg) => {
32911
32962
  const hook = configHooks[name];
32912
32963
  if (!hook) return;
32964
+ if (shouldAwaitConfig) {
32965
+ await hook(arg);
32966
+ return;
32967
+ }
32913
32968
  const logHookFailure = (error) => omDebug(`[OM:hooks] config-level ${name} hook failed: ${error instanceof Error ? error.message : String(error)}`);
32914
32969
  try {
32915
- const out = hook(arg);
32916
- if (out && typeof out.then === "function") out.then(void 0, logHookFailure);
32970
+ const result = hook(arg);
32971
+ if (result && typeof result.then === "function") result.then(void 0, logHookFailure);
32917
32972
  } catch (error) {
32918
32973
  logHookFailure(error);
32919
32974
  }
32920
32975
  };
32921
32976
  return {
32922
- onObservationStart: () => {
32923
- fireConfigHook("onObservationStart", context);
32924
- callHooks?.onObservationStart?.();
32977
+ onObservationStart: async () => {
32978
+ await invokeConfigHook("onObservationStart", context);
32979
+ await callHooks?.onObservationStart?.();
32925
32980
  },
32926
- onObservationEnd: (result) => {
32927
- fireConfigHook("onObservationEnd", {
32981
+ onObservationEnd: async (result) => {
32982
+ await invokeConfigHook("onObservationEnd", {
32928
32983
  ...context,
32929
32984
  ...result
32930
32985
  });
32931
- callHooks?.onObservationEnd?.(result);
32986
+ await callHooks?.onObservationEnd?.(result);
32932
32987
  },
32933
- onReflectionStart: () => {
32934
- fireConfigHook("onReflectionStart", context);
32935
- callHooks?.onReflectionStart?.();
32988
+ onReflectionStart: async () => {
32989
+ await invokeConfigHook("onReflectionStart", context);
32990
+ await callHooks?.onReflectionStart?.();
32936
32991
  },
32937
- onReflectionEnd: (result) => {
32938
- fireConfigHook("onReflectionEnd", {
32992
+ onReflectionEnd: async (result) => {
32993
+ await invokeConfigHook("onReflectionEnd", {
32939
32994
  ...context,
32940
32995
  ...result
32941
32996
  });
32942
- callHooks?.onReflectionEnd?.(result);
32997
+ await callHooks?.onReflectionEnd?.(result);
32943
32998
  }
32944
32999
  };
32945
33000
  }
@@ -32952,22 +33007,29 @@ ${formattedMessages}
32952
33007
  * end hook reports `error` for failed cycles even though nothing throws.
32953
33008
  */
32954
33009
  async runBufferedObservationCycle(context, run) {
32955
- const hooks = this.composeHooks(void 0, context);
32956
- hooks?.onObservationStart?.();
33010
+ const hooks = this.composeHooks(void 0, context, "non-blocking");
32957
33011
  let runResult;
32958
33012
  let runError;
33013
+ let lifecycleError;
32959
33014
  try {
33015
+ await hooks?.onObservationStart?.();
32960
33016
  runResult = await run();
32961
33017
  return runResult;
32962
33018
  } catch (error) {
33019
+ lifecycleError = error;
32963
33020
  runError = error instanceof Error ? error : new Error(String(error));
32964
33021
  throw error;
32965
33022
  } finally {
32966
- hooks?.onObservationEnd?.({
32967
- usage: runResult?.usage,
32968
- error: runError ?? runResult?.error,
32969
- ...runResult?.providerMetadata ? { providerMetadata: runResult.providerMetadata } : {}
32970
- });
33023
+ try {
33024
+ await hooks?.onObservationEnd?.({
33025
+ usage: runResult?.usage,
33026
+ error: runError ?? runResult?.error,
33027
+ ...runResult?.providerMetadata ? { providerMetadata: runResult.providerMetadata } : {}
33028
+ });
33029
+ } catch (endHookError) {
33030
+ if (lifecycleError === void 0) throw endHookError;
33031
+ omDebug(`[OM:hooks] async-buffer onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
33032
+ }
32971
33033
  }
32972
33034
  }
32973
33035
  /**
@@ -32995,18 +33057,21 @@ ${formattedMessages}
32995
33057
  let observed = false;
32996
33058
  let observationUsage;
32997
33059
  let observationProviderMetadata;
33060
+ let observationError;
33061
+ let lifecycleError;
33062
+ let observationStarted = false;
32998
33063
  let generationBefore = -1;
32999
- await this.withLock(lockKey, async () => {
33000
- const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
33001
- generationBefore = freshRecord.generationCount;
33002
- const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadMessagesFromStorage(threadId, resourceId, freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : void 0);
33003
- if (!this.meetsObservationThreshold({
33004
- record: freshRecord,
33005
- unobservedTokens: await this.tokenCounter.countMessagesAsync(unobservedMessages)
33006
- })) return;
33007
- hooks?.onObservationStart?.();
33008
- let observationError;
33009
- try {
33064
+ try {
33065
+ await this.withLock(lockKey, async () => {
33066
+ const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
33067
+ generationBefore = freshRecord.generationCount;
33068
+ const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadMessagesFromStorage(threadId, resourceId, freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : void 0);
33069
+ if (!this.meetsObservationThreshold({
33070
+ record: freshRecord,
33071
+ unobservedTokens: await this.tokenCounter.countMessagesAsync(unobservedMessages)
33072
+ })) return;
33073
+ observationStarted = true;
33074
+ await hooks?.onObservationStart?.();
33010
33075
  const result = await ObservationStrategy.create(this, {
33011
33076
  record: freshRecord,
33012
33077
  threadId,
@@ -33024,17 +33089,22 @@ ${formattedMessages}
33024
33089
  observed = result.observed;
33025
33090
  observationUsage = result.usage;
33026
33091
  observationProviderMetadata = result.providerMetadata;
33027
- } catch (error) {
33028
- observationError = error instanceof Error ? error : new Error(String(error));
33029
- throw error;
33030
- } finally {
33031
- hooks?.onObservationEnd?.({
33032
- usage: observationUsage,
33033
- error: observationError,
33034
- ...observationProviderMetadata ? { providerMetadata: observationProviderMetadata } : {}
33035
- });
33036
- }
33037
- });
33092
+ });
33093
+ } catch (error) {
33094
+ lifecycleError = error;
33095
+ observationError = error instanceof Error ? error : new Error(String(error));
33096
+ }
33097
+ if (observationStarted) try {
33098
+ await hooks?.onObservationEnd?.({
33099
+ usage: observationUsage,
33100
+ error: observationError,
33101
+ ...observationProviderMetadata ? { providerMetadata: observationProviderMetadata } : {}
33102
+ });
33103
+ } catch (endHookError) {
33104
+ if (lifecycleError === void 0) throw endHookError;
33105
+ omDebug(`[OM:hooks] onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
33106
+ }
33107
+ if (lifecycleError !== void 0) throw lifecycleError;
33038
33108
  const record = await this.getOrCreateRecord(threadId, resourceId);
33039
33109
  const reflected = record.generationCount > generationBefore && generationBefore >= 0;
33040
33110
  if (observed) this.maybeTriggerCadenceCuration(threadId, resourceId, record, requestContext).catch((error) => {
@@ -33108,11 +33178,18 @@ ${formattedMessages}
33108
33178
  resourceId,
33109
33179
  trigger: "manual"
33110
33180
  });
33111
- hooks?.onReflectionStart?.();
33112
33181
  let reflectionUsage;
33113
33182
  let reflectionProviderMetadata;
33114
33183
  let reflectionError;
33184
+ let lifecycleError;
33115
33185
  try {
33186
+ try {
33187
+ await hooks?.onReflectionStart?.();
33188
+ } catch (error) {
33189
+ lifecycleError = error;
33190
+ reflectionError = error instanceof Error ? error : new Error(String(error));
33191
+ throw error;
33192
+ }
33116
33193
  const thread = await this.storage.getThreadById({ threadId });
33117
33194
  const previousOmMetadata = (0, _mastra_core_memory.getThreadOMMetadata)(thread?.metadata);
33118
33195
  const priorExtractedValues = getPriorExtractedValues(previousOmMetadata, this.reflectionConfig.extractors);
@@ -33150,6 +33227,7 @@ ${formattedMessages}
33150
33227
  };
33151
33228
  } catch (error) {
33152
33229
  reflectionError = error instanceof Error ? error : new Error(String(error));
33230
+ if (lifecycleError !== void 0) throw error;
33153
33231
  omError("[OM] reflect() failed", error);
33154
33232
  return {
33155
33233
  reflected: false,
@@ -33157,13 +33235,25 @@ ${formattedMessages}
33157
33235
  usage: void 0
33158
33236
  };
33159
33237
  } finally {
33160
- hooks?.onReflectionEnd?.({
33161
- usage: reflectionUsage,
33162
- error: reflectionError,
33163
- ...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
33164
- });
33165
- await this.storage.setReflectingFlag(record.id, false);
33166
- unregisterOp(record.id, "reflecting");
33238
+ try {
33239
+ await this.storage.setReflectingFlag(record.id, false);
33240
+ } finally {
33241
+ unregisterOp(record.id, "reflecting");
33242
+ }
33243
+ let endHookError;
33244
+ try {
33245
+ await hooks?.onReflectionEnd?.({
33246
+ usage: reflectionUsage,
33247
+ error: reflectionError,
33248
+ ...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
33249
+ });
33250
+ } catch (error) {
33251
+ endHookError = error;
33252
+ }
33253
+ if (endHookError !== void 0) {
33254
+ if (lifecycleError === void 0) throw endHookError;
33255
+ omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
33256
+ }
33167
33257
  }
33168
33258
  }
33169
33259
  /**
@@ -33455,7 +33545,9 @@ var ObservationalMemoryProcessor = class {
33455
33545
  return messageList;
33456
33546
  }
33457
33547
  const { threadId, resourceId } = context;
33458
- const readOnly = (0, _mastra_core_memory.parseMemoryRequestContext)(requestContext)?.memoryConfig?.readOnly;
33548
+ const memoryContext = (0, _mastra_core_memory.parseMemoryRequestContext)(requestContext);
33549
+ const runState = memoryContext?.runState?.();
33550
+ const readOnly = memoryContext?.memoryConfig?.readOnly;
33459
33551
  const actorModelContext = model?.modelId ? {
33460
33552
  provider: model.provider,
33461
33553
  modelId: model.modelId,
@@ -33472,7 +33564,8 @@ var ObservationalMemoryProcessor = class {
33472
33564
  memory: this.memory,
33473
33565
  messageList,
33474
33566
  threadId,
33475
- resourceId
33567
+ resourceId,
33568
+ runState
33476
33569
  });
33477
33570
  const systemMessages = ctx.omRecord ? await this.engine.buildContextSystemMessages({
33478
33571
  threadId,
@@ -33513,7 +33606,7 @@ var ObservationalMemoryProcessor = class {
33513
33606
  this.turn.sendStateSignal = args.sendStateSignal;
33514
33607
  this.turn.agent = args.agent;
33515
33608
  this.turn.requestContext = requestContext;
33516
- await this.turn.start(this.memory);
33609
+ await this.turn.start(this.memory, runState);
33517
33610
  if (stepNumber === 0 && this.temporalMarkers) await insertTemporalGapMarkers({
33518
33611
  messageList,
33519
33612
  sendSignal: args.sendSignal
@@ -34660,14 +34753,18 @@ ${workingMemory}`;
34660
34753
  if (!this.threadConfig.workingMemory?.enabled) return null;
34661
34754
  return extractWorkingMemoryContent(text)?.trim() ?? null;
34662
34755
  }
34663
- async getWorkingMemory({ threadId, resourceId, memoryConfig }) {
34756
+ async getWorkingMemory({ threadId, resourceId, memoryConfig, runState }) {
34664
34757
  const config = this.getMergedThreadConfig(memoryConfig || {});
34665
34758
  if (!config.workingMemory?.enabled) return null;
34666
34759
  const scope = config.workingMemory.scope || "resource";
34667
34760
  let workingMemoryData = null;
34668
34761
  if (scope === "resource" && !resourceId) throw new Error("Memory error: Resource-scoped working memory is enabled but no resourceId was provided. Either provide a resourceId or explicitly set workingMemory.scope to 'thread'.");
34669
- if (scope === "resource" && resourceId) workingMemoryData = (await (await this.getMemoryStore()).getResourceById({ resourceId }))?.workingMemory || null;
34670
- else workingMemoryData = (await this.getThreadById({ threadId }))?.metadata?.workingMemory;
34762
+ if (scope === "resource" && resourceId) {
34763
+ const loadWorkingMemory = async () => {
34764
+ return (await (await this.getMemoryStore()).getResourceById({ resourceId }))?.workingMemory || null;
34765
+ };
34766
+ workingMemoryData = runState ? await runState.load(`working-memory:resource:${resourceId}`, loadWorkingMemory) : await loadWorkingMemory();
34767
+ } else workingMemoryData = (runState?.threadLoaded ? runState.thread : await this.getThreadById({ threadId }))?.metadata?.workingMemory;
34671
34768
  if (!workingMemoryData) return null;
34672
34769
  return workingMemoryData;
34673
34770
  }
@@ -34699,16 +34796,18 @@ ${workingMemory}`;
34699
34796
  content: (config.workingMemory.template || this.defaultWorkingMemoryTemplate).trim()
34700
34797
  };
34701
34798
  }
34702
- async getSystemMessage({ threadId, resourceId, memoryConfig }) {
34799
+ async getSystemMessage({ threadId, resourceId, memoryConfig, runState }) {
34703
34800
  const config = this.getMergedThreadConfig(memoryConfig);
34704
34801
  this.assertWorkingMemoryStateSignalsCompatibility(config);
34705
34802
  if (!config.workingMemory?.enabled) return null;
34706
34803
  if (config.workingMemory?.useStateSignals) return null;
34707
- const workingMemoryTemplate = await this.getWorkingMemoryTemplate({ memoryConfig });
34804
+ const loadTemplate = () => this.getWorkingMemoryTemplate({ memoryConfig });
34805
+ const workingMemoryTemplate = runState ? await runState.load("working-memory:template", loadTemplate) : await loadTemplate();
34708
34806
  const workingMemoryData = await this.getWorkingMemory({
34709
34807
  threadId,
34710
34808
  resourceId,
34711
- memoryConfig: config
34809
+ memoryConfig: config,
34810
+ runState
34712
34811
  });
34713
34812
  if (!workingMemoryTemplate) return null;
34714
34813
  const workingMemoryConfig = config.workingMemory;
@@ -34741,7 +34840,7 @@ ${workingMemory}`;
34741
34840
  * ```
34742
34841
  */
34743
34842
  async getContext(opts) {
34744
- const { threadId, resourceId, memoryConfig } = opts;
34843
+ const { threadId, resourceId, memoryConfig, runState } = opts;
34745
34844
  const config = this.getMergedThreadConfig(memoryConfig);
34746
34845
  const memoryStore = await this.getMemoryStore();
34747
34846
  const systemParts = [];
@@ -34751,10 +34850,14 @@ ${workingMemory}`;
34751
34850
  let otherThreadsContext;
34752
34851
  const omEngine = await this.omEngine;
34753
34852
  if (omEngine) {
34754
- omRecord = await omEngine.getRecord(threadId, resourceId);
34853
+ const loadOmRecord = () => omEngine.getRecord(threadId, resourceId);
34854
+ omRecord = runState ? await runState.load(`observational-memory:record:${threadId}:${resourceId ?? ""}`, loadOmRecord) : await loadOmRecord();
34755
34855
  if (omRecord?.activeObservations) {
34756
34856
  hasObservations = true;
34757
- if (omEngine.scope === "resource" && resourceId) otherThreadsContext = await omEngine.getOtherThreadsContext(resourceId, threadId);
34857
+ if (omEngine.scope === "resource" && resourceId) {
34858
+ const loadOtherThreadsContext = () => omEngine.getOtherThreadsContext(resourceId, threadId);
34859
+ otherThreadsContext = runState ? await runState.load(`observational-memory:other-threads:${resourceId}:${threadId}:${omRecord.lastObservedAt ?? ""}`, loadOtherThreadsContext) : await loadOtherThreadsContext();
34860
+ }
34758
34861
  const obsSystemMessage = await omEngine.buildContextSystemMessage({
34759
34862
  threadId,
34760
34863
  resourceId,
@@ -34782,30 +34885,41 @@ ${workingMemory}`;
34782
34885
  const workingMemoryMessage = await this.getSystemMessage({
34783
34886
  threadId,
34784
34887
  resourceId,
34785
- memoryConfig: config
34888
+ memoryConfig: config,
34889
+ runState
34786
34890
  });
34787
34891
  if (workingMemoryMessage) systemParts.push(workingMemoryMessage);
34788
34892
  let messages;
34789
34893
  if (omEngine && omRecord) {
34790
34894
  const dateFilter = omRecord.lastObservedAt ? { dateRange: { start: new Date(new Date(omRecord.lastObservedAt).getTime() + 1) } } : void 0;
34791
- if (omEngine.scope === "resource" && resourceId) messages = (await memoryStore.listMessagesByResourceId({
34792
- resourceId,
34793
- orderBy: {
34794
- field: "createdAt",
34795
- direction: "ASC"
34796
- },
34797
- perPage: false,
34798
- filter: dateFilter
34799
- })).messages;
34800
- else messages = (await memoryStore.listMessages({
34801
- threadId,
34802
- orderBy: {
34803
- field: "createdAt",
34804
- direction: "ASC"
34805
- },
34806
- perPage: false,
34807
- filter: dateFilter
34808
- })).messages;
34895
+ const boundary = omRecord.lastObservedAt ? new Date(omRecord.lastObservedAt).toISOString() : "";
34896
+ if (omEngine.scope === "resource" && resourceId) {
34897
+ const loadMessages = async () => {
34898
+ return (await memoryStore.listMessagesByResourceId({
34899
+ resourceId,
34900
+ orderBy: {
34901
+ field: "createdAt",
34902
+ direction: "ASC"
34903
+ },
34904
+ perPage: false,
34905
+ filter: dateFilter
34906
+ })).messages;
34907
+ };
34908
+ messages = runState ? await runState.load(`observational-memory:messages:resource:${resourceId}:${boundary}`, loadMessages) : await loadMessages();
34909
+ } else {
34910
+ const loadMessages = async () => {
34911
+ return (await memoryStore.listMessages({
34912
+ threadId,
34913
+ orderBy: {
34914
+ field: "createdAt",
34915
+ direction: "ASC"
34916
+ },
34917
+ perPage: false,
34918
+ filter: dateFilter
34919
+ })).messages;
34920
+ };
34921
+ messages = runState ? await runState.load(`observational-memory:messages:thread:${threadId}:${boundary}`, loadMessages) : await loadMessages();
34922
+ }
34809
34923
  } else {
34810
34924
  const lastMessages = config.lastMessages;
34811
34925
  if (lastMessages === false) messages = [];
@@ -46199,4 +46313,4 @@ const agentBuilderWorkflows = {
46199
46313
  //#endregion
46200
46314
  exports.agentBuilderWorkflows = agentBuilderWorkflows;
46201
46315
 
46202
- //# sourceMappingURL=dist-DERatX43.cjs.map
46316
+ //# sourceMappingURL=dist-CY6Z5mkR.cjs.map