@mastra/memory 0.0.0-studio-deploy-20260403185613 → 0.0.0-studio-deploy-20260403231316

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 (31) hide show
  1. package/CHANGELOG.md +63 -3
  2. package/dist/{chunk-HLGFIN4J.cjs → chunk-4FMHSWZD.cjs} +149 -29
  3. package/dist/chunk-4FMHSWZD.cjs.map +1 -0
  4. package/dist/{chunk-DDQHE4NV.js → chunk-C7PARRAD.js} +149 -29
  5. package/dist/chunk-C7PARRAD.js.map +1 -0
  6. package/dist/docs/SKILL.md +1 -1
  7. package/dist/docs/assets/SOURCE_MAP.json +39 -39
  8. package/dist/docs/references/reference-processors-token-limiter-processor.md +2 -0
  9. package/dist/index.cjs +12 -12
  10. package/dist/index.js +4 -4
  11. package/dist/{observational-memory-34W4S4I5.cjs → observational-memory-5YDQLKHE.cjs} +26 -26
  12. package/dist/{observational-memory-34W4S4I5.cjs.map → observational-memory-5YDQLKHE.cjs.map} +1 -1
  13. package/dist/{observational-memory-B25SASRW.js → observational-memory-B7AUSTEY.js} +3 -3
  14. package/dist/{observational-memory-B25SASRW.js.map → observational-memory-B7AUSTEY.js.map} +1 -1
  15. package/dist/processors/index.cjs +24 -24
  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/observation-strategies/sync.d.ts.map +1 -1
  19. package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
  20. package/dist/processors/observational-memory/observation-turn/types.d.ts +3 -0
  21. package/dist/processors/observational-memory/observation-turn/types.d.ts.map +1 -1
  22. package/dist/processors/observational-memory/observational-memory.d.ts +16 -1
  23. package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
  24. package/dist/processors/observational-memory/observer-runner.d.ts +21 -0
  25. package/dist/processors/observational-memory/observer-runner.d.ts.map +1 -1
  26. package/dist/processors/observational-memory/processor.d.ts.map +1 -1
  27. package/dist/processors/observational-memory/repro-capture.d.ts +2 -0
  28. package/dist/processors/observational-memory/repro-capture.d.ts.map +1 -1
  29. package/package.json +8 -8
  30. package/dist/chunk-DDQHE4NV.js.map +0 -1
  31. package/dist/chunk-HLGFIN4J.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,11 +1,71 @@
1
1
  # @mastra/memory
2
2
 
3
- ## 0.0.0-studio-deploy-20260403185613
3
+ ## 0.0.0-studio-deploy-20260403231316
4
4
 
5
5
  ### Patch Changes
6
6
 
7
- - Updated dependencies [[`c55b527`](https://github.com/mastra-ai/mastra/commit/c55b52758a31368b2077b0dbbc3badfe4063f560)]:
8
- - @mastra/core@0.0.0-studio-deploy-20260403185613
7
+ - Fixed observational memory buffering so sealed assistant chunks stay split instead of being merged back into one persisted message during long tool runs. ([#14995](https://github.com/mastra-ai/mastra/pull/14995))
8
+
9
+ - Updated dependencies [[`c55b527`](https://github.com/mastra-ai/mastra/commit/c55b52758a31368b2077b0dbbc3badfe4063f560), [`7eb2596`](https://github.com/mastra-ai/mastra/commit/7eb25960d607e07468c9a10c5437abd2deaf1e9a)]:
10
+ - @mastra/core@0.0.0-studio-deploy-20260403231316
11
+
12
+ ## 1.13.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Fixed thread titles not persisting when generated during async buffered observation. Titles now update immediately when the observer produces them, rather than being lost until activation. ([#14992](https://github.com/mastra-ai/mastra/pull/14992))
17
+
18
+ - Updated dependencies [[`cb15509`](https://github.com/mastra-ai/mastra/commit/cb15509b58f6a83e11b765c945082afc027db972), [`81e4259`](https://github.com/mastra-ai/mastra/commit/81e425939b4ceeb4f586e9b6d89c3b1c1f2d2fe7), [`951b8a1`](https://github.com/mastra-ai/mastra/commit/951b8a1b5ef7e1474c59dc4f2b9fc1a8b1e508b6), [`80c5668`](https://github.com/mastra-ai/mastra/commit/80c5668e365470d3a96d3e953868fd7a643ff67c), [`3d478c1`](https://github.com/mastra-ai/mastra/commit/3d478c1e13f17b80f330ac49d7aa42ef929b93ff), [`2b4ea10`](https://github.com/mastra-ai/mastra/commit/2b4ea10b053e4ea1ab232d536933a4a3c4cba999), [`a0544f0`](https://github.com/mastra-ai/mastra/commit/a0544f0a1e6bd52ac12676228967c1938e43648d), [`6039f17`](https://github.com/mastra-ai/mastra/commit/6039f176f9c457304825ff1df8c83b8e457376c0), [`06b928d`](https://github.com/mastra-ai/mastra/commit/06b928dfc2f5630d023467476cc5919dfa858d0a), [`6a8d984`](https://github.com/mastra-ai/mastra/commit/6a8d9841f2933456ee1598099f488d742b600054), [`c8c86aa`](https://github.com/mastra-ai/mastra/commit/c8c86aa1458017fbd1c0776fdc0c520d129df8a6)]:
19
+ - @mastra/core@1.22.0
20
+
21
+ ## 1.13.1-alpha.0
22
+
23
+ ### Patch Changes
24
+
25
+ - Fixed thread titles not persisting when generated during async buffered observation. Titles now update immediately when the observer produces them, rather than being lost until activation. ([#14992](https://github.com/mastra-ai/mastra/pull/14992))
26
+
27
+ - Updated dependencies [[`cb15509`](https://github.com/mastra-ai/mastra/commit/cb15509b58f6a83e11b765c945082afc027db972), [`80c5668`](https://github.com/mastra-ai/mastra/commit/80c5668e365470d3a96d3e953868fd7a643ff67c), [`3d478c1`](https://github.com/mastra-ai/mastra/commit/3d478c1e13f17b80f330ac49d7aa42ef929b93ff), [`6039f17`](https://github.com/mastra-ai/mastra/commit/6039f176f9c457304825ff1df8c83b8e457376c0), [`06b928d`](https://github.com/mastra-ai/mastra/commit/06b928dfc2f5630d023467476cc5919dfa858d0a), [`6a8d984`](https://github.com/mastra-ai/mastra/commit/6a8d9841f2933456ee1598099f488d742b600054)]:
28
+ - @mastra/core@1.22.0-alpha.2
29
+
30
+ ## 1.13.0
31
+
32
+ ### Minor Changes
33
+
34
+ - Added `loadUnobservedMessages({ threadId, resourceId? })` as a public method on `ObservationalMemory`. ([#14921](https://github.com/mastra-ai/mastra/pull/14921))
35
+
36
+ This lets external consumers (e.g. the Mastra gateway proxy) load previously-stored messages that haven't been observed yet, without having to reimplement the internal storage query and part-level filtering logic. The method fetches the OM record, queries storage for messages after the `lastObservedAt` cursor, and applies part-level filtering so partially-observed messages only return their unobserved parts.
37
+
38
+ ```ts
39
+ const unobserved = await om.loadUnobservedMessages({
40
+ threadId: 'thread-123',
41
+ resourceId: 'user-456',
42
+ });
43
+ ```
44
+
45
+ ### Patch Changes
46
+
47
+ - Updated dependencies [[`9a43b47`](https://github.com/mastra-ai/mastra/commit/9a43b476465e86c9aca381c2831066b5c33c999a), [`ec5c319`](https://github.com/mastra-ai/mastra/commit/ec5c3197a50d034cb8e9cc494eebfddc684b5d81), [`6517789`](https://github.com/mastra-ai/mastra/commit/65177895b74b5471fe2245c7292f0176d9b3385d), [`13f4327`](https://github.com/mastra-ai/mastra/commit/13f4327f052faebe199cefbe906d33bf90238767), [`9ad6aa6`](https://github.com/mastra-ai/mastra/commit/9ad6aa6dfe858afc6955d1df5f3f78c40bb96b9c), [`2862127`](https://github.com/mastra-ai/mastra/commit/2862127d0a7cbd28523120ad64fea067a95838e6), [`3d16814`](https://github.com/mastra-ai/mastra/commit/3d16814c395931373543728994ff45ac98093074), [`7f498d0`](https://github.com/mastra-ai/mastra/commit/7f498d099eacef64fd43ee412e3bd6f87965a8a6), [`8cf8a67`](https://github.com/mastra-ai/mastra/commit/8cf8a67b061b737cb06d501fb8c1967a98bbf3cb), [`d7827e3`](https://github.com/mastra-ai/mastra/commit/d7827e393937c6cb0c7a744dde4d31538cb542b7)]:
48
+ - @mastra/core@1.21.0
49
+
50
+ ## 1.13.0-alpha.0
51
+
52
+ ### Minor Changes
53
+
54
+ - Added `loadUnobservedMessages({ threadId, resourceId? })` as a public method on `ObservationalMemory`. ([#14921](https://github.com/mastra-ai/mastra/pull/14921))
55
+
56
+ This lets external consumers (e.g. the Mastra gateway proxy) load previously-stored messages that haven't been observed yet, without having to reimplement the internal storage query and part-level filtering logic. The method fetches the OM record, queries storage for messages after the `lastObservedAt` cursor, and applies part-level filtering so partially-observed messages only return their unobserved parts.
57
+
58
+ ```ts
59
+ const unobserved = await om.loadUnobservedMessages({
60
+ threadId: 'thread-123',
61
+ resourceId: 'user-456',
62
+ });
63
+ ```
64
+
65
+ ### Patch Changes
66
+
67
+ - Updated dependencies [[`13f4327`](https://github.com/mastra-ai/mastra/commit/13f4327f052faebe199cefbe906d33bf90238767)]:
68
+ - @mastra/core@1.21.0-alpha.1
9
69
 
10
70
  ## 1.12.1
11
71
 
@@ -1406,8 +1406,6 @@ var SyncObservationStrategy = class extends ObservationStrategy {
1406
1406
  }
1407
1407
  }
1408
1408
  };
1409
-
1410
- // src/processors/observational-memory/observation-strategies/async-buffer.ts
1411
1409
  var AsyncBufferObservationStrategy = class extends ObservationStrategy {
1412
1410
  startedAt;
1413
1411
  cycleId;
@@ -1498,6 +1496,30 @@ var AsyncBufferObservationStrategy = class extends ObservationStrategy {
1498
1496
  lastBufferedAtTime: processed.lastObservedAt
1499
1497
  });
1500
1498
  await this.indexObservationGroups(processed.observations, threadId, resourceId, processed.lastObservedAt);
1499
+ const newTitle = processed.threadTitle?.trim();
1500
+ if (newTitle && newTitle.length >= 3) {
1501
+ const thread = await this.storage.getThreadById({ threadId });
1502
+ if (thread) {
1503
+ const oldTitle = thread.title?.trim();
1504
+ if (newTitle !== oldTitle) {
1505
+ const newMetadata = memory.setThreadOMMetadata(thread.metadata, {
1506
+ threadTitle: processed.threadTitle
1507
+ });
1508
+ await this.storage.updateThread({
1509
+ id: threadId,
1510
+ title: newTitle,
1511
+ metadata: newMetadata
1512
+ });
1513
+ const marker = createThreadUpdateMarker({
1514
+ cycleId: this.cycleId,
1515
+ threadId,
1516
+ oldTitle,
1517
+ newTitle
1518
+ });
1519
+ await this.streamMarker(marker);
1520
+ }
1521
+ }
1522
+ }
1501
1523
  }
1502
1524
  async emitEndMarkers(_cycleId, processed) {
1503
1525
  if (!processed.observations || !this.opts.writer) return;
@@ -1952,6 +1974,7 @@ var ObservationStep = class {
1952
1974
  let buffered = false;
1953
1975
  let reflected = false;
1954
1976
  let didThresholdCleanup = false;
1977
+ let observerExchange;
1955
1978
  if (this.stepNumber === 0) {
1956
1979
  const step0Messages = messageList.get.all.db();
1957
1980
  const activation = await om.activate({
@@ -2007,6 +2030,26 @@ var ObservationStep = class {
2007
2030
  if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
2008
2031
  const allMessages = messageList.get.all.db();
2009
2032
  const unobservedMessages = om.getUnobservedMessages(allMessages, statusSnapshot.record);
2033
+ const candidates = om.getUnobservedMessages(unobservedMessages, statusSnapshot.record, {
2034
+ excludeBuffered: true
2035
+ });
2036
+ if (candidates.length > 0) {
2037
+ om.sealMessagesForBuffering(candidates);
2038
+ try {
2039
+ await this.turn.hooks?.onBufferChunkSealed?.();
2040
+ } catch (error) {
2041
+ omDebug(
2042
+ `[OM:buffer] onBufferChunkSealed hook failed: ${error instanceof Error ? error.message : String(error)}`
2043
+ );
2044
+ }
2045
+ if (this.turn.memory) {
2046
+ await this.turn.memory.persistMessages(candidates);
2047
+ }
2048
+ messageList.removeByIds(candidates.map((msg) => msg.id));
2049
+ for (const msg of candidates) {
2050
+ messageList.add(msg, "memory");
2051
+ }
2052
+ }
2010
2053
  void om.buffer({
2011
2054
  threadId,
2012
2055
  resourceId,
@@ -2015,23 +2058,7 @@ var ObservationStep = class {
2015
2058
  record: statusSnapshot.record,
2016
2059
  writer: this.turn.writer,
2017
2060
  requestContext: this.turn.requestContext,
2018
- observabilityContext: this.turn.observabilityContext,
2019
- beforeBuffer: async (candidates) => {
2020
- if (candidates.length === 0) {
2021
- return;
2022
- }
2023
- om.sealMessagesForBuffering(candidates);
2024
- try {
2025
- await this.turn.hooks?.onBufferChunkSealed?.();
2026
- } catch (error) {
2027
- omDebug(
2028
- `[OM:buffer] onBufferChunkSealed hook failed: ${error instanceof Error ? error.message : String(error)}`
2029
- );
2030
- }
2031
- if (this.turn.memory) {
2032
- await this.turn.memory.persistMessages(candidates);
2033
- }
2034
- }
2061
+ observabilityContext: this.turn.observabilityContext
2035
2062
  }).catch((err) => {
2036
2063
  omDebug(`[OM:buffer] fire-and-forget buffer failed: ${err?.message}`);
2037
2064
  });
@@ -2050,6 +2077,7 @@ var ObservationStep = class {
2050
2077
  if (statusSnapshot.shouldObserve && !hasIncompleteToolCalls) {
2051
2078
  const preObsGeneration = this.turn.record.generationCount;
2052
2079
  const obsResult = await this.runThresholdObservation();
2080
+ observerExchange = obsResult.observerExchange;
2053
2081
  if (obsResult.succeeded) {
2054
2082
  observed = true;
2055
2083
  didThresholdCleanup = true;
@@ -2103,6 +2131,7 @@ var ObservationStep = class {
2103
2131
  }
2104
2132
  this._context = {
2105
2133
  systemMessage,
2134
+ observerExchange,
2106
2135
  activated,
2107
2136
  observed,
2108
2137
  buffered,
@@ -2170,7 +2199,11 @@ var ObservationStep = class {
2170
2199
  writer: this.turn.writer,
2171
2200
  observabilityContext: this.turn.observabilityContext
2172
2201
  });
2173
- return { succeeded: obsResult.observed, record: obsResult.record };
2202
+ return {
2203
+ succeeded: obsResult.observed,
2204
+ record: obsResult.record,
2205
+ observerExchange: om.observer.lastExchange
2206
+ };
2174
2207
  }
2175
2208
  };
2176
2209
 
@@ -3496,6 +3529,8 @@ var ObserverRunner = class {
3496
3529
  observedMessageIds;
3497
3530
  resolveModel;
3498
3531
  tokenCounter;
3532
+ /** Captured prompt/response from the last observer call (for repro capture). */
3533
+ lastExchange;
3499
3534
  constructor(opts) {
3500
3535
  this.observationConfig = opts.observationConfig;
3501
3536
  this.observedMessageIds = opts.observedMessageIds;
@@ -3571,15 +3606,38 @@ var ObserverRunner = class {
3571
3606
  };
3572
3607
  let result = await doGenerate();
3573
3608
  let parsed = parseObserverOutput(result.text);
3609
+ let retriedDueToDegenerate = false;
3574
3610
  if (parsed.degenerate) {
3575
3611
  omDebug(`[OM:callObserver] degenerate repetition detected, retrying once`);
3576
3612
  result = await doGenerate();
3577
3613
  parsed = parseObserverOutput(result.text);
3614
+ retriedDueToDegenerate = true;
3578
3615
  if (parsed.degenerate) {
3579
3616
  omDebug(`[OM:callObserver] degenerate repetition on retry, failing`);
3580
3617
  throw new Error("Observer produced degenerate output after retry");
3581
3618
  }
3582
3619
  }
3620
+ const systemPrompt = buildObserverSystemPrompt(
3621
+ false,
3622
+ this.observationConfig.instruction,
3623
+ this.observationConfig.threadTitle
3624
+ );
3625
+ this.lastExchange = {
3626
+ systemPrompt,
3627
+ observerMessages,
3628
+ rawOutput: result.text,
3629
+ parsedResult: {
3630
+ observations: parsed.observations,
3631
+ currentTask: parsed.currentTask,
3632
+ suggestedContinuation: parsed.suggestedContinuation,
3633
+ threadTitle: parsed.threadTitle,
3634
+ degenerate: parsed.degenerate
3635
+ },
3636
+ model: String(resolvedModel.model),
3637
+ inputTokens,
3638
+ isMultiThread: false,
3639
+ retriedDueToDegenerate
3640
+ };
3583
3641
  const usage = result.totalUsage ?? result.usage;
3584
3642
  return {
3585
3643
  observations: parsed.observations,
@@ -3646,15 +3704,36 @@ var ObserverRunner = class {
3646
3704
  };
3647
3705
  let result = await doGenerate();
3648
3706
  let parsed = parseMultiThreadObserverOutput(result.text);
3707
+ let retriedDueToDegenerate = false;
3649
3708
  if (parsed.degenerate) {
3650
3709
  omDebug(`[OM:callMultiThreadObserver] degenerate repetition detected, retrying once`);
3651
3710
  result = await doGenerate();
3652
3711
  parsed = parseMultiThreadObserverOutput(result.text);
3712
+ retriedDueToDegenerate = true;
3653
3713
  if (parsed.degenerate) {
3654
3714
  omDebug(`[OM:callMultiThreadObserver] degenerate repetition on retry, failing`);
3655
3715
  throw new Error("Multi-thread observer produced degenerate output after retry");
3656
3716
  }
3657
3717
  }
3718
+ const systemPrompt = buildObserverSystemPrompt(
3719
+ true,
3720
+ this.observationConfig.instruction,
3721
+ this.observationConfig.threadTitle
3722
+ );
3723
+ this.lastExchange = {
3724
+ systemPrompt,
3725
+ observerMessages,
3726
+ rawOutput: result.text,
3727
+ parsedResult: {
3728
+ observations: Array.from(parsed.threads.values()).map((t) => t.observations).join("\n"),
3729
+ threadTitle: Array.from(parsed.threads.values()).map((t) => t.threadTitle).filter(Boolean).join(", "),
3730
+ degenerate: parsed.degenerate
3731
+ },
3732
+ model: String(resolvedModel.model),
3733
+ inputTokens,
3734
+ isMultiThread: true,
3735
+ retriedDueToDegenerate
3736
+ };
3658
3737
  const results = /* @__PURE__ */ new Map();
3659
3738
  for (const [threadId, threadResult] of parsed.threads) {
3660
3739
  results.set(threadId, {
@@ -6715,7 +6794,7 @@ ${suggestedResponse}
6715
6794
  * In resource scope mode, loads messages for the entire resource (all threads).
6716
6795
  * In thread scope mode, loads messages for just the current thread.
6717
6796
  */
6718
- async loadUnobservedMessages(threadId, resourceId, lastObservedAt) {
6797
+ async loadMessagesFromStorage(threadId, resourceId, lastObservedAt) {
6719
6798
  const startDate = lastObservedAt ? new Date(lastObservedAt.getTime() + 1) : void 0;
6720
6799
  let result;
6721
6800
  if (this.scope === "resource" && resourceId) {
@@ -7403,7 +7482,7 @@ ${grouped}` : grouped;
7403
7482
  if (opts.messages) {
7404
7483
  unobservedMessages = this.getUnobservedMessages(opts.messages, record);
7405
7484
  } else {
7406
- const rawMessages = await this.loadUnobservedMessages(
7485
+ const rawMessages = await this.loadMessagesFromStorage(
7407
7486
  threadId,
7408
7487
  resourceId,
7409
7488
  record.lastObservedAt ? new Date(record.lastObservedAt) : void 0
@@ -7516,6 +7595,27 @@ ${grouped}` : grouped;
7516
7595
  const record = await this.getOrCreateRecord(threadId, resourceId);
7517
7596
  return this.getUnobservedMessages(messages, record);
7518
7597
  }
7598
+ /**
7599
+ * Load unobserved messages from storage for a thread/resource.
7600
+ *
7601
+ * Fetches the OM record, queries storage for messages after the
7602
+ * lastObservedAt cursor, then applies part-level filtering so
7603
+ * partially-observed messages only include their unobserved parts.
7604
+ *
7605
+ * Use this when you need to load stored conversation history that
7606
+ * hasn't been observed yet (e.g. in a stateless gateway proxy that
7607
+ * only receives the latest message from the HTTP request).
7608
+ */
7609
+ async loadUnobservedMessages(opts) {
7610
+ const { threadId, resourceId } = opts;
7611
+ const record = await this.getOrCreateRecord(threadId, resourceId);
7612
+ const rawMessages = await this.loadMessagesFromStorage(
7613
+ threadId,
7614
+ resourceId,
7615
+ record.lastObservedAt ? new Date(record.lastObservedAt) : void 0
7616
+ );
7617
+ return this.getUnobservedMessages(rawMessages, record);
7618
+ }
7519
7619
  /**
7520
7620
  * Create a buffered observation chunk without merging into active observations.
7521
7621
  *
@@ -7577,7 +7677,7 @@ ${grouped}` : grouped;
7577
7677
  if (opts.messages) {
7578
7678
  candidateMessages = this.getUnobservedMessages(opts.messages, record, { excludeBuffered: true });
7579
7679
  } else {
7580
- const rawMessages = await this.loadUnobservedMessages(
7680
+ const rawMessages = await this.loadMessagesFromStorage(
7581
7681
  threadId,
7582
7682
  resourceId,
7583
7683
  record.lastObservedAt ? new Date(record.lastObservedAt) : void 0
@@ -7782,13 +7882,18 @@ ${grouped}` : grouped;
7782
7882
  const activatedChunks = freshChunks.filter((c) => activationResult.activatedCycleIds.includes(c.cycleId));
7783
7883
  const lastActivated = activatedChunks[activatedChunks.length - 1];
7784
7884
  if (lastActivated) {
7885
+ const chunkThreadTitle = lastActivated.threadTitle;
7785
7886
  const newMetadata = memory.setThreadOMMetadata(thread.metadata, {
7786
7887
  suggestedResponse: lastActivated.suggestedContinuation,
7787
- currentTask: lastActivated.currentTask
7888
+ currentTask: lastActivated.currentTask,
7889
+ threadTitle: chunkThreadTitle
7788
7890
  });
7891
+ const oldTitle = thread.title?.trim();
7892
+ const newTitle = chunkThreadTitle?.trim();
7893
+ const shouldUpdateThreadTitle = !!newTitle && newTitle.length >= 3 && newTitle !== oldTitle;
7789
7894
  await this.storage.updateThread({
7790
7895
  id: threadId,
7791
- title: thread.title ?? "",
7896
+ title: shouldUpdateThreadTitle ? newTitle : thread.title ?? "",
7792
7897
  metadata: newMetadata
7793
7898
  });
7794
7899
  }
@@ -7819,7 +7924,7 @@ ${grouped}` : grouped;
7819
7924
  await this.withLock(lockKey, async () => {
7820
7925
  const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
7821
7926
  generationBefore = freshRecord.generationCount;
7822
- const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadUnobservedMessages(
7927
+ const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadMessagesFromStorage(
7823
7928
  threadId,
7824
7929
  resourceId,
7825
7930
  freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : void 0
@@ -8223,6 +8328,20 @@ function writeProcessInputStepReproCapture(params) {
8223
8328
  `
8224
8329
  );
8225
8330
  }
8331
+ if (params.observerExchange) {
8332
+ const serialized = safeCaptureJsonOrError(params.observerExchange);
8333
+ if (serialized.ok) {
8334
+ fs.writeFileSync(path.join(captureDir, "observer-exchange.json"), `${JSON.stringify(serialized.value, null, 2)}
8335
+ `);
8336
+ } else {
8337
+ captureErrors.push({ fileName: "observer-exchange.json", error: serialized.error });
8338
+ fs.writeFileSync(
8339
+ path.join(captureDir, "observer-exchange.json"),
8340
+ `${JSON.stringify({ __captureError: serialized.error }, null, 2)}
8341
+ `
8342
+ );
8343
+ }
8344
+ }
8226
8345
  if (captureErrors.length > 0) {
8227
8346
  fs.writeFileSync(path.join(captureDir, "capture-error.json"), `${JSON.stringify(captureErrors, null, 2)}
8228
8347
  `);
@@ -8387,7 +8506,8 @@ var ObservationalMemoryProcessor = class {
8387
8506
  postBufferedChunks: [],
8388
8507
  postContextTokenCount: finalTotalPending,
8389
8508
  messageList,
8390
- details: {}
8509
+ details: {},
8510
+ observerExchange: ctx.observerExchange
8391
8511
  });
8392
8512
  }
8393
8513
  }
@@ -8475,5 +8595,5 @@ exports.stripEphemeralAnchorIds = stripEphemeralAnchorIds;
8475
8595
  exports.stripObservationGroups = stripObservationGroups;
8476
8596
  exports.truncateStringByTokens = truncateStringByTokens;
8477
8597
  exports.wrapInObservationGroup = wrapInObservationGroup;
8478
- //# sourceMappingURL=chunk-HLGFIN4J.cjs.map
8479
- //# sourceMappingURL=chunk-HLGFIN4J.cjs.map
8598
+ //# sourceMappingURL=chunk-4FMHSWZD.cjs.map
8599
+ //# sourceMappingURL=chunk-4FMHSWZD.cjs.map