@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
@@ -15635,6 +15635,16 @@ function sanitizeToolResultValue(value, seen = /* @__PURE__ */ new WeakMap()) {
15635
15635
  }
15636
15636
  return sanitizedObject;
15637
15637
  }
15638
+ /**
15639
+ * Serializes a tool result without truncating it.
15640
+ *
15641
+ * Token accounting must see the full result: the truncation applied by
15642
+ * {@link formatToolResultForObserver} exists to bound what the Observer LLM reads,
15643
+ * not to describe what the agent's provider context actually holds.
15644
+ */
15645
+ function serializeToolResultForTokenCounting(value) {
15646
+ return stringifyToolResult(value);
15647
+ }
15638
15648
  function stringifyToolResult(value) {
15639
15649
  if (typeof value === "string") return value;
15640
15650
  const sanitized = sanitizeToolResultValue(value);
@@ -18240,7 +18250,7 @@ var TokenCounter = class TokenCounter {
18240
18250
  let tokens = 0;
18241
18251
  const cacheParts = [];
18242
18252
  const countJsonContentPart = (contentPart) => {
18243
- const formatted = formatToolResultForObserver(contentPart);
18253
+ const formatted = serializeToolResultForTokenCounting(contentPart);
18244
18254
  tokens += this.countString(formatted);
18245
18255
  cacheParts.push({
18246
18256
  type: "json",
@@ -18542,39 +18552,68 @@ var TokenCounter = class TokenCounter {
18542
18552
  if (isImageAttachment) await resolveImageDimensionsAsync(part);
18543
18553
  return this.countAttachmentPartSync(part);
18544
18554
  }
18555
+ /**
18556
+ * Count the name and the arguments of a tool call. Every state before the tool produces an
18557
+ * output holds the same call signature in the context window, so all of those states share
18558
+ * these cache kinds. `buildEstimateKey` hashes the text, so a shared kind stays correct and
18559
+ * keeps the estimate warm while the invocation moves from one state to the next.
18560
+ */
18561
+ countToolCallSignature(part, invocation) {
18562
+ let tokens = 0;
18563
+ let overheadDelta = 0;
18564
+ if (invocation.toolName) tokens += this.readOrPersistPartEstimate(part, "tool-call-name", invocation.toolName);
18565
+ if (invocation.args) if (typeof invocation.args === "string") tokens += this.readOrPersistPartEstimate(part, "tool-call-args", invocation.args);
18566
+ else {
18567
+ const argsJson = JSON.stringify(invocation.args);
18568
+ tokens += this.readOrPersistPartEstimate(part, "tool-call-args-json", argsJson);
18569
+ overheadDelta -= 12;
18570
+ }
18571
+ return {
18572
+ tokens,
18573
+ overheadDelta
18574
+ };
18575
+ }
18545
18576
  countNonAttachmentPart(part) {
18546
18577
  let overheadDelta = 0;
18547
- let toolResultDelta = 0;
18578
+ let extraMessageDelta = 0;
18548
18579
  if (part.type === "text") return {
18549
18580
  tokens: this.readOrPersistPartEstimate(part, "text", part.text),
18550
18581
  overheadDelta,
18551
- toolResultDelta
18582
+ extraMessageDelta
18552
18583
  };
18553
18584
  if (part.type === "tool-invocation") {
18554
18585
  const invocation = part.toolInvocation;
18586
+ const state = invocation.state;
18555
18587
  let tokens = 0;
18556
- if (invocation.state === "call" || invocation.state === "partial-call") {
18557
- if (invocation.toolName) tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-name`, invocation.toolName);
18558
- if (invocation.args) if (typeof invocation.args === "string") tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-args`, invocation.args);
18559
- else {
18560
- const argsJson = JSON.stringify(invocation.args);
18561
- tokens += this.readOrPersistPartEstimate(part, `tool-${invocation.state}-args-json`, argsJson);
18562
- overheadDelta -= 12;
18563
- }
18588
+ if (state === "call" || state === "partial-call" || state === "approval-requested") {
18589
+ const signature = this.countToolCallSignature(part, invocation);
18590
+ return {
18591
+ tokens: signature.tokens,
18592
+ overheadDelta: overheadDelta + signature.overheadDelta,
18593
+ extraMessageDelta
18594
+ };
18595
+ }
18596
+ if (state === "approval-responded") {
18597
+ extraMessageDelta++;
18598
+ const signature = this.countToolCallSignature(part, invocation);
18599
+ tokens += signature.tokens;
18600
+ overheadDelta += signature.overheadDelta;
18601
+ const reason = invocation.approval?.reason;
18602
+ if (reason) tokens += this.readOrPersistPartEstimate(part, "tool-approval-reason", reason);
18564
18603
  return {
18565
18604
  tokens,
18566
18605
  overheadDelta,
18567
- toolResultDelta
18606
+ extraMessageDelta
18568
18607
  };
18569
18608
  }
18570
- if (invocation.state === "result") {
18571
- toolResultDelta++;
18609
+ if (state === "result") {
18610
+ extraMessageDelta++;
18572
18611
  const { value: resultForCounting, usingStoredModelOutput } = this.resolveToolResultForTokenCounting(part, invocation.result);
18573
18612
  if (resultForCounting !== void 0) {
18574
18613
  const contentTokens = this.countMultimodalToolResultContent(part, resultForCounting);
18575
18614
  if (contentTokens !== void 0) tokens += contentTokens;
18576
18615
  else {
18577
- const formattedResult = formatToolResultForObserver(resultForCounting);
18616
+ const formattedResult = serializeToolResultForTokenCounting(resultForCounting);
18578
18617
  tokens += this.readOrPersistPartEstimate(part, usingStoredModelOutput ? "tool-result-model-output-json" : "tool-result-json", formattedResult);
18579
18618
  }
18580
18619
  if (typeof resultForCounting !== "string") overheadDelta -= 12;
@@ -18582,47 +18621,45 @@ var TokenCounter = class TokenCounter {
18582
18621
  return {
18583
18622
  tokens,
18584
18623
  overheadDelta,
18585
- toolResultDelta
18624
+ extraMessageDelta
18586
18625
  };
18587
18626
  }
18588
- if (invocation.state === "output-denied") {
18589
- toolResultDelta++;
18627
+ if (state === "output-denied") {
18628
+ extraMessageDelta++;
18590
18629
  const reason = invocation.approval?.reason ?? "Tool call was not approved by the user";
18591
18630
  tokens += this.readOrPersistPartEstimate(part, "tool-result-denied", reason);
18592
18631
  return {
18593
18632
  tokens,
18594
18633
  overheadDelta,
18595
- toolResultDelta
18634
+ extraMessageDelta
18596
18635
  };
18597
18636
  }
18598
- if (invocation.state === "output-error") {
18599
- toolResultDelta++;
18600
- const errorText = invocation.errorText;
18601
- const errorMessage = typeof errorText === "string" ? errorText : "Tool execution failed";
18637
+ if (state === "output-error") {
18638
+ extraMessageDelta++;
18639
+ const errorMessage = typeof invocation.errorText === "string" ? invocation.errorText : "Tool execution failed";
18602
18640
  tokens += this.readOrPersistPartEstimate(part, "tool-result-error", errorMessage);
18603
18641
  return {
18604
18642
  tokens,
18605
18643
  overheadDelta,
18606
- toolResultDelta
18644
+ extraMessageDelta
18607
18645
  };
18608
18646
  }
18609
- throw new Error(`Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`);
18610
18647
  }
18611
18648
  if (typeof part.type === "string" && part.type.startsWith("data-")) return {
18612
18649
  tokens: 0,
18613
18650
  overheadDelta,
18614
- toolResultDelta
18651
+ extraMessageDelta
18615
18652
  };
18616
18653
  if (part.type === "reasoning") return {
18617
18654
  tokens: 0,
18618
18655
  overheadDelta,
18619
- toolResultDelta
18656
+ extraMessageDelta
18620
18657
  };
18621
18658
  const serialized = serializePartForTokenCounting(part);
18622
18659
  return {
18623
18660
  tokens: this.readOrPersistPartEstimate(part, `part-${part.type}`, serialized),
18624
18661
  overheadDelta,
18625
- toolResultDelta
18662
+ extraMessageDelta
18626
18663
  };
18627
18664
  }
18628
18665
  /**
@@ -18631,7 +18668,7 @@ var TokenCounter = class TokenCounter {
18631
18668
  countMessage(message) {
18632
18669
  let payloadTokens = this.countString(message.role);
18633
18670
  let overhead = TokenCounter.TOKENS_PER_MESSAGE;
18634
- let toolResultCount = 0;
18671
+ let extraMessageCount = 0;
18635
18672
  if (typeof message.content === "string") payloadTokens += this.readOrPersistMessageEstimate(message, "message-content", message.content);
18636
18673
  else if (message.content && typeof message.content === "object") {
18637
18674
  if (message.content.content && !Array.isArray(message.content.parts)) payloadTokens += this.readOrPersistMessageEstimate(message, "content-content", message.content.content);
@@ -18644,16 +18681,16 @@ var TokenCounter = class TokenCounter {
18644
18681
  const result = this.countNonAttachmentPart(part);
18645
18682
  payloadTokens += result.tokens;
18646
18683
  overhead += result.overheadDelta;
18647
- toolResultCount += result.toolResultDelta;
18684
+ extraMessageCount += result.extraMessageDelta;
18648
18685
  }
18649
18686
  }
18650
- if (toolResultCount > 0) overhead += toolResultCount * TokenCounter.TOKENS_PER_MESSAGE;
18687
+ if (extraMessageCount > 0) overhead += extraMessageCount * TokenCounter.TOKENS_PER_MESSAGE;
18651
18688
  return Math.round(payloadTokens + overhead);
18652
18689
  }
18653
18690
  async countMessageAsync(message) {
18654
18691
  let payloadTokens = this.countString(message.role);
18655
18692
  let overhead = TokenCounter.TOKENS_PER_MESSAGE;
18656
- let toolResultCount = 0;
18693
+ let extraMessageCount = 0;
18657
18694
  if (typeof message.content === "string") payloadTokens += this.readOrPersistMessageEstimate(message, "message-content", message.content);
18658
18695
  else if (message.content && typeof message.content === "object") {
18659
18696
  if (message.content.content && !Array.isArray(message.content.parts)) payloadTokens += this.readOrPersistMessageEstimate(message, "content-content", message.content.content);
@@ -18666,10 +18703,10 @@ var TokenCounter = class TokenCounter {
18666
18703
  const result = this.countNonAttachmentPart(part);
18667
18704
  payloadTokens += result.tokens;
18668
18705
  overhead += result.overheadDelta;
18669
- toolResultCount += result.toolResultDelta;
18706
+ extraMessageCount += result.extraMessageDelta;
18670
18707
  }
18671
18708
  }
18672
- if (toolResultCount > 0) overhead += toolResultCount * TokenCounter.TOKENS_PER_MESSAGE;
18709
+ if (extraMessageCount > 0) overhead += extraMessageCount * TokenCounter.TOKENS_PER_MESSAGE;
18673
18710
  return Math.round(payloadTokens + overhead);
18674
18711
  }
18675
18712
  /**
@@ -19772,6 +19809,7 @@ function deepMergeWorkingMemory(existing, update) {
19772
19809
  for (const key of Object.keys(update)) {
19773
19810
  const updateValue = update[key];
19774
19811
  const existingValue = result[key];
19812
+ if (updateValue === void 0) continue;
19775
19813
  if (updateValue === null) delete result[key];
19776
19814
  else if (Array.isArray(updateValue)) result[key] = updateValue;
19777
19815
  else if (typeof updateValue === "object" && updateValue !== null && typeof existingValue === "object" && existingValue !== null && !Array.isArray(existingValue)) result[key] = deepMergeWorkingMemory(existingValue, updateValue);
@@ -19824,7 +19862,7 @@ const updateWorkingMemoryTool = (memoryConfig) => {
19824
19862
  version: 1,
19825
19863
  vendor: "mastra",
19826
19864
  validate: (value) => {
19827
- const memoryValue = !!value && typeof value === "object" && !Array.isArray(value) && "memory" in value ? value.memory : stripNullsFromOptional(value, jsonSchema);
19865
+ const memoryValue = stripNullsFromOptional(!!value && typeof value === "object" && !Array.isArray(value) && "memory" in value ? value.memory : value, jsonSchema);
19828
19866
  const result = validateMemory(memoryValue);
19829
19867
  return result instanceof Promise ? result.then(toWrappedResult) : toWrappedResult(result);
19830
19868
  },
@@ -19841,6 +19879,7 @@ const updateWorkingMemoryTool = (memoryConfig) => {
19841
19879
  id: "update-working-memory",
19842
19880
  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.`,
19843
19881
  inputSchema,
19882
+ ...usesMergeSemantics ? { strict: false } : {},
19844
19883
  execute: async (inputData, context) => {
19845
19884
  const workingMemoryInput = inputData;
19846
19885
  const threadId = context?.agent?.threadId;
@@ -21363,7 +21402,7 @@ var SyncObservationStrategy = class extends ObservationStrategy {
21363
21402
  });
21364
21403
  await this.storage.updateThread({
21365
21404
  id: threadId,
21366
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21405
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21367
21406
  metadata: newMetadata
21368
21407
  });
21369
21408
  if (shouldUpdateThreadTitle) threadUpdateMarker = createThreadUpdateMarker({
@@ -21555,7 +21594,7 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
21555
21594
  });
21556
21595
  await this.storage.updateThread({
21557
21596
  id: threadId,
21558
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21597
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21559
21598
  metadata: newMetadata
21560
21599
  });
21561
21600
  if (shouldUpdateThreadTitle) {
@@ -21900,7 +21939,7 @@ var ResourceScopedObservationStrategy = class extends ObservationStrategy {
21900
21939
  });
21901
21940
  await this.storage.updateThread({
21902
21941
  id: update.threadId,
21903
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
21942
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
21904
21943
  metadata: newMetadata
21905
21944
  });
21906
21945
  if (shouldUpdateThreadTitle) threadUpdateMarkers.push(createThreadUpdateMarker({
@@ -22843,7 +22882,6 @@ async function persistThreadExtractedValues(storage, extractors, threadId, value
22843
22882
  });
22844
22883
  await storage.updateThread({
22845
22884
  id: threadId,
22846
- title: thread.title ?? "",
22847
22885
  metadata: newMetadata
22848
22886
  });
22849
22887
  }
@@ -25815,7 +25853,7 @@ ${formattedMessages}
25815
25853
  const shouldUpdateThreadTitle = !!newTitle && newTitle.length >= 3 && newTitle !== oldTitle;
25816
25854
  await this.storage.updateThread({
25817
25855
  id: threadId,
25818
- title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
25856
+ ...shouldUpdateThreadTitle ? { title: newTitle } : {},
25819
25857
  metadata: newMetadata
25820
25858
  });
25821
25859
  }
@@ -26033,7 +26071,6 @@ ${formattedMessages}
26033
26071
  });
26034
26072
  await this.storage.updateThread({
26035
26073
  id: threadId,
26036
- title: thread.title ?? "",
26037
26074
  metadata: newMetadata
26038
26075
  });
26039
26076
  }
@@ -27179,7 +27216,6 @@ var Memory = class extends _mastra_core_memory.MastraMemory {
27179
27216
  if (!thread) throw new Error(`Thread ${threadId} not found`);
27180
27217
  await memoryStore.updateThread({
27181
27218
  id: threadId,
27182
- title: thread.title || "",
27183
27219
  metadata: {
27184
27220
  ...thread.metadata,
27185
27221
  workingMemory
@@ -27268,7 +27304,6 @@ ${workingMemory}`;
27268
27304
  if (!thread) throw new Error(`Thread ${threadId} not found`);
27269
27305
  await memoryStore.updateThread({
27270
27306
  id: threadId,
27271
- title: thread.title || "",
27272
27307
  metadata: {
27273
27308
  ...thread.metadata,
27274
27309
  workingMemory
@@ -28838,4 +28873,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
28838
28873
  }
28839
28874
  });
28840
28875
 
28841
- //# sourceMappingURL=src-DY9-_lul.cjs.map
28876
+ //# sourceMappingURL=src-kjoZv97r.cjs.map