@mastra/memory 1.36.0-alpha.1 → 1.36.0-alpha.3

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.
@@ -3712,7 +3712,7 @@ function trimStartOfStream() {
3712
3712
  };
3713
3713
  }
3714
3714
  //#endregion
3715
- //#region ../_vendored/ai_v5/dist/dist-DqVGDtnX.js
3715
+ //#region ../_vendored/ai_v5/dist/dist-CwCWl16R.js
3716
3716
  var marker$2$4 = "vercel.ai.error";
3717
3717
  var symbol$2$4 = Symbol.for(marker$2$4);
3718
3718
  var _a$2$4;
@@ -8999,7 +8999,7 @@ var object$1 = ({ schema: inputSchema }) => {
8999
8999
  };
9000
9000
  };
9001
9001
  //#endregion
9002
- //#region ../_vendored/ai_v6/dist/dist-BcG-LFmj.js
9002
+ //#region ../_vendored/ai_v6/dist/dist-B5Rt0qDx.js
9003
9003
  var marker$2 = "vercel.ai.error";
9004
9004
  var symbol$2 = Symbol.for(marker$2);
9005
9005
  var _a$2;
@@ -11544,7 +11544,7 @@ var _b14;
11544
11544
  }
11545
11545
  });
11546
11546
  //#endregion
11547
- //#region ../_vendored/ai_v6/dist/dist-t-eoX9xC.js
11547
+ //#region ../_vendored/ai_v6/dist/dist-BgUIUei9.js
11548
11548
  function getContext() {
11549
11549
  return { headers: {} };
11550
11550
  }
@@ -20804,6 +20804,25 @@ function getObserverMessageLabel(msg) {
20804
20804
  if (isSystemReminderMessage(msg)) return "system-reminder";
20805
20805
  return msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
20806
20806
  }
20807
+ /**
20808
+ * Attachment URLs the agent already found undownloadable. Core records them on the user
20809
+ * message (`metadata.mastra.unavailableAttachments`) so they are not fetched again.
20810
+ */
20811
+ function getUnavailableAttachmentUrls(msg) {
20812
+ const mastra = msg.content?.metadata?.mastra;
20813
+ const urls = isRecord$2(mastra) ? mastra.unavailableAttachments : void 0;
20814
+ return new Set(Array.isArray(urls) ? urls.filter((url) => typeof url === "string") : []);
20815
+ }
20816
+ function getObserverAttachmentUrl(part) {
20817
+ const asset = part.type === "image" ? part.image : part.data ?? part.url;
20818
+ if (asset instanceof URL) return asset.toString();
20819
+ if (typeof asset !== "string") return void 0;
20820
+ try {
20821
+ return new URL(asset).toString();
20822
+ } catch {
20823
+ return;
20824
+ }
20825
+ }
20807
20826
  function formatObserverMessage(msg, counter, toolFormatting, options) {
20808
20827
  const maxLen = options?.maxPartLength;
20809
20828
  const maxToolResultTokens = options?.maxToolResultTokens ?? 5e3;
@@ -20812,6 +20831,7 @@ function formatObserverMessage(msg, counter, toolFormatting, options) {
20812
20831
  const role = getObserverMessageLabel(msg);
20813
20832
  const attachments = [];
20814
20833
  const messageCreatedAt = normalizeObserverCreatedAt(msg.createdAt);
20834
+ const unavailableUrls = getUnavailableAttachmentUrls(msg);
20815
20835
  let lines = [];
20816
20836
  const temporalGapText = isTemporalGapMarker(msg) ? getTemporalGapMarkerText(msg) : void 0;
20817
20837
  const pushLine = (title, body, createdAt) => {
@@ -20870,7 +20890,8 @@ function formatObserverMessage(msg, counter, toolFormatting, options) {
20870
20890
  }
20871
20891
  if (partType === "image" || partType === "file") {
20872
20892
  const attachment = part;
20873
- if (shouldIncludeObserverAttachment(attachment, attachmentFilter)) {
20893
+ const attachmentUrl = unavailableUrls.size > 0 ? getObserverAttachmentUrl(attachment) : void 0;
20894
+ if (!(attachmentUrl !== void 0 && unavailableUrls.has(attachmentUrl)) && shouldIncludeObserverAttachment(attachment, attachmentFilter)) {
20874
20895
  const inputAttachment = toObserverInputAttachmentPart(attachment);
20875
20896
  if (inputAttachment) attachments.push(inputAttachment);
20876
20897
  }
@@ -22180,6 +22201,7 @@ function serializeNonImageFilePartForTokenCounting(part) {
22180
22201
  function isValidCacheEntry(entry, expectedKey, expectedSource) {
22181
22202
  return Boolean(entry && entry.v === TOKEN_ESTIMATE_CACHE_VERSION && entry.source === expectedSource && entry.key === expectedKey && Number.isFinite(entry.tokens));
22182
22203
  }
22204
+ const modelContextStorage = new AsyncLocalStorage();
22183
22205
  function parseModelContext(model) {
22184
22206
  if (!model) return void 0;
22185
22207
  if (typeof model === "object") return model.provider || model.modelId ? {
@@ -22801,7 +22823,6 @@ async function fetchGoogleAttachmentTokenEstimate(modelId, part) {
22801
22823
  var TokenCounter = class TokenCounter {
22802
22824
  cacheSource;
22803
22825
  defaultModelContext;
22804
- modelContextStorage = new AsyncLocalStorage();
22805
22826
  inFlightAttachmentCounts = /* @__PURE__ */ new Map();
22806
22827
  multimodalToolResultCounts = /* @__PURE__ */ new WeakMap();
22807
22828
  static TOKENS_PER_MESSAGE = 3.8;
@@ -22811,10 +22832,12 @@ var TokenCounter = class TokenCounter {
22811
22832
  this.defaultModelContext = parseModelContext(options?.model);
22812
22833
  }
22813
22834
  runWithModelContext(model, fn) {
22814
- return this.modelContextStorage.run(parseModelContext(model), fn);
22835
+ const contexts = new Map(modelContextStorage.getStore());
22836
+ contexts.set(this, parseModelContext(model));
22837
+ return modelContextStorage.run(contexts, fn);
22815
22838
  }
22816
22839
  getModelContext() {
22817
- return this.modelContextStorage.getStore() ?? this.defaultModelContext;
22840
+ return modelContextStorage.getStore()?.get(this) ?? this.defaultModelContext;
22818
22841
  }
22819
22842
  /**
22820
22843
  * Count tokens in a plain string
@@ -28018,7 +28041,7 @@ var ObservationStep = class {
28018
28041
  if (obsResult.succeeded) {
28019
28042
  observed = true;
28020
28043
  didThresholdCleanup = true;
28021
- const observedIds = obsResult.activatedMessageIds ?? obsResult.record.observedMessageIds ?? [];
28044
+ const observedIds = obsResult.cleanupMessageIds;
28022
28045
  const minRemaining = resolveRetentionFloor(om.getObservationConfig().bufferActivation ?? 1, statusSnapshot.threshold);
28023
28046
  await om.cleanupMessages({
28024
28047
  threadId,
@@ -28085,8 +28108,8 @@ var ObservationStep = class {
28085
28108
  }
28086
28109
  /**
28087
28110
  * Run the full threshold observation pipeline:
28088
- * waitForBuffering → re-check → activate → reflect → observe (sync fallback when
28089
- * buffered activation did not happen)
28111
+ * waitForBuffering → re-check → activate buffered chunks → reflect → observe
28112
+ * (sync fallback when pending tokens are still at or above the threshold)
28090
28113
  */
28091
28114
  async runThresholdObservation() {
28092
28115
  const { threadId, resourceId, messageList } = this.turn;
@@ -28094,59 +28117,76 @@ var ObservationStep = class {
28094
28117
  await om.waitForBuffering(threadId, resourceId);
28095
28118
  await this.turn.refreshRecord();
28096
28119
  const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
28097
- const freshStatus = await om.getStatus({
28120
+ let status = await om.getStatus({
28098
28121
  threadId,
28099
28122
  resourceId,
28100
28123
  record: this.turn.record,
28101
28124
  messages: observableMessages
28102
28125
  });
28103
- if (!freshStatus.shouldObserve) return {
28126
+ if (!status.shouldObserve) return {
28104
28127
  succeeded: false,
28105
- record: freshStatus.record
28128
+ record: status.record,
28129
+ cleanupMessageIds: []
28106
28130
  };
28107
- if (freshStatus.canActivate) {
28131
+ let pendingMessages = observableMessages;
28132
+ const activatedMessageIds = [];
28133
+ let activated = false;
28134
+ while (status.shouldObserve && status.canActivate) {
28108
28135
  const activation = await om.activate({
28109
28136
  threadId,
28110
28137
  resourceId,
28111
28138
  record: this.turn.record,
28112
- messages: observableMessages,
28139
+ messages: pendingMessages,
28140
+ pendingTokens: status.pendingTokens,
28113
28141
  currentModel: this.turn.actorModelContext,
28114
28142
  writer: this.turn.writer,
28115
28143
  messageList
28116
28144
  });
28117
28145
  this.turn.setRecord(activation.record);
28118
- if (activation.activated) {
28119
- const postActivationRecord = activation.record;
28120
- await om.reflector.maybeReflect({
28121
- record: postActivationRecord,
28122
- observationTokens: postActivationRecord.observationTokenCount ?? 0,
28146
+ if (!activation.activated) break;
28147
+ activated = true;
28148
+ const ids = new Set(activation.activatedMessageIds ?? []);
28149
+ activatedMessageIds.push(...ids);
28150
+ pendingMessages = pendingMessages.filter((msg) => !ids.has(msg.id));
28151
+ status = await om.getStatus({
28152
+ threadId,
28153
+ resourceId,
28154
+ record: this.turn.record,
28155
+ messages: pendingMessages
28156
+ });
28157
+ }
28158
+ if (activated) {
28159
+ const postActivationRecord = this.turn.record;
28160
+ await om.reflector.maybeReflect({
28161
+ record: postActivationRecord,
28162
+ observationTokens: postActivationRecord.observationTokenCount ?? 0,
28163
+ threadId,
28164
+ writer: this.turn.writer,
28165
+ messageList,
28166
+ currentModel: this.turn.actorModelContext,
28167
+ requestContext: this.turn.requestContext,
28168
+ observabilityContext: this.turn.observabilityContext,
28169
+ lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
28170
+ reflectionHooks: om.composeHooks(void 0, {
28123
28171
  threadId,
28124
- writer: this.turn.writer,
28125
- messageList,
28126
- currentModel: this.turn.actorModelContext,
28127
- requestContext: this.turn.requestContext,
28128
- observabilityContext: this.turn.observabilityContext,
28129
- lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
28130
- reflectionHooks: om.composeHooks(void 0, {
28131
- threadId,
28132
- resourceId,
28133
- trigger: "turn-sync"
28134
- }),
28172
+ resourceId,
28135
28173
  trigger: "turn-sync"
28136
- });
28137
- return {
28138
- succeeded: true,
28139
- record: activation.record,
28140
- activatedMessageIds: activation.activatedMessageIds
28141
- };
28142
- }
28174
+ }),
28175
+ trigger: "turn-sync"
28176
+ });
28177
+ if (!status.shouldObserve) return {
28178
+ succeeded: true,
28179
+ record: postActivationRecord,
28180
+ activatedMessageIds,
28181
+ cleanupMessageIds: activatedMessageIds
28182
+ };
28143
28183
  }
28144
28184
  let obsResult;
28145
28185
  try {
28146
28186
  obsResult = await om.observe({
28147
28187
  threadId,
28148
28188
  resourceId,
28149
- messages: observableMessages,
28189
+ messages: pendingMessages,
28150
28190
  messageList,
28151
28191
  trigger: "turn-sync",
28152
28192
  agent: this.turn.agent,
@@ -28159,8 +28199,10 @@ var ObservationStep = class {
28159
28199
  } catch (error) {
28160
28200
  if (om.config.observation.failurePolicy !== "continue" || !isOmModelExecutionError(error) || error.failureKind !== "observer-model") throw error;
28161
28201
  return {
28162
- succeeded: false,
28163
- record: freshStatus.record
28202
+ succeeded: activated,
28203
+ record: this.turn.record,
28204
+ activatedMessageIds: activated ? activatedMessageIds : void 0,
28205
+ cleanupMessageIds: activatedMessageIds
28164
28206
  };
28165
28207
  }
28166
28208
  if (obsResult.observed) {
@@ -28187,8 +28229,10 @@ var ObservationStep = class {
28187
28229
  if (messagesToSeal.length > 0) await om.persistMessages(messagesToSeal, threadId, resourceId);
28188
28230
  }
28189
28231
  return {
28190
- succeeded: obsResult.observed,
28232
+ succeeded: activated || obsResult.observed,
28191
28233
  record: obsResult.record,
28234
+ activatedMessageIds: activated ? activatedMessageIds : void 0,
28235
+ cleanupMessageIds: [.../* @__PURE__ */ new Set([...activatedMessageIds, ...obsResult.observed ? obsResult.record.observedMessageIds ?? [] : []])],
28192
28236
  observerExchange: om.observer.lastExchange
28193
28237
  };
28194
28238
  }
@@ -31876,6 +31920,7 @@ ${formattedMessages}
31876
31920
  let activateAfterIdleExpiredMs;
31877
31921
  let previousModel;
31878
31922
  let currentModel;
31923
+ let livePendingTokens = opts.pendingTokens;
31879
31924
  if (opts.checkThreshold) {
31880
31925
  const thresholdMessages = opts.messages ?? await this.loadMessagesFromStorage(threadId, resourceId, record.lastObservedAt ? new Date(record.lastObservedAt) : void 0);
31881
31926
  const activateAfterIdle = resolveActivationTTL(this.observationConfig.activateAfterIdle, opts.currentModel);
@@ -31904,6 +31949,7 @@ ${formattedMessages}
31904
31949
  activated: false,
31905
31950
  record
31906
31951
  };
31952
+ livePendingTokens ??= status.pendingTokens;
31907
31953
  }
31908
31954
  }
31909
31955
  if (record.isBufferingObservation) {
@@ -31927,8 +31973,9 @@ ${formattedMessages}
31927
31973
  const messageTokensThreshold = getMaxThreshold(this.getEffectiveMessageTokens(freshRecord));
31928
31974
  const activationRatio = resolveActivationRatio(this.observationConfig.bufferActivation ?? .7, messageTokensThreshold);
31929
31975
  const totalChunkMessageTokens = freshChunks.reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
31930
- const currentPendingTokens = freshRecord.pendingMessageTokens || totalChunkMessageTokens;
31976
+ const currentPendingTokens = livePendingTokens ?? (freshRecord.pendingMessageTokens || totalChunkMessageTokens);
31931
31977
  const forceMaxActivation = !!(this.observationConfig.blockAfter && currentPendingTokens >= this.observationConfig.blockAfter);
31978
+ if (freshRecord.pendingMessageTokens !== currentPendingTokens) await this.storage.setPendingMessageTokens(freshRecord.id, currentPendingTokens);
31932
31979
  const activationResult = await this.storage.swapBufferedToActive({
31933
31980
  id: freshRecord.id,
31934
31981
  activationRatio,
@@ -35250,4 +35297,4 @@ Notes:
35250
35297
  //#endregion
35251
35298
  export { formatMessagesForObserver as A, OBSERVATION_CONTEXT_PROMPT_THREAD as B, SUMMARIZE_THREAD_DEFAULTS as C, buildObserverPrompt as D, OBSERVER_SYSTEM_PROMPT as E, parseAnchorId as F, StaleKnowledgeSemanticIndexError as G, getObservationContextPrompt as H, stripEphemeralAnchorIds as I, SUBCONSCIOUS_ACTIVITY_STATE_ID as J, SubconsciousRemindExtractor as K, OBSERVATIONAL_MEMORY_DEFAULTS as L, optimizeObservationsForContext as M, parseObserverOutput as N, buildObserverSystemPrompt as O, injectAnchorIds as P, Extractor as Q, OBSERVATION_CONTEXT_INSTRUCTIONS as R, deepMergeWorkingMemory as S, TokenCounter as T, Subconscious as U, OBSERVATION_CONTINUATION_HINT as V, KnowledgeSemanticIndexCoordinator as W, publishSubconsciousActivity as X, buildSubconsciousActivitySnapshot as Y, renderSubconsciousActivity as Z, reconcileObservationGroupsFromReflection as _, extractWorkingMemoryContent as a, wrapInObservationGroup as b, getObservationsAsOf as c, WORKING_MEMORY_STATE_ID as d, WORKING_MEMORY_STATE_PROCESSOR_ID as f, parseObservationGroups as g, deriveObservationGroupProvenance as h, WorkingMemory as i, hasCurrentTaskSection as j, extractCurrentTask as k, ObservationalMemoryProcessor as l, combineObservationGroupRanges as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, WorkingMemoryStateProcessor as p, ModelByInputTokens as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, renderObservationGroupsForReflection as v, summarizeConversation as w, WorkingMemoryExtractor as x, stripObservationGroups as y, OBSERVATION_CONTEXT_PROMPT as z };
35252
35299
 
35253
- //# sourceMappingURL=src-CFTlELNa.js.map
35300
+ //# sourceMappingURL=src-BQOm4kZc.js.map