@mastra/memory 1.25.0-alpha.0 → 1.25.0-alpha.2

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/docs/SKILL.md +1 -1
  3. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  4. package/dist/docs/references/docs-agents-agent-approval.md +2 -2
  5. package/dist/docs/references/docs-agents-supervisor-agents.md +2 -2
  6. package/dist/docs/references/docs-evals-evals-with-memory.md +1 -1
  7. package/dist/docs/references/docs-memory-observational-memory.md +28 -5
  8. package/dist/docs/references/docs-memory-overview.md +1 -1
  9. package/dist/docs/references/reference-memory-observational-memory.md +3 -1
  10. package/dist/docs/references/reference-processors-token-limiter-processor.md +15 -1
  11. package/dist/docs/references/reference-vectors-mongodb.md +13 -13
  12. package/dist/index.cjs +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/processors/index.cjs +1 -1
  16. package/dist/processors/index.js +1 -1
  17. package/dist/processors/observational-memory/constants.d.ts +13 -1
  18. package/dist/processors/observational-memory/constants.d.ts.map +1 -1
  19. package/dist/processors/observational-memory/internal-request-context.d.ts +7 -0
  20. package/dist/processors/observational-memory/internal-request-context.d.ts.map +1 -1
  21. package/dist/processors/observational-memory/observational-memory.d.ts +5 -0
  22. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  23. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  24. package/dist/processors/observational-memory/types.d.ts +5 -0
  25. package/dist/processors/observational-memory/types.d.ts.map +1 -1
  26. package/dist/{src-BYZh9IBv.js → src-BgdYYHLc.js} +73 -14
  27. package/dist/src-BgdYYHLc.js.map +1 -0
  28. package/dist/{src-naeQog_T.cjs → src-DQO6B1AU.cjs} +73 -14
  29. package/dist/src-DQO6B1AU.cjs.map +1 -0
  30. package/package.json +4 -4
  31. package/dist/src-BYZh9IBv.js.map +0 -1
  32. package/dist/src-naeQog_T.cjs.map +0 -1
@@ -14604,7 +14604,7 @@ var constants_exports = /* @__PURE__ */ __exportAll({
14604
14604
  OBSERVATION_CONTEXT_INSTRUCTIONS: () => OBSERVATION_CONTEXT_INSTRUCTIONS,
14605
14605
  OBSERVATION_CONTEXT_PROMPT: () => OBSERVATION_CONTEXT_PROMPT,
14606
14606
  OBSERVATION_CONTINUATION_HINT: () => OBSERVATION_CONTINUATION_HINT,
14607
- OBSERVATION_RETRIEVAL_INSTRUCTIONS: () => OBSERVATION_RETRIEVAL_INSTRUCTIONS
14607
+ getRetrievalInstructions: () => getRetrievalInstructions
14608
14608
  });
14609
14609
  /**
14610
14610
  * Default configuration values matching the spec
@@ -14667,8 +14667,22 @@ SYSTEM REMINDERS: Messages wrapped in <system-reminder>...</system-reminder> con
14667
14667
  /**
14668
14668
  * Instructions for retrieval mode — explains observation-group ranges and the recall tool.
14669
14669
  * Appended to context when `retrieval` is enabled.
14670
+ *
14671
+ * The content adapts to the retrieval scope:
14672
+ * - `'resource'`: covers routing between `search`, `threads`, and `messages` across
14673
+ * all of the user's threads, including fallback when search results are unsuitable.
14674
+ * - `'thread'`: covers cursor-based browsing and search within the current thread.
14675
+ *
14676
+ * @param scope - The retrieval scope the recall tool was registered with.
14677
+ * @param customInstructions - Optional application-provided guidance appended after
14678
+ * the native instructions. Never replaces them.
14679
+ * @param searchEnabled - Whether semantic search (`retrieval: { vector: true }`) is
14680
+ * available. When false, the guidance only covers \`threads\`/\`messages\` browsing so
14681
+ * the agent is not steered toward a mode that cannot work.
14670
14682
  */
14671
- const OBSERVATION_RETRIEVAL_INSTRUCTIONS = `## Recall looking up source messages
14683
+ function getRetrievalInstructions(scope = "resource", customInstructions, searchEnabled = true) {
14684
+ const isResource = scope === "resource";
14685
+ const base = `## Recall — looking up source messages
14672
14686
 
14673
14687
  Your memory is comprised of observations which are sometimes wrapped in <observation-group> xml tags containing ranges like <observation-group range="startId:endId">. These ranges point back to the raw messages that each observation group was derived from. The original messages are still available — use the **recall** tool to retrieve them.
14674
14688
 
@@ -14676,11 +14690,32 @@ Your memory is comprised of observations which are sometimes wrapped in <observa
14676
14690
  - The user asks you to **repeat, show, or reproduce** something from a past conversation
14677
14691
  - The user asks for **exact content** — code, text, quotes, error messages, URLs, file paths, specific numbers
14678
14692
  - Your observations mention something but your memory lacks the detail needed to fully answer (e.g. you know a blog post was shared but only have a summary of it)
14679
- - You want to **verify or expand on** an observation before responding
14693
+ - You want to **verify or expand on** an observation before responding${isResource ? `
14694
+ - The user references another conversation that your observations don't cover — even if you have no observations yet, their other threads may contain it` : ""}
14680
14695
 
14681
14696
  **Default to using recall when the user references specific past content.** Your observations capture the gist, not the details. If there's any doubt whether your memory is complete enough, use recall.
14682
14697
 
14683
- ### How to use recall
14698
+ ${isResource ? searchEnabled ? `### Choosing a mode
14699
+ The recall tool works across ALL of this user's conversation threads, not just the current one.
14700
+
14701
+ - Use \`mode: "search"\` with a \`query\` when you don't know which thread contains the answer. Each result includes its thread ID and the raw message IDs it came from, which you can use as a \`cursor\`.
14702
+ - Use \`mode: "messages"\` when you already know the thread — pass \`threadId\` to read another thread, or a \`cursor\` from an observation-group range or a search result.
14703
+ - Use \`mode: "threads"\` to list the user's threads (IDs, titles, dates) when you need to discover where something was discussed. Use \`before\`/\`after\` to narrow by date.
14704
+
14705
+ **If search results look irrelevant, do not give up.** Search only covers content that has been indexed — a short or recent conversation may exist in raw message history before any observation of it was created. When search returns nothing suitable but the user is clearly referring to a past conversation, call \`mode: "threads"\` to find candidate threads (titles and dates are strong clues), then read them with \`mode: "messages"\`. If a search result already gives you a thread ID, go straight to \`mode: "messages"\`.` : `### Choosing a mode
14706
+ The recall tool works across ALL of this user's conversation threads, not just the current one.
14707
+
14708
+ - Use \`mode: "threads"\` to list the user's threads (IDs, titles, dates) when you need to discover where something was discussed. Use \`before\`/\`after\` to narrow by date.
14709
+ - Use \`mode: "messages"\` when you know the thread — pass \`threadId\` to read another thread, or a \`cursor\` from an observation-group range.
14710
+
14711
+ When the user refers to a past conversation you don't have a cursor for, call \`mode: "threads"\` to find candidate threads (titles and dates are strong clues), then read them with \`mode: "messages"\`. Raw history may exist for threads that have no observations yet.` : `### Choosing a mode
14712
+ The recall tool is limited to the current conversation thread.
14713
+
14714
+ - Use \`mode: "messages"\` (default) to page through this thread's message history near a cursor.${searchEnabled ? `
14715
+ - Use \`mode: "search"\` with a \`query\` to find messages by content within this thread.` : ""}
14716
+ - Use \`mode: "threads"\` to get the current thread's ID, title, and dates.`}
14717
+
14718
+ ### How to use recall with a cursor
14684
14719
  Each range has the format \`startId:endId\` where both are message IDs separated by a colon.
14685
14720
 
14686
14721
  1. Find the observation group relevant to the user's question and extract the start or end ID from its range.
@@ -14706,9 +14741,16 @@ Low-detail results may include truncation hints like:
14706
14741
  ### When recall is NOT needed
14707
14742
  - The user is asking for a high-level summary and your observations already cover it
14708
14743
  - The question is about general preferences or facts that don't require source text
14709
- - There is no relevant range in your observations for the topic
14744
+ ${isResource ? `- No relevant observation range exists AND ${searchEnabled ? "`search`/`threads`" : "`threads`"} turned up nothing — but remember that raw history may exist for threads that have no observations yet, so check before concluding the information is unavailable` : `- There is no relevant range in your observations for the topic`}
14710
14745
 
14711
14746
  Observation groups with range IDs and your recall tool allows you to think back and remember details you're fuzzy on.`;
14747
+ const custom = customInstructions?.trim();
14748
+ if (!custom) return base;
14749
+ return `${base}
14750
+
14751
+ ### Additional recall guidance
14752
+ ${custom}`;
14753
+ }
14712
14754
  //#endregion
14713
14755
  //#region src/processors/observational-memory/extractor.ts
14714
14756
  const BUILT_IN_SLUGS = /* @__PURE__ */ new Set([
@@ -15211,13 +15253,19 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
15211
15253
  * auth, versions, routing hints, and resource id, but they must not present as
15212
15254
  * another run on the parent thread or core's cross-agent thread wait can block
15213
15255
  * on the parent run that is waiting for OM to complete.
15256
+ *
15257
+ * A fresh RequestContext clone is always returned so that memory-scoped writes
15258
+ * made by the internal agent run (e.g. the `MastraMemory` entry that agent.generate
15259
+ * sets from the observer's temporary `structured-observer` memory) cannot leak back
15260
+ * into the parent's RequestContext. Without this isolation the parent's OM turn later
15261
+ * reads the temporary observer's resourceId and injects a continuation message that
15262
+ * fails MessageList's resourceId validation.
15214
15263
  */
15215
15264
  function withOmInternalThreadId(requestContext, omAgentId) {
15216
15265
  if (!requestContext) return void 0;
15217
- const parentThreadId = requestContext.get(_mastra_core_request_context.MASTRA_THREAD_ID_KEY);
15218
- if (typeof parentThreadId !== "string" || !parentThreadId) return requestContext;
15219
15266
  const internalRequestContext = new _mastra_core_request_context.RequestContext(requestContext.entries());
15220
- internalRequestContext.set(_mastra_core_request_context.MASTRA_THREAD_ID_KEY, `${parentThreadId}-${omAgentId}`);
15267
+ const parentThreadId = requestContext.get(_mastra_core_request_context.MASTRA_THREAD_ID_KEY);
15268
+ if (typeof parentThreadId === "string" && parentThreadId) internalRequestContext.set(_mastra_core_request_context.MASTRA_THREAD_ID_KEY, `${parentThreadId}-${omAgentId}`);
15221
15269
  return internalRequestContext;
15222
15270
  }
15223
15271
  //#endregion
@@ -17051,7 +17099,7 @@ var ObserverRunner = class {
17051
17099
  extractors: activeExtractors,
17052
17100
  memory: temporaryMemory?.options,
17053
17101
  priorExtractedValues: options?.priorExtractedValues,
17054
- requestContext: options?.requestContext,
17102
+ requestContext: internalRequestContext,
17055
17103
  observabilityContext: options?.observabilityContext,
17056
17104
  abortSignal
17057
17105
  });
@@ -22841,7 +22889,7 @@ var ReflectorRunner = class {
22841
22889
  extractors: activeExtractors,
22842
22890
  memory: temporaryMemory?.options,
22843
22891
  priorExtractedValues,
22844
- requestContext,
22892
+ requestContext: internalRequestContext,
22845
22893
  observabilityContext,
22846
22894
  abortSignal
22847
22895
  });
@@ -23726,6 +23774,11 @@ var ObservationalMemory = class ObservationalMemory {
23726
23774
  scope;
23727
23775
  /** Whether retrieval-mode observation groups are enabled. */
23728
23776
  retrieval;
23777
+ /** Scope the recall tool was registered with — controls which retrieval instructions are injected. */
23778
+ retrievalScope;
23779
+ /** Application-provided guidance appended after the native retrieval instructions. */
23780
+ retrievalInstructions;
23781
+ retrievalSearch;
23729
23782
  observationConfig;
23730
23783
  reflectionConfig;
23731
23784
  onDebugEvent;
@@ -23791,6 +23844,9 @@ var ObservationalMemory = class ObservationalMemory {
23791
23844
  this.storage = config.storage;
23792
23845
  this.scope = config.scope ?? "thread";
23793
23846
  this.retrieval = Boolean(config.retrieval);
23847
+ this.retrievalScope = typeof config.retrieval === "object" ? config.retrieval.scope ?? "resource" : "resource";
23848
+ this.retrievalInstructions = typeof config.retrieval === "object" ? config.retrieval.instructions : void 0;
23849
+ this.retrievalSearch = typeof config.retrieval === "object" && Boolean(config.retrieval.vector);
23794
23850
  this.onIndexObservations = config.onIndexObservations;
23795
23851
  this.hooks = config.hooks;
23796
23852
  this.mastra = config.mastra;
@@ -24439,7 +24495,7 @@ var ObservationalMemory = class ObservationalMemory {
24439
24495
  formatObservationsForContext(observations, currentTask, suggestedResponse, extractedValues, unobservedContextBlocks, currentDate, retrieval = false) {
24440
24496
  let optimized = retrieval ? renderObservationGroupsForReflection(observations) ?? optimizeObservationsForContext(observations) : optimizeObservationsForContext(observations);
24441
24497
  if (currentDate) optimized = addRelativeTimeToObservations(optimized, currentDate);
24442
- const messages = [`${OBSERVATION_CONTEXT_PROMPT}\n\n${OBSERVATION_CONTEXT_INSTRUCTIONS}${retrieval ? `\n\n${OBSERVATION_RETRIEVAL_INSTRUCTIONS}` : ""}`];
24498
+ const messages = [`${OBSERVATION_CONTEXT_PROMPT}\n\n${OBSERVATION_CONTEXT_INSTRUCTIONS}${retrieval ? `\n\n${getRetrievalInstructions(this.retrievalScope, this.retrievalInstructions, this.retrievalSearch)}` : ""}`];
24443
24499
  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`);
24444
24500
  const observationChunks = this.splitObservationContextChunks(optimized);
24445
24501
  if (observationChunks.length > 0) messages.push("<observations>", ...observationChunks);
@@ -24941,7 +24997,10 @@ ${formattedMessages}
24941
24997
  async buildContextSystemMessages(opts) {
24942
24998
  const { threadId, resourceId, unobservedContextBlocks } = opts;
24943
24999
  const record = opts.record ?? await this.getOrCreateRecord(threadId, resourceId);
24944
- if (!record.activeObservations) return void 0;
25000
+ if (!record.activeObservations) {
25001
+ if (this.retrieval && this.retrievalScope === "resource") return [getRetrievalInstructions(this.retrievalScope, this.retrievalInstructions, this.retrievalSearch)];
25002
+ return;
25003
+ }
24945
25004
  const omMetadata = (0, _mastra_core_memory.getThreadOMMetadata)((await this.storage.getThreadById({ threadId }))?.metadata);
24946
25005
  const currentTask = omMetadata?.currentTask;
24947
25006
  const suggestedResponse = omMetadata?.suggestedResponse;
@@ -26073,7 +26132,7 @@ var ObservationalMemoryProcessor = class {
26073
26132
  threadId,
26074
26133
  resourceId
26075
26134
  });
26076
- const systemMessages = ctx.hasObservations && ctx.omRecord ? await this.engine.buildContextSystemMessages({
26135
+ const systemMessages = ctx.omRecord ? await this.engine.buildContextSystemMessages({
26077
26136
  threadId,
26078
26137
  resourceId,
26079
26138
  record: ctx.omRecord,
@@ -28501,4 +28560,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
28501
28560
  }
28502
28561
  });
28503
28562
 
28504
- //# sourceMappingURL=src-naeQog_T.cjs.map
28563
+ //# sourceMappingURL=src-DQO6B1AU.cjs.map