@mastra/memory 1.36.0-alpha.4 → 1.36.0-alpha.6

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.
@@ -20052,8 +20052,9 @@ function stringifyToolResult(value) {
20052
20052
  }
20053
20053
  function resolveToolResultValue(part, invocationResult) {
20054
20054
  const mastraMetadata = part?.providerMetadata?.mastra;
20055
- if (mastraMetadata && typeof mastraMetadata === "object" && "modelOutput" in mastraMetadata) return {
20056
- value: mastraMetadata.modelOutput,
20055
+ const modelOutput = mastraMetadata && typeof mastraMetadata === "object" ? mastraMetadata.modelOutput : void 0;
20056
+ if (modelOutput != null) return {
20057
+ value: modelOutput,
20057
20058
  usingStoredModelOutput: true
20058
20059
  };
20059
20060
  return {
@@ -21096,7 +21097,7 @@ function buildMultiThreadObserverContextPrompt(existingObservations, threadOrder
21096
21097
  */
21097
21098
  function parseMultiThreadObserverOutput(output, extractors = []) {
21098
21099
  const threads = /* @__PURE__ */ new Map();
21099
- if (detectDegenerateRepetition(output)) return {
21100
+ if (detectDegenerateRepetition(sanitizeObservationLines(output))) return {
21100
21101
  threads,
21101
21102
  rawOutput: output,
21102
21103
  degenerate: true
@@ -21202,7 +21203,7 @@ function getStringExtractedValue$1(values, slug) {
21202
21203
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
21203
21204
  }
21204
21205
  function parseObserverOutput(output, extractors = []) {
21205
- if (detectDegenerateRepetition(output)) return {
21206
+ if (detectDegenerateRepetition(sanitizeObservationLines(output))) return {
21206
21207
  observations: "",
21207
21208
  rawOutput: output,
21208
21209
  degenerate: true
@@ -21265,6 +21266,34 @@ const MAX_OBSERVATION_LINE_CHARS = 1e4;
21265
21266
  */
21266
21267
  const MIN_DUPLICATE_LINE_CHARS = 24;
21267
21268
  /**
21269
+ * Collapse a run of back-to-back identical lines to a single line when that
21270
+ * run is the line's only occurrence and is no bigger than one maximum-length
21271
+ * observation line. A faithful summary of a repetitive tool loop (e.g. 30×
21272
+ * "pnpm --filter … build → ok") produces exactly that shape at any line
21273
+ * length. Loops are left intact: a model stuck on one line runs far past the
21274
+ * size bound, and a line that keeps recurring between other lines has more
21275
+ * than one run.
21276
+ */
21277
+ function collapseBoundedLineRuns(lines) {
21278
+ const runs = [];
21279
+ for (const line of lines) {
21280
+ const last = runs[runs.length - 1];
21281
+ if (last && last.line === line) last.count++;
21282
+ else runs.push({
21283
+ line,
21284
+ count: 1
21285
+ });
21286
+ }
21287
+ const runsPerLine = /* @__PURE__ */ new Map();
21288
+ for (const run of runs) runsPerLine.set(run.line, (runsPerLine.get(run.line) ?? 0) + 1);
21289
+ const result = [];
21290
+ for (const run of runs) {
21291
+ const collapse = runsPerLine.get(run.line) === 1 && run.count * (run.line.length + 1) <= MAX_OBSERVATION_LINE_CHARS;
21292
+ for (let j = 0; j < (collapse ? 1 : run.count); j++) result.push(run.line);
21293
+ }
21294
+ return result;
21295
+ }
21296
+ /**
21268
21297
  * Truncate individual observation lines that exceed the maximum length.
21269
21298
  */
21270
21299
  function sanitizeObservationLines(observations) {
@@ -21277,31 +21306,28 @@ function sanitizeObservationLines(observations) {
21277
21306
  }
21278
21307
  return changed ? lines.join("\n") : observations;
21279
21308
  }
21280
- /**
21281
- * Detect degenerate repetition in observer/reflector output.
21282
- * Returns true if the text contains suspicious levels of repeated content,
21283
- * which indicates an LLM repeat-penalty bug (e.g., Gemini Flash looping).
21284
- *
21285
- * Strategy: sample sequential chunks of the text and check if a high
21286
- * proportion are near-identical to previous chunks.
21287
- */
21288
- function detectDegenerateRepetition(text) {
21289
- if (!text || text.length < 2e3) return false;
21309
+ function analyzeDegenerateRepetition(text) {
21310
+ const lines = collapseBoundedLineRuns(text.split("\n"));
21311
+ const windowText = lines.filter((line) => line.trim().length >= MIN_DUPLICATE_LINE_CHARS && line.length <= MAX_OBSERVATION_LINE_CHARS).join("\n");
21290
21312
  const windowSize = 200;
21291
- const step = Math.max(1, Math.floor(text.length / 50));
21313
+ const step = Math.max(1, Math.floor(windowText.length / 50));
21292
21314
  const seen = /* @__PURE__ */ new Map();
21293
21315
  let duplicateWindows = 0;
21294
21316
  let totalWindows = 0;
21295
- for (let i = 0; i + windowSize <= text.length; i += step) {
21296
- const window = text.slice(i, i + windowSize);
21317
+ let topWindow = "";
21318
+ let topWindowCount = 0;
21319
+ for (let i = 0; i + windowSize <= windowText.length; i += step) {
21320
+ const window = windowText.slice(i, i + windowSize);
21297
21321
  totalWindows++;
21298
21322
  const count = (seen.get(window) ?? 0) + 1;
21299
21323
  seen.set(window, count);
21300
21324
  if (count > 1) duplicateWindows++;
21325
+ if (count > topWindowCount) {
21326
+ topWindowCount = count;
21327
+ topWindow = window;
21328
+ }
21301
21329
  }
21302
- if (totalWindows > 5 && duplicateWindows / totalWindows > .4) return true;
21303
- const lines = text.split("\n");
21304
- for (const line of lines) if (line.length > 5e4) return true;
21330
+ const windowFired = windowText.length >= 2e3 && totalWindows > 5 && duplicateWindows / totalWindows > .4;
21305
21331
  const seenLines = /* @__PURE__ */ new Map();
21306
21332
  let duplicateLines = 0;
21307
21333
  let totalCountedLines = 0;
@@ -21313,8 +21339,50 @@ function detectDegenerateRepetition(text) {
21313
21339
  seenLines.set(trimmed, count);
21314
21340
  if (count > 1) duplicateLines++;
21315
21341
  }
21316
- if (totalCountedLines >= 20 && duplicateLines / totalCountedLines > .5) return true;
21317
- return false;
21342
+ const lineFired = totalCountedLines >= 20 && duplicateLines / totalCountedLines > .5;
21343
+ let shortLineFired = false;
21344
+ let shortLineCounts = /* @__PURE__ */ new Map();
21345
+ const runExceedsBudget = () => {
21346
+ let repeatedShortChars = 0;
21347
+ for (const { count, chars } of shortLineCounts.values()) if (count > 1) repeatedShortChars += chars;
21348
+ return repeatedShortChars - 1 > MAX_OBSERVATION_LINE_CHARS;
21349
+ };
21350
+ for (const line of lines) {
21351
+ const trimmed = line.trim();
21352
+ if (!trimmed) continue;
21353
+ if (trimmed.length >= MIN_DUPLICATE_LINE_CHARS) {
21354
+ if (runExceedsBudget()) shortLineFired = true;
21355
+ shortLineCounts = /* @__PURE__ */ new Map();
21356
+ continue;
21357
+ }
21358
+ if (/^<\/?[A-Za-z][\w-]*(?:\s[^<>]*)?>$/.test(trimmed) || trimmed.startsWith("Date:")) continue;
21359
+ const entry = shortLineCounts.get(trimmed) ?? {
21360
+ count: 0,
21361
+ chars: 0
21362
+ };
21363
+ entry.count++;
21364
+ entry.chars += line.length + 1;
21365
+ shortLineCounts.set(trimmed, entry);
21366
+ }
21367
+ if (runExceedsBudget()) shortLineFired = true;
21368
+ const eligible = text.length >= 2e3;
21369
+ return {
21370
+ windowText,
21371
+ totalWindows,
21372
+ duplicateWindows,
21373
+ topWindow,
21374
+ topWindowCount,
21375
+ totalCountedLines,
21376
+ duplicateLines,
21377
+ windowFired: eligible && windowFired,
21378
+ lineFired: eligible && lineFired,
21379
+ shortLineFired: eligible && shortLineFired
21380
+ };
21381
+ }
21382
+ function detectDegenerateRepetition(text) {
21383
+ if (!text || text.length < 2e3) return false;
21384
+ const analysis = analyzeDegenerateRepetition(text);
21385
+ return analysis.windowFired || analysis.lineFired || analysis.shortLineFired;
21318
21386
  }
21319
21387
  /**
21320
21388
  * Build a single-line diagnostic description of output flagged by
@@ -21323,55 +21391,35 @@ function detectDegenerateRepetition(text) {
21323
21391
  * without it there is no way to tell a real repetition loop apart from a
21324
21392
  * detector false-positive on legitimately repetitive content.
21325
21393
  *
21326
- * Reuses the detector's sampling parameters (200-char windows, ~50 samples)
21327
- * so the reported duplicate ratio and most-repeated window match what
21328
- * triggered the detection. Snippets are JSON-escaped so the result stays on
21329
- * one line.
21394
+ * Runs the detector's analysis on the same sanitized text the detector judges
21395
+ * (giant lines truncated), so `strategy=` names what triggered the rejection.
21396
+ * For a short-line loop the window and line ratios read n/a or low, because
21397
+ * short lines are excluded from both. `length` and `longestLine` describe the
21398
+ * raw output. Snippets are JSON-escaped so the result stays on one line.
21330
21399
  */
21331
21400
  function describeDegenerateOutput(text, snippetChars = 400) {
21332
- const windowSize = 200;
21333
- const step = Math.max(1, Math.floor(text.length / 50));
21334
- const seen = /* @__PURE__ */ new Map();
21335
- let duplicateWindows = 0;
21336
- let totalWindows = 0;
21337
- for (let i = 0; i + windowSize <= text.length; i += step) {
21338
- const window = text.slice(i, i + windowSize);
21339
- totalWindows++;
21340
- const count = (seen.get(window) ?? 0) + 1;
21341
- seen.set(window, count);
21342
- if (count > 1) duplicateWindows++;
21343
- }
21344
- let topWindow = "";
21345
- let topCount = 0;
21346
- for (const [window, count] of seen) if (count > topCount) {
21347
- topCount = count;
21348
- topWindow = window;
21349
- }
21401
+ const a = analyzeDegenerateRepetition(sanitizeObservationLines(text));
21350
21402
  let longestLine = 0;
21351
- const seenLines = /* @__PURE__ */ new Map();
21352
- let duplicateLines = 0;
21353
- let totalCountedLines = 0;
21354
- for (const line of text.split("\n")) {
21355
- if (line.length > longestLine) longestLine = line.length;
21356
- const trimmed = line.trim();
21357
- if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
21358
- totalCountedLines++;
21359
- const count = (seenLines.get(trimmed) ?? 0) + 1;
21360
- seenLines.set(trimmed, count);
21361
- if (count > 1) duplicateLines++;
21362
- }
21363
- const duplicateRatio = totalWindows > 0 ? (duplicateWindows / totalWindows).toFixed(2) : "n/a";
21364
- const duplicateLineRatio = totalCountedLines > 0 ? (duplicateLines / totalCountedLines).toFixed(2) : "n/a";
21403
+ for (const line of text.split("\n")) if (line.length > longestLine) longestLine = line.length;
21404
+ const fired = [
21405
+ a.windowFired && "window",
21406
+ a.lineFired && "duplicateLines",
21407
+ a.shortLineFired && "shortLineLoop"
21408
+ ].filter(Boolean).join("+") || "none";
21409
+ const duplicateRatio = a.totalWindows > 0 ? (a.duplicateWindows / a.totalWindows).toFixed(2) : "n/a";
21410
+ const duplicateLineRatio = a.totalCountedLines > 0 ? (a.duplicateLines / a.totalCountedLines).toFixed(2) : "n/a";
21365
21411
  const parts = [
21412
+ `strategy=${fired}`,
21366
21413
  `length=${text.length}`,
21367
- `sampledWindows=${totalWindows}`,
21414
+ `windowTextLength=${a.windowText.length}`,
21415
+ `sampledWindows=${a.totalWindows}`,
21368
21416
  `duplicateRatio=${duplicateRatio}`,
21369
21417
  `duplicateLineRatio=${duplicateLineRatio}`,
21370
- `countedLines=${totalCountedLines}`,
21418
+ `countedLines=${a.totalCountedLines}`,
21371
21419
  `longestLine=${longestLine}`,
21372
- `topWindowCount=${topCount}`
21420
+ `topWindowCount=${a.topWindowCount}`
21373
21421
  ];
21374
- if (topCount > 1) parts.push(`topWindow=${JSON.stringify(topWindow)}`);
21422
+ if (a.topWindowCount > 1) parts.push(`topWindow=${JSON.stringify(a.topWindow)}`);
21375
21423
  parts.push(`head=${JSON.stringify(text.slice(0, snippetChars))}`);
21376
21424
  if (text.length > snippetChars * 2) parts.push(`tail=${JSON.stringify(text.slice(-snippetChars))}`);
21377
21425
  return parts.join(" ");
@@ -26431,6 +26479,7 @@ function createObservationFailedMarker(params) {
26431
26479
  tokensAttempted: params.tokensAttempted,
26432
26480
  error: formatOmError(params.error),
26433
26481
  ...getOmFailureMetadata(params.error, params.failurePolicy ?? "abort"),
26482
+ ...params.retrying ? { retrying: true } : {},
26434
26483
  recordId: params.recordId,
26435
26484
  threadId: params.threadId
26436
26485
  }
@@ -28727,7 +28776,7 @@ function getStringExtractedValue(values, slug) {
28727
28776
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
28728
28777
  }
28729
28778
  function parseReflectorOutput(output, sourceObservations, extractors = []) {
28730
- if (detectDegenerateRepetition(output)) return {
28779
+ if (detectDegenerateRepetition(sanitizeObservationLines(output))) return {
28731
28780
  observations: "",
28732
28781
  degenerate: true
28733
28782
  };
@@ -29072,6 +29121,7 @@ var ReflectorRunner = class {
29072
29121
  startedAt: streamContext.startedAt,
29073
29122
  tokensAttempted: originalTokens,
29074
29123
  error: `Did not compress below threshold (${originalTokens} → ${reflectedTokens}, target: ${targetThreshold}), retrying at level ${currentLevel + 1}`,
29124
+ retrying: true,
29075
29125
  recordId: streamContext.recordId,
29076
29126
  threadId: streamContext.threadId
29077
29127
  });
@@ -35336,4 +35386,4 @@ Notes:
35336
35386
  //#endregion
35337
35387
  export { formatMessagesForObserver as A, OBSERVATION_CONTEXT_PROMPT_THREAD as B, SUMMARIZE_THREAD_DEFAULTS as C, buildObserverPrompt as D, OBSERVER_SYSTEM_PROMPT as E, parseAnchorId as F, StaleKnowledgeSemanticIndexError as G, getObservationContextPrompt as H, stripEphemeralAnchorIds as I, SUBCONSCIOUS_ACTIVITY_STATE_ID as J, SubconsciousRemindExtractor as K, OBSERVATIONAL_MEMORY_DEFAULTS as L, optimizeObservationsForContext as M, parseObserverOutput as N, buildObserverSystemPrompt as O, injectAnchorIds as P, Extractor as Q, OBSERVATION_CONTEXT_INSTRUCTIONS as R, deepMergeWorkingMemory as S, TokenCounter as T, Subconscious as U, OBSERVATION_CONTINUATION_HINT as V, KnowledgeSemanticIndexCoordinator as W, publishSubconsciousActivity as X, buildSubconsciousActivitySnapshot as Y, renderSubconsciousActivity as Z, reconcileObservationGroupsFromReflection as _, extractWorkingMemoryContent as a, wrapInObservationGroup as b, getObservationsAsOf as c, WORKING_MEMORY_STATE_ID as d, WORKING_MEMORY_STATE_PROCESSOR_ID as f, parseObservationGroups as g, deriveObservationGroupProvenance as h, WorkingMemory as i, hasCurrentTaskSection as j, extractCurrentTask as k, ObservationalMemoryProcessor as l, combineObservationGroupRanges as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, WorkingMemoryStateProcessor as p, ModelByInputTokens as q, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, ObservationalMemory as u, renderObservationGroupsForReflection as v, summarizeConversation as w, WorkingMemoryExtractor as x, stripObservationGroups as y, OBSERVATION_CONTEXT_PROMPT as z };
35338
35388
 
35339
- //# sourceMappingURL=src-BPHEGTkT.js.map
35389
+ //# sourceMappingURL=src-yhShj4JX.js.map