@mastra/memory 1.9.0 → 1.9.1-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.
@@ -1729,6 +1729,7 @@ User messages are extremely important. If the user asks a question or gives a ne
1729
1729
 
1730
1730
  ${instruction}` : ""}`;
1731
1731
  }
1732
+ var MAX_COMPRESSION_LEVEL = 4;
1732
1733
  var COMPRESSION_GUIDANCE = {
1733
1734
  0: "",
1734
1735
  1: `
@@ -1741,11 +1742,11 @@ Please re-process with slightly more compression:
1741
1742
  - Closer to the end, retain more fine details (recent context matters more)
1742
1743
  - Memory is getting long - use a more condensed style throughout
1743
1744
  - Combine related items more aggressively but do not lose important specific details of names, places, events, and people
1745
+ - Combine repeated similar tool calls (e.g. multiple file views, searches, or edits in the same area) into a single summary line describing what was explored/changed and the outcome
1744
1746
  - Preserve \u2705 completion markers \u2014 they are memory signals that tell the assistant what is already resolved and help prevent repeated work
1745
1747
  - Preserve the concrete resolved outcome captured by \u2705 markers so the assistant knows what exactly is done
1746
- - For example if there is a long nested observation list about repeated tool calls, you can combine those into a single line and observe that the tool was called multiple times for x reason, and finally y outcome happened.
1747
1748
 
1748
- Your current detail level was a 10/10, lets aim for a 8/10 detail level.
1749
+ Aim for a 8/10 detail level.
1749
1750
  `,
1750
1751
  2: `
1751
1752
  ## AGGRESSIVE COMPRESSION REQUIRED
@@ -1757,12 +1758,13 @@ Please re-process with much more aggressive compression:
1757
1758
  - Closer to the end, retain fine details (recent context matters more)
1758
1759
  - Memory is getting very long - use a significantly more condensed style throughout
1759
1760
  - Combine related items aggressively but do not lose important specific details of names, places, events, and people
1761
+ - Combine repeated similar tool calls (e.g. multiple file views, searches, or edits in the same area) into a single summary line describing what was explored/changed and the outcome
1762
+ - If the same file or module is mentioned across many observations, merge into one entry covering the full arc
1760
1763
  - Preserve \u2705 completion markers \u2014 they are memory signals that tell the assistant what is already resolved and help prevent repeated work
1761
1764
  - Preserve the concrete resolved outcome captured by \u2705 markers so the assistant knows what exactly is done
1762
- - For example if there is a long nested observation list about repeated tool calls, you can combine those into a single line and observe that the tool was called multiple times for x reason, and finally y outcome happened.
1763
1765
  - Remove redundant information and merge overlapping observations
1764
1766
 
1765
- Your current detail level was a 10/10, lets aim for a 6/10 detail level.
1767
+ Aim for a 6/10 detail level.
1766
1768
  `,
1767
1769
  3: `
1768
1770
  ## CRITICAL COMPRESSION REQUIRED
@@ -1773,13 +1775,32 @@ Please re-process with maximum compression:
1773
1775
  - Summarize the oldest observations (first 50-70%) into brief high-level paragraphs \u2014 only key facts, decisions, and outcomes
1774
1776
  - For the most recent observations (last 30-50%), retain important details but still use a condensed style
1775
1777
  - Ruthlessly merge related observations \u2014 if 10 observations are about the same topic, combine into 1-2 lines
1778
+ - Combine all tool call sequences (file views, searches, edits, builds) into outcome-only summaries \u2014 drop individual steps entirely
1776
1779
  - Drop procedural details (tool calls, retries, intermediate steps) \u2014 keep only final outcomes
1777
1780
  - Drop observations that are no longer relevant or have been superseded by newer information
1778
1781
  - Preserve \u2705 completion markers \u2014 they are memory signals that tell the assistant what is already resolved and help prevent repeated work
1779
1782
  - Preserve the concrete resolved outcome captured by \u2705 markers so the assistant knows what exactly is done
1780
1783
  - Preserve: names, dates, decisions, errors, user preferences, and architectural choices
1781
1784
 
1782
- Your current detail level was a 10/10, lets aim for a 4/10 detail level.
1785
+ Aim for a 4/10 detail level.
1786
+ `,
1787
+ 4: `
1788
+ ## EXTREME COMPRESSION REQUIRED
1789
+
1790
+ Multiple compression attempts have failed. The content may already be dense from a prior reflection.
1791
+
1792
+ You MUST dramatically reduce the number of observations while keeping the standard observation format (date groups with bullet points and priority emojis):
1793
+ - Tool call observations are the biggest source of bloat. Collapse ALL tool call sequences into outcome-only observations \u2014 e.g. 10 observations about viewing/searching/editing files become 1 observation about what was actually learned or achieved (e.g. "Investigated auth module and found token validation was skipping expiry check")
1794
+ - Never preserve individual tool calls (viewed file X, searched for Y, ran build) \u2014 only preserve what was discovered or accomplished
1795
+ - Consolidate many related observations into single, more generic observations
1796
+ - Merge all same-day date groups into at most 2-3 date groups per day
1797
+ - For older content, each topic or task should be at most 1-2 observations capturing the key outcome
1798
+ - For recent content, retain more detail but still merge related items aggressively
1799
+ - If multiple observations describe incremental progress on the same task, keep only the final state
1800
+ - Preserve \u2705 completion markers and their outcomes but merge related completions into fewer lines
1801
+ - Preserve: user preferences, key decisions, architectural choices, and unresolved issues
1802
+
1803
+ Aim for a 2/10 detail level. Fewer, more generic observations are better than many specific ones that exceed the budget.
1783
1804
  `
1784
1805
  };
1785
1806
  function buildReflectorPrompt(observations, manualPrompt, compressionLevel, skipContinuationHints) {
@@ -3905,6 +3926,22 @@ Async buffering is enabled by default \u2014 this opt-out is only needed when us
3905
3926
  modelId: resolved.modelId
3906
3927
  };
3907
3928
  }
3929
+ /**
3930
+ * Get the default compression start level based on model behavior.
3931
+ * gemini-2.5-flash is a faithful transcriber that needs explicit pressure to compress effectively.
3932
+ */
3933
+ async getCompressionStartLevel(requestContext) {
3934
+ try {
3935
+ const resolved = await this.resolveModelContext(this.reflectionConfig.model, requestContext);
3936
+ const modelId = resolved?.modelId ?? "";
3937
+ if (modelId.includes("gemini-2.5-flash")) {
3938
+ return 2;
3939
+ }
3940
+ return 1;
3941
+ } catch {
3942
+ return 1;
3943
+ }
3944
+ }
3908
3945
  getRuntimeModelContext(model) {
3909
3946
  if (!model?.modelId) {
3910
3947
  return void 0;
@@ -4702,8 +4739,9 @@ ${unreflectedContent}` : bufferedReflection;
4702
4739
  const originalTokens = this.tokenCounter.countObservations(observations);
4703
4740
  const targetThreshold = observationTokensThreshold ?? getMaxThreshold(this.reflectionConfig.observationTokens);
4704
4741
  let totalUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
4705
- let currentLevel = compressionStartLevel ?? 0;
4706
- const maxLevel = 3;
4742
+ const startLevel = compressionStartLevel ?? 0;
4743
+ let currentLevel = startLevel;
4744
+ const maxLevel = Math.min(MAX_COMPRESSION_LEVEL, startLevel + 3);
4707
4745
  let parsed = { observations: "", suggestedContinuation: void 0 };
4708
4746
  let reflectedTokens = 0;
4709
4747
  let attemptNumber = 0;
@@ -4774,13 +4812,17 @@ ${unreflectedContent}` : bufferedReflection;
4774
4812
  omDebug(`[OM:callReflector] degenerate output persists at maxLevel=${maxLevel}, breaking`);
4775
4813
  break;
4776
4814
  }
4815
+ if (currentLevel >= maxLevel) {
4816
+ break;
4817
+ }
4818
+ const nextLevel = currentLevel + 1;
4777
4819
  if (streamContext?.writer) {
4778
4820
  const failedMarker = createObservationFailedMarker({
4779
4821
  cycleId: streamContext.cycleId,
4780
4822
  operationType: "reflection",
4781
4823
  startedAt: streamContext.startedAt,
4782
4824
  tokensAttempted: originalTokens,
4783
- error: `Did not compress below threshold (${originalTokens} \u2192 ${reflectedTokens}, target: ${targetThreshold}), retrying at level ${currentLevel + 1}`,
4825
+ error: `Did not compress below threshold (${originalTokens} \u2192 ${reflectedTokens}, target: ${targetThreshold}), retrying at level ${nextLevel}`,
4784
4826
  recordId: streamContext.recordId,
4785
4827
  threadId: streamContext.threadId
4786
4828
  });
@@ -4801,7 +4843,7 @@ ${unreflectedContent}` : bufferedReflection;
4801
4843
  await streamContext.writer.custom(startMarker).catch(() => {
4802
4844
  });
4803
4845
  }
4804
- currentLevel = Math.min(currentLevel + 1, maxLevel);
4846
+ currentLevel = nextLevel;
4805
4847
  }
4806
4848
  return {
4807
4849
  observations: parsed.observations,
@@ -6702,9 +6744,6 @@ ${bufferedObservations}`;
6702
6744
  omDebug(
6703
6745
  `[OM:reflect] doAsyncBufferedReflection: slicing observations for reflection \u2014 totalLines=${totalLines}, avgTokPerLine=${avgTokensPerLine.toFixed(1)}, activationPointTokens=${activationPointTokens}, linesToReflect=${linesToReflect}/${totalLines}, sliceTokenEstimate=${sliceTokenEstimate}, compressionTarget=${compressionTarget}`
6704
6746
  );
6705
- omDebug(
6706
- `[OM:reflect] doAsyncBufferedReflection: starting reflector call, recordId=${currentRecord.id}, observationTokens=${sliceTokenEstimate}, compressionTarget=${compressionTarget} (inputTokens), activeObsLength=${activeObservations.length}, reflectedLineCount=${reflectedObservationLineCount}`
6707
- );
6708
6747
  if (writer) {
6709
6748
  const startMarker = createBufferingStartMarker({
6710
6749
  cycleId,
@@ -6718,6 +6757,9 @@ ${bufferedObservations}`;
6718
6757
  void writer.custom(startMarker).catch(() => {
6719
6758
  });
6720
6759
  }
6760
+ omDebug(
6761
+ `[OM:reflect] doAsyncBufferedReflection: starting reflector call, recordId=${currentRecord.id}, observationTokens=${sliceTokenEstimate}, compressionTarget=${compressionTarget} (inputTokens), activeObsLength=${activeObservations.length}, reflectedLineCount=${reflectedObservationLineCount}`
6762
+ );
6721
6763
  const reflectResult = await this.callReflector(
6722
6764
  activeObservations,
6723
6765
  void 0,
@@ -6729,8 +6771,7 @@ ${bufferedObservations}`;
6729
6771
  // No abort signal for background ops
6730
6772
  true,
6731
6773
  // Skip continuation hints for async buffering
6732
- 1,
6733
- // Start at compression level 1 for buffered reflection
6774
+ await this.getCompressionStartLevel(requestContext),
6734
6775
  requestContext
6735
6776
  );
6736
6777
  const reflectionTokenCount = this.tokenCounter.countObservations(reflectResult.observations);
@@ -7564,5 +7605,5 @@ function getObservationsAsOf(activeObservations, asOf) {
7564
7605
  }
7565
7606
 
7566
7607
  export { OBSERVATIONAL_MEMORY_DEFAULTS, OBSERVATION_CONTEXT_INSTRUCTIONS, OBSERVATION_CONTEXT_PROMPT, OBSERVATION_CONTINUATION_HINT, OBSERVER_SYSTEM_PROMPT, ObservationalMemory, TokenCounter, buildObserverPrompt, buildObserverSystemPrompt, combineObservationGroupRanges, deriveObservationGroupProvenance, extractCurrentTask, formatMessagesForObserver, formatToolResultForObserver, getObservationsAsOf, hasCurrentTaskSection, injectAnchorIds, optimizeObservationsForContext, parseAnchorId, parseObservationGroups, parseObserverOutput, reconcileObservationGroupsFromReflection, renderObservationGroupsForReflection, resolveToolResultValue, stripEphemeralAnchorIds, stripObservationGroups, truncateStringByTokens, wrapInObservationGroup };
7567
- //# sourceMappingURL=chunk-JJBSFPC5.js.map
7568
- //# sourceMappingURL=chunk-JJBSFPC5.js.map
7608
+ //# sourceMappingURL=chunk-T5FHEWK6.js.map
7609
+ //# sourceMappingURL=chunk-T5FHEWK6.js.map