@mastra/memory 1.10.1-alpha.1 → 1.10.1-alpha.3

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 +22 -0
  2. package/dist/{chunk-NS47X3OB.cjs → chunk-DTAZSLVU.cjs} +214 -79
  3. package/dist/chunk-DTAZSLVU.cjs.map +1 -0
  4. package/dist/{chunk-2QSOQQPM.js → chunk-SKRONGCV.js} +214 -79
  5. package/dist/chunk-SKRONGCV.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/index.cjs +11 -11
  9. package/dist/index.js +4 -4
  10. package/dist/{observational-memory-WMCWT577.js → observational-memory-UGDENJPE.js} +3 -3
  11. package/dist/{observational-memory-WMCWT577.js.map → observational-memory-UGDENJPE.js.map} +1 -1
  12. package/dist/{observational-memory-I5UTOG63.cjs → observational-memory-XIZTJN3S.cjs} +26 -26
  13. package/dist/{observational-memory-I5UTOG63.cjs.map → observational-memory-XIZTJN3S.cjs.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/observation-turn/index.d.ts +1 -1
  17. package/dist/processors/observational-memory/observation-turn/index.d.ts.map +1 -1
  18. package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
  19. package/dist/processors/observational-memory/observation-turn/turn.d.ts +15 -7
  20. package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
  21. package/dist/processors/observational-memory/observation-turn/types.d.ts +4 -0
  22. package/dist/processors/observational-memory/observation-turn/types.d.ts.map +1 -1
  23. package/dist/processors/observational-memory/observational-memory.d.ts +2 -0
  24. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  25. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  26. package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -1
  27. package/package.json +2 -2
  28. package/dist/chunk-2QSOQQPM.js.map +0 -1
  29. package/dist/chunk-NS47X3OB.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @mastra/memory
2
2
 
3
+ ## 1.10.1-alpha.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed OM repro capture so recordings keep writing usable artifacts even when live state contains circular values. ([#14744](https://github.com/mastra-ai/mastra/pull/14744))
8
+
9
+ - Fixed observational memory response ID rotation at buffered chunk boundaries so assistant output continues in a fresh message slot. ([#14745](https://github.com/mastra-ai/mastra/pull/14745))
10
+
11
+ - Updated dependencies [[`dc9fc19`](https://github.com/mastra-ai/mastra/commit/dc9fc19da4437f6b508cc355f346a8856746a76b), [`260fe12`](https://github.com/mastra-ai/mastra/commit/260fe1295fe7354e39d6def2775e0797a7a277f0)]:
12
+ - @mastra/core@1.18.0-alpha.1
13
+
14
+ ## 1.10.1-alpha.2
15
+
16
+ ### Patch Changes
17
+
18
+ - The internal architecture of observational memory has been refactored. The public API and behavior remain unchanged. ([#14453](https://github.com/mastra-ai/mastra/pull/14453))
19
+
20
+ - Improved observational memory continuation prompts to reduce leaked context-management language in long conversations. ([#14650](https://github.com/mastra-ai/mastra/pull/14650))
21
+
22
+ - Updated dependencies [[`dc514a8`](https://github.com/mastra-ai/mastra/commit/dc514a83dba5f719172dddfd2c7b858e4943d067), [`404fea1`](https://github.com/mastra-ai/mastra/commit/404fea13042181f0b0c73a101392ac87c79ceae2), [`ebf5047`](https://github.com/mastra-ai/mastra/commit/ebf5047e825c38a1a356f10b214c1d4260dfcd8d), [`675f15b`](https://github.com/mastra-ai/mastra/commit/675f15b7eaeea649158d228ea635be40480c584d), [`b174c63`](https://github.com/mastra-ai/mastra/commit/b174c63a093108d4e53b9bc89a078d9f66202b3f), [`eef7cb2`](https://github.com/mastra-ai/mastra/commit/eef7cb2abe7ef15951e2fdf792a5095c6c643333), [`e8a5b0b`](https://github.com/mastra-ai/mastra/commit/e8a5b0b9bc94d12dee4150095512ca27a288d778)]:
23
+ - @mastra/core@1.18.0-alpha.0
24
+
3
25
  ## 1.10.1-alpha.1
4
26
 
5
27
  ### Patch Changes
@@ -13,6 +13,7 @@ var tokenx = require('tokenx');
13
13
  var agent = require('@mastra/core/agent');
14
14
  var async_hooks = require('async_hooks');
15
15
  var imageSize = require('image-size');
16
+ var util = require('util');
16
17
 
17
18
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
19
 
@@ -1946,7 +1947,17 @@ var ObservationStep = class {
1946
1947
  writer: this.turn.writer,
1947
1948
  requestContext: this.turn.requestContext,
1948
1949
  beforeBuffer: async (candidates) => {
1950
+ if (candidates.length === 0) {
1951
+ return;
1952
+ }
1949
1953
  om.sealMessagesForBuffering(candidates);
1954
+ try {
1955
+ await this.turn.hooks?.onBufferChunkSealed?.();
1956
+ } catch (error) {
1957
+ omDebug(
1958
+ `[OM:buffer] onBufferChunkSealed hook failed: ${error instanceof Error ? error.message : String(error)}`
1959
+ );
1960
+ }
1950
1961
  if (this.turn.memory) {
1951
1962
  await this.turn.memory.persistMessages(candidates);
1952
1963
  }
@@ -2093,12 +2104,6 @@ var ObservationStep = class {
2093
2104
 
2094
2105
  // src/processors/observational-memory/observation-turn/turn.ts
2095
2106
  var ObservationTurn = class {
2096
- constructor(om, threadId, resourceId, messageList) {
2097
- this.om = om;
2098
- this.threadId = threadId;
2099
- this.resourceId = resourceId;
2100
- this.messageList = messageList;
2101
- }
2102
2107
  _record;
2103
2108
  _context;
2104
2109
  _currentStep;
@@ -2112,6 +2117,19 @@ var ObservationTurn = class {
2112
2117
  writer;
2113
2118
  /** Optional request context for observation calls. */
2114
2119
  requestContext;
2120
+ /** Optional processor-provided hooks for turn/step lifecycle integration. */
2121
+ hooks;
2122
+ constructor(opts) {
2123
+ this.om = opts.om;
2124
+ this.threadId = opts.threadId;
2125
+ this.resourceId = opts.resourceId;
2126
+ this.messageList = opts.messageList;
2127
+ this.hooks = opts.hooks;
2128
+ }
2129
+ om;
2130
+ threadId;
2131
+ resourceId;
2132
+ messageList;
2115
2133
  /** The current cached record. Refreshed after mutations (activate/observe/reflect). */
2116
2134
  get record() {
2117
2135
  if (!this._record) throw new Error("Turn not started \u2014 call start() first");
@@ -2174,7 +2192,7 @@ var ObservationTurn = class {
2174
2192
  return this._currentStep;
2175
2193
  }
2176
2194
  /**
2177
- * Finalize the turn: save any remaining messages, await in-flight buffering, return final state.
2195
+ * Finalize the turn: save any remaining messages and return the latest record state.
2178
2196
  */
2179
2197
  async end() {
2180
2198
  if (this._ended) throw new Error("Turn already ended");
@@ -2185,22 +2203,6 @@ var ObservationTurn = class {
2185
2203
  if (unsavedMessages.length > 0) {
2186
2204
  await this.om.persistMessages(unsavedMessages, this.threadId, this.resourceId);
2187
2205
  }
2188
- await this.om.waitForBuffering(this.threadId, this.resourceId);
2189
- const status = await this.om.getStatus({
2190
- threadId: this.threadId,
2191
- resourceId: this.resourceId,
2192
- messages: this.messageList.get.all.db()
2193
- });
2194
- if (status.shouldObserve) {
2195
- await this.om.observe({
2196
- threadId: this.threadId,
2197
- resourceId: this.resourceId,
2198
- messages: this.messageList.get.all.db(),
2199
- requestContext: this.requestContext,
2200
- writer: this.writer
2201
- });
2202
- }
2203
- await this.refreshRecord();
2204
2206
  return { record: this._record };
2205
2207
  }
2206
2208
  /**
@@ -7723,7 +7725,13 @@ ${grouped}` : grouped;
7723
7725
  * ```
7724
7726
  */
7725
7727
  beginTurn(opts) {
7726
- return new ObservationTurn(this, opts.threadId, opts.resourceId, opts.messageList);
7728
+ return new ObservationTurn({
7729
+ om: this,
7730
+ threadId: opts.threadId,
7731
+ resourceId: opts.resourceId,
7732
+ messageList: opts.messageList,
7733
+ hooks: opts.hooks
7734
+ });
7727
7735
  }
7728
7736
  };
7729
7737
  var OM_REPRO_CAPTURE_DIR = process.env.OM_REPRO_CAPTURE_DIR ?? ".mastra-om-repro";
@@ -7739,6 +7747,7 @@ function safeCaptureJson(value) {
7739
7747
  JSON.stringify(value, (_key, current) => {
7740
7748
  if (typeof current === "bigint") return current.toString();
7741
7749
  if (typeof current === "function") return "[function]";
7750
+ if (typeof current === "symbol") return current.toString();
7742
7751
  if (current instanceof Error) return { name: current.name, message: current.message, stack: current.stack };
7743
7752
  if (current instanceof Set) return { __type: "Set", values: Array.from(current.values()) };
7744
7753
  if (current instanceof Map) return { __type: "Map", entries: Array.from(current.entries()) };
@@ -7746,6 +7755,87 @@ function safeCaptureJson(value) {
7746
7755
  })
7747
7756
  );
7748
7757
  }
7758
+ function safeCaptureJsonOrError(value) {
7759
+ try {
7760
+ return { ok: true, value: safeCaptureJson(value) };
7761
+ } catch (error) {
7762
+ return {
7763
+ ok: false,
7764
+ error: safeCaptureJson({
7765
+ message: error instanceof Error ? error.message : String(error),
7766
+ stack: error instanceof Error ? error.stack : void 0,
7767
+ inspected: util.inspect(value, { depth: 3, maxArrayLength: 20, breakLength: 120 })
7768
+ })
7769
+ };
7770
+ }
7771
+ }
7772
+ function formatCaptureDate(value) {
7773
+ if (!value) return void 0;
7774
+ if (value instanceof Date) return value.toISOString();
7775
+ try {
7776
+ return new Date(value).toISOString();
7777
+ } catch {
7778
+ return void 0;
7779
+ }
7780
+ }
7781
+ function summarizeOmTurn(value) {
7782
+ if (!value || typeof value !== "object") {
7783
+ return value;
7784
+ }
7785
+ const turn = value;
7786
+ return {
7787
+ __type: "ObservationTurn",
7788
+ threadId: turn.threadId,
7789
+ resourceId: turn.resourceId,
7790
+ started: turn._started,
7791
+ ended: turn._ended,
7792
+ generationCountAtStart: turn._generationCountAtStart,
7793
+ record: turn._record ? {
7794
+ id: turn._record.id,
7795
+ scope: turn._record.scope,
7796
+ threadId: turn._record.threadId,
7797
+ resourceId: turn._record.resourceId,
7798
+ createdAt: formatCaptureDate(turn._record.createdAt),
7799
+ updatedAt: formatCaptureDate(turn._record.updatedAt),
7800
+ lastObservedAt: formatCaptureDate(turn._record.lastObservedAt),
7801
+ generationCount: turn._record.generationCount,
7802
+ observationTokenCount: turn._record.observationTokenCount,
7803
+ pendingMessageTokens: turn._record.pendingMessageTokens,
7804
+ isBufferingObservation: turn._record.isBufferingObservation,
7805
+ isBufferingReflection: turn._record.isBufferingReflection
7806
+ } : void 0,
7807
+ context: turn._context ? {
7808
+ messageCount: Array.isArray(turn._context.messages) ? turn._context.messages.length : void 0,
7809
+ hasSystemMessage: Array.isArray(turn._context.systemMessage) ? turn._context.systemMessage.length > 0 : Boolean(turn._context.systemMessage),
7810
+ continuationId: turn._context.continuation?.id,
7811
+ hasOtherThreadsContext: Boolean(turn._context.otherThreadsContext),
7812
+ recordId: turn._context.record?.id
7813
+ } : void 0,
7814
+ currentStep: turn._currentStep ? {
7815
+ stepNumber: turn._currentStep.stepNumber,
7816
+ prepared: turn._currentStep._prepared,
7817
+ context: turn._currentStep._context ? {
7818
+ activated: turn._currentStep._context.activated,
7819
+ observed: turn._currentStep._context.observed,
7820
+ buffered: turn._currentStep._context.buffered,
7821
+ reflected: turn._currentStep._context.reflected,
7822
+ didThresholdCleanup: turn._currentStep._context.didThresholdCleanup,
7823
+ messageCount: Array.isArray(turn._currentStep._context.messages) ? turn._currentStep._context.messages.length : void 0,
7824
+ systemMessageCount: Array.isArray(turn._currentStep._context.systemMessage) ? turn._currentStep._context.systemMessage.length : void 0
7825
+ } : void 0
7826
+ } : void 0
7827
+ };
7828
+ }
7829
+ function sanitizeCaptureState(rawState) {
7830
+ return Object.fromEntries(
7831
+ Object.entries(rawState).map(([key, value]) => {
7832
+ if (key === "__omTurn") {
7833
+ return [key, summarizeOmTurn(value)];
7834
+ }
7835
+ return [key, value];
7836
+ })
7837
+ );
7838
+ }
7749
7839
  function buildReproMessageFingerprint(message) {
7750
7840
  const createdAt = message.createdAt instanceof Date ? message.createdAt.toISOString() : message.createdAt ? new Date(message.createdAt).toISOString() : "";
7751
7841
  return JSON.stringify({
@@ -7801,60 +7891,88 @@ function writeProcessInputStepReproCapture(params) {
7801
7891
  const addedMessageIds = contextMessages.map((message) => message.id).filter((id) => Boolean(id) && !preMessageIds.has(id));
7802
7892
  const idRemap = inferReproIdRemap(params.preMessages, contextMessages);
7803
7893
  const rawState = params.args.state ?? {};
7804
- const inputPayload = safeCaptureJson({
7805
- stepNumber: params.stepNumber,
7806
- threadId: params.threadId,
7807
- resourceId: params.resourceId,
7808
- readOnly: memoryContext?.memoryConfig?.readOnly,
7809
- messageCount: contextMessages.length,
7810
- messageIds: contextMessages.map((message) => message.id),
7811
- stateKeys: Object.keys(rawState),
7812
- state: rawState,
7813
- args: {
7814
- messages: params.args.messages,
7815
- steps: params.args.steps,
7816
- systemMessages: params.args.systemMessages,
7817
- retryCount: params.args.retryCount,
7818
- tools: params.args.tools,
7819
- toolChoice: params.args.toolChoice,
7820
- activeTools: params.args.activeTools,
7821
- providerOptions: params.args.providerOptions,
7822
- modelSettings: params.args.modelSettings,
7823
- structuredOutput: params.args.structuredOutput
7824
- }
7825
- });
7826
- const preStatePayload = safeCaptureJson({
7827
- record: params.preRecord,
7828
- bufferedChunks: params.preBufferedChunks,
7829
- contextTokenCount: params.preContextTokenCount,
7830
- messages: params.preMessages,
7831
- messageList: params.preSerializedMessageList
7832
- });
7833
- const outputPayload = safeCaptureJson({
7834
- details: params.details,
7835
- messageDiff: {
7836
- removedMessageIds,
7837
- addedMessageIds,
7838
- idRemap
7894
+ const sanitizedState = sanitizeCaptureState(rawState);
7895
+ const payloads = [
7896
+ {
7897
+ fileName: "input.json",
7898
+ data: {
7899
+ stepNumber: params.stepNumber,
7900
+ threadId: params.threadId,
7901
+ resourceId: params.resourceId,
7902
+ readOnly: memoryContext?.memoryConfig?.readOnly,
7903
+ messageCount: contextMessages.length,
7904
+ messageIds: contextMessages.map((message) => message.id),
7905
+ stateKeys: Object.keys(rawState),
7906
+ state: sanitizedState,
7907
+ args: {
7908
+ messages: params.args.messages,
7909
+ steps: params.args.steps,
7910
+ systemMessages: params.args.systemMessages,
7911
+ retryCount: params.args.retryCount,
7912
+ toolChoice: params.args.toolChoice,
7913
+ activeTools: params.args.activeTools,
7914
+ modelSettings: params.args.modelSettings,
7915
+ structuredOutput: params.args.structuredOutput
7916
+ }
7917
+ }
7918
+ },
7919
+ {
7920
+ fileName: "pre-state.json",
7921
+ data: {
7922
+ record: params.preRecord,
7923
+ bufferedChunks: params.preBufferedChunks,
7924
+ contextTokenCount: params.preContextTokenCount,
7925
+ messages: params.preMessages,
7926
+ messageList: params.preSerializedMessageList
7927
+ }
7928
+ },
7929
+ {
7930
+ fileName: "output.json",
7931
+ data: {
7932
+ details: params.details,
7933
+ messageDiff: {
7934
+ removedMessageIds,
7935
+ addedMessageIds,
7936
+ idRemap
7937
+ }
7938
+ }
7939
+ },
7940
+ {
7941
+ fileName: "post-state.json",
7942
+ data: {
7943
+ record: params.postRecord,
7944
+ bufferedChunks: params.postBufferedChunks,
7945
+ contextTokenCount: params.postContextTokenCount,
7946
+ messageCount: contextMessages.length,
7947
+ messageIds: contextMessages.map((message) => message.id),
7948
+ messages: contextMessages,
7949
+ messageList: params.messageList.serialize()
7950
+ }
7839
7951
  }
7840
- });
7841
- const postStatePayload = safeCaptureJson({
7842
- record: params.postRecord,
7843
- bufferedChunks: params.postBufferedChunks,
7844
- contextTokenCount: params.postContextTokenCount,
7845
- messageCount: contextMessages.length,
7846
- messageIds: contextMessages.map((message) => message.id),
7847
- messages: contextMessages,
7848
- messageList: params.messageList.serialize()
7849
- });
7850
- fs.writeFileSync(path.join(captureDir, "input.json"), `${JSON.stringify(inputPayload, null, 2)}
7851
- `);
7852
- fs.writeFileSync(path.join(captureDir, "pre-state.json"), `${JSON.stringify(preStatePayload, null, 2)}
7853
- `);
7854
- fs.writeFileSync(path.join(captureDir, "output.json"), `${JSON.stringify(outputPayload, null, 2)}
7952
+ ];
7953
+ const captureErrors = [];
7954
+ for (const payload of payloads) {
7955
+ const serialized = safeCaptureJsonOrError(payload.data);
7956
+ if (serialized.ok) {
7957
+ fs.writeFileSync(path.join(captureDir, payload.fileName), `${JSON.stringify(serialized.value, null, 2)}
7855
7958
  `);
7856
- fs.writeFileSync(path.join(captureDir, "post-state.json"), `${JSON.stringify(postStatePayload, null, 2)}
7959
+ continue;
7960
+ }
7961
+ captureErrors.push({ fileName: payload.fileName, error: serialized.error });
7962
+ fs.writeFileSync(
7963
+ path.join(captureDir, payload.fileName),
7964
+ `${JSON.stringify({ __captureError: serialized.error }, null, 2)}
7965
+ `
7966
+ );
7967
+ }
7968
+ if (captureErrors.length > 0) {
7969
+ fs.writeFileSync(path.join(captureDir, "capture-error.json"), `${JSON.stringify(captureErrors, null, 2)}
7857
7970
  `);
7971
+ params.debug?.(
7972
+ `[OM:repro-capture] wrote processInputStep capture with ${captureErrors.length} serialization error(s) to ${captureDir}`
7973
+ );
7974
+ return;
7975
+ }
7858
7976
  params.debug?.(`[OM:repro-capture] wrote processInputStep capture to ${captureDir}`);
7859
7977
  } catch (error) {
7860
7978
  params.debug?.(`[OM:repro-capture] failed to write processInputStep capture: ${String(error)}`);
@@ -7877,7 +7995,17 @@ var ObservationalMemoryProcessor = class {
7877
7995
  }
7878
7996
  // ─── Processor lifecycle hooks ──────────────────────────────────────────
7879
7997
  async processInputStep(args) {
7880
- const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort } = args;
7998
+ const {
7999
+ messageList,
8000
+ requestContext,
8001
+ stepNumber,
8002
+ state: _state,
8003
+ writer,
8004
+ model,
8005
+ abortSignal,
8006
+ abort,
8007
+ rotateResponseMessageId
8008
+ } = args;
7881
8009
  const state = _state ?? {};
7882
8010
  omDebug(
7883
8011
  `[OM:processInputStep:ENTER] step=${stepNumber}, hasMastraMemory=${!!requestContext?.get("MastraMemory")}, hasMemoryInfo=${!!messageList?.serialize()?.memoryInfo?.threadId}`
@@ -7905,7 +8033,14 @@ var ObservationalMemoryProcessor = class {
7905
8033
  await this.turn.end().catch(() => {
7906
8034
  });
7907
8035
  }
7908
- this.turn = this.engine.beginTurn({ threadId, resourceId, messageList });
8036
+ this.turn = this.engine.beginTurn({
8037
+ threadId,
8038
+ resourceId,
8039
+ messageList,
8040
+ hooks: {
8041
+ onBufferChunkSealed: rotateResponseMessageId
8042
+ }
8043
+ });
7909
8044
  this.turn.writer = writer;
7910
8045
  this.turn.requestContext = requestContext;
7911
8046
  await this.turn.start(this.memory);
@@ -8065,5 +8200,5 @@ exports.stripEphemeralAnchorIds = stripEphemeralAnchorIds;
8065
8200
  exports.stripObservationGroups = stripObservationGroups;
8066
8201
  exports.truncateStringByTokens = truncateStringByTokens;
8067
8202
  exports.wrapInObservationGroup = wrapInObservationGroup;
8068
- //# sourceMappingURL=chunk-NS47X3OB.cjs.map
8069
- //# sourceMappingURL=chunk-NS47X3OB.cjs.map
8203
+ //# sourceMappingURL=chunk-DTAZSLVU.cjs.map
8204
+ //# sourceMappingURL=chunk-DTAZSLVU.cjs.map