@mastra/memory 1.26.1-alpha.2 → 1.26.1-alpha.4

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 (29) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/docs/SKILL.md +3 -1
  3. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  4. package/dist/docs/references/docs-memory-multi-user-threads.md +1 -1
  5. package/dist/docs/references/docs-memory-observational-memory.md +1 -1
  6. package/dist/docs/references/docs-memory-semantic-recall.md +2 -1
  7. package/dist/docs/references/docs-memory-working-memory.md +1 -0
  8. package/dist/docs/references/docs-storage-overview.md +1 -0
  9. package/dist/docs/references/reference-storage-oracledb.md +239 -0
  10. package/dist/docs/references/reference-vectors-oracledb.md +347 -0
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.d.ts +2 -2
  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/observation-strategies/async-buffer.d.ts.map +1 -1
  18. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  19. package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
  20. package/dist/processors/observational-memory/token-counter.d.ts +7 -0
  21. package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
  22. package/dist/processors/observational-memory/tool-result-helpers.d.ts +8 -0
  23. package/dist/processors/observational-memory/tool-result-helpers.d.ts.map +1 -1
  24. package/dist/{src-CdqJP57F.js → src-hv0DMVM-.js} +79 -44
  25. package/dist/{src-CdqJP57F.js.map → src-hv0DMVM-.js.map} +1 -1
  26. package/dist/{src-DY9-_lul.cjs → src-kjoZv97r.cjs} +79 -44
  27. package/dist/{src-DY9-_lul.cjs.map → src-kjoZv97r.cjs.map} +1 -1
  28. package/dist/tools/working-memory.d.ts.map +1 -1
  29. package/package.json +4 -4
@@ -15614,6 +15614,16 @@ function sanitizeToolResultValue(value, seen = /* @__PURE__ */ new WeakMap()) {
15614
15614
  }
15615
15615
  return sanitizedObject;
15616
15616
  }
15617
+ /**
15618
+ * Serializes a tool result without truncating it.
15619
+ *
15620
+ * Token accounting must see the full result: the truncation applied by
15621
+ * {@link formatToolResultForObserver} exists to bound what the Observer LLM reads,
15622
+ * not to describe what the agent's provider context actually holds.
15623
+ */
15624
+ function serializeToolResultForTokenCounting(value) {
15625
+ return stringifyToolResult(value);
15626
+ }
15617
15627
  function stringifyToolResult(value) {
15618
15628
  if (typeof value === "string") return value;
15619
15629
  const sanitized = sanitizeToolResultValue(value);
@@ -18219,7 +18229,7 @@ var TokenCounter = class TokenCounter {
18219
18229
  let tokens = 0;
18220
18230
  const cacheParts = [];
18221
18231
  const countJsonContentPart = (contentPart) => {
18222
- const formatted = formatToolResultForObserver(contentPart);
18232
+ const formatted = serializeToolResultForTokenCounting(contentPart);
18223
18233
  tokens += this.countString(formatted);
18224
18234
  cacheParts.push({
18225
18235
  type: "json",
@@ -18521,39 +18531,68 @@ var TokenCounter = class TokenCounter {
18521
18531
  if (isImageAttachment) await resolveImageDimensionsAsync(part);
18522
18532
  return this.countAttachmentPartSync(part);
18523
18533
  }
18534
+ /**
18535
+ * Count the name and the arguments of a tool call. Every state before the tool produces an
18536
+ * output holds the same call signature in the context window, so all of those states share
18537
+ * these cache kinds. `buildEstimateKey` hashes the text, so a shared kind stays correct and
18538
+ * keeps the estimate warm while the invocation moves from one state to the next.
18539
+ */
18540
+ countToolCallSignature(part, invocation) {
18541
+ let tokens = 0;
18542
+ let overheadDelta = 0;
18543
+ if (invocation.toolName) tokens += this.readOrPersistPartEstimate(part, "tool-call-name", invocation.toolName);
18544
+ if (invocation.args) if (typeof invocation.args === "string") tokens += this.readOrPersistPartEstimate(part, "tool-call-args", invocation.args);
18545
+ else {
18546
+ const argsJson = JSON.stringify(invocation.args);
18547
+ tokens += this.readOrPersistPartEstimate(part, "tool-call-args-json", argsJson);
18548
+ overheadDelta -= 12;
18549
+ }
18550
+ return {
18551
+ tokens,
18552
+ overheadDelta
18553
+ };
18554
+ }
18524
18555
  countNonAttachmentPart(part) {
18525
18556
  let overheadDelta = 0;
18526
- let toolResultDelta = 0;
18557
+ let extraMessageDelta = 0;
18527
18558
  if (part.type === "text") return {
18528
18559
  tokens: this.readOrPersistPartEstimate(part, "text", part.text),
18529
18560
  overheadDelta,
18530
- toolResultDelta
18561
+ extraMessageDelta
18531
18562
  };
18532
18563
  if (part.type === "tool-invocation") {
18533
18564
  const invocation = part.toolInvocation;
18565
+ const state = invocation.state;
18534
18566
  let tokens = 0;
18535
- if (invocation.state === "call" || invocation.state === "partial-call") {
18536
- if (invocation.toolName) tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-name`, invocation.toolName);
18537
- if (invocation.args) if (typeof invocation.args === "string") tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-args`, invocation.args);
18538
- else {
18539
- const argsJson = JSON.stringify(invocation.args);
18540
- tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-args-json`, argsJson);
18541
- overheadDelta -= 12;
18542
- }
18567
+ if (state === "call" || state === "partial-call" || state === "approval-requested") {
18568
+ const signature = this.countToolCallSignature(part, invocation);
18569
+ return {
18570
+ tokens: signature.tokens,
18571
+ overheadDelta: overheadDelta + signature.overheadDelta,
18572
+ extraMessageDelta
18573
+ };
18574
+ }
18575
+ if (state === "approval-responded") {
18576
+ extraMessageDelta++;
18577
+ const signature = this.countToolCallSignature(part, invocation);
18578
+ tokens += signature.tokens;
18579
+ overheadDelta += signature.overheadDelta;
18580
+ const reason = invocation.approval?.reason;
18581
+ if (reason) tokens += this.readOrPersistPartEstimate(part, "tool-approval-reason", reason);
18543
18582
  return {
18544
18583
  tokens,
18545
18584
  overheadDelta,
18546
- toolResultDelta
18585
+ extraMessageDelta
18547
18586
  };
18548
18587
  }
18549
- if (invocation.state === "result") {
18550
- toolResultDelta++;
18588
+ if (state === "result") {
18589
+ extraMessageDelta++;
18551
18590
  const { value: resultForCounting, usingStoredModelOutput } = this.resolveToolResultForTokenCounting(part, invocation.result);
18552
18591
  if (resultForCounting !== void 0) {
18553
18592
  const contentTokens = this.countMultimodalToolResultContent(part, resultForCounting);
18554
18593
  if (contentTokens !== void 0) tokens += contentTokens;
18555
18594
  else {
18556
- const formattedResult = formatToolResultForObserver(resultForCounting);
18595
+ const formattedResult = serializeToolResultForTokenCounting(resultForCounting);
18557
18596
  tokens += this.readOrPersistPartEstimate(part, usingStoredModelOutput ? "tool-result-model-output-json" : "tool-result-json", formattedResult);
18558
18597
  }
18559
18598
  if (typeof resultForCounting !== "string") overheadDelta -= 12;
@@ -18561,47 +18600,45 @@ var TokenCounter = class TokenCounter {
18561
18600
  return {
18562
18601
  tokens,
18563
18602
  overheadDelta,
18564
- toolResultDelta
18603
+ extraMessageDelta
18565
18604
  };
18566
18605
  }
18567
- if (invocation.state === "output-denied") {
18568
- toolResultDelta++;
18606
+ if (state === "output-denied") {
18607
+ extraMessageDelta++;
18569
18608
  const reason = invocation.approval?.reason ?? "Tool call was not approved by the user";
18570
18609
  tokens += this.readOrPersistPartEstimate(part, "tool-result-denied", reason);
18571
18610
  return {
18572
18611
  tokens,
18573
18612
  overheadDelta,
18574
- toolResultDelta
18613
+ extraMessageDelta
18575
18614
  };
18576
18615
  }
18577
- if (invocation.state === "output-error") {
18578
- toolResultDelta++;
18579
- const errorText = invocation.errorText;
18580
- const errorMessage = typeof errorText === "string" ? errorText : "Tool execution failed";
18616
+ if (state === "output-error") {
18617
+ extraMessageDelta++;
18618
+ const errorMessage = typeof invocation.errorText === "string" ? invocation.errorText : "Tool execution failed";
18581
18619
  tokens += this.readOrPersistPartEstimate(part, "tool-result-error", errorMessage);
18582
18620
  return {
18583
18621
  tokens,
18584
18622
  overheadDelta,
18585
- toolResultDelta
18623
+ extraMessageDelta
18586
18624
  };
18587
18625
  }
18588
- throw new Error(`Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`);
18589
18626
  }
18590
18627
  if (typeof part.type === "string" && part.type.startsWith("data-")) return {
18591
18628
  tokens: 0,
18592
18629
  overheadDelta,
18593
- toolResultDelta
18630
+ extraMessageDelta
18594
18631
  };
18595
18632
  if (part.type === "reasoning") return {
18596
18633
  tokens: 0,
18597
18634
  overheadDelta,
18598
- toolResultDelta
18635
+ extraMessageDelta
18599
18636
  };
18600
18637
  const serialized = serializePartForTokenCounting(part);
18601
18638
  return {
18602
18639
  tokens: this.readOrPersistPartEstimate(part, `part-${part.type}`, serialized),
18603
18640
  overheadDelta,
18604
- toolResultDelta
18641
+ extraMessageDelta
18605
18642
  };
18606
18643
  }
18607
18644
  /**
@@ -18610,7 +18647,7 @@ var TokenCounter = class TokenCounter {
18610
18647
  countMessage(message) {
18611
18648
  let payloadTokens = this.countString(message.role);
18612
18649
  let overhead = TokenCounter.TOKENS_PER_MESSAGE;
18613
- let toolResultCount = 0;
18650
+ let extraMessageCount = 0;
18614
18651
  if (typeof message.content === "string") payloadTokens += this.readOrPersistMessageEstimate(message, "message-content", message.content);
18615
18652
  else if (message.content && typeof message.content === "object") {
18616
18653
  if (message.content.content && !Array.isArray(message.content.parts)) payloadTokens += this.readOrPersistMessageEstimate(message, "content-content", message.content.content);
@@ -18623,16 +18660,16 @@ var TokenCounter = class TokenCounter {
18623
18660
  const result = this.countNonAttachmentPart(part);
18624
18661
  payloadTokens += result.tokens;
18625
18662
  overhead += result.overheadDelta;
18626
- toolResultCount += result.toolResultDelta;
18663
+ extraMessageCount += result.extraMessageDelta;
18627
18664
  }
18628
18665
  }
18629
- if (toolResultCount > 0) overhead += toolResultCount * TokenCounter.TOKENS_PER_MESSAGE;
18666
+ if (extraMessageCount > 0) overhead += extraMessageCount * TokenCounter.TOKENS_PER_MESSAGE;
18630
18667
  return Math.round(payloadTokens + overhead);
18631
18668
  }
18632
18669
  async countMessageAsync(message) {
18633
18670
  let payloadTokens = this.countString(message.role);
18634
18671
  let overhead = TokenCounter.TOKENS_PER_MESSAGE;
18635
- let toolResultCount = 0;
18672
+ let extraMessageCount = 0;
18636
18673
  if (typeof message.content === "string") payloadTokens += this.readOrPersistMessageEstimate(message, "message-content", message.content);
18637
18674
  else if (message.content && typeof message.content === "object") {
18638
18675
  if (message.content.content && !Array.isArray(message.content.parts)) payloadTokens += this.readOrPersistMessageEstimate(message, "content-content", message.content.content);
@@ -18645,10 +18682,10 @@ var TokenCounter = class TokenCounter {
18645
18682
  const result = this.countNonAttachmentPart(part);
18646
18683
  payloadTokens += result.tokens;
18647
18684
  overhead += result.overheadDelta;
18648
- toolResultCount += result.toolResultDelta;
18685
+ extraMessageCount += result.extraMessageDelta;
18649
18686
  }
18650
18687
  }
18651
- if (toolResultCount > 0) overhead += toolResultCount * TokenCounter.TOKENS_PER_MESSAGE;
18688
+ if (extraMessageCount > 0) overhead += extraMessageCount * TokenCounter.TOKENS_PER_MESSAGE;
18652
18689
  return Math.round(payloadTokens + overhead);
18653
18690
  }
18654
18691
  /**
@@ -19751,6 +19788,7 @@ function deepMergeWorkingMemory(existing, update) {
19751
19788
  for (const key of Object.keys(update)) {
19752
19789
  const updateValue = update[key];
19753
19790
  const existingValue = result[key];
19791
+ if (updateValue === void 0) continue;
19754
19792
  if (updateValue === null) delete result[key];
19755
19793
  else if (Array.isArray(updateValue)) result[key] = updateValue;
19756
19794
  else if (typeof updateValue === "object" && updateValue !== null && typeof existingValue === "object" && existingValue !== null && !Array.isArray(existingValue)) result[key] = deepMergeWorkingMemory(existingValue, updateValue);
@@ -19803,7 +19841,7 @@ const updateWorkingMemoryTool = (memoryConfig) => {
19803
19841
  version: 1,
19804
19842
  vendor: "mastra",
19805
19843
  validate: (value) => {
19806
- const memoryValue = !!value && typeof value === "object" && !Array.isArray(value) && "memory" in value ? value.memory : stripNullsFromOptional(value, jsonSchema);
19844
+ const memoryValue = stripNullsFromOptional(!!value && typeof value === "object" && !Array.isArray(value) && "memory" in value ? value.memory : value, jsonSchema);
19807
19845
  const result = validateMemory(memoryValue);
19808
19846
  return result instanceof Promise ? result.then(toWrappedResult) : toWrappedResult(result);
19809
19847
  },
@@ -19820,6 +19858,7 @@ const updateWorkingMemoryTool = (memoryConfig) => {
19820
19858
  id: "update-working-memory",
19821
19859
  description: schema ? useStateSignals ? `${stateSignalsPreamble} Data is merged with existing memory — only include fields you want to add or update.` : `Update the working memory with new information. Data is merged with existing memory - only include fields you want to add or update. To preserve existing data, omit the field entirely. Arrays are replaced entirely when provided, so pass the complete array or omit it to keep the existing values.` : useStateSignals ? `${stateSignalsPreamble} Pass the full updated Markdown blob as a string in the memory field.` : `Update the working memory with new information. Any data not included will be overwritten. Always pass data as string to the memory field. Never pass an object.`,
19822
19860
  inputSchema,
19861
+ ...usesMergeSemantics ? { strict: false } : {},
19823
19862
  execute: async (inputData, context) => {
19824
19863
  const workingMemoryInput = inputData;
19825
19864
  const threadId = context?.agent?.threadId;
@@ -21342,7 +21381,7 @@ var SyncObservationStrategy = class extends ObservationStrategy {
21342
21381
  });
21343
21382
  await this.storage.updateThread({
21344
21383
  id: threadId,
21345
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21384
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21346
21385
  metadata: newMetadata
21347
21386
  });
21348
21387
  if (shouldUpdateThreadTitle) threadUpdateMarker = createThreadUpdateMarker({
@@ -21534,7 +21573,7 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
21534
21573
  });
21535
21574
  await this.storage.updateThread({
21536
21575
  id: threadId,
21537
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21576
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21538
21577
  metadata: newMetadata
21539
21578
  });
21540
21579
  if (shouldUpdateThreadTitle) {
@@ -21879,7 +21918,7 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
21879
21918
  });
21880
21919
  await this.storage.updateThread({
21881
21920
  id: update.threadId,
21882
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21921
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21883
21922
  metadata: newMetadata
21884
21923
  });
21885
21924
  if (shouldUpdateThreadTitle) threadUpdateMarkers.push(createThreadUpdateMarker({
@@ -22822,7 +22861,6 @@ async function persistThreadExtractedValues(storage, extractors, threadId, value
22822
22861
  });
22823
22862
  await storage.updateThread({
22824
22863
  id: threadId,
22825
- title: thread.title ?? "",
22826
22864
  metadata: newMetadata
22827
22865
  });
22828
22866
  }
@@ -25794,7 +25832,7 @@ ${formattedMessages}
25794
25832
  const shouldUpdateThreadTitle = !!newTitle && newTitle.length >= 3 && newTitle !== oldTitle;
25795
25833
  await this.storage.updateThread({
25796
25834
  id: threadId,
25797
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
25835
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
25798
25836
  metadata: newMetadata
25799
25837
  });
25800
25838
  }
@@ -26012,7 +26050,6 @@ ${formattedMessages}
26012
26050
  });
26013
26051
  await this.storage.updateThread({
26014
26052
  id: threadId,
26015
- title: thread.title ?? "",
26016
26053
  metadata: newMetadata
26017
26054
  });
26018
26055
  }
@@ -27158,7 +27195,6 @@ var Memory = class extends MastraMemory {
27158
27195
  if (!thread) throw new Error(`Thread ${threadId} not found`);
27159
27196
  await memoryStore.updateThread({
27160
27197
  id: threadId,
27161
- title: thread.title || "",
27162
27198
  metadata: {
27163
27199
  ...thread.metadata,
27164
27200
  workingMemory
@@ -27247,7 +27283,6 @@ ${workingMemory}`;
27247
27283
  if (!thread) throw new Error(`Thread ${threadId} not found`);
27248
27284
  await memoryStore.updateThread({
27249
27285
  id: threadId,
27250
- title: thread.title || "",
27251
27286
  metadata: {
27252
27287
  ...thread.metadata,
27253
27288
  workingMemory
@@ -28584,4 +28619,4 @@ Notes:
28584
28619
  //#endregion
28585
28620
  export { extractCurrentTask as A, OBSERVATION_CONTEXT_INSTRUCTIONS as B, WorkingMemoryExtractor as C, OBSERVER_SYSTEM_PROMPT as D, TokenCounter as E, injectAnchorIds as F, OBSERVATION_CONTINUATION_HINT as H, parseAnchorId as I, stripEphemeralAnchorIds as L, hasCurrentTaskSection as M, optimizeObservationsForContext as N, buildObserverPrompt as O, parseObserverOutput as P, Extractor as R, deepMergeWorkingMemory as S, summarizeConversation as T, OBSERVATION_CONTEXT_PROMPT as V, reconcileObservationGroupsFromReflection as _, extractWorkingMemoryContent as a, wrapInObservationGroup as b, WORKING_MEMORY_STATE_ID as c, getObservationsAsOf as d, ObservationalMemoryProcessor as f, parseObservationGroups as g, deriveObservationGroupProvenance as h, WorkingMemory as i, formatMessagesForObserver as j, buildObserverSystemPrompt as k, WORKING_MEMORY_STATE_PROCESSOR_ID as l, combineObservationGroupRanges as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, ObservationalMemory as p, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, WorkingMemoryStateProcessor as u, renderObservationGroupsForReflection as v, SUMMARIZE_THREAD_DEFAULTS as w, ModelByInputTokens as x, stripObservationGroups as y, OBSERVATIONAL_MEMORY_DEFAULTS as z };
28586
28621
 
28587
- //# sourceMappingURL=src-CdqJP57F.js.map
28622
+ //# sourceMappingURL=src-hv0DMVM-.js.map