@mastra/memory 1.36.0-alpha.4 → 1.36.0
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.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-memory-observational-memory.md +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/markers.d.ts +2 -0
- package/dist/processors/observational-memory/markers.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-agent.d.ts +5 -12
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/tool-result-helpers.d.ts.map +1 -1
- package/dist/processors/observational-memory/types.d.ts +2 -0
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/dist/{src-B07BdDQ-.cjs → src-DwfyRK9Q.cjs} +114 -64
- package/dist/{src-B07BdDQ-.cjs.map → src-DwfyRK9Q.cjs.map} +1 -1
- package/dist/{src-BPHEGTkT.js → src-yhShj4JX.js} +114 -64
- package/dist/{src-BPHEGTkT.js.map → src-yhShj4JX.js.map} +1 -1
- package/package.json +8 -8
|
@@ -20052,8 +20052,9 @@ function stringifyToolResult(value) {
|
|
|
20052
20052
|
}
|
|
20053
20053
|
function resolveToolResultValue(part, invocationResult) {
|
|
20054
20054
|
const mastraMetadata = part?.providerMetadata?.mastra;
|
|
20055
|
-
|
|
20056
|
-
|
|
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
|
-
|
|
21282
|
-
|
|
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(
|
|
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
|
-
|
|
21296
|
-
|
|
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
|
-
|
|
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
|
-
|
|
21317
|
-
|
|
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
|
-
*
|
|
21327
|
-
*
|
|
21328
|
-
*
|
|
21329
|
-
*
|
|
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
|
|
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
|
|
21352
|
-
|
|
21353
|
-
|
|
21354
|
-
|
|
21355
|
-
|
|
21356
|
-
|
|
21357
|
-
|
|
21358
|
-
|
|
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
|
-
`
|
|
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=${
|
|
21420
|
+
`topWindowCount=${a.topWindowCount}`
|
|
21373
21421
|
];
|
|
21374
|
-
if (
|
|
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-
|
|
35389
|
+
//# sourceMappingURL=src-yhShj4JX.js.map
|