@mastra/memory 1.26.2-alpha.0 → 1.26.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 (30) hide show
  1. package/CHANGELOG.md +35 -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-capabilities-subagents.md +2 -2
  5. package/dist/docs/references/docs-long-running-agents-background-tasks.md +2 -2
  6. package/dist/docs/references/docs-long-running-agents-goals.md +3 -2
  7. package/dist/docs/references/docs-memory-memory-processors.md +1 -1
  8. package/dist/docs/references/docs-memory-message-history.md +2 -2
  9. package/dist/docs/references/docs-memory-observational-memory.md +13 -13
  10. package/dist/docs/references/docs-memory-semantic-recall.md +1 -1
  11. package/dist/docs/references/docs-memory-working-memory.md +1 -1
  12. package/dist/docs/references/reference-memory-observational-memory.md +12 -4
  13. package/dist/docs/references/reference-vectors-mongodb.md +2 -2
  14. package/dist/docs/references/reference-vectors-pg.md +1 -1
  15. package/dist/index.cjs +1 -1
  16. package/dist/index.js +1 -1
  17. package/dist/processors/index.cjs +1 -1
  18. package/dist/processors/index.js +1 -1
  19. package/dist/processors/observational-memory/constants.d.ts.map +1 -1
  20. package/dist/processors/observational-memory/observation-turn/step.d.ts +2 -1
  21. package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
  22. package/dist/processors/observational-memory/types.d.ts +12 -10
  23. package/dist/processors/observational-memory/types.d.ts.map +1 -1
  24. package/dist/{src-DGdlH4fo.js → src-BYD6Wp5m.js} +58 -14
  25. package/dist/{src-DGdlH4fo.js.map → src-BYD6Wp5m.js.map} +1 -1
  26. package/dist/{src-CTwoCwmY.cjs → src-b5E69E65.cjs} +58 -14
  27. package/dist/{src-CTwoCwmY.cjs.map → src-b5E69E65.cjs.map} +1 -1
  28. package/dist/tools/om-tools.d.ts +5 -1
  29. package/dist/tools/om-tools.d.ts.map +1 -1
  30. package/package.json +8 -8
@@ -14769,7 +14769,7 @@ By default recall returns **low** detail: truncated text and tool names only. Ea
14769
14769
  - Use \`detail: "high"\` to get full message content including tool arguments and results. This will only return the high detail version of a single message part at a time.
14770
14770
  - Use \`partIndex\` with a cursor to fetch a single part at full detail — for example, to read one specific tool result or code block without loading every part.
14771
14771
 
14772
- If the result says \`truncated: true\`, the output was cut to fit the token budget. You can paginate or use \`partIndex\` to target specific content.
14772
+ If the result says \`truncated: true\`, the output was cut to fit the token budget. You can paginate or use \`partIndex\` to target specific content. If a single part is itself too large, follow the returned \`nextCharOffset\` as described below.
14773
14773
 
14774
14774
  ### Following up on truncated parts
14775
14775
  Low-detail results may include truncation hints like:
@@ -14777,6 +14777,8 @@ Low-detail results may include truncation hints like:
14777
14777
 
14778
14778
  **When you see these hints and need the full content, make the exact call described in the hint.** This is the normal workflow: first recall at low detail to scan, then drill into specific parts at high detail. Do not stop at the low-detail result if the user asked for exact content.
14779
14779
 
14780
+ If a single part is larger than the token budget, the \`partIndex\` result is \`truncated: true\` and includes \`nextCharOffset\`. Repeat the same call with \`charOffset\` set to that exact value to read the next chunk from where the previous one ended. Keep following \`nextCharOffset\` until the result no longer includes it — the chunks together contain the full part. Retrying without \`charOffset\` returns the same prefix again.
14781
+
14780
14782
  ### When recall is NOT needed
14781
14783
  - The user is asking for a high-level summary and your observations already cover it
14782
14784
  - The question is about general preferences or facts that don't require source text
@@ -19143,6 +19145,36 @@ function truncateByTokens(text, maxTokens, hint) {
19143
19145
  wasTruncated: true
19144
19146
  };
19145
19147
  }
19148
+ function chunkTextByTokens(text, maxTokens, charOffset = 0) {
19149
+ let startOffset = Math.max(0, Math.min(Math.floor(charOffset), text.length));
19150
+ const startCode = text.charCodeAt(startOffset);
19151
+ if (startCode >= 56320 && startCode <= 57343) startOffset += 1;
19152
+ const remaining = text.slice(startOffset);
19153
+ if (!remaining || (0, tokenx.estimateTokenCount)(remaining) <= maxTokens) return {
19154
+ text: remaining,
19155
+ charOffset: startOffset,
19156
+ truncated: false
19157
+ };
19158
+ let low = 0;
19159
+ let high = remaining.length;
19160
+ let best = "";
19161
+ while (low <= high) {
19162
+ const mid = Math.floor((low + high) / 2);
19163
+ const candidate = safeSlice(remaining, mid);
19164
+ const candidateTokens = (0, tokenx.estimateTokenCount)(candidate);
19165
+ if (candidate && candidateTokens <= maxTokens) {
19166
+ best = candidate;
19167
+ low = mid + 1;
19168
+ } else high = mid - 1;
19169
+ }
19170
+ const nextCharOffset = startOffset + best.length;
19171
+ return {
19172
+ text: best,
19173
+ charOffset: startOffset,
19174
+ nextCharOffset,
19175
+ truncated: nextCharOffset < text.length
19176
+ };
19177
+ }
19146
19178
  function lowDetailPartLimit(type) {
19147
19179
  if (type === "text") return AUTO_EXPAND_TEXT_TOKENS;
19148
19180
  if (type === "tool-result" || type === "tool-call") return AUTO_EXPAND_TOOL_TOKENS;
@@ -19360,7 +19392,7 @@ function renderFormattedParts(parts, timestamps, options) {
19360
19392
  tokenOffset: expandedTokens - options.maxTokens
19361
19393
  };
19362
19394
  }
19363
- async function recallPart({ memory, threadId, resourceId, cursor, partIndex, threadScope, maxTokens = DEFAULT_MAX_RESULT_TOKENS }) {
19395
+ async function recallPart({ memory, threadId, resourceId, cursor, partIndex, charOffset, threadScope, maxTokens = DEFAULT_MAX_RESULT_TOKENS }) {
19364
19396
  if (!memory || typeof memory.getMemoryStore !== "function") throw new Error("Memory instance is required for recall");
19365
19397
  if (!threadId) throw new Error("Thread ID is required for recall");
19366
19398
  const resolved = await resolveCursorMessage(memory, cursor, {
@@ -19384,31 +19416,36 @@ async function recallPart({ memory, threadId, resourceId, cursor, partIndex, thr
19384
19416
  if (nextMessage) {
19385
19417
  const firstNextPart = formatMessageParts(nextMessage, "high")[0];
19386
19418
  if (firstNextPart) {
19387
- const fallbackText = `${`Part index ${partIndex} not found in message ${cursor}; showing partIndex ${firstNextPart.partIndex} from next message ${firstNextPart.messageId}.\n\n`}${firstNextPart.text}`;
19388
- const truncatedText = truncateStringByTokens(fallbackText, maxTokens);
19389
- const wasTruncated = truncatedText !== fallbackText;
19419
+ const fallbackChunk = chunkTextByTokens(`${`Part index ${partIndex} not found in message ${cursor}; showing partIndex ${firstNextPart.partIndex} from next message ${firstNextPart.messageId}.\n\n`}${firstNextPart.text}`, maxTokens, charOffset);
19420
+ const fallbackContinuation = fallbackChunk.nextCharOffset ? `To continue this part, call recall cursor="${cursor}" partIndex=${partIndex} detail="high" charOffset=${fallbackChunk.nextCharOffset}.` : void 0;
19390
19421
  return {
19391
- text: truncatedText,
19422
+ text: fallbackChunk.text,
19392
19423
  messageId: firstNextPart.messageId,
19393
19424
  partIndex: firstNextPart.partIndex,
19394
19425
  role: firstNextPart.role,
19395
19426
  type: firstNextPart.type,
19396
- truncated: wasTruncated
19427
+ truncated: fallbackChunk.truncated,
19428
+ charOffset: fallbackChunk.charOffset,
19429
+ nextCharOffset: fallbackChunk.nextCharOffset,
19430
+ note: fallbackContinuation
19397
19431
  };
19398
19432
  }
19399
19433
  }
19400
19434
  }
19401
19435
  throw new Error(`Part index ${partIndex} not found in message ${cursor}. Available indices: ${availableIndices}`);
19402
19436
  }
19403
- const truncatedText = truncateStringByTokens(target.text, maxTokens);
19404
- const wasTruncated = truncatedText !== target.text;
19437
+ const chunk = chunkTextByTokens(target.text, maxTokens, charOffset);
19438
+ const note = chunk.nextCharOffset ? `To continue this part, call recall cursor="${target.messageId}" partIndex=${target.partIndex} detail="high" charOffset=${chunk.nextCharOffset}.` : void 0;
19405
19439
  return {
19406
- text: truncatedText,
19440
+ text: chunk.text,
19407
19441
  messageId: target.messageId,
19408
19442
  partIndex: target.partIndex,
19409
19443
  role: target.role,
19410
19444
  type: target.type,
19411
- truncated: wasTruncated
19445
+ truncated: chunk.truncated,
19446
+ charOffset: chunk.charOffset,
19447
+ nextCharOffset: chunk.nextCharOffset,
19448
+ note
19412
19449
  };
19413
19450
  }
19414
19451
  async function recallMessages({ memory, threadId, resourceId, cursor, page = 1, limit = 20, detail = "low", partType, toolName, threadScope, maxTokens = DEFAULT_MAX_RESULT_TOKENS }) {
@@ -19690,11 +19727,16 @@ const recallTool = (_memoryConfig, options) => {
19690
19727
  type: "integer",
19691
19728
  minimum: 0,
19692
19729
  description: "Fetch a single part from the cursor message by its positional index. When provided, returns only that part at high detail. Indices are shown as [p0], [p1], etc. in recall results."
19730
+ },
19731
+ charOffset: {
19732
+ type: "integer",
19733
+ minimum: 0,
19734
+ description: "Continue reading a truncated single part from this position. Pass the exact nextCharOffset value returned by a previous call; do not compute it yourself. Only applies with cursor and partIndex in mode=\"messages\"."
19693
19735
  }
19694
19736
  }
19695
19737
  },
19696
19738
  execute: async (inputData, context) => {
19697
- const { mode, query, cursor, threadId: explicitThreadId, anchor, page, limit, detail, partType, toolName, partIndex, before, after } = inputData;
19739
+ const { mode, query, cursor, threadId: explicitThreadId, anchor, page, limit, detail, partType, toolName, partIndex, charOffset, before, after } = inputData;
19698
19740
  const memory = context?.memory;
19699
19741
  const currentThreadId = context?.agent?.threadId;
19700
19742
  const resourceId = context?.agent?.resourceId;
@@ -19807,6 +19849,7 @@ const recallTool = (_memoryConfig, options) => {
19807
19849
  resourceId: isResourceScope ? resourceId : void 0,
19808
19850
  cursor,
19809
19851
  partIndex,
19852
+ charOffset,
19810
19853
  threadScope
19811
19854
  });
19812
19855
  return recallMessages({
@@ -22320,7 +22363,8 @@ var ObservationStep = class {
22320
22363
  }
22321
22364
  /**
22322
22365
  * Run the full threshold observation pipeline:
22323
- * waitForBuffering → re-check → activate → reflect → blockAfter gate observe
22366
+ * waitForBuffering → re-check → activate → reflect → observe (sync fallback when
22367
+ * buffered activation did not happen)
22324
22368
  */
22325
22369
  async runThresholdObservation() {
22326
22370
  const { threadId, resourceId, messageList } = this.turn;
@@ -28906,4 +28950,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
28906
28950
  }
28907
28951
  });
28908
28952
 
28909
- //# sourceMappingURL=src-CTwoCwmY.cjs.map
28953
+ //# sourceMappingURL=src-b5E69E65.cjs.map