@mastra/memory 1.15.1-alpha.1 → 1.16.0-alpha.0

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 (35) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/{chunk-OUMWCVQI.cjs → chunk-3NECGYWZ.cjs} +121 -16
  3. package/dist/chunk-3NECGYWZ.cjs.map +1 -0
  4. package/dist/{chunk-HAEQMUD4.js → chunk-HB6AYAFD.js} +121 -16
  5. package/dist/chunk-HB6AYAFD.js.map +1 -0
  6. package/dist/docs/SKILL.md +1 -1
  7. package/dist/docs/assets/SOURCE_MAP.json +47 -47
  8. package/dist/docs/references/docs-memory-message-history.md +6 -0
  9. package/dist/docs/references/docs-memory-observational-memory.md +29 -7
  10. package/dist/docs/references/reference-memory-observational-memory.md +2 -0
  11. package/dist/index.cjs +15 -14
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +6 -5
  16. package/dist/index.js.map +1 -1
  17. package/dist/{observational-memory-H74M5SB6.js → observational-memory-WWAB2MMI.js} +3 -3
  18. package/dist/{observational-memory-H74M5SB6.js.map → observational-memory-WWAB2MMI.js.map} +1 -1
  19. package/dist/{observational-memory-TKXRH2LD.cjs → observational-memory-X4N2R4CA.cjs} +26 -26
  20. package/dist/{observational-memory-TKXRH2LD.cjs.map → observational-memory-X4N2R4CA.cjs.map} +1 -1
  21. package/dist/processors/index.cjs +24 -24
  22. package/dist/processors/index.js +1 -1
  23. package/dist/processors/observational-memory/markers.d.ts +3 -0
  24. package/dist/processors/observational-memory/markers.d.ts.map +1 -1
  25. package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
  26. package/dist/processors/observational-memory/observational-memory.d.ts +6 -0
  27. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  28. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  29. package/dist/processors/observational-memory/reflector-runner.d.ts +1 -0
  30. package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
  31. package/dist/processors/observational-memory/types.d.ts +19 -0
  32. package/dist/processors/observational-memory/types.d.ts.map +1 -1
  33. package/package.json +8 -8
  34. package/dist/chunk-HAEQMUD4.js.map +0 -1
  35. package/dist/chunk-OUMWCVQI.cjs.map +0 -1
@@ -484,7 +484,10 @@ function createActivationMarker(params) {
484
484
  threadId: params.threadId,
485
485
  generationCount: params.generationCount,
486
486
  config: params.config,
487
- observations: params.observations
487
+ observations: params.observations,
488
+ triggeredBy: params.triggeredBy,
489
+ lastActivityAt: params.lastActivityAt,
490
+ ttlExpiredMs: params.ttlExpiredMs
488
491
  }
489
492
  };
490
493
  }
@@ -934,6 +937,8 @@ var ObservationStrategy = class _ObservationStrategy {
934
937
  this.scope = deps.scope;
935
938
  this.retrieval = deps.retrieval;
936
939
  }
940
+ deps;
941
+ opts;
937
942
  storage;
938
943
  messageHistory;
939
944
  tokenCounter;
@@ -1940,6 +1945,8 @@ var ObservationStep = class {
1940
1945
  this.turn = turn;
1941
1946
  this.stepNumber = stepNumber;
1942
1947
  }
1948
+ turn;
1949
+ stepNumber;
1943
1950
  _prepared = false;
1944
1951
  _context;
1945
1952
  /** Whether this step has been prepared. */
@@ -1999,7 +2006,8 @@ var ObservationStep = class {
1999
2006
  threadId,
2000
2007
  writer: this.turn.writer,
2001
2008
  requestContext: this.turn.requestContext,
2002
- observabilityContext: this.turn.observabilityContext
2009
+ observabilityContext: this.turn.observabilityContext,
2010
+ lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
2003
2011
  });
2004
2012
  await this.turn.refreshRecord();
2005
2013
  if (this.turn.record.generationCount > preReflectGeneration) {
@@ -2175,7 +2183,8 @@ var ObservationStep = class {
2175
2183
  writer: this.turn.writer,
2176
2184
  messageList,
2177
2185
  requestContext: this.turn.requestContext,
2178
- observabilityContext: this.turn.observabilityContext
2186
+ observabilityContext: this.turn.observabilityContext,
2187
+ lastActivityAt: getLastActivityFromMessages(messageList.get.all.db())
2179
2188
  });
2180
2189
  return {
2181
2190
  succeeded: true,
@@ -4130,7 +4139,8 @@ var ReflectorRunner = class {
4130
4139
  observationTokens: getMaxThreshold(
4131
4140
  record ? this.getEffectiveReflectionTokens(record) : this.reflectionConfig.observationTokens
4132
4141
  ),
4133
- scope: this.scope
4142
+ scope: this.scope,
4143
+ activateAfterIdle: this.reflectionConfig.activateAfterIdle
4134
4144
  };
4135
4145
  }
4136
4146
  /**
@@ -4416,7 +4426,7 @@ var ReflectorRunner = class {
4416
4426
  * Try to activate buffered reflection when threshold is reached.
4417
4427
  * Returns true if activation succeeded.
4418
4428
  */
4419
- async tryActivateBufferedReflection(record, lockKey, writer, messageList) {
4429
+ async tryActivateBufferedReflection(record, lockKey, writer, messageList, activationMetadata) {
4420
4430
  const bufferKey = this.buffering.getReflectionBufferKey(lockKey);
4421
4431
  const asyncOp = BufferingCoordinator.asyncBufferingOps.get(bufferKey);
4422
4432
  if (asyncOp) {
@@ -4476,6 +4486,9 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4476
4486
  threadId: freshRecord.threadId ?? "",
4477
4487
  generationCount: afterRecord?.generationCount ?? freshRecord.generationCount ?? 0,
4478
4488
  observations: afterRecord?.activeObservations,
4489
+ triggeredBy: activationMetadata?.triggeredBy,
4490
+ lastActivityAt: activationMetadata?.lastActivityAt,
4491
+ ttlExpiredMs: activationMetadata?.ttlExpiredMs,
4479
4492
  config: this.getObservationMarkerConfig(freshRecord)
4480
4493
  });
4481
4494
  void writer.custom(activationMarker).catch(() => {
@@ -4504,7 +4517,9 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4504
4517
  messageList,
4505
4518
  reflectionHooks,
4506
4519
  requestContext,
4507
- observabilityContext
4520
+ observabilityContext,
4521
+ lastActivityAt,
4522
+ threadId: requestedThreadId
4508
4523
  } = opts;
4509
4524
  const lockKey = this.buffering.getLockKey(record.threadId, record.resourceId);
4510
4525
  const reflectThreshold = getMaxThreshold(this.getEffectiveReflectionTokens(record));
@@ -4536,9 +4551,17 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4536
4551
  );
4537
4552
  }
4538
4553
  }
4539
- if (observationTokens < reflectThreshold) {
4554
+ const activateAfterIdle = this.reflectionConfig.activateAfterIdle;
4555
+ const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
4556
+ const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
4557
+ if (observationTokens < reflectThreshold && !ttlExpired) {
4540
4558
  return;
4541
4559
  }
4560
+ const activationMetadata = {
4561
+ triggeredBy: ttlExpired ? "ttl" : "threshold",
4562
+ lastActivityAt: ttlExpired ? lastActivityAt : void 0,
4563
+ ttlExpiredMs: ttlExpired ? ttlExpiredMs : void 0
4564
+ };
4542
4565
  if (record.isReflecting) {
4543
4566
  if (isOpActiveInProcess(record.id, "reflecting")) {
4544
4567
  omDebug(`[OM:reflect] isReflecting=true and active in this process, skipping`);
@@ -4548,7 +4571,13 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4548
4571
  await this.storage.setReflectingFlag(record.id, false);
4549
4572
  }
4550
4573
  if (this.buffering.isAsyncReflectionEnabled()) {
4551
- const activationSuccess = await this.tryActivateBufferedReflection(record, lockKey, writer, messageList);
4574
+ const activationSuccess = await this.tryActivateBufferedReflection(
4575
+ record,
4576
+ lockKey,
4577
+ writer,
4578
+ messageList,
4579
+ activationMetadata
4580
+ );
4552
4581
  if (activationSuccess) {
4553
4582
  return;
4554
4583
  }
@@ -4577,7 +4606,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4577
4606
  registerOp(record.id, "reflecting");
4578
4607
  const cycleId = crypto.randomUUID();
4579
4608
  const startedAt = (/* @__PURE__ */ new Date()).toISOString();
4580
- const threadId = opts.threadId ?? "unknown";
4609
+ const threadId = requestedThreadId ?? "unknown";
4581
4610
  if (writer) {
4582
4611
  const startMarker = createObservationStartMarker({
4583
4612
  cycleId,
@@ -6227,6 +6256,58 @@ function buildMessageRange(messages) {
6227
6256
  const last = [...messages].reverse().find(messageHasVisibleContent) ?? messages[messages.length - 1];
6228
6257
  return `${first.id}:${last.id}`;
6229
6258
  }
6259
+ function getLastActivityFromMessages(messages) {
6260
+ if (!messages) return void 0;
6261
+ for (let i = messages.length - 1; i >= 0; i--) {
6262
+ const message = messages[i];
6263
+ if (!message || message.role !== "assistant") {
6264
+ continue;
6265
+ }
6266
+ if (!message.content || typeof message.content === "string") {
6267
+ return message.createdAt ? new Date(message.createdAt).getTime() : void 0;
6268
+ }
6269
+ for (let j = message.content.parts.length - 1; j >= 0; j--) {
6270
+ const part = message.content.parts[j];
6271
+ if (!part || part.type?.startsWith("data-")) {
6272
+ continue;
6273
+ }
6274
+ if (part.createdAt !== void 0) {
6275
+ return part.createdAt;
6276
+ }
6277
+ }
6278
+ return message.createdAt ? new Date(message.createdAt).getTime() : void 0;
6279
+ }
6280
+ return void 0;
6281
+ }
6282
+ function parseActivationTTL(value, fieldPath) {
6283
+ if (value === void 0) {
6284
+ return void 0;
6285
+ }
6286
+ if (typeof value === "number") {
6287
+ if (!Number.isFinite(value) || value < 0) {
6288
+ throw new Error(`${fieldPath} must be a non-negative number of milliseconds or a duration string like "5m".`);
6289
+ }
6290
+ return value;
6291
+ }
6292
+ const trimmed = value.trim();
6293
+ const match = trimmed.match(
6294
+ /^(\d+(?:\.\d+)?)\s*(ms|msec|msecs|millisecond|milliseconds|s|sec|secs|second|seconds|m|min|mins|minute|minutes|h|hr|hrs|hour|hours)$/i
6295
+ );
6296
+ if (!match) {
6297
+ throw new Error(
6298
+ `${fieldPath} must be a non-negative number of milliseconds or a duration string like "5m" or "1hr".`
6299
+ );
6300
+ }
6301
+ const rawAmount = match[1];
6302
+ const rawUnit = match[2];
6303
+ const amount = Number(rawAmount);
6304
+ const unit = rawUnit.toLowerCase();
6305
+ if (!Number.isFinite(amount) || amount < 0) {
6306
+ throw new Error(`${fieldPath} must be a non-negative number of milliseconds or a duration string like "5m".`);
6307
+ }
6308
+ const multiplier = unit === "ms" || unit === "msec" || unit === "msecs" || unit === "millisecond" || unit === "milliseconds" ? 1 : unit === "s" || unit === "sec" || unit === "secs" || unit === "second" || unit === "seconds" ? 1e3 : unit === "m" || unit === "min" || unit === "mins" || unit === "minute" || unit === "minutes" ? 6e4 : 36e5;
6309
+ return amount * multiplier;
6310
+ }
6230
6311
  var ObservationalMemory = class _ObservationalMemory {
6231
6312
  storage;
6232
6313
  tokenCounter;
@@ -6373,6 +6454,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
6373
6454
  config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
6374
6455
  ),
6375
6456
  bufferActivation: asyncBufferingDisabled ? void 0 : config.observation?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferActivation,
6457
+ activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
6376
6458
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
6377
6459
  config.observation?.blockAfter ?? (config.observation?.bufferTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.bufferTokens ? 1.2 : void 0),
6378
6460
  config.observation?.messageTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.observation.messageTokens
@@ -6391,6 +6473,7 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
6391
6473
  },
6392
6474
  providerOptions: config.reflection?.providerOptions ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.providerOptions,
6393
6475
  bufferActivation: asyncBufferingDisabled ? void 0 : config?.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation,
6476
+ activateAfterIdle: parseActivationTTL(config.activateAfterIdle, "activateAfterIdle"),
6394
6477
  blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(
6395
6478
  config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation ? 1.2 : void 0),
6396
6479
  config.reflection?.observationTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens
@@ -6785,7 +6868,8 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
6785
6868
  return {
6786
6869
  messageTokens: getMaxThreshold(this.observationConfig.messageTokens),
6787
6870
  observationTokens: getMaxThreshold(this.reflectionConfig.observationTokens),
6788
- scope: this.scope
6871
+ scope: this.scope,
6872
+ activateAfterIdle: this.observationConfig.activateAfterIdle
6789
6873
  };
6790
6874
  }
6791
6875
  /**
@@ -8023,7 +8107,7 @@ ${grouped}` : grouped;
8023
8107
  await BufferingCoordinator.awaitBuffering(threadId, resourceId ?? null, this.scope);
8024
8108
  const preStatus = await this.getStatus({ threadId, resourceId, messages });
8025
8109
  if (preStatus.canActivate) {
8026
- const actResult = await this.activate({ threadId, resourceId });
8110
+ const actResult = await this.activate({ threadId, resourceId, messages });
8027
8111
  activated = actResult.activated;
8028
8112
  }
8029
8113
  const postStatus = await this.getStatus({ threadId, resourceId, messages });
@@ -8283,10 +8367,28 @@ ${grouped}` : grouped;
8283
8367
  if (!chunks.length) {
8284
8368
  return { activated: false, record };
8285
8369
  }
8370
+ let activationTriggeredBy = "threshold";
8371
+ let activationLastActivityAt;
8372
+ let activateAfterIdleExpiredMs;
8286
8373
  if (opts.checkThreshold) {
8287
- const status = await this.getStatus({ threadId, resourceId, messages: opts.messages });
8288
- if (status.pendingTokens < status.threshold) {
8289
- return { activated: false, record };
8374
+ const thresholdMessages = opts.messages ?? await this.loadMessagesFromStorage(
8375
+ threadId,
8376
+ resourceId,
8377
+ record.lastObservedAt ? new Date(record.lastObservedAt) : void 0
8378
+ );
8379
+ const activateAfterIdle = this.observationConfig.activateAfterIdle;
8380
+ const lastActivityAt = getLastActivityFromMessages(thresholdMessages);
8381
+ const ttlExpiredMs = activateAfterIdle !== void 0 && lastActivityAt !== void 0 ? Date.now() - lastActivityAt : void 0;
8382
+ const ttlExpired = ttlExpiredMs !== void 0 && activateAfterIdle !== void 0 && ttlExpiredMs >= activateAfterIdle;
8383
+ if (ttlExpired) {
8384
+ activationTriggeredBy = "ttl";
8385
+ activationLastActivityAt = lastActivityAt;
8386
+ activateAfterIdleExpiredMs = ttlExpiredMs;
8387
+ } else {
8388
+ const status = await this.getStatus({ threadId, resourceId, messages: thresholdMessages });
8389
+ if (status.pendingTokens < status.threshold) {
8390
+ return { activated: false, record };
8391
+ }
8290
8392
  }
8291
8393
  }
8292
8394
  if (record.isBufferingObservation) {
@@ -8344,6 +8446,9 @@ ${grouped}` : grouped;
8344
8446
  threadId: postSwapRecord.threadId ?? record.threadId ?? "",
8345
8447
  generationCount: postSwapRecord.generationCount ?? 0,
8346
8448
  observations: chunkData?.observations ?? activationResult.observations,
8449
+ triggeredBy: activationTriggeredBy,
8450
+ lastActivityAt: activationLastActivityAt,
8451
+ ttlExpiredMs: activateAfterIdleExpiredMs,
8347
8452
  config: this.getObservationMarkerConfig()
8348
8453
  });
8349
8454
  void opts.writer.custom(activationMarker).catch(() => {
@@ -8834,5 +8939,5 @@ function getObservationsAsOf(activeObservations, asOf) {
8834
8939
  }
8835
8940
 
8836
8941
  export { ModelByInputTokens, OBSERVER_SYSTEM_PROMPT, ObservationalMemory, ObservationalMemoryProcessor, TokenCounter, buildObserverPrompt, buildObserverSystemPrompt, combineObservationGroupRanges, deriveObservationGroupProvenance, extractCurrentTask, formatMessagesForObserver, formatToolResultForObserver, getObservationsAsOf, hasCurrentTaskSection, injectAnchorIds, optimizeObservationsForContext, parseAnchorId, parseObservationGroups, parseObserverOutput, reconcileObservationGroupsFromReflection, renderObservationGroupsForReflection, resolveToolResultValue, stripEphemeralAnchorIds, stripObservationGroups, truncateStringByTokens, wrapInObservationGroup };
8837
- //# sourceMappingURL=chunk-HAEQMUD4.js.map
8838
- //# sourceMappingURL=chunk-HAEQMUD4.js.map
8942
+ //# sourceMappingURL=chunk-HB6AYAFD.js.map
8943
+ //# sourceMappingURL=chunk-HB6AYAFD.js.map