@mastra/memory 1.39.1-alpha.0 → 1.39.1-alpha.1

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.
@@ -36647,7 +36647,6 @@ var ObservationStep = class {
36647
36647
  let observerExchange;
36648
36648
  const step0Messages = this.stepNumber === 0 ? getObservableMessages(messageList) : [];
36649
36649
  if (this.stepNumber === 0) {
36650
- this.turn.inputMessageIds = messageList.get.input.db().map((msg) => msg.id);
36651
36650
  const activation = await om.activate({
36652
36651
  threadId,
36653
36652
  resourceId,
@@ -36778,7 +36777,7 @@ var ObservationStep = class {
36778
36777
  drainedKeys.set(msg.id, /* @__PURE__ */ new Set([...seen ?? [], ...keys]));
36779
36778
  return !seen || keys.some((key) => !seen.has(key));
36780
36779
  }).map((msg) => msg.id);
36781
- inFlightIds = [.../* @__PURE__ */ new Set([...this.turn.inputMessageIds, ...unreadIds])];
36780
+ inFlightIds = [...new Set(unreadIds)];
36782
36781
  if (messagesToSave.length > 0) {
36783
36782
  for (const msg of messagesToSave) messageList.add(msg, "memory");
36784
36783
  try {
@@ -36855,7 +36854,7 @@ var ObservationStep = class {
36855
36854
  });
36856
36855
  if (!didThresholdCleanup) {
36857
36856
  const fallbackCursor = this.turn.record.threadId ? getThreadOMMetadata((await om.getStorage().getThreadById({ threadId: this.turn.record.threadId }))?.metadata)?.lastObservedMessageCursor : void 0;
36858
- const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).concat(inFlightIds ?? [], this.turn.inputMessageIds, this.changedSinceDrain(messageList)).filter(Boolean));
36857
+ const pendingMessageIds = new Set([...messageList.get.input.db(), ...messageList.get.response.db()].map((msg) => msg.id).concat(inFlightIds ?? [], this.changedSinceDrain(messageList)).filter(Boolean));
36859
36858
  filterObservedMessages({
36860
36859
  messageList,
36861
36860
  record: this.turn.record,
@@ -37141,12 +37140,6 @@ var ObservationTurn = class {
37141
37140
  /** Generation count at turn start — used to detect if reflection happened during the turn. */
37142
37141
  _generationCountAtStart = -1;
37143
37142
  /**
37144
- * Ids of the messages this turn was started with (the user's request). Mid-turn
37145
- * observation may record them, but they stay in the live prompt until the turn ends.
37146
- * @internal Set by step 0.
37147
- */
37148
- inputMessageIds = [];
37149
- /**
37150
37143
  * Fingerprints of the non-marker parts each message had when a step last drained it. A message
37151
37144
  * is unread step output only if it gained a part the model has not seen — including a tool result
37152
37145
  * merged in place into an existing tool-invocation part — not when it only gained OM markers.
@@ -41917,7 +41910,6 @@ var ObservationalMemoryProcessor = class {
41917
41910
  this.turn.requestContext = requestContext;
41918
41911
  await this.turn.start(this.memory, runState);
41919
41912
  if (stepNumber > 0) {
41920
- this.turn.inputMessageIds = messageList.getPersisted.input.db().map((message) => message.id);
41921
41913
  if (this.memory?.getPersistedMessages) {
41922
41914
  const responseIds = messageList.getPersisted.response.db().map((message) => message.id);
41923
41915
  const snapshotMessages = new Map(messageList.get.all.db().map((message) => [message.id, message]));
@@ -42084,6 +42076,7 @@ var ObservationalMemoryProcessor = class {
42084
42076
  writer: args.writer,
42085
42077
  observabilityContext: getOmObservabilityContext(args)
42086
42078
  }));
42079
+ if (observed) args.rotateResponseMessageId?.();
42087
42080
  return { retry: activated || observed };
42088
42081
  }
42089
42082
  get config() {
@@ -43169,9 +43162,7 @@ ${workingMemory}`;
43169
43162
  async saveMessages({ messages, memoryConfig, observabilityContext }) {
43170
43163
  const span = this.createMemorySpan("save", observabilityContext, void 0, { messageCount: messages.length });
43171
43164
  try {
43172
- const updatedMessages = messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m)).map((m) => {
43173
- return this.updateMessageToHideWorkingMemoryV2(m);
43174
- }).filter((m) => Boolean(m));
43165
+ const updatedMessages = this.prepareMessagesForPersistence(messages);
43175
43166
  const config = this.getMergedThreadConfig(memoryConfig);
43176
43167
  const dbMessages = new MessageList({ generateMessageId: () => this.generateId() }).add(updatedMessages, "memory").get.all.db();
43177
43168
  const memoryStore = await this.getMemoryStore();
@@ -43277,12 +43268,17 @@ ${workingMemory}`;
43277
43268
  throw error;
43278
43269
  }
43279
43270
  }
43271
+ prepareMessagesForPersistence(messages) {
43272
+ return messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m)).map((m) => this.updateMessageToHideWorkingMemoryV2(m)).filter((m) => m !== null);
43273
+ }
43280
43274
  updateMessageToHideWorkingMemoryV2(message) {
43281
43275
  const newMessage = { ...message };
43282
43276
  if (message.content && typeof message.content === "object" && !Array.isArray(message.content)) newMessage.content = { ...message.content };
43283
43277
  if (typeof newMessage.content?.content === "string" && newMessage.content.content.length > 0) newMessage.content.content = removeWorkingMemoryTags(newMessage.content.content).trim();
43284
43278
  if (Array.isArray(newMessage.content?.parts)) {
43285
43279
  if (Array.isArray(newMessage.content.toolInvocations)) newMessage.content.toolInvocations = removeWorkingMemoryToolInvocations(newMessage.content.toolInvocations);
43280
+ const lastOriginalPart = newMessage.content.parts.at(-1);
43281
+ const sealMetadata = lastOriginalPart && "metadata" in lastOriginalPart ? lastOriginalPart.metadata : void 0;
43286
43282
  newMessage.content.parts = removeWorkingMemoryToolInvocationParts(newMessage.content.parts).map((part) => {
43287
43283
  if (part?.type === "text") {
43288
43284
  const text = typeof part.text === "string" ? part.text : "";
@@ -43293,6 +43289,26 @@ ${workingMemory}`;
43293
43289
  }
43294
43290
  return part;
43295
43291
  });
43292
+ const lastIndex = newMessage.content.parts.length - 1;
43293
+ const lastPart = newMessage.content.parts[lastIndex];
43294
+ if (lastPart && sealMetadata && typeof sealMetadata === "object" && "mastra" in sealMetadata) {
43295
+ const mastra = sealMetadata.mastra;
43296
+ if (mastra && typeof mastra === "object" && "sealedAt" in mastra && typeof mastra.sealedAt === "number") {
43297
+ const existingMetadata = "metadata" in lastPart ? lastPart.metadata : void 0;
43298
+ const metadata = existingMetadata && typeof existingMetadata === "object" ? existingMetadata : {};
43299
+ const existingMastra = "mastra" in metadata && metadata.mastra && typeof metadata.mastra === "object" ? metadata.mastra : {};
43300
+ newMessage.content.parts[lastIndex] = {
43301
+ ...lastPart,
43302
+ metadata: {
43303
+ ...metadata,
43304
+ mastra: {
43305
+ ...existingMastra,
43306
+ sealedAt: mastra.sealedAt
43307
+ }
43308
+ }
43309
+ };
43310
+ }
43311
+ }
43296
43312
  if (newMessage.content.parts.length === 0) {
43297
43313
  if (!(typeof newMessage.content.content === "string" && newMessage.content.content.trim().length > 0)) return null;
43298
43314
  }
@@ -43542,12 +43558,12 @@ ${workingMemory}`;
43542
43558
  };
43543
43559
  }
43544
43560
  /**
43545
- * Raw message upsert — persist messages to storage without embedding or working memory processing.
43561
+ * Raw message upsert — apply the persistence projection without embedding or extracting working memory.
43546
43562
  * Used by the processor to save sealed messages before firing a background buffer operation.
43547
43563
  */
43548
43564
  async persistMessages(messages) {
43549
43565
  if (messages.length === 0) return;
43550
- const persistableMessages = messages.filter((m) => m.role !== "system" && !isTransientSignalMessage(m));
43566
+ const persistableMessages = this.prepareMessagesForPersistence(messages);
43551
43567
  if (persistableMessages.length === 0) return;
43552
43568
  await (await this.getMemoryStore()).saveMessages({ messages: persistableMessages });
43553
43569
  }
@@ -44029,27 +44045,75 @@ Notes:
44029
44045
  if (messages.length === 0) return [];
44030
44046
  const memoryStore = await this.getMemoryStore();
44031
44047
  const config = this.getMergedThreadConfig(memoryConfig);
44048
+ const existing = await memoryStore.listMessagesById({ messageIds: messages.map((m) => m.id) });
44049
+ const existingById = new Map(existing.messages.map((m) => [m.id, m]));
44050
+ const textForEmbeddingById = /* @__PURE__ */ new Map();
44051
+ const textFields = ["content", "parts"];
44052
+ const textOf = (content, fields) => {
44053
+ for (const field of fields) {
44054
+ const text = field === "content" ? content.content?.trim() ? content.content : null : (content.parts ?? []).filter((part) => part?.type === "text").map((part) => part.text).join(" ").trim();
44055
+ if (text) return text;
44056
+ }
44057
+ return null;
44058
+ };
44059
+ messages = messages.flatMap((update) => {
44060
+ const stored = existingById.get(update.id);
44061
+ if (!stored) return [];
44062
+ const effective = {
44063
+ ...stored,
44064
+ ...update,
44065
+ content: update.content === void 0 ? stored.content : {
44066
+ ...stored.content,
44067
+ ...update.content,
44068
+ metadata: {
44069
+ ...stored.content.metadata,
44070
+ ...update.content.metadata
44071
+ }
44072
+ }
44073
+ };
44074
+ const [projected] = this.prepareMessagesForPersistence([effective]);
44075
+ if (!projected) return [];
44076
+ if (update.content === void 0) {
44077
+ existingById.set(update.id, effective);
44078
+ return [update];
44079
+ }
44080
+ const content = {
44081
+ ...update.content,
44082
+ ...update.content.parts !== void 0 ? { parts: projected.content.parts } : {},
44083
+ ...update.content.content !== void 0 ? { content: projected.content.content } : {},
44084
+ ...update.content.toolInvocations !== void 0 ? { toolInvocations: projected.content.toolInvocations } : {}
44085
+ };
44086
+ existingById.set(update.id, {
44087
+ ...effective,
44088
+ content: {
44089
+ ...effective.content,
44090
+ ...content
44091
+ }
44092
+ });
44093
+ const patched = textFields.filter((field) => update.content?.[field] !== void 0);
44094
+ if (patched.length > 0) {
44095
+ const omitted = textFields.filter((field) => !patched.includes(field));
44096
+ const text = textOf(projected.content, patched) ?? (textOf(update.content, patched) ? textOf(projected.content, omitted) : null);
44097
+ textForEmbeddingById.set(update.id, text);
44098
+ }
44099
+ return [{
44100
+ ...update,
44101
+ content
44102
+ }];
44103
+ });
44104
+ if (messages.length === 0) return [];
44032
44105
  if (this.vector && config.semanticRecall) {
44033
- const messagesWithContent = messages.filter((m) => m.content !== void 0);
44034
- if (messagesWithContent.length > 0) {
44035
- const existingMessagesResult = await memoryStore.listMessagesById({ messageIds: messagesWithContent.map((m) => m.id) });
44036
- const existingMessagesMap = new Map(existingMessagesResult.messages.map((m) => [m.id, m]));
44106
+ const messagesWithTextUpdates = [...textForEmbeddingById.keys()].map((id) => ({ id }));
44107
+ if (messagesWithTextUpdates.length > 0) {
44108
+ const existingMessagesMap = new Map(existing.messages.map((m) => [m.id, m]));
44037
44109
  const embeddingData = [];
44038
44110
  let dimension;
44039
44111
  const messageIdsWithNewEmbeddings = /* @__PURE__ */ new Set();
44040
44112
  const messageIdsWithClearedContent = /* @__PURE__ */ new Set();
44041
- await Promise.all(messagesWithContent.map(async (message) => {
44113
+ await Promise.all(messagesWithTextUpdates.map(async (message) => {
44042
44114
  const existingMessage = existingMessagesMap.get(message.id);
44043
44115
  if (!existingMessage) return;
44044
- let textForEmbedding = null;
44045
- const content = message.content;
44046
- if (content) {
44047
- if ("content" in content && content.content && typeof content.content === "string" && content.content.trim() !== "") textForEmbedding = content.content;
44048
- else if ("parts" in content && content.parts && Array.isArray(content.parts) && content.parts.length > 0) {
44049
- const joined = content.parts.filter((part) => part?.type === "text").map((part) => part.text).join(" ").trim();
44050
- if (joined) textForEmbedding = joined;
44051
- }
44052
- }
44116
+ const textForEmbedding = textForEmbeddingById.get(message.id) ?? null;
44053
44117
  if (textForEmbedding) {
44054
44118
  let embeddings = [];
44055
44119
  let documents;
@@ -44796,4 +44860,4 @@ Notes:
44796
44860
  //#endregion
44797
44861
  export { renderSubconsciousActivity as $, buildObserverSystemPrompt as A, OBSERVATION_CONTEXT_INSTRUCTIONS as B, WorkingMemoryExtractor as C, TokenCounter as D, summarizeConversation as E, parseObserverOutput as F, Subconscious as G, OBSERVATION_CONTEXT_PROMPT_THREAD as H, injectAnchorIds as I, SubconsciousRemindExtractor as J, KnowledgeSemanticIndexCoordinator as K, parseAnchorId as L, formatMessagesForObserver as M, hasCurrentTaskSection as N, OBSERVER_SYSTEM_PROMPT as O, optimizeObservationsForContext as P, publishSubconsciousActivity as Q, stripEphemeralAnchorIds as R, wrapInObservationGroup as S, SUMMARIZE_THREAD_DEFAULTS as T, OBSERVATION_CONTINUATION_HINT as U, OBSERVATION_CONTEXT_PROMPT as V, getObservationContextPrompt as W, SUBCONSCIOUS_ACTIVITY_STATE_ID as X, ModelByInputTokens as Y, buildSubconsciousActivitySnapshot as Z, deriveObservationGroupProvenance as _, extractWorkingMemoryContent as a, renderObservationGroupsForReflection as b, getObservationsAsOf as c, AUTO_MODEL_BY_PROVIDER as d, Extractor as et, resolveAutoModelId as f, combineObservationGroupRanges as g, WorkingMemoryStateProcessor as h, WorkingMemory as i, extractCurrentTask as j, buildObserverPrompt as k, ObservationalMemoryProcessor as l, WORKING_MEMORY_STATE_PROCESSOR_ID as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, WORKING_MEMORY_STATE_ID as p, StaleKnowledgeSemanticIndexError as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, parseObservationGroups as v, deepMergeWorkingMemory as w, stripObservationGroups as x, reconcileObservationGroupsFromReflection as y, OBSERVATIONAL_MEMORY_DEFAULTS as z };
44798
44862
 
44799
- //# sourceMappingURL=src-DQ-kLMpB.js.map
44863
+ //# sourceMappingURL=src-BUWL69LT.js.map