@mastra/memory 1.13.2-alpha.0 → 1.14.0-alpha.1

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 +38 -0
  2. package/dist/{chunk-C7PARRAD.js → chunk-FQGF36BE.js} +39 -18
  3. package/dist/chunk-FQGF36BE.js.map +1 -0
  4. package/dist/{chunk-4FMHSWZD.cjs → chunk-X7E3WPF2.cjs} +39 -18
  5. package/dist/chunk-X7E3WPF2.cjs.map +1 -0
  6. package/dist/docs/SKILL.md +1 -1
  7. package/dist/docs/assets/SOURCE_MAP.json +29 -29
  8. package/dist/index.cjs +12 -12
  9. package/dist/index.js +4 -4
  10. package/dist/{observational-memory-5YDQLKHE.cjs → observational-memory-22RZ4253.cjs} +26 -26
  11. package/dist/{observational-memory-5YDQLKHE.cjs.map → observational-memory-22RZ4253.cjs.map} +1 -1
  12. package/dist/{observational-memory-B7AUSTEY.js → observational-memory-JQ34KLFS.js} +3 -3
  13. package/dist/{observational-memory-B7AUSTEY.js.map → observational-memory-JQ34KLFS.js.map} +1 -1
  14. package/dist/processors/index.cjs +24 -24
  15. package/dist/processors/index.js +1 -1
  16. package/dist/processors/observational-memory/index.d.ts +1 -1
  17. package/dist/processors/observational-memory/index.d.ts.map +1 -1
  18. package/dist/processors/observational-memory/observation-strategies/base.d.ts +3 -3
  19. package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -1
  20. package/dist/processors/observational-memory/observation-strategies/types.d.ts +9 -0
  21. package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
  22. package/dist/processors/observational-memory/observational-memory.d.ts +4 -3
  23. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  24. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  25. package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
  26. package/dist/processors/observational-memory/types.d.ts +13 -2
  27. package/dist/processors/observational-memory/types.d.ts.map +1 -1
  28. package/package.json +4 -4
  29. package/dist/chunk-4FMHSWZD.cjs.map +0 -1
  30. package/dist/chunk-C7PARRAD.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @mastra/memory
2
2
 
3
+ ## 1.14.0-alpha.1
4
+
5
+ ### Minor Changes
6
+
7
+ - Added usage data to ObserveHooks callbacks and standalone reflect() return. ([#15047](https://github.com/mastra-ai/mastra/pull/15047))
8
+
9
+ **ObserveHooks:** `onObservationEnd` and `onReflectionEnd` now receive a result object containing token usage from the underlying LLM call. This enables reliable usage tracking across all observation and reflection paths (sync, async buffered, and resource-scoped).
10
+
11
+ **Standalone reflect():** `reflect()` now returns `{ reflected, record, usage? }` so callers can capture token usage without hooks.
12
+
13
+ **Examples**
14
+
15
+ ```ts
16
+ // Via hooks
17
+ await memory.observe({
18
+ threadId,
19
+ messages,
20
+ hooks: {
21
+ onObservationEnd: ({ usage }) => {
22
+ // usage: { inputTokens, outputTokens, totalTokens }
23
+ },
24
+ onReflectionEnd: ({ usage }) => {
25
+ // usage: { inputTokens, outputTokens, totalTokens }
26
+ },
27
+ },
28
+ });
29
+
30
+ // Via standalone reflect()
31
+ const { reflected, usage } = await memory.reflect(threadId, resourceId);
32
+ ```
33
+
34
+ Existing callbacks that accept no arguments continue to work without changes.
35
+
36
+ ### Patch Changes
37
+
38
+ - Updated dependencies [[`fff91cf`](https://github.com/mastra-ai/mastra/commit/fff91cf914de0e731578aacebffdeebef82f0440)]:
39
+ - @mastra/core@1.23.0-alpha.4
40
+
3
41
  ## 1.13.2-alpha.0
4
42
 
5
43
  ### Patch Changes
@@ -945,7 +945,7 @@ var ObservationStrategy = class _ObservationStrategy {
945
945
  static create;
946
946
  /**
947
947
  * Run the full observation lifecycle.
948
- * @returns `true` if a full observation cycle completed; `false` if skipped (stale lock) or async-buffer failure was swallowed.
948
+ * @returns Result with `observed` flag and optional `usage` from the observer LLM call.
949
949
  * @throws On sync/resource-scoped observer failure after failed markers (same as pre–Option-A contract).
950
950
  */
951
951
  async run() {
@@ -955,7 +955,7 @@ var ObservationStrategy = class _ObservationStrategy {
955
955
  if (this.needsLock) {
956
956
  const fresh = await this.storage.getObservationalMemory(record.threadId, record.resourceId);
957
957
  if (fresh?.lastObservedAt && record.lastObservedAt && fresh.lastObservedAt > record.lastObservedAt) {
958
- return false;
958
+ return { observed: false };
959
959
  }
960
960
  }
961
961
  const { messages, existingObservations } = await this.prepare();
@@ -976,7 +976,7 @@ var ObservationStrategy = class _ObservationStrategy {
976
976
  observabilityContext: this.opts.observabilityContext
977
977
  });
978
978
  }
979
- return true;
979
+ return { observed: true, usage: output.usage };
980
980
  } catch (error) {
981
981
  await this.emitFailedMarkers(cycleId, error);
982
982
  if (!this.rethrowOnFailure) {
@@ -995,7 +995,7 @@ var ObservationStrategy = class _ObservationStrategy {
995
995
  });
996
996
  if (abortSignal?.aborted) throw error;
997
997
  omError("[OM] Observation failed", error);
998
- return false;
998
+ return { observed: false };
999
999
  }
1000
1000
  omError("[OM] Observation failed", error);
1001
1001
  throw error;
@@ -4193,7 +4193,7 @@ var ReflectorRunner = class {
4193
4193
  /**
4194
4194
  * Start an async buffered reflection in the background.
4195
4195
  */
4196
- startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext) {
4196
+ startAsyncBufferedReflection(record, observationTokens, lockKey, writer, requestContext, observabilityContext, reflectionHooks) {
4197
4197
  const bufferKey = this.buffering.getReflectionBufferKey(lockKey);
4198
4198
  if (this.buffering.isAsyncBufferingInProgress(bufferKey)) {
4199
4199
  return;
@@ -4203,7 +4203,10 @@ var ReflectorRunner = class {
4203
4203
  this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
4204
4204
  omError("[OM] Failed to set buffering reflection flag", err);
4205
4205
  });
4206
- const asyncOp = this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext).catch(async (error) => {
4206
+ reflectionHooks?.onReflectionStart?.();
4207
+ const asyncOp = this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext).then((usage) => {
4208
+ reflectionHooks?.onReflectionEnd?.({ usage });
4209
+ }).catch(async (error) => {
4207
4210
  if (writer) {
4208
4211
  const failedMarker = createBufferingFailedMarker({
4209
4212
  cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
@@ -4219,6 +4222,10 @@ var ReflectorRunner = class {
4219
4222
  await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
4220
4223
  }
4221
4224
  omError("[OM] Async buffered reflection failed", error);
4225
+ reflectionHooks?.onReflectionEnd?.({
4226
+ usage: void 0,
4227
+ error: error instanceof Error ? error : new Error(String(error))
4228
+ });
4222
4229
  BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
4223
4230
  }).finally(() => {
4224
4231
  BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
@@ -4312,6 +4319,7 @@ var ReflectorRunner = class {
4312
4319
  });
4313
4320
  await this.persistMarkerToStorage(endMarker, currentRecord.threadId ?? "", currentRecord.resourceId ?? void 0);
4314
4321
  }
4322
+ return reflectResult.usage;
4315
4323
  }
4316
4324
  /**
4317
4325
  * Try to activate buffered reflection when threshold is reached.
@@ -4432,7 +4440,8 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4432
4440
  lockKey,
4433
4441
  writer,
4434
4442
  requestContext,
4435
- observabilityContext
4443
+ observabilityContext,
4444
+ reflectionHooks
4436
4445
  );
4437
4446
  }
4438
4447
  }
@@ -4466,7 +4475,8 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4466
4475
  lockKey,
4467
4476
  writer,
4468
4477
  requestContext,
4469
- observabilityContext
4478
+ observabilityContext,
4479
+ reflectionHooks
4470
4480
  );
4471
4481
  return;
4472
4482
  }
@@ -4505,6 +4515,8 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4505
4515
  recordId: record.id,
4506
4516
  threadId
4507
4517
  } : void 0;
4518
+ let reflectionUsage;
4519
+ let reflectionError;
4508
4520
  try {
4509
4521
  const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
4510
4522
  const reflectResult = await this.call(
@@ -4518,6 +4530,7 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4518
4530
  requestContext,
4519
4531
  observabilityContext
4520
4532
  );
4533
+ reflectionUsage = reflectResult.usage;
4521
4534
  const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);
4522
4535
  await this.storage.createReflectionGeneration({
4523
4536
  currentRecord: record,
@@ -4562,13 +4575,14 @@ ${unreflectedContent}` : freshRecord.bufferedReflection;
4562
4575
  await writer.custom(failedMarker).catch(() => {
4563
4576
  });
4564
4577
  }
4578
+ reflectionError = error instanceof Error ? error : new Error(String(error));
4565
4579
  if (abortSignal?.aborted) {
4566
4580
  throw error;
4567
4581
  }
4568
4582
  omError("[OM] Reflection failed", error);
4569
4583
  } finally {
4570
4584
  await this.storage.setReflectingFlag(record.id, false);
4571
- reflectionHooks?.onReflectionEnd?.();
4585
+ reflectionHooks?.onReflectionEnd?.({ usage: reflectionUsage, error: reflectionError });
4572
4586
  unregisterOp(record.id, "reflecting");
4573
4587
  }
4574
4588
  }
@@ -7913,6 +7927,7 @@ ${grouped}` : grouped;
7913
7927
  const lockKey = this.buffering.getLockKey(threadId, resourceId);
7914
7928
  const reflectionHooks = hooks ? { onReflectionStart: hooks.onReflectionStart, onReflectionEnd: hooks.onReflectionEnd } : void 0;
7915
7929
  let observed = false;
7930
+ let observationUsage;
7916
7931
  let generationBefore = -1;
7917
7932
  await this.withLock(lockKey, async () => {
7918
7933
  const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
@@ -7929,8 +7944,9 @@ ${grouped}` : grouped;
7929
7944
  return;
7930
7945
  }
7931
7946
  hooks?.onObservationStart?.();
7947
+ let observationError;
7932
7948
  try {
7933
- observed = await ObservationStrategy.create(this, {
7949
+ const result = await ObservationStrategy.create(this, {
7934
7950
  record: freshRecord,
7935
7951
  threadId,
7936
7952
  resourceId,
@@ -7940,8 +7956,13 @@ ${grouped}` : grouped;
7940
7956
  writer: opts.writer,
7941
7957
  observabilityContext: opts.observabilityContext
7942
7958
  }).run();
7959
+ observed = result.observed;
7960
+ observationUsage = result.usage;
7961
+ } catch (error) {
7962
+ observationError = error instanceof Error ? error : new Error(String(error));
7963
+ throw error;
7943
7964
  } finally {
7944
- hooks?.onObservationEnd?.();
7965
+ hooks?.onObservationEnd?.({ usage: observationUsage, error: observationError });
7945
7966
  }
7946
7967
  });
7947
7968
  const record = await this.getOrCreateRecord(threadId, resourceId);
@@ -7962,7 +7983,7 @@ ${grouped}` : grouped;
7962
7983
  async reflect(threadId, resourceId, prompt, requestContext, observabilityContext) {
7963
7984
  const record = await this.getOrCreateRecord(threadId, resourceId);
7964
7985
  if (!record.activeObservations) {
7965
- return { reflected: false, record };
7986
+ return { reflected: false, record, usage: void 0 };
7966
7987
  }
7967
7988
  await this.storage.setReflectingFlag(record.id, true);
7968
7989
  registerOp(record.id, "reflecting");
@@ -7987,11 +8008,11 @@ ${grouped}` : grouped;
7987
8008
  tokenCount: reflectionTokenCount
7988
8009
  });
7989
8010
  const updatedRecord = await this.getOrCreateRecord(threadId, resourceId);
7990
- return { reflected: true, record: updatedRecord };
8011
+ return { reflected: true, record: updatedRecord, usage: reflectResult.usage };
7991
8012
  } catch (error) {
7992
8013
  omError("[OM] reflect() failed", error);
7993
8014
  const latestRecord = await this.getOrCreateRecord(threadId, resourceId);
7994
- return { reflected: false, record: latestRecord };
8015
+ return { reflected: false, record: latestRecord, usage: void 0 };
7995
8016
  } finally {
7996
8017
  await this.storage.setReflectingFlag(record.id, false);
7997
8018
  unregisterOp(record.id, "reflecting");
@@ -8015,9 +8036,9 @@ ${grouped}` : grouped;
8015
8036
  /**
8016
8037
  * Get observation history (previous generations)
8017
8038
  */
8018
- async getHistory(threadId, resourceId, limit) {
8039
+ async getHistory(threadId, resourceId, limit, options) {
8019
8040
  const ids = this.getStorageIds(threadId, resourceId);
8020
- return this.storage.getObservationalMemoryHistory(ids.threadId, ids.resourceId, limit);
8041
+ return this.storage.getObservationalMemoryHistory(ids.threadId, ids.resourceId, limit, options);
8021
8042
  }
8022
8043
  /**
8023
8044
  * Clear all memory for a specific thread/resource
@@ -8563,5 +8584,5 @@ function getObservationsAsOf(activeObservations, asOf) {
8563
8584
  }
8564
8585
 
8565
8586
  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 };
8566
- //# sourceMappingURL=chunk-C7PARRAD.js.map
8567
- //# sourceMappingURL=chunk-C7PARRAD.js.map
8587
+ //# sourceMappingURL=chunk-FQGF36BE.js.map
8588
+ //# sourceMappingURL=chunk-FQGF36BE.js.map