@mastra/memory 1.5.1 → 1.5.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 (52) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/{chunk-6PKWQ3GH.js → chunk-HNPAIFCZ.js} +59 -16
  3. package/dist/chunk-HNPAIFCZ.js.map +1 -0
  4. package/dist/{chunk-6XVTMLW4.cjs → chunk-PVFLHAZX.cjs} +59 -16
  5. package/dist/chunk-PVFLHAZX.cjs.map +1 -0
  6. package/dist/docs/SKILL.md +55 -0
  7. package/dist/docs/assets/SOURCE_MAP.json +103 -0
  8. package/dist/docs/references/docs-agents-agent-approval.md +558 -0
  9. package/dist/docs/references/docs-agents-agent-memory.md +209 -0
  10. package/dist/docs/references/docs-agents-network-approval.md +275 -0
  11. package/dist/docs/references/docs-agents-networks.md +299 -0
  12. package/dist/docs/references/docs-agents-supervisor-agents.md +304 -0
  13. package/dist/docs/references/docs-memory-memory-processors.md +314 -0
  14. package/dist/docs/references/docs-memory-message-history.md +260 -0
  15. package/dist/docs/references/docs-memory-observational-memory.md +248 -0
  16. package/dist/docs/references/docs-memory-overview.md +45 -0
  17. package/dist/docs/references/docs-memory-semantic-recall.md +272 -0
  18. package/dist/docs/references/docs-memory-storage.md +261 -0
  19. package/dist/docs/references/docs-memory-working-memory.md +400 -0
  20. package/dist/docs/references/reference-core-getMemory.md +50 -0
  21. package/dist/docs/references/reference-core-listMemory.md +56 -0
  22. package/dist/docs/references/reference-memory-clone-utilities.md +199 -0
  23. package/dist/docs/references/reference-memory-cloneThread.md +130 -0
  24. package/dist/docs/references/reference-memory-createThread.md +68 -0
  25. package/dist/docs/references/reference-memory-getThreadById.md +24 -0
  26. package/dist/docs/references/reference-memory-listThreads.md +145 -0
  27. package/dist/docs/references/reference-memory-memory-class.md +147 -0
  28. package/dist/docs/references/reference-memory-observational-memory.md +565 -0
  29. package/dist/docs/references/reference-processors-token-limiter-processor.md +115 -0
  30. package/dist/docs/references/reference-storage-dynamodb.md +282 -0
  31. package/dist/docs/references/reference-storage-libsql.md +135 -0
  32. package/dist/docs/references/reference-storage-mongodb.md +262 -0
  33. package/dist/docs/references/reference-storage-postgresql.md +526 -0
  34. package/dist/docs/references/reference-storage-upstash.md +160 -0
  35. package/dist/docs/references/reference-vectors-libsql.md +305 -0
  36. package/dist/docs/references/reference-vectors-mongodb.md +295 -0
  37. package/dist/docs/references/reference-vectors-pg.md +408 -0
  38. package/dist/docs/references/reference-vectors-upstash.md +294 -0
  39. package/dist/index.cjs +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/{observational-memory-AJWSMZVP.js → observational-memory-KAFD4QZK.js} +3 -3
  42. package/dist/{observational-memory-AJWSMZVP.js.map → observational-memory-KAFD4QZK.js.map} +1 -1
  43. package/dist/{observational-memory-Q5TO525O.cjs → observational-memory-Q47HN5YL.cjs} +17 -17
  44. package/dist/{observational-memory-Q5TO525O.cjs.map → observational-memory-Q47HN5YL.cjs.map} +1 -1
  45. package/dist/processors/index.cjs +15 -15
  46. package/dist/processors/index.js +1 -1
  47. package/dist/processors/observational-memory/observational-memory.d.ts +2 -2
  48. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  49. package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
  50. package/package.json +8 -8
  51. package/dist/chunk-6PKWQ3GH.js.map +0 -1
  52. package/dist/chunk-6XVTMLW4.cjs.map +0 -1
@@ -986,7 +986,7 @@ var TokenCounter = class _TokenCounter {
986
986
  `Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`
987
987
  );
988
988
  }
989
- } else if (typeof part.type === "string" && part.type.startsWith("data-")) ; else {
989
+ } else if (typeof part.type === "string" && part.type.startsWith("data-")) ; else if (part.type === "reasoning") ; else {
990
990
  tokenString += JSON.stringify(part);
991
991
  }
992
992
  }
@@ -1482,10 +1482,12 @@ var ObservationalMemory = class _ObservationalMemory {
1482
1482
  const maxOvershoot = retentionFloor * 0.95;
1483
1483
  const overshoot = bestOverTokens - targetMessageTokens;
1484
1484
  const remainingAfterOver = currentPendingTokens - bestOverTokens;
1485
+ const remainingAfterUnder = currentPendingTokens - bestUnderTokens;
1486
+ const minRemaining = Math.min(1e3, retentionFloor);
1485
1487
  let bestBoundaryMessageTokens;
1486
- if (bestOverBoundary > 0 && overshoot <= maxOvershoot && (remainingAfterOver >= 1e3 || retentionFloor === 0)) {
1488
+ if (bestOverBoundary > 0 && overshoot <= maxOvershoot && remainingAfterOver >= minRemaining) {
1487
1489
  bestBoundaryMessageTokens = bestOverTokens;
1488
- } else if (bestUnderBoundary > 0) {
1490
+ } else if (bestUnderBoundary > 0 && remainingAfterUnder >= minRemaining) {
1489
1491
  bestBoundaryMessageTokens = bestUnderTokens;
1490
1492
  } else if (bestOverBoundary > 0) {
1491
1493
  bestBoundaryMessageTokens = bestOverTokens;
@@ -1845,14 +1847,14 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
1845
1847
  }
1846
1848
  /**
1847
1849
  * Resolve blockAfter config value.
1848
- * Values between 1 and 2 (exclusive) are treated as multipliers of the threshold.
1850
+ * Values in [1, 100) are treated as multipliers of the threshold.
1849
1851
  * e.g. blockAfter: 1.5 with messageTokens: 20_000 → 30_000
1850
- * Values >= 2 are treated as absolute token counts.
1852
+ * Values >= 100 are treated as absolute token counts.
1851
1853
  * Defaults to 1.2 (120% of threshold) when async buffering is enabled but blockAfter is omitted.
1852
1854
  */
1853
1855
  resolveBlockAfter(blockAfter, messageTokens) {
1854
1856
  if (blockAfter === void 0) return void 0;
1855
- if (blockAfter >= 1 && blockAfter < 2) {
1857
+ if (blockAfter >= 1 && blockAfter < 100) {
1856
1858
  const threshold = typeof messageTokens === "number" ? messageTokens : messageTokens.max;
1857
1859
  return Math.round(threshold * blockAfter);
1858
1860
  }
@@ -2986,7 +2988,7 @@ ${suggestedResponse}
2986
2988
  * Remove observed messages from message list after successful observation.
2987
2989
  * Accepts optional observedMessageIds for activation-based cleanup (when no markers are present).
2988
2990
  */
2989
- async cleanupAfterObservation(messageList, sealedIds, threadId, resourceId, state, observedMessageIds) {
2991
+ async cleanupAfterObservation(messageList, sealedIds, threadId, resourceId, state, observedMessageIds, minRemaining) {
2990
2992
  const allMsgs = messageList.get.all.db();
2991
2993
  let markerIdx = -1;
2992
2994
  let markerMsg = null;
@@ -3030,13 +3032,25 @@ ${suggestedResponse}
3030
3032
  } else if (observedMessageIds && observedMessageIds.length > 0) {
3031
3033
  const observedSet = new Set(observedMessageIds);
3032
3034
  const idsToRemove = [];
3035
+ const totalTokens = typeof minRemaining === "number" ? this.tokenCounter.countMessages(allMsgs) : void 0;
3036
+ let removedTokens = 0;
3037
+ let skipped = 0;
3033
3038
  for (const msg of allMsgs) {
3034
3039
  if (msg?.id && msg.id !== "om-continuation" && observedSet.has(msg.id)) {
3040
+ if (typeof minRemaining === "number") {
3041
+ const msgTokens = this.tokenCounter.countMessage(msg);
3042
+ const remainingIfRemoved = (totalTokens ?? 0) - removedTokens - msgTokens;
3043
+ if (remainingIfRemoved < minRemaining) {
3044
+ skipped += 1;
3045
+ continue;
3046
+ }
3047
+ removedTokens += msgTokens;
3048
+ }
3035
3049
  idsToRemove.push(msg.id);
3036
3050
  }
3037
3051
  }
3038
3052
  omDebug(
3039
- `[OM:cleanupActivation] observedSet=${[...observedSet].map((id) => id.slice(0, 8)).join(",")}, matched=${idsToRemove.length}, idsToRemove=${idsToRemove.map((id) => id.slice(0, 8)).join(",")}`
3053
+ `[OM:cleanupActivation] observedSet=${[...observedSet].map((id) => id.slice(0, 8)).join(",")}, matched=${idsToRemove.length}, skipped=${skipped}, idsToRemove=${idsToRemove.map((id) => id.slice(0, 8)).join(",")}`
3040
3054
  );
3041
3055
  if (idsToRemove.length > 0) {
3042
3056
  messageList.removeByIds(idsToRemove);
@@ -3185,8 +3199,12 @@ ${suggestedResponse}
3185
3199
  async processInputStep(args) {
3186
3200
  const { messageList, requestContext, stepNumber, state: _state, writer, abortSignal, abort } = args;
3187
3201
  const state = _state ?? {};
3202
+ omDebug(
3203
+ `[OM:processInputStep:ENTER] step=${stepNumber}, hasMastraMemory=${!!requestContext?.get("MastraMemory")}, hasMemoryInfo=${!!messageList?.serialize()?.memoryInfo?.threadId}`
3204
+ );
3188
3205
  const context = this.getThreadContext(requestContext, messageList);
3189
3206
  if (!context) {
3207
+ omDebug(`[OM:processInputStep:NO-CONTEXT] getThreadContext returned null \u2014 returning early`);
3190
3208
  return messageList;
3191
3209
  }
3192
3210
  const { threadId, resourceId } = context;
@@ -3325,7 +3343,7 @@ ${suggestedResponse}
3325
3343
  record
3326
3344
  );
3327
3345
  const { totalPendingTokens, threshold } = thresholds;
3328
- const bufferedChunkTokens = this.getBufferedChunks(record).reduce((sum, c) => sum + (c.tokenCount ?? 0), 0);
3346
+ const bufferedChunkTokens = this.getBufferedChunks(record).reduce((sum, c) => sum + (c.messageTokens ?? 0), 0);
3329
3347
  const unbufferedPendingTokens = Math.max(0, totalPendingTokens - bufferedChunkTokens);
3330
3348
  const stateSealedIds = state.sealedIds ?? /* @__PURE__ */ new Set();
3331
3349
  const staticSealedIds = _ObservationalMemory.sealedMessageIds.get(threadId) ?? /* @__PURE__ */ new Set();
@@ -3333,7 +3351,7 @@ ${suggestedResponse}
3333
3351
  state.sealedIds = sealedIds;
3334
3352
  const lockKey = this.getLockKey(threadId, resourceId);
3335
3353
  if (this.isAsyncObservationEnabled() && totalPendingTokens < threshold) {
3336
- const shouldTrigger = this.shouldTriggerAsyncObservation(unbufferedPendingTokens, lockKey, record, threshold);
3354
+ const shouldTrigger = this.shouldTriggerAsyncObservation(totalPendingTokens, lockKey, record, threshold);
3337
3355
  omDebug(
3338
3356
  `[OM:async-obs] belowThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, shouldTrigger=${shouldTrigger}, isBufferingObs=${record.isBufferingObservation}, lastBufferedAt=${record.lastBufferedAtTokens}`
3339
3357
  );
@@ -3349,7 +3367,7 @@ ${suggestedResponse}
3349
3367
  );
3350
3368
  }
3351
3369
  } else if (this.isAsyncObservationEnabled()) {
3352
- const shouldTrigger = this.shouldTriggerAsyncObservation(unbufferedPendingTokens, lockKey, record, threshold);
3370
+ const shouldTrigger = this.shouldTriggerAsyncObservation(totalPendingTokens, lockKey, record, threshold);
3353
3371
  omDebug(
3354
3372
  `[OM:async-obs] atOrAboveThreshold: pending=${totalPendingTokens}, unbuffered=${unbufferedPendingTokens}, threshold=${threshold}, step=${stepNumber}, shouldTrigger=${shouldTrigger}`
3355
3373
  );
@@ -3383,10 +3401,19 @@ ${suggestedResponse}
3383
3401
  );
3384
3402
  if (observationSucceeded) {
3385
3403
  const observedIds = activatedMessageIds?.length ? activatedMessageIds : Array.isArray(updatedRecord.observedMessageIds) ? updatedRecord.observedMessageIds : void 0;
3404
+ const minRemaining = typeof this.observationConfig.bufferActivation === "number" ? Math.min(1e3, this.resolveRetentionFloor(this.observationConfig.bufferActivation, threshold)) : void 0;
3386
3405
  omDebug(
3387
- `[OM:cleanup] observedIds=${observedIds?.length ?? "undefined"}, ids=${observedIds?.join(",") ?? "none"}, updatedRecord.observedMessageIds=${JSON.stringify(updatedRecord.observedMessageIds)}`
3406
+ `[OM:cleanup] observedIds=${observedIds?.length ?? "undefined"}, ids=${observedIds?.join(",") ?? "none"}, updatedRecord.observedMessageIds=${JSON.stringify(updatedRecord.observedMessageIds)}, minRemaining=${minRemaining ?? "n/a"}`
3407
+ );
3408
+ await this.cleanupAfterObservation(
3409
+ messageList,
3410
+ sealedIds,
3411
+ threadId,
3412
+ resourceId,
3413
+ state,
3414
+ observedIds,
3415
+ minRemaining
3388
3416
  );
3389
- await this.cleanupAfterObservation(messageList, sealedIds, threadId, resourceId, state, observedIds);
3390
3417
  if (activatedMessageIds?.length) {
3391
3418
  this.cleanupStaticMaps(threadId, resourceId, activatedMessageIds);
3392
3419
  }
@@ -3983,7 +4010,7 @@ ${result.observations}` : result.observations;
3983
4010
  }
3984
4011
  try {
3985
4012
  omDebug(
3986
- `[OM:bufferInput] cycleId=${cycleId}, msgCount=${messagesToBuffer.length}, msgTokens=${this.tokenCounter.countMessages(messagesToBuffer)}, ids=${messagesToBuffer.map((m) => `${m.id?.slice(0, 8)}@${m.createdAt ? new Date(m.createdAt).toISOString() : "none"}`).join(",")}`
4013
+ `[OM:bufferInput] cycleId=${cycleId}, msgCount=${messagesToBuffer.length}, msgTokens=${tokensToBuffer}, ids=${messagesToBuffer.map((m) => `${m.id?.slice(0, 8)}@${m.createdAt ? new Date(m.createdAt).toISOString() : "none"}`).join(",")}`
3987
4014
  );
3988
4015
  await this.doAsyncBufferedObservation(
3989
4016
  freshRecord,
@@ -4150,6 +4177,22 @@ ${bufferedObservations}`;
4150
4177
  const bufferActivation = this.observationConfig.bufferActivation ?? 0.7;
4151
4178
  const activationRatio = this.resolveActivationRatio(bufferActivation, messageTokensThreshold);
4152
4179
  const forceMaxActivation = !!(this.observationConfig.blockAfter && effectivePendingTokens >= this.observationConfig.blockAfter);
4180
+ const bufferTokens = this.observationConfig.bufferTokens ?? 0;
4181
+ const retentionFloor = this.resolveRetentionFloor(bufferActivation, messageTokensThreshold);
4182
+ const projectedMessageRemoval = this.calculateProjectedMessageRemoval(
4183
+ freshChunks,
4184
+ bufferActivation,
4185
+ messageTokensThreshold,
4186
+ effectivePendingTokens
4187
+ );
4188
+ const projectedRemaining = Math.max(0, effectivePendingTokens - projectedMessageRemoval);
4189
+ const maxRemaining = retentionFloor + bufferTokens;
4190
+ if (!forceMaxActivation && bufferTokens > 0 && projectedRemaining > maxRemaining) {
4191
+ omDebug(
4192
+ `[OM:tryActivate] skipping activation: projectedRemaining=${projectedRemaining} > maxRemaining=${maxRemaining} (retentionFloor=${retentionFloor}, bufferTokens=${bufferTokens})`
4193
+ );
4194
+ return { success: false };
4195
+ }
4153
4196
  omDebug(
4154
4197
  `[OM:tryActivate] swapping: freshChunks=${freshChunks.length}, bufferActivation=${bufferActivation}, activationRatio=${activationRatio}, forceMax=${forceMaxActivation}, totalChunkTokens=${freshChunks.reduce((s, c) => s + (c.tokenCount ?? 0), 0)}`
4155
4198
  );
@@ -5085,5 +5128,5 @@ exports.formatMessagesForObserver = formatMessagesForObserver;
5085
5128
  exports.hasCurrentTaskSection = hasCurrentTaskSection;
5086
5129
  exports.optimizeObservationsForContext = optimizeObservationsForContext;
5087
5130
  exports.parseObserverOutput = parseObserverOutput;
5088
- //# sourceMappingURL=chunk-6XVTMLW4.cjs.map
5089
- //# sourceMappingURL=chunk-6XVTMLW4.cjs.map
5131
+ //# sourceMappingURL=chunk-PVFLHAZX.cjs.map
5132
+ //# sourceMappingURL=chunk-PVFLHAZX.cjs.map