@mastra/memory 1.32.0-alpha.0 → 1.32.0-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.
@@ -18377,7 +18377,9 @@ var constants_exports = /* @__PURE__ */ __exportAll({
18377
18377
  OBSERVATIONAL_MEMORY_DEFAULTS: () => OBSERVATIONAL_MEMORY_DEFAULTS,
18378
18378
  OBSERVATION_CONTEXT_INSTRUCTIONS: () => OBSERVATION_CONTEXT_INSTRUCTIONS,
18379
18379
  OBSERVATION_CONTEXT_PROMPT: () => OBSERVATION_CONTEXT_PROMPT,
18380
+ OBSERVATION_CONTEXT_PROMPT_THREAD: () => OBSERVATION_CONTEXT_PROMPT_THREAD,
18380
18381
  OBSERVATION_CONTINUATION_HINT: () => OBSERVATION_CONTINUATION_HINT,
18382
+ getObservationContextPrompt: () => getObservationContextPrompt,
18381
18383
  getRetrievalInstructions: () => getRetrievalInstructions
18382
18384
  });
18383
18385
  /**
@@ -18427,6 +18429,19 @@ Any messages following this reminder are newer and should take priority.`;
18427
18429
  */
18428
18430
  const OBSERVATION_CONTEXT_PROMPT = `The following observations block contains your memory of past conversations with this user.`;
18429
18431
  /**
18432
+ * Preamble used when observations are thread-scoped: they describe earlier parts
18433
+ * of the current conversation, not other conversations.
18434
+ */
18435
+ const OBSERVATION_CONTEXT_PROMPT_THREAD = `The following observations block contains your memory of earlier parts of this current conversation. Everything recorded here (including IDs, artifacts, and tool results) came from this conversation and is available for you to reuse.`;
18436
+ /**
18437
+ * Returns the observations preamble matching the memory scope.
18438
+ * - `'thread'`: observations are earlier parts of the current conversation.
18439
+ * - `'resource'`: observations span past conversations with this user.
18440
+ */
18441
+ function getObservationContextPrompt(scope = "thread") {
18442
+ return scope === "resource" ? OBSERVATION_CONTEXT_PROMPT : OBSERVATION_CONTEXT_PROMPT_THREAD;
18443
+ }
18444
+ /**
18430
18445
  * Instructions that tell the model how to interpret and use observations.
18431
18446
  * Place AFTER the `<observations>` block so the model sees the data before the rules.
18432
18447
  */
@@ -18704,7 +18719,7 @@ async function applyExtractorHooks(opts) {
18704
18719
  }
18705
18720
  //#endregion
18706
18721
  //#region src/processors/observational-memory/error.ts
18707
- function isRecord$4(value) {
18722
+ function isRecord$5(value) {
18708
18723
  return typeof value === "object" && value !== null;
18709
18724
  }
18710
18725
  /** Keep provider diagnostics in streamed/persisted markers, not whole API request/response objects. */
@@ -18716,7 +18731,7 @@ function formatOmError(error) {
18716
18731
  };
18717
18732
  function collectErrorDetails(value, depth) {
18718
18733
  if (depth > 5) return;
18719
- if (!isRecord$4(value)) {
18734
+ if (!isRecord$5(value)) {
18720
18735
  if (value !== void 0) add(String(value));
18721
18736
  return;
18722
18737
  }
@@ -18726,10 +18741,10 @@ function formatOmError(error) {
18726
18741
  if (typeof value.statusCode === "number") add(`HTTP ${value.statusCode}`);
18727
18742
  if (typeof value.responseBody === "string") try {
18728
18743
  const body = JSON.parse(value.responseBody);
18729
- if (isRecord$4(body)) {
18744
+ if (isRecord$5(body)) {
18730
18745
  add(body.message);
18731
18746
  add(body.detail);
18732
- if (isRecord$4(body.error)) add(body.error.message);
18747
+ if (isRecord$5(body.error)) add(body.error.message);
18733
18748
  else add(body.error);
18734
18749
  }
18735
18750
  } catch {}
@@ -18835,6 +18850,21 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
18835
18850
  };
18836
18851
  }
18837
18852
  //#endregion
18853
+ //#region src/system-reminders.ts
18854
+ const LEGACY_SYSTEM_REMINDER_METADATA_KEY = "dynamicAgentsMdReminder";
18855
+ function isRecord$4(value) {
18856
+ return typeof value === "object" && value !== null;
18857
+ }
18858
+ function isSystemReminderMessage(message) {
18859
+ if (!isRecord$4(message.content)) return false;
18860
+ const metadata = message.content.metadata;
18861
+ if (message.role === "signal") return isRecord$4(metadata) && isRecord$4(metadata.signal) && (metadata.signal.type === "system-reminder" || metadata.signal.type === "reactive");
18862
+ if (message.role !== "user") return false;
18863
+ if (isRecord$4(metadata) && (isRecord$4(metadata.systemReminder) || LEGACY_SYSTEM_REMINDER_METADATA_KEY in metadata)) return true;
18864
+ const firstTextPart = message.content.parts.find((part) => part.type === "text");
18865
+ return typeof firstTextPart?.text === "string" && firstTextPart.text.startsWith("<system-reminder");
18866
+ }
18867
+ //#endregion
18838
18868
  //#region src/processors/observational-memory/anchor-ids.ts
18839
18869
  const ANCHOR_ID_PATTERN = /^\[(O\d+(?:-N\d+)?)\]\s*/;
18840
18870
  const OBSERVATION_DATE_HEADER_PATTERN = /^\s*Date:\s+/;
@@ -20331,11 +20361,23 @@ function formatObserverToolArguments(args, maxCharacters) {
20331
20361
  if (args === void 0) return maybeTruncate("[arguments unavailable]", maxCharacters);
20332
20362
  return formatToolArgumentsForObserver(args, { maxCharacters: maxCharacters || void 0 });
20333
20363
  }
20364
+ /**
20365
+ * Labels signals and system reminders by their tag instead of as "User", so the Observer
20366
+ * does not record runtime instructions as things the user said (#22195).
20367
+ */
20368
+ function getObserverMessageLabel(msg) {
20369
+ if (msg.role === "signal") {
20370
+ const signal = msg.content?.metadata?.signal;
20371
+ return signal?.type === "user" ? "User" : signal?.tagName ?? signal?.type ?? "Signal";
20372
+ }
20373
+ if (isSystemReminderMessage(msg)) return "system-reminder";
20374
+ return msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
20375
+ }
20334
20376
  function formatObserverMessage(msg, counter, toolFormatting, options) {
20335
20377
  const maxLen = options?.maxPartLength;
20336
20378
  const maxToolResultTokens = options?.maxToolResultTokens ?? 5e3;
20337
20379
  const attachmentFilter = options?.attachmentFilter;
20338
- const role = msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
20380
+ const role = getObserverMessageLabel(msg);
20339
20381
  const attachments = [];
20340
20382
  const messageCreatedAt = normalizeObserverCreatedAt(msg.createdAt);
20341
20383
  let lines = [];
@@ -20509,7 +20551,36 @@ function buildMultiThreadObserverHistoryMessage(messagesByThread, threadOrder, o
20509
20551
  content
20510
20552
  };
20511
20553
  }
20512
- function buildMultiThreadObserverTaskPrompt(existingObservations, threadOrder, priorMetadataByThread, wasTruncated, includeThreadTitle, extractors = []) {
20554
+ /**
20555
+ * Build the Observer's single multi-thread request message: prior memory first, then the
20556
+ * thread histories, then the task. Keeping everything in one user message, with the task
20557
+ * after the history, stops the Observer from reading its own instructions as something
20558
+ * the user said (#22195).
20559
+ */
20560
+ function buildMultiThreadObserverRequestMessage(existingObservations, messagesByThread, threadOrder, priorMetadataByThread, wasTruncated, includeThreadTitle, extractors = [], formatOptions) {
20561
+ return surroundObserverHistory(buildMultiThreadObserverHistoryMessage(messagesByThread, threadOrder, formatOptions), buildMultiThreadObserverContextPrompt(existingObservations, threadOrder, priorMetadataByThread, wasTruncated, includeThreadTitle, extractors), buildMultiThreadObserverTaskInstructions(includeThreadTitle));
20562
+ }
20563
+ function surroundObserverHistory(history, contextPrompt, taskInstructions) {
20564
+ const historyContent = history.content;
20565
+ return {
20566
+ role: "user",
20567
+ content: [
20568
+ ...contextPrompt ? [{
20569
+ type: "text",
20570
+ text: contextPrompt
20571
+ }] : [],
20572
+ ...historyContent,
20573
+ {
20574
+ type: "text",
20575
+ text: `\n\n---\n\n${taskInstructions}`
20576
+ }
20577
+ ]
20578
+ };
20579
+ }
20580
+ function buildMultiThreadObserverTaskInstructions(includeThreadTitle) {
20581
+ return `## Your Task\n\nExtract new observations from each thread. Output your observations grouped by thread using <thread id="..."> tags inside your <observations> block. Each thread block should contain that thread's observations, current-task, suggested-response${includeThreadTitle ? ", and thread-title" : ""}, in the format specified in your instructions.`;
20582
+ }
20583
+ function buildMultiThreadObserverContextPrompt(existingObservations, threadOrder, priorMetadataByThread, wasTruncated, includeThreadTitle, extractors = []) {
20513
20584
  let prompt = "";
20514
20585
  if (existingObservations) {
20515
20586
  prompt += `## Previous Observations\n\n${existingObservations}\n\n---\n\n`;
@@ -20535,25 +20606,6 @@ function buildMultiThreadObserverTaskPrompt(existingObservations, threadOrder, p
20535
20606
  }
20536
20607
  prompt += `Use each thread's prior current-task, suggested-response${includeThreadTitle ? ", and thread-title" : ""} as continuity hints, then update them based on that thread's new messages.\n\n---\n\n`;
20537
20608
  }
20538
- prompt += `## Your Task\n\n`;
20539
- prompt += `Extract new observations from each thread. Output your observations grouped by thread using <thread id="..."> tags inside your <observations> block. Each thread block should contain that thread's observations, current-task, suggested-response${includeThreadTitle ? ", and thread-title" : ""}.\n\n`;
20540
- prompt += `Example output format:\n`;
20541
- prompt += `<observations>\n`;
20542
- prompt += `<thread id="thread1">\n`;
20543
- prompt += `Date: Dec 4, 2025\n`;
20544
- prompt += `* 🔴 (14:30) User prefers direct answers\n`;
20545
- prompt += `<current-task>Working on feature X</current-task>\n`;
20546
- prompt += `<suggested-response>Continue with the implementation</suggested-response>\n`;
20547
- if (includeThreadTitle) prompt += `<thread-title>Feature X implementation</thread-title>\n`;
20548
- prompt += `</thread>\n`;
20549
- prompt += `<thread id="thread2">\n`;
20550
- prompt += `Date: Dec 5, 2025\n`;
20551
- prompt += `* 🔴 (09:15) User asked about deployment\n`;
20552
- prompt += `<current-task>Discussing deployment options</current-task>\n`;
20553
- prompt += `<suggested-response>Explain the deployment process</suggested-response>\n`;
20554
- if (includeThreadTitle) prompt += `<thread-title>Deployment setup</thread-title>\n`;
20555
- prompt += `</thread>\n`;
20556
- prompt += `</observations>`;
20557
20609
  return prompt;
20558
20610
  }
20559
20611
  /**
@@ -20611,6 +20663,24 @@ function parseMultiThreadObserverOutput(output, extractors = []) {
20611
20663
  };
20612
20664
  }
20613
20665
  function buildObserverTaskPrompt(existingObservations, options) {
20666
+ return buildObserverContextPrompt(existingObservations, options) + buildObserverTaskInstructions(options);
20667
+ }
20668
+ /**
20669
+ * Build the Observer's single request message: prior memory first, then the message
20670
+ * history, then the task. Keeping everything in one user message, with the task after
20671
+ * the history, stops the Observer from reading its own instructions as something the
20672
+ * user said (#22195).
20673
+ */
20674
+ function buildObserverRequestMessage(existingObservations, messagesToObserve, options, formatOptions) {
20675
+ return surroundObserverHistory(buildObserverHistoryMessage(messagesToObserve, formatOptions), buildObserverContextPrompt(existingObservations, options), buildObserverTaskInstructions(options));
20676
+ }
20677
+ function buildObserverTaskInstructions(options) {
20678
+ let prompt = `## Your Task\n\n`;
20679
+ prompt += `Extract new observations from the message history above. Do not repeat observations that are already in the previous observations. Add your new observations in the format specified in your instructions.`;
20680
+ if (options?.skipContinuationHints) prompt += `\n\nOutput <observations> every time.`;
20681
+ return prompt;
20682
+ }
20683
+ function buildObserverContextPrompt(existingObservations, options) {
20614
20684
  let prompt = "";
20615
20685
  if (existingObservations) {
20616
20686
  prompt += `## Previous Observations\n\n${existingObservations}\n\n---\n\n`;
@@ -20631,9 +20701,6 @@ function buildObserverTaskPrompt(existingObservations, options) {
20631
20701
  const titleHint = options?.includeThreadTitle ? ", and thread-title" : "";
20632
20702
  prompt += `Use the prior current-task, suggested-response${titleHint} as continuity hints, then update them based on the new messages.\n\n---\n\n`;
20633
20703
  }
20634
- prompt += `## Your Task\n\n`;
20635
- prompt += `Extract new observations from the message history above. Do not repeat observations that are already in the previous observations. Add your new observations in the format specified in your instructions.`;
20636
- if (options?.skipContinuationHints) prompt += `\n\nOutput <observations> every time.`;
20637
20704
  return prompt;
20638
20705
  }
20639
20706
  /**
@@ -21272,14 +21339,11 @@ var ObserverRunner = class {
21272
21339
  const agent = temporaryMemory ? this.createAgent(resolvedModel.model, false, temporaryMemory.memory, activeExtractors) : this.createAgent(resolvedModel.model, false, void 0, activeExtractors);
21273
21340
  const internalRequestContext = withOmInternalThreadId(options?.requestContext, agent.id);
21274
21341
  const attachmentFilter = this.resolveAttachmentFilter(resolvedModel.model, options?.requestContext);
21275
- const observerMessages = [{
21276
- role: "user",
21277
- content: buildObserverTaskPrompt(existingObservations, {
21278
- ...options,
21279
- includeThreadTitle: this.observationConfig.threadTitle,
21280
- extractors: activeExtractors
21281
- })
21282
- }, buildObserverHistoryMessage(messagesToObserve, { attachmentFilter })];
21342
+ const observerMessages = [buildObserverRequestMessage(existingObservations, messagesToObserve, {
21343
+ ...options,
21344
+ includeThreadTitle: this.observationConfig.threadTitle,
21345
+ extractors: activeExtractors
21346
+ }, { attachmentFilter })];
21283
21347
  const doGenerate = async () => {
21284
21348
  return withRetry(() => withOmTracingSpan({
21285
21349
  phase: "observer",
@@ -21479,10 +21543,7 @@ var ObserverRunner = class {
21479
21543
  const agent = this.createAgent(resolvedModel.model, true, void 0, activeExtractors);
21480
21544
  const internalRequestContext = withOmInternalThreadId(requestContext, agent.id);
21481
21545
  const multiThreadAttachmentFilter = this.resolveAttachmentFilter(resolvedModel.model, requestContext);
21482
- const observerMessages = [{
21483
- role: "user",
21484
- content: buildMultiThreadObserverTaskPrompt(existingObservations, threadOrder, priorMetadataByThread, void 0, this.observationConfig.threadTitle, activeExtractors)
21485
- }, buildMultiThreadObserverHistoryMessage(messagesByThread, threadOrder, { attachmentFilter: multiThreadAttachmentFilter })];
21546
+ const observerMessages = [buildMultiThreadObserverRequestMessage(existingObservations, messagesByThread, threadOrder, priorMetadataByThread, void 0, this.observationConfig.threadTitle, activeExtractors, { attachmentFilter: multiThreadAttachmentFilter })];
21486
21547
  for (const msgs of messagesByThread.values()) for (const msg of msgs) this.observedMessageIds.add(msg.id);
21487
21548
  const doGenerate = async () => {
21488
21549
  return withRetry(() => withOmTracingSpan({
@@ -29701,7 +29762,7 @@ var ObservationalMemory = class ObservationalMemory {
29701
29762
  formatObservationsForContext(observations, currentTask, suggestedResponse, extractedValues, unobservedContextBlocks, currentDate, retrieval = false) {
29702
29763
  let optimized = retrieval ? renderObservationGroupsForReflection(observations) ?? optimizeObservationsForContext(observations) : optimizeObservationsForContext(observations);
29703
29764
  if (currentDate) optimized = addRelativeTimeToObservations(optimized, currentDate);
29704
- const messages = [`${OBSERVATION_CONTEXT_PROMPT}\n\n${OBSERVATION_CONTEXT_INSTRUCTIONS}${retrieval ? `\n\n${getRetrievalInstructions(this.retrievalScope, this.retrievalInstructions, this.retrievalSearch)}` : ""}`];
29765
+ const messages = [`${getObservationContextPrompt(this.scope)}\n\n${OBSERVATION_CONTEXT_INSTRUCTIONS}${retrieval ? `\n\n${getRetrievalInstructions(this.retrievalScope, this.retrievalInstructions, this.retrievalSearch)}` : ""}`];
29705
29766
  if (unobservedContextBlocks) messages.push(`The following content is from OTHER conversations different from the current conversation, they're here for reference, but they're not necessarily your focus:\nSTART_OTHER_CONVERSATIONS_BLOCK\n${unobservedContextBlocks}\nEND_OTHER_CONVERSATIONS_BLOCK`);
29706
29767
  const observationChunks = this.splitObservationContextChunks(optimized);
29707
29768
  if (observationChunks.length > 0) messages.push("<observations>", ...observationChunks);
@@ -31645,6 +31706,7 @@ var observational_memory_exports = /* @__PURE__ */ __exportAll({
31645
31706
  OBSERVATIONAL_MEMORY_DEFAULTS: () => OBSERVATIONAL_MEMORY_DEFAULTS,
31646
31707
  OBSERVATION_CONTEXT_INSTRUCTIONS: () => OBSERVATION_CONTEXT_INSTRUCTIONS,
31647
31708
  OBSERVATION_CONTEXT_PROMPT: () => OBSERVATION_CONTEXT_PROMPT,
31709
+ OBSERVATION_CONTEXT_PROMPT_THREAD: () => OBSERVATION_CONTEXT_PROMPT_THREAD,
31648
31710
  OBSERVATION_CONTINUATION_HINT: () => OBSERVATION_CONTINUATION_HINT,
31649
31711
  OBSERVER_SYSTEM_PROMPT: () => OBSERVER_SYSTEM_PROMPT,
31650
31712
  ObservationalMemory: () => ObservationalMemory,
@@ -31662,6 +31724,7 @@ var observational_memory_exports = /* @__PURE__ */ __exportAll({
31662
31724
  deriveObservationGroupProvenance: () => deriveObservationGroupProvenance,
31663
31725
  extractCurrentTask: () => extractCurrentTask,
31664
31726
  formatMessagesForObserver: () => formatMessagesForObserver,
31727
+ getObservationContextPrompt: () => getObservationContextPrompt,
31665
31728
  getObservationsAsOf: () => getObservationsAsOf,
31666
31729
  hasCurrentTaskSection: () => hasCurrentTaskSection,
31667
31730
  injectAnchorIds: () => injectAnchorIds,
@@ -31689,7 +31752,6 @@ var working_memory_state_exports = /* @__PURE__ */ __exportAll({
31689
31752
  //#region src/index.ts
31690
31753
  const WORKING_MEMORY_START_TAG = "<working_memory>";
31691
31754
  const WORKING_MEMORY_END_TAG = "</working_memory>";
31692
- const LEGACY_SYSTEM_REMINDER_METADATA_KEY = "dynamicAgentsMdReminder";
31693
31755
  function isRecord(value) {
31694
31756
  return typeof value === "object" && value !== null;
31695
31757
  }
@@ -31733,15 +31795,6 @@ function extractWorkingMemoryContent(text) {
31733
31795
  if (end === -1) return null;
31734
31796
  return text.substring(contentStart, end);
31735
31797
  }
31736
- function isSystemReminderMessage(message) {
31737
- if (!isRecord(message.content)) return false;
31738
- const metadata = message.content.metadata;
31739
- if (message.role === "signal") return isRecord(metadata) && isRecord(metadata.signal) && (metadata.signal.type === "system-reminder" || metadata.signal.type === "reactive");
31740
- if (message.role !== "user") return false;
31741
- if (isRecord(metadata) && (isRecord(metadata.systemReminder) || LEGACY_SYSTEM_REMINDER_METADATA_KEY in metadata)) return true;
31742
- const firstTextPart = message.content.parts.find((part) => part.type === "text");
31743
- return typeof firstTextPart?.text === "string" && firstTextPart.text.startsWith("<system-reminder");
31744
- }
31745
31798
  function isRecallSignalType(type) {
31746
31799
  return type === "user" || type === "state" || type === "reactive" || type === "notification" || type === "user-message" || type === "system-reminder";
31747
31800
  }
@@ -34021,6 +34074,12 @@ Object.defineProperty(exports, "OBSERVATION_CONTEXT_PROMPT", {
34021
34074
  return OBSERVATION_CONTEXT_PROMPT;
34022
34075
  }
34023
34076
  });
34077
+ Object.defineProperty(exports, "OBSERVATION_CONTEXT_PROMPT_THREAD", {
34078
+ enumerable: true,
34079
+ get: function() {
34080
+ return OBSERVATION_CONTEXT_PROMPT_THREAD;
34081
+ }
34082
+ });
34024
34083
  Object.defineProperty(exports, "OBSERVATION_CONTINUATION_HINT", {
34025
34084
  enumerable: true,
34026
34085
  get: function() {
@@ -34165,6 +34224,12 @@ Object.defineProperty(exports, "formatMessagesForObserver", {
34165
34224
  return formatMessagesForObserver;
34166
34225
  }
34167
34226
  });
34227
+ Object.defineProperty(exports, "getObservationContextPrompt", {
34228
+ enumerable: true,
34229
+ get: function() {
34230
+ return getObservationContextPrompt;
34231
+ }
34232
+ });
34168
34233
  Object.defineProperty(exports, "getObservationsAsOf", {
34169
34234
  enumerable: true,
34170
34235
  get: function() {
@@ -34262,4 +34327,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
34262
34327
  }
34263
34328
  });
34264
34329
 
34265
- //# sourceMappingURL=src-DmZEArj1.cjs.map
34330
+ //# sourceMappingURL=src-C7u5SaET.cjs.map