@mastra/server 1.62.0-alpha.12 → 1.62.0-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.
- package/CHANGELOG.md +0 -90
- package/dist/_types/@internal_core/dist/storage/index.d.ts +13 -13
- package/dist/{datasets-DYhcB-od.cjs → datasets-CNtKg_3d.cjs} +1 -3
- package/dist/datasets-CNtKg_3d.cjs.map +1 -0
- package/dist/{datasets-CInAtVdf.js → datasets-DmN9V4rU.js} +1 -3
- package/dist/datasets-DmN9V4rU.js.map +1 -0
- package/dist/{dist-L0EogwX_.js → dist-HzWDFjPH.js} +275 -401
- package/dist/dist-HzWDFjPH.js.map +1 -0
- package/dist/{dist-Xj9TvH1A.cjs → dist-LHYHUQ8P.cjs} +275 -401
- package/dist/dist-LHYHUQ8P.cjs.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-server-middleware.md +0 -30
- package/dist/server/handlers/agent-builder.cjs +1 -1
- package/dist/server/handlers/agent-builder.js +1 -1
- package/dist/server/handlers/datasets.cjs +1 -1
- package/dist/server/handlers/datasets.d.ts +0 -10
- package/dist/server/handlers/datasets.d.ts.map +1 -1
- package/dist/server/handlers/datasets.js +1 -1
- package/dist/server/handlers/observability-new-endpoints.d.ts +28 -28
- package/dist/server/schemas/datasets.d.ts +0 -4
- package/dist/server/schemas/datasets.d.ts.map +1 -1
- package/dist/server/schemas/index.cjs +1 -1
- package/dist/server/schemas/index.js +1 -1
- package/dist/server/server-adapter/index.cjs +2 -22
- package/dist/server/server-adapter/index.cjs.map +1 -1
- package/dist/server/server-adapter/index.d.ts +0 -14
- package/dist/server/server-adapter/index.d.ts.map +1 -1
- package/dist/server/server-adapter/index.js +3 -22
- package/dist/server/server-adapter/index.js.map +1 -1
- package/dist/server/server-adapter/routes/datasets.d.ts +0 -10
- package/dist/server/server-adapter/routes/datasets.d.ts.map +1 -1
- package/dist/server/server-adapter/routes/observability.d.ts +14 -14
- package/package.json +6 -6
- package/dist/datasets-CInAtVdf.js.map +0 -1
- package/dist/datasets-DYhcB-od.cjs.map +0 -1
- package/dist/dist-L0EogwX_.js.map +0 -1
- package/dist/dist-Xj9TvH1A.cjs.map +0 -1
|
@@ -4693,7 +4693,7 @@ function splitLines(text) {
|
|
|
4693
4693
|
return result;
|
|
4694
4694
|
}
|
|
4695
4695
|
//#endregion
|
|
4696
|
-
//#region ../memory/dist/src-
|
|
4696
|
+
//#region ../memory/dist/src-BlQjkJzk.js
|
|
4697
4697
|
var __defProp$3 = Object.defineProperty;
|
|
4698
4698
|
var __exportAll = (all, no_symbols) => {
|
|
4699
4699
|
let target = {};
|
|
@@ -8927,7 +8927,6 @@ async function cancelResponseBody$1(response) {
|
|
|
8927
8927
|
var initialGlobalFetch$1 = globalThis.fetch;
|
|
8928
8928
|
isNodeDefaultFetch$1(initialGlobalFetch$1);
|
|
8929
8929
|
function isNodeDefaultFetch$1(fetch) {
|
|
8930
|
-
if (typeof fetch !== "function") return false;
|
|
8931
8930
|
const source = Function.prototype.toString.call(fetch);
|
|
8932
8931
|
return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
|
|
8933
8932
|
}
|
|
@@ -13819,7 +13818,6 @@ var DownloadError$2 = class extends (_b$2$1 = AISDKError$3, _a$2$1 = symbol$2$1,
|
|
|
13819
13818
|
var initialGlobalFetch$2 = globalThis.fetch;
|
|
13820
13819
|
isNodeDefaultFetch$2(initialGlobalFetch$2);
|
|
13821
13820
|
function isNodeDefaultFetch$2(fetch) {
|
|
13822
|
-
if (typeof fetch !== "function") return false;
|
|
13823
13821
|
const source = Function.prototype.toString.call(fetch);
|
|
13824
13822
|
return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
|
|
13825
13823
|
}
|
|
@@ -23482,12 +23480,6 @@ function extractListItemsOnly(content) {
|
|
|
23482
23480
|
*/
|
|
23483
23481
|
const MAX_OBSERVATION_LINE_CHARS = 1e4;
|
|
23484
23482
|
/**
|
|
23485
|
-
* Minimum trimmed line length considered by the duplicate-line degenerate
|
|
23486
|
-
* check. Short lines (blank lines, separators, terse bullets) legitimately
|
|
23487
|
-
* repeat; long identical lines almost never do.
|
|
23488
|
-
*/
|
|
23489
|
-
const MIN_DUPLICATE_LINE_CHARS = 24;
|
|
23490
|
-
/**
|
|
23491
23483
|
* Truncate individual observation lines that exceed the maximum length.
|
|
23492
23484
|
*/
|
|
23493
23485
|
function sanitizeObservationLines(observations) {
|
|
@@ -23525,18 +23517,6 @@ function detectDegenerateRepetition(text) {
|
|
|
23525
23517
|
if (totalWindows > 5 && duplicateWindows / totalWindows > .4) return true;
|
|
23526
23518
|
const lines = text.split("\n");
|
|
23527
23519
|
for (const line of lines) if (line.length > 5e4) return true;
|
|
23528
|
-
const seenLines = /* @__PURE__ */ new Map();
|
|
23529
|
-
let duplicateLines = 0;
|
|
23530
|
-
let totalCountedLines = 0;
|
|
23531
|
-
for (const line of lines) {
|
|
23532
|
-
const trimmed = line.trim();
|
|
23533
|
-
if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
|
|
23534
|
-
totalCountedLines++;
|
|
23535
|
-
const count = (seenLines.get(trimmed) ?? 0) + 1;
|
|
23536
|
-
seenLines.set(trimmed, count);
|
|
23537
|
-
if (count > 1) duplicateLines++;
|
|
23538
|
-
}
|
|
23539
|
-
if (totalCountedLines >= 20 && duplicateLines / totalCountedLines > .5) return true;
|
|
23540
23520
|
return false;
|
|
23541
23521
|
}
|
|
23542
23522
|
/**
|
|
@@ -23571,26 +23551,12 @@ function describeDegenerateOutput(text, snippetChars = 400) {
|
|
|
23571
23551
|
topWindow = window;
|
|
23572
23552
|
}
|
|
23573
23553
|
let longestLine = 0;
|
|
23574
|
-
const
|
|
23575
|
-
let duplicateLines = 0;
|
|
23576
|
-
let totalCountedLines = 0;
|
|
23577
|
-
for (const line of text.split("\n")) {
|
|
23578
|
-
if (line.length > longestLine) longestLine = line.length;
|
|
23579
|
-
const trimmed = line.trim();
|
|
23580
|
-
if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
|
|
23581
|
-
totalCountedLines++;
|
|
23582
|
-
const count = (seenLines.get(trimmed) ?? 0) + 1;
|
|
23583
|
-
seenLines.set(trimmed, count);
|
|
23584
|
-
if (count > 1) duplicateLines++;
|
|
23585
|
-
}
|
|
23554
|
+
for (const line of text.split("\n")) if (line.length > longestLine) longestLine = line.length;
|
|
23586
23555
|
const duplicateRatio = totalWindows > 0 ? (duplicateWindows / totalWindows).toFixed(2) : "n/a";
|
|
23587
|
-
const duplicateLineRatio = totalCountedLines > 0 ? (duplicateLines / totalCountedLines).toFixed(2) : "n/a";
|
|
23588
23556
|
const parts = [
|
|
23589
23557
|
`length=${text.length}`,
|
|
23590
23558
|
`sampledWindows=${totalWindows}`,
|
|
23591
23559
|
`duplicateRatio=${duplicateRatio}`,
|
|
23592
|
-
`duplicateLineRatio=${duplicateLineRatio}`,
|
|
23593
|
-
`countedLines=${totalCountedLines}`,
|
|
23594
23560
|
`longestLine=${longestLine}`,
|
|
23595
23561
|
`topWindowCount=${topCount}`
|
|
23596
23562
|
];
|
|
@@ -26969,149 +26935,6 @@ function createWorkingMemoryTool(config, options = {}) {
|
|
|
26969
26935
|
tool
|
|
26970
26936
|
};
|
|
26971
26937
|
}
|
|
26972
|
-
/**
|
|
26973
|
-
* WorkingMemoryStateProcessor
|
|
26974
|
-
*
|
|
26975
|
-
* Experimental: delivers working memory to the model as a state signal instead
|
|
26976
|
-
* of folding it into the system message. Storage and the `setWorkingMemory`
|
|
26977
|
-
* tool are unchanged — this processor only changes the delivery path.
|
|
26978
|
-
*
|
|
26979
|
-
* Pattern matches `BrowserContextProcessor` in `@mastra/core/browser`:
|
|
26980
|
-
* - `stateId` namespaces the state lane on the thread.
|
|
26981
|
-
* - `cacheKey` is derived from the rendered payload so dedup is automatic.
|
|
26982
|
-
* - `contextWindow.hasSnapshot` re-injection ensures the model still sees the
|
|
26983
|
-
* current snapshot after older messages drop out of the window.
|
|
26984
|
-
*
|
|
26985
|
-
* Delta emission (markdown mode only): when a prior snapshot exists in the
|
|
26986
|
-
* context window, the processor emits a unified-diff delta against that
|
|
26987
|
-
* snapshot's contents. Schema mode and the snapshot fallback always emit a
|
|
26988
|
-
* full snapshot.
|
|
26989
|
-
*
|
|
26990
|
-
* @example
|
|
26991
|
-
* ```ts
|
|
26992
|
-
* new Memory({
|
|
26993
|
-
* options: {
|
|
26994
|
-
* workingMemory: {
|
|
26995
|
-
* enabled: true,
|
|
26996
|
-
* template: '...',
|
|
26997
|
-
* useStateSignals: true, // auto-attaches this processor
|
|
26998
|
-
* },
|
|
26999
|
-
* },
|
|
27000
|
-
* });
|
|
27001
|
-
* ```
|
|
27002
|
-
*/
|
|
27003
|
-
const WORKING_MEMORY_STATE_ID = "working-memory";
|
|
27004
|
-
const WORKING_MEMORY_STATE_PROCESSOR_ID = "working-memory-state";
|
|
27005
|
-
var WorkingMemoryStateProcessor = class {
|
|
27006
|
-
memory;
|
|
27007
|
-
memoryConfig;
|
|
27008
|
-
id = WORKING_MEMORY_STATE_PROCESSOR_ID;
|
|
27009
|
-
stateId = WORKING_MEMORY_STATE_ID;
|
|
27010
|
-
constructor(memory, memoryConfig) {
|
|
27011
|
-
this.memory = memory;
|
|
27012
|
-
this.memoryConfig = memoryConfig;
|
|
27013
|
-
}
|
|
27014
|
-
async computeStateSignal(args) {
|
|
27015
|
-
const template = await this.memory.getWorkingMemoryTemplate({ memoryConfig: this.memoryConfig });
|
|
27016
|
-
if (!template) return;
|
|
27017
|
-
const contents = (await this.memory.getWorkingMemory({
|
|
27018
|
-
threadId: args.threadId,
|
|
27019
|
-
resourceId: args.resourceId,
|
|
27020
|
-
memoryConfig: this.memoryConfig
|
|
27021
|
-
}))?.trim();
|
|
27022
|
-
if (!contents) return;
|
|
27023
|
-
const cacheKey = stableWorkingMemoryCacheKey({
|
|
27024
|
-
format: template.format,
|
|
27025
|
-
data: contents
|
|
27026
|
-
});
|
|
27027
|
-
const shouldMakeSnapshot = !args.contextWindow.hasSnapshot;
|
|
27028
|
-
if (args.tracking?.currentCacheKey === cacheKey && !shouldMakeSnapshot) return;
|
|
27029
|
-
const scope = this.memory.getMergedThreadConfig(this.memoryConfig).workingMemory?.scope ?? "resource";
|
|
27030
|
-
const deltaCandidate = template.format === "markdown" && !shouldMakeSnapshot ? buildMarkdownDelta({
|
|
27031
|
-
lastSnapshot: args.lastSnapshot,
|
|
27032
|
-
deltasSinceSnapshot: args.deltasSinceSnapshot,
|
|
27033
|
-
nextContents: contents
|
|
27034
|
-
}) : void 0;
|
|
27035
|
-
if (deltaCandidate) return {
|
|
27036
|
-
id: WORKING_MEMORY_STATE_ID,
|
|
27037
|
-
mode: "delta",
|
|
27038
|
-
cacheKey,
|
|
27039
|
-
tagName: "working-memory",
|
|
27040
|
-
contents: deltaCandidate.contents,
|
|
27041
|
-
delta: deltaCandidate.contents,
|
|
27042
|
-
value: contents,
|
|
27043
|
-
attributes: {
|
|
27044
|
-
format: template.format,
|
|
27045
|
-
scope,
|
|
27046
|
-
patch: "unified-diff"
|
|
27047
|
-
}
|
|
27048
|
-
};
|
|
27049
|
-
return {
|
|
27050
|
-
id: WORKING_MEMORY_STATE_ID,
|
|
27051
|
-
mode: "snapshot",
|
|
27052
|
-
cacheKey,
|
|
27053
|
-
tagName: "working-memory",
|
|
27054
|
-
contents,
|
|
27055
|
-
value: contents,
|
|
27056
|
-
attributes: {
|
|
27057
|
-
format: template.format,
|
|
27058
|
-
scope
|
|
27059
|
-
}
|
|
27060
|
-
};
|
|
27061
|
-
}
|
|
27062
|
-
};
|
|
27063
|
-
/**
|
|
27064
|
-
* Stable cache key for the rendered working memory payload. Returns a SHA-256
|
|
27065
|
-
* digest so dedup metadata stays compact regardless of payload size (working
|
|
27066
|
-
* memory blobs can grow arbitrarily long).
|
|
27067
|
-
*/
|
|
27068
|
-
function stableWorkingMemoryCacheKey(input) {
|
|
27069
|
-
const hash = createHash("sha256");
|
|
27070
|
-
hash.update(input.format);
|
|
27071
|
-
hash.update("\0");
|
|
27072
|
-
hash.update(input.data ?? "");
|
|
27073
|
-
return `sha256:${hash.digest("hex")}`;
|
|
27074
|
-
}
|
|
27075
|
-
/**
|
|
27076
|
-
* Build a unified-diff delta against the most recently emitted state. Prefers
|
|
27077
|
-
* the latest delta's `value` (the post-edit full text) when available, falling
|
|
27078
|
-
* back to the snapshot's `value` and finally the snapshot's `contents`. This
|
|
27079
|
-
* keeps deltas incremental (B→C) instead of cumulative against a stale
|
|
27080
|
-
* snapshot (A→C), which matters when many small edits land between snapshots.
|
|
27081
|
-
*
|
|
27082
|
-
* Returns undefined when:
|
|
27083
|
-
* - there's no prior state to diff against
|
|
27084
|
-
* - the prior state isn't a plain string (multimodal signal)
|
|
27085
|
-
*
|
|
27086
|
-
* In either case the caller falls back to emitting a full snapshot.
|
|
27087
|
-
*/
|
|
27088
|
-
function buildMarkdownDelta(args) {
|
|
27089
|
-
const { lastSnapshot, deltasSinceSnapshot, nextContents } = args;
|
|
27090
|
-
const prior = pickStringValue(readSignalValue(deltasSinceSnapshot.at(-1))) ?? pickStringValue(readSignalValue(lastSnapshot)) ?? (typeof lastSnapshot?.contents === "string" ? lastSnapshot.contents : void 0);
|
|
27091
|
-
if (!prior) return;
|
|
27092
|
-
return { contents: renderHunksOnly(prior, nextContents) };
|
|
27093
|
-
}
|
|
27094
|
-
function pickStringValue(value) {
|
|
27095
|
-
return typeof value === "string" ? value : void 0;
|
|
27096
|
-
}
|
|
27097
|
-
function readSignalValue(signal) {
|
|
27098
|
-
return (signal?.metadata)?.value;
|
|
27099
|
-
}
|
|
27100
|
-
/**
|
|
27101
|
-
* Render a unified-diff-style patch body containing only `@@` hunks and their
|
|
27102
|
-
* lines — dropping the filename preamble (`Index:` / `===` / `---` / `+++`)
|
|
27103
|
-
* that `createPatch` emits and the `` trailer.
|
|
27104
|
-
* The preamble exists for tooling like `patch -p1` to know which file to
|
|
27105
|
-
* apply to; we only ever diff a single working-memory blob. The newline
|
|
27106
|
-
* trailer is semantically meaningless to the model and adds noise to the
|
|
27107
|
-
* state signal.
|
|
27108
|
-
*/
|
|
27109
|
-
function renderHunksOnly(prior, next) {
|
|
27110
|
-
const { hunks } = structuredPatch("", "", prior, next, "", "", { context: 0 });
|
|
27111
|
-
return hunks.map((hunk) => {
|
|
27112
|
-
return [`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`, ...hunk.lines.filter((line) => !line.startsWith("\"))].join("\n");
|
|
27113
|
-
}).join("\n");
|
|
27114
|
-
}
|
|
27115
26938
|
const MINUTE = 6e4;
|
|
27116
26939
|
const HOUR = 60 * MINUTE;
|
|
27117
26940
|
const SHORT_TTL = 5 * MINUTE;
|
|
@@ -30053,21 +29876,6 @@ var ReflectorRunner = class {
|
|
|
30053
29876
|
memory;
|
|
30054
29877
|
onReflectionCommitted;
|
|
30055
29878
|
mastra;
|
|
30056
|
-
/**
|
|
30057
|
-
* Per-lock-key observation-token count of the last unproductive synchronous
|
|
30058
|
-
* reflection (failed, or committed while still over the reflection
|
|
30059
|
-
* threshold). `call()` already runs the full bounded compression ladder for
|
|
30060
|
-
* a given input, so re-running it against unchanged observations cannot
|
|
30061
|
-
* succeed — threshold-triggered sync reflection is skipped while the count
|
|
30062
|
-
* is unchanged and retried as soon as the input differs.
|
|
30063
|
-
* Keyed by lock key (thread/resource), which is stable across generations —
|
|
30064
|
-
* record ids change every time a generation is created.
|
|
30065
|
-
*
|
|
30066
|
-
* Lifecycle: an entry is deleted when a sync reflection finishes under
|
|
30067
|
-
* threshold and replaced on each unproductive attempt. Entries are one
|
|
30068
|
-
* number per active thread/resource key and live for the runner's lifetime.
|
|
30069
|
-
*/
|
|
30070
|
-
syncReflectionSuppression = /* @__PURE__ */ new Map();
|
|
30071
29879
|
constructor(opts) {
|
|
30072
29880
|
this.reflectionConfig = opts.reflectionConfig;
|
|
30073
29881
|
this.observationConfig = opts.observationConfig;
|
|
@@ -30150,8 +29958,8 @@ var ReflectorRunner = class {
|
|
|
30150
29958
|
};
|
|
30151
29959
|
let reflectedTokens = 0;
|
|
30152
29960
|
let attemptNumber = 0;
|
|
30153
|
-
/**
|
|
30154
|
-
let
|
|
29961
|
+
/** Observations from the previous attempt, used to detect a no-progress ladder. */
|
|
29962
|
+
let previousObservations;
|
|
30155
29963
|
while (currentLevel <= maxLevel) {
|
|
30156
29964
|
attemptNumber++;
|
|
30157
29965
|
const isRetry = attemptNumber > 1;
|
|
@@ -30215,20 +30023,21 @@ var ReflectorRunner = class {
|
|
|
30215
30023
|
}
|
|
30216
30024
|
finalProviderMetadata = result.providerMetadata ?? finalProviderMetadata;
|
|
30217
30025
|
parsed = parseReflectorOutput(result.text, observations, activeExtractors);
|
|
30218
|
-
emptyOutput = !parsed.degenerate && observations.trim().length > 0 && parsed.observations.trim().length === 0;
|
|
30219
30026
|
if (parsed.degenerate) {
|
|
30220
30027
|
omDebug(`[OM:callReflector] attempt #${attemptNumber}: degenerate repetition detected, treating as compression failure. ${describeDegenerateOutput(result.text, 2e3)}`);
|
|
30221
30028
|
reflectedTokens = originalTokens;
|
|
30222
|
-
} else if (emptyOutput) {
|
|
30223
|
-
omDebug(`[OM:callReflector] attempt #${attemptNumber}: empty observations block for non-empty input, treating as compression failure`);
|
|
30224
|
-
reflectedTokens = originalTokens;
|
|
30225
30029
|
} else reflectedTokens = this.tokenCounter.countObservations(parsed.observations);
|
|
30226
30030
|
omDebug(`[OM:callReflector] attempt #${attemptNumber} parsed: reflectedTokens=${reflectedTokens}, targetThreshold=${targetThreshold}, compressionValid=${validateCompression(reflectedTokens, targetThreshold)}, parsedObsLen=${parsed.observations?.length}, degenerate=${parsed.degenerate ?? false}`);
|
|
30227
|
-
if (!parsed.degenerate &&
|
|
30228
|
-
if (
|
|
30229
|
-
omDebug(`[OM:callReflector]
|
|
30031
|
+
if (!parsed.degenerate && (validateCompression(reflectedTokens, targetThreshold) || currentLevel >= maxLevel)) break;
|
|
30032
|
+
if (parsed.degenerate && currentLevel >= maxLevel) {
|
|
30033
|
+
omDebug(`[OM:callReflector] degenerate output persists at maxLevel=${maxLevel}, breaking`);
|
|
30034
|
+
break;
|
|
30035
|
+
}
|
|
30036
|
+
if (!parsed.degenerate && previousObservations !== void 0 && parsed.observations === previousObservations) {
|
|
30037
|
+
omDebug(`[OM:callReflector] attempt #${attemptNumber} returned output identical to the previous attempt; escalating cannot help, stopping the ladder`);
|
|
30230
30038
|
break;
|
|
30231
30039
|
}
|
|
30040
|
+
previousObservations = parsed.observations;
|
|
30232
30041
|
if (streamContext?.writer) {
|
|
30233
30042
|
const failedMarker = createObservationFailedMarker({
|
|
30234
30043
|
cycleId: streamContext.cycleId,
|
|
@@ -30264,7 +30073,6 @@ var ReflectorRunner = class {
|
|
|
30264
30073
|
}
|
|
30265
30074
|
currentLevel = Math.min(currentLevel + 1, maxLevel);
|
|
30266
30075
|
}
|
|
30267
|
-
if (observations.trim().length > 0 && parsed.observations.trim().length === 0) throw new Error(`Reflector produced empty output after ${attemptNumber} attempt(s)${parsed.degenerate ? " (degenerate repetition)" : ""} — refusing to commit an empty reflection over ${originalTokens} observation tokens`);
|
|
30268
30076
|
const structuredExtraction = await extractStructuredValues({
|
|
30269
30077
|
agent,
|
|
30270
30078
|
source: "reflector",
|
|
@@ -30313,51 +30121,52 @@ var ReflectorRunner = class {
|
|
|
30313
30121
|
this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
|
|
30314
30122
|
omError("[OM] Failed to set buffering reflection flag", err);
|
|
30315
30123
|
});
|
|
30316
|
-
|
|
30317
|
-
|
|
30318
|
-
let reflectionError;
|
|
30124
|
+
reflectionHooks?.onReflectionStart?.();
|
|
30125
|
+
const asyncOp = this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal).then((outcome) => {
|
|
30319
30126
|
try {
|
|
30320
|
-
|
|
30321
|
-
|
|
30322
|
-
|
|
30323
|
-
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
30324
|
-
if (writer) try {
|
|
30325
|
-
const failedMarker = createBufferingFailedMarker({
|
|
30326
|
-
cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
|
|
30327
|
-
operationType: "reflection",
|
|
30328
|
-
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30329
|
-
tokensAttempted: observationTokens,
|
|
30330
|
-
error: reflectionError.message,
|
|
30331
|
-
recordId: record.id,
|
|
30332
|
-
threadId: record.threadId ?? ""
|
|
30333
|
-
});
|
|
30334
|
-
writer.custom({
|
|
30335
|
-
...failedMarker,
|
|
30336
|
-
transient: true
|
|
30337
|
-
}).catch(() => {});
|
|
30338
|
-
await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
|
|
30339
|
-
} catch (markerError) {
|
|
30340
|
-
omError("[OM] Failed to persist buffering-failed marker after async buffered reflection failure", markerError);
|
|
30341
|
-
}
|
|
30342
|
-
omError("[OM] Async buffered reflection failed", error);
|
|
30343
|
-
BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
|
|
30344
|
-
} finally {
|
|
30345
|
-
try {
|
|
30346
|
-
await reflectionHooks?.onReflectionEnd?.({
|
|
30347
|
-
usage: outcome?.usage,
|
|
30348
|
-
error: reflectionError,
|
|
30349
|
-
...outcome?.providerMetadata ? { providerMetadata: outcome.providerMetadata } : {}
|
|
30350
|
-
});
|
|
30351
|
-
} catch (hookError) {
|
|
30352
|
-
omError("[OM] onReflectionEnd hook failed after async buffered reflection", hookError);
|
|
30353
|
-
}
|
|
30354
|
-
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
30355
|
-
unregisterOp(record.id, "bufferingReflection");
|
|
30356
|
-
this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
|
|
30357
|
-
omError("[OM] Failed to clear buffering reflection flag", err);
|
|
30127
|
+
reflectionHooks?.onReflectionEnd?.({
|
|
30128
|
+
usage: outcome?.usage,
|
|
30129
|
+
...outcome?.providerMetadata ? { providerMetadata: outcome.providerMetadata } : {}
|
|
30358
30130
|
});
|
|
30131
|
+
} catch (hookError) {
|
|
30132
|
+
omError("[OM] onReflectionEnd hook failed after async buffered reflection", hookError);
|
|
30359
30133
|
}
|
|
30360
|
-
}
|
|
30134
|
+
}, async (error) => {
|
|
30135
|
+
if (writer) try {
|
|
30136
|
+
const failedMarker = createBufferingFailedMarker({
|
|
30137
|
+
cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
|
|
30138
|
+
operationType: "reflection",
|
|
30139
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
30140
|
+
tokensAttempted: observationTokens,
|
|
30141
|
+
error: error instanceof Error ? error.message : String(error),
|
|
30142
|
+
recordId: record.id,
|
|
30143
|
+
threadId: record.threadId ?? ""
|
|
30144
|
+
});
|
|
30145
|
+
writer.custom({
|
|
30146
|
+
...failedMarker,
|
|
30147
|
+
transient: true
|
|
30148
|
+
}).catch(() => {});
|
|
30149
|
+
await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
|
|
30150
|
+
} catch (markerError) {
|
|
30151
|
+
omError("[OM] Failed to persist buffering-failed marker after async buffered reflection failure", markerError);
|
|
30152
|
+
}
|
|
30153
|
+
omError("[OM] Async buffered reflection failed", error);
|
|
30154
|
+
try {
|
|
30155
|
+
reflectionHooks?.onReflectionEnd?.({
|
|
30156
|
+
usage: void 0,
|
|
30157
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
30158
|
+
});
|
|
30159
|
+
} catch (hookError) {
|
|
30160
|
+
omError("[OM] onReflectionEnd hook failed after async buffered reflection failure", hookError);
|
|
30161
|
+
}
|
|
30162
|
+
BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
|
|
30163
|
+
}).finally(() => {
|
|
30164
|
+
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
30165
|
+
unregisterOp(record.id, "bufferingReflection");
|
|
30166
|
+
this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
|
|
30167
|
+
omError("[OM] Failed to clear buffering reflection flag", err);
|
|
30168
|
+
});
|
|
30169
|
+
});
|
|
30361
30170
|
BufferingCoordinator.asyncBufferingOps.set(bufferKey, asyncOp);
|
|
30362
30171
|
}
|
|
30363
30172
|
/**
|
|
@@ -30618,13 +30427,6 @@ var ReflectorRunner = class {
|
|
|
30618
30427
|
return;
|
|
30619
30428
|
}
|
|
30620
30429
|
}
|
|
30621
|
-
if (activationTriggeredBy === "threshold") {
|
|
30622
|
-
const suppressedAtTokens = this.syncReflectionSuppression.get(lockKey);
|
|
30623
|
-
if (suppressedAtTokens !== void 0 && observationTokens === suppressedAtTokens) {
|
|
30624
|
-
omDebug(`[OM:reflect] skipping sync reflection — observations unchanged at ${observationTokens} tokens since the last unproductive attempt; retrying once they change`);
|
|
30625
|
-
return;
|
|
30626
|
-
}
|
|
30627
|
-
}
|
|
30628
30430
|
await this.storage.setReflectingFlag(record.id, true);
|
|
30629
30431
|
registerOp(record.id, "reflecting");
|
|
30630
30432
|
const cycleId = crypto.randomUUID();
|
|
@@ -30665,15 +30467,8 @@ var ReflectorRunner = class {
|
|
|
30665
30467
|
let reflectionUsage;
|
|
30666
30468
|
let reflectionProviderMetadata;
|
|
30667
30469
|
let reflectionError;
|
|
30668
|
-
|
|
30470
|
+
reflectionHooks?.onReflectionStart?.();
|
|
30669
30471
|
try {
|
|
30670
|
-
try {
|
|
30671
|
-
await reflectionHooks?.onReflectionStart?.();
|
|
30672
|
-
} catch (error) {
|
|
30673
|
-
lifecycleError = error;
|
|
30674
|
-
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
30675
|
-
throw error;
|
|
30676
|
-
}
|
|
30677
30472
|
const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
|
|
30678
30473
|
const reflectResult = await this.call(record.activeObservations, void 0, streamContext, reflectThreshold, abortSignal, void 0, compressionStartLevel, requestContext, priorExtractedValues, observabilityContext, void 0, mainAgent, sendSignal);
|
|
30679
30474
|
reflectionUsage = reflectResult.usage;
|
|
@@ -30685,8 +30480,6 @@ var ReflectorRunner = class {
|
|
|
30685
30480
|
reflection: reflectResult.observations,
|
|
30686
30481
|
tokenCount: reflectionTokenCount
|
|
30687
30482
|
});
|
|
30688
|
-
if (reflectionTokenCount >= reflectThreshold) this.syncReflectionSuppression.set(lockKey, reflectionTokenCount);
|
|
30689
|
-
else this.syncReflectionSuppression.delete(lockKey);
|
|
30690
30483
|
await this.notifyReflectionCommitted({
|
|
30691
30484
|
parentThreadId: requestedThreadId ?? record.threadId ?? "",
|
|
30692
30485
|
resourceId: record.resourceId ?? "",
|
|
@@ -30745,28 +30538,18 @@ var ReflectorRunner = class {
|
|
|
30745
30538
|
await this.persistMarkerToStorage(failedMarker, threadId, record.resourceId ?? void 0);
|
|
30746
30539
|
}
|
|
30747
30540
|
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
30748
|
-
if (
|
|
30749
|
-
this.syncReflectionSuppression.set(lockKey, observationTokens);
|
|
30541
|
+
if (abortSignal?.aborted) throw error;
|
|
30750
30542
|
omError("[OM] Reflection failed", error);
|
|
30751
30543
|
} finally {
|
|
30544
|
+
await this.storage.setReflectingFlag(record.id, false);
|
|
30752
30545
|
try {
|
|
30753
|
-
|
|
30754
|
-
} finally {
|
|
30755
|
-
unregisterOp(record.id, "reflecting");
|
|
30756
|
-
}
|
|
30757
|
-
let endHookError;
|
|
30758
|
-
try {
|
|
30759
|
-
await reflectionHooks?.onReflectionEnd?.({
|
|
30546
|
+
reflectionHooks?.onReflectionEnd?.({
|
|
30760
30547
|
usage: reflectionUsage,
|
|
30761
30548
|
error: reflectionError,
|
|
30762
30549
|
...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
|
|
30763
30550
|
});
|
|
30764
|
-
}
|
|
30765
|
-
|
|
30766
|
-
}
|
|
30767
|
-
if (endHookError !== void 0) {
|
|
30768
|
-
if (lifecycleError === void 0 && !abortSignal?.aborted) throw endHookError;
|
|
30769
|
-
omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
30551
|
+
} finally {
|
|
30552
|
+
unregisterOp(record.id, "reflecting");
|
|
30770
30553
|
}
|
|
30771
30554
|
}
|
|
30772
30555
|
}
|
|
@@ -31089,24 +30872,10 @@ function getLatestStepParts(parts) {
|
|
|
31089
30872
|
return parts;
|
|
31090
30873
|
}
|
|
31091
30874
|
/**
|
|
31092
|
-
* Returns true
|
|
31093
|
-
*
|
|
31094
|
-
*
|
|
31095
|
-
* loop that can overwrite stored working memory (#21961). Only the working-memory lane
|
|
31096
|
-
* is filtered — other state lanes are outside OM's write path, so re-observing them
|
|
31097
|
-
* cannot corrupt OM-managed state; excluding them broadly is a separate decision.
|
|
30875
|
+
* Returns true when a message contains at least one part with visible user/assistant
|
|
30876
|
+
* content (text, tool-invocation, reasoning, image, file). Messages that only carry
|
|
30877
|
+
* internal `data-*` parts (buffering markers, observation markers, etc.) return false.
|
|
31098
30878
|
*/
|
|
31099
|
-
function isWorkingMemoryStateSignal(message) {
|
|
31100
|
-
if (message.role !== "signal") return false;
|
|
31101
|
-
const signal = message.content.metadata?.signal;
|
|
31102
|
-
if (!signal || typeof signal !== "object" || Array.isArray(signal)) return false;
|
|
31103
|
-
const signalRecord = signal;
|
|
31104
|
-
if ((signalRecord.type ?? message.type) !== "state") return false;
|
|
31105
|
-
const metadata = signalRecord.metadata;
|
|
31106
|
-
if (!metadata || typeof metadata !== "object" || Array.isArray(metadata)) return false;
|
|
31107
|
-
const state = metadata.state;
|
|
31108
|
-
return !!state && typeof state === "object" && !Array.isArray(state) && state.id === "working-memory";
|
|
31109
|
-
}
|
|
31110
30879
|
function messageHasVisibleContent(msg) {
|
|
31111
30880
|
const content = msg.content;
|
|
31112
30881
|
if (content?.parts && Array.isArray(content.parts)) return content.parts.some((p) => {
|
|
@@ -31237,8 +31006,6 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
31237
31006
|
onIndexObservations;
|
|
31238
31007
|
/** Config-level lifecycle hooks fired for every observation/reflection cycle. */
|
|
31239
31008
|
hooks;
|
|
31240
|
-
/** Execution policy for config-level hooks on manual and turn-synchronous cycles. */
|
|
31241
|
-
hookExecution;
|
|
31242
31009
|
/** Observer agent runner — handles LLM calls for extracting observations. */
|
|
31243
31010
|
observer;
|
|
31244
31011
|
/** Reflector agent runner — handles LLM calls for compressing observations. */
|
|
@@ -31345,7 +31112,6 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
31345
31112
|
this.retrievalSearch = typeof config.retrieval === "object" && Boolean(config.retrieval.vector);
|
|
31346
31113
|
this.onIndexObservations = config.onIndexObservations;
|
|
31347
31114
|
this.hooks = config.hooks;
|
|
31348
|
-
this.hookExecution = config.hookExecution ?? "non-blocking";
|
|
31349
31115
|
this.mastra = config.mastra;
|
|
31350
31116
|
this.memory = config.memory;
|
|
31351
31117
|
this.curationCadence = config.curationCadence;
|
|
@@ -31877,7 +31643,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
31877
31643
|
}
|
|
31878
31644
|
const result = [];
|
|
31879
31645
|
for (const msg of allMessages) {
|
|
31880
|
-
if (msg.role === "system"
|
|
31646
|
+
if (msg.role === "system") continue;
|
|
31881
31647
|
if (observedMessageIds?.has(msg.id)) continue;
|
|
31882
31648
|
const endMarkerIndex = findLastCompletedObservationBoundary(msg);
|
|
31883
31649
|
if (this.hasInProgressObservation(msg)) result.push(msg);
|
|
@@ -32099,7 +31865,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
32099
31865
|
},
|
|
32100
31866
|
filter: startDate ? { dateRange: { start: startDate } } : void 0
|
|
32101
31867
|
});
|
|
32102
|
-
return result.messages.filter((msg) => msg.role !== "system"
|
|
31868
|
+
return result.messages.filter((msg) => msg.role !== "system");
|
|
32103
31869
|
}
|
|
32104
31870
|
/**
|
|
32105
31871
|
* Format unobserved messages from other threads as <unobserved-context> blocks.
|
|
@@ -32558,7 +32324,7 @@ ${formattedMessages}
|
|
|
32558
32324
|
direction: "ASC"
|
|
32559
32325
|
},
|
|
32560
32326
|
filter: startDate ? { dateRange: { start: startDate } } : void 0
|
|
32561
|
-
})).messages.filter((
|
|
32327
|
+
})).messages.filter((m) => !this.observedMessageIds.has(m.id));
|
|
32562
32328
|
if (filtered.length > 0) messagesByThread.set(thread.id, filtered);
|
|
32563
32329
|
}
|
|
32564
32330
|
if (messagesByThread.size === 0) return void 0;
|
|
@@ -33138,54 +32904,57 @@ ${formattedMessages}
|
|
|
33138
32904
|
};
|
|
33139
32905
|
}
|
|
33140
32906
|
/**
|
|
33141
|
-
* Compose config-level hooks with optional per-call hooks
|
|
33142
|
-
*
|
|
33143
|
-
*
|
|
32907
|
+
* Compose the config-level hooks with optional per-call hooks into a single
|
|
32908
|
+
* `ObserveHooks` object, binding call context onto the config-level
|
|
32909
|
+
* callbacks. Config-level hooks are guarded so a throwing consumer hook can
|
|
32910
|
+
* never fail an observation/reflection cycle; per-call hooks keep their
|
|
32911
|
+
* existing payloads and propagation semantics. Returns undefined when
|
|
32912
|
+
* neither is configured, so call sites stay zero-cost.
|
|
32913
|
+
*
|
|
32914
|
+
* Used internally by every pipeline path (manual observe/reflect,
|
|
32915
|
+
* turn-engine sync observation, async buffering); public only so the
|
|
32916
|
+
* observation turn engine can thread config-level reflection hooks into
|
|
32917
|
+
* reflector calls.
|
|
33144
32918
|
*
|
|
33145
32919
|
* @internal
|
|
33146
32920
|
*/
|
|
33147
|
-
composeHooks(callHooks, context
|
|
32921
|
+
composeHooks(callHooks, context) {
|
|
33148
32922
|
const configHooks = this.hooks;
|
|
33149
32923
|
if (!configHooks) return callHooks;
|
|
33150
32924
|
if (!callHooks && !Object.keys(configHooks).length) return void 0;
|
|
33151
|
-
const
|
|
33152
|
-
const invokeConfigHook = async (name, arg) => {
|
|
32925
|
+
const fireConfigHook = (name, arg) => {
|
|
33153
32926
|
const hook = configHooks[name];
|
|
33154
32927
|
if (!hook) return;
|
|
33155
|
-
if (shouldAwaitConfig) {
|
|
33156
|
-
await hook(arg);
|
|
33157
|
-
return;
|
|
33158
|
-
}
|
|
33159
32928
|
const logHookFailure = (error) => omDebug(`[OM:hooks] config-level ${name} hook failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
33160
32929
|
try {
|
|
33161
|
-
const
|
|
33162
|
-
if (
|
|
32930
|
+
const out = hook(arg);
|
|
32931
|
+
if (out && typeof out.then === "function") out.then(void 0, logHookFailure);
|
|
33163
32932
|
} catch (error) {
|
|
33164
32933
|
logHookFailure(error);
|
|
33165
32934
|
}
|
|
33166
32935
|
};
|
|
33167
32936
|
return {
|
|
33168
|
-
onObservationStart:
|
|
33169
|
-
|
|
33170
|
-
|
|
32937
|
+
onObservationStart: () => {
|
|
32938
|
+
fireConfigHook("onObservationStart", context);
|
|
32939
|
+
callHooks?.onObservationStart?.();
|
|
33171
32940
|
},
|
|
33172
|
-
onObservationEnd:
|
|
33173
|
-
|
|
32941
|
+
onObservationEnd: (result) => {
|
|
32942
|
+
fireConfigHook("onObservationEnd", {
|
|
33174
32943
|
...context,
|
|
33175
32944
|
...result
|
|
33176
32945
|
});
|
|
33177
|
-
|
|
32946
|
+
callHooks?.onObservationEnd?.(result);
|
|
33178
32947
|
},
|
|
33179
|
-
onReflectionStart:
|
|
33180
|
-
|
|
33181
|
-
|
|
32948
|
+
onReflectionStart: () => {
|
|
32949
|
+
fireConfigHook("onReflectionStart", context);
|
|
32950
|
+
callHooks?.onReflectionStart?.();
|
|
33182
32951
|
},
|
|
33183
|
-
onReflectionEnd:
|
|
33184
|
-
|
|
32952
|
+
onReflectionEnd: (result) => {
|
|
32953
|
+
fireConfigHook("onReflectionEnd", {
|
|
33185
32954
|
...context,
|
|
33186
32955
|
...result
|
|
33187
32956
|
});
|
|
33188
|
-
|
|
32957
|
+
callHooks?.onReflectionEnd?.(result);
|
|
33189
32958
|
}
|
|
33190
32959
|
};
|
|
33191
32960
|
}
|
|
@@ -33198,29 +32967,22 @@ ${formattedMessages}
|
|
|
33198
32967
|
* end hook reports `error` for failed cycles even though nothing throws.
|
|
33199
32968
|
*/
|
|
33200
32969
|
async runBufferedObservationCycle(context, run) {
|
|
33201
|
-
const hooks = this.composeHooks(void 0, context
|
|
32970
|
+
const hooks = this.composeHooks(void 0, context);
|
|
32971
|
+
hooks?.onObservationStart?.();
|
|
33202
32972
|
let runResult;
|
|
33203
32973
|
let runError;
|
|
33204
|
-
let lifecycleError;
|
|
33205
32974
|
try {
|
|
33206
|
-
await hooks?.onObservationStart?.();
|
|
33207
32975
|
runResult = await run();
|
|
33208
32976
|
return runResult;
|
|
33209
32977
|
} catch (error) {
|
|
33210
|
-
lifecycleError = error;
|
|
33211
32978
|
runError = error instanceof Error ? error : new Error(String(error));
|
|
33212
32979
|
throw error;
|
|
33213
32980
|
} finally {
|
|
33214
|
-
|
|
33215
|
-
|
|
33216
|
-
|
|
33217
|
-
|
|
33218
|
-
|
|
33219
|
-
});
|
|
33220
|
-
} catch (endHookError) {
|
|
33221
|
-
if (lifecycleError === void 0) throw endHookError;
|
|
33222
|
-
omDebug(`[OM:hooks] async-buffer onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
33223
|
-
}
|
|
32981
|
+
hooks?.onObservationEnd?.({
|
|
32982
|
+
usage: runResult?.usage,
|
|
32983
|
+
error: runError ?? runResult?.error,
|
|
32984
|
+
...runResult?.providerMetadata ? { providerMetadata: runResult.providerMetadata } : {}
|
|
32985
|
+
});
|
|
33224
32986
|
}
|
|
33225
32987
|
}
|
|
33226
32988
|
/**
|
|
@@ -33248,21 +33010,18 @@ ${formattedMessages}
|
|
|
33248
33010
|
let observed = false;
|
|
33249
33011
|
let observationUsage;
|
|
33250
33012
|
let observationProviderMetadata;
|
|
33251
|
-
let observationError;
|
|
33252
|
-
let lifecycleError;
|
|
33253
|
-
let observationStarted = false;
|
|
33254
33013
|
let generationBefore = -1;
|
|
33255
|
-
|
|
33256
|
-
await this.
|
|
33257
|
-
|
|
33258
|
-
|
|
33259
|
-
|
|
33260
|
-
|
|
33261
|
-
|
|
33262
|
-
|
|
33263
|
-
|
|
33264
|
-
|
|
33265
|
-
|
|
33014
|
+
await this.withLock(lockKey, async () => {
|
|
33015
|
+
const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
|
|
33016
|
+
generationBefore = freshRecord.generationCount;
|
|
33017
|
+
const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadMessagesFromStorage(threadId, resourceId, freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : void 0);
|
|
33018
|
+
if (!this.meetsObservationThreshold({
|
|
33019
|
+
record: freshRecord,
|
|
33020
|
+
unobservedTokens: await this.tokenCounter.countMessagesAsync(unobservedMessages)
|
|
33021
|
+
})) return;
|
|
33022
|
+
hooks?.onObservationStart?.();
|
|
33023
|
+
let observationError;
|
|
33024
|
+
try {
|
|
33266
33025
|
const result = await ObservationStrategy.create(this, {
|
|
33267
33026
|
record: freshRecord,
|
|
33268
33027
|
threadId,
|
|
@@ -33280,22 +33039,17 @@ ${formattedMessages}
|
|
|
33280
33039
|
observed = result.observed;
|
|
33281
33040
|
observationUsage = result.usage;
|
|
33282
33041
|
observationProviderMetadata = result.providerMetadata;
|
|
33283
|
-
})
|
|
33284
|
-
|
|
33285
|
-
|
|
33286
|
-
|
|
33287
|
-
|
|
33288
|
-
|
|
33289
|
-
|
|
33290
|
-
|
|
33291
|
-
|
|
33292
|
-
|
|
33293
|
-
|
|
33294
|
-
} catch (endHookError) {
|
|
33295
|
-
if (lifecycleError === void 0) throw endHookError;
|
|
33296
|
-
omDebug(`[OM:hooks] onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
33297
|
-
}
|
|
33298
|
-
if (lifecycleError !== void 0) throw lifecycleError;
|
|
33042
|
+
} catch (error) {
|
|
33043
|
+
observationError = error instanceof Error ? error : new Error(String(error));
|
|
33044
|
+
throw error;
|
|
33045
|
+
} finally {
|
|
33046
|
+
hooks?.onObservationEnd?.({
|
|
33047
|
+
usage: observationUsage,
|
|
33048
|
+
error: observationError,
|
|
33049
|
+
...observationProviderMetadata ? { providerMetadata: observationProviderMetadata } : {}
|
|
33050
|
+
});
|
|
33051
|
+
}
|
|
33052
|
+
});
|
|
33299
33053
|
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
33300
33054
|
const reflected = record.generationCount > generationBefore && generationBefore >= 0;
|
|
33301
33055
|
if (observed) this.maybeTriggerCadenceCuration(threadId, resourceId, record, requestContext).catch((error) => {
|
|
@@ -33369,18 +33123,11 @@ ${formattedMessages}
|
|
|
33369
33123
|
resourceId,
|
|
33370
33124
|
trigger: "manual"
|
|
33371
33125
|
});
|
|
33126
|
+
hooks?.onReflectionStart?.();
|
|
33372
33127
|
let reflectionUsage;
|
|
33373
33128
|
let reflectionProviderMetadata;
|
|
33374
33129
|
let reflectionError;
|
|
33375
|
-
let lifecycleError;
|
|
33376
33130
|
try {
|
|
33377
|
-
try {
|
|
33378
|
-
await hooks?.onReflectionStart?.();
|
|
33379
|
-
} catch (error) {
|
|
33380
|
-
lifecycleError = error;
|
|
33381
|
-
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
33382
|
-
throw error;
|
|
33383
|
-
}
|
|
33384
33131
|
const thread = await this.storage.getThreadById({ threadId });
|
|
33385
33132
|
const previousOmMetadata = getThreadOMMetadata(thread?.metadata);
|
|
33386
33133
|
const priorExtractedValues = getPriorExtractedValues(previousOmMetadata, this.reflectionConfig.extractors);
|
|
@@ -33418,7 +33165,6 @@ ${formattedMessages}
|
|
|
33418
33165
|
};
|
|
33419
33166
|
} catch (error) {
|
|
33420
33167
|
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
33421
|
-
if (lifecycleError !== void 0) throw error;
|
|
33422
33168
|
omError("[OM] reflect() failed", error);
|
|
33423
33169
|
return {
|
|
33424
33170
|
reflected: false,
|
|
@@ -33426,25 +33172,13 @@ ${formattedMessages}
|
|
|
33426
33172
|
usage: void 0
|
|
33427
33173
|
};
|
|
33428
33174
|
} finally {
|
|
33429
|
-
|
|
33430
|
-
|
|
33431
|
-
|
|
33432
|
-
|
|
33433
|
-
}
|
|
33434
|
-
|
|
33435
|
-
|
|
33436
|
-
await hooks?.onReflectionEnd?.({
|
|
33437
|
-
usage: reflectionUsage,
|
|
33438
|
-
error: reflectionError,
|
|
33439
|
-
...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
|
|
33440
|
-
});
|
|
33441
|
-
} catch (error) {
|
|
33442
|
-
endHookError = error;
|
|
33443
|
-
}
|
|
33444
|
-
if (endHookError !== void 0) {
|
|
33445
|
-
if (lifecycleError === void 0) throw endHookError;
|
|
33446
|
-
omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
33447
|
-
}
|
|
33175
|
+
hooks?.onReflectionEnd?.({
|
|
33176
|
+
usage: reflectionUsage,
|
|
33177
|
+
error: reflectionError,
|
|
33178
|
+
...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
|
|
33179
|
+
});
|
|
33180
|
+
await this.storage.setReflectingFlag(record.id, false);
|
|
33181
|
+
unregisterOp(record.id, "reflecting");
|
|
33448
33182
|
}
|
|
33449
33183
|
}
|
|
33450
33184
|
/**
|
|
@@ -33975,6 +33709,149 @@ var observational_memory_exports = /* @__PURE__ */ __exportAll({
|
|
|
33975
33709
|
summarizeConversation: () => summarizeConversation,
|
|
33976
33710
|
wrapInObservationGroup: () => wrapInObservationGroup
|
|
33977
33711
|
});
|
|
33712
|
+
/**
|
|
33713
|
+
* WorkingMemoryStateProcessor
|
|
33714
|
+
*
|
|
33715
|
+
* Experimental: delivers working memory to the model as a state signal instead
|
|
33716
|
+
* of folding it into the system message. Storage and the `setWorkingMemory`
|
|
33717
|
+
* tool are unchanged — this processor only changes the delivery path.
|
|
33718
|
+
*
|
|
33719
|
+
* Pattern matches `BrowserContextProcessor` in `@mastra/core/browser`:
|
|
33720
|
+
* - `stateId` namespaces the state lane on the thread.
|
|
33721
|
+
* - `cacheKey` is derived from the rendered payload so dedup is automatic.
|
|
33722
|
+
* - `contextWindow.hasSnapshot` re-injection ensures the model still sees the
|
|
33723
|
+
* current snapshot after older messages drop out of the window.
|
|
33724
|
+
*
|
|
33725
|
+
* Delta emission (markdown mode only): when a prior snapshot exists in the
|
|
33726
|
+
* context window, the processor emits a unified-diff delta against that
|
|
33727
|
+
* snapshot's contents. Schema mode and the snapshot fallback always emit a
|
|
33728
|
+
* full snapshot.
|
|
33729
|
+
*
|
|
33730
|
+
* @example
|
|
33731
|
+
* ```ts
|
|
33732
|
+
* new Memory({
|
|
33733
|
+
* options: {
|
|
33734
|
+
* workingMemory: {
|
|
33735
|
+
* enabled: true,
|
|
33736
|
+
* template: '...',
|
|
33737
|
+
* useStateSignals: true, // auto-attaches this processor
|
|
33738
|
+
* },
|
|
33739
|
+
* },
|
|
33740
|
+
* });
|
|
33741
|
+
* ```
|
|
33742
|
+
*/
|
|
33743
|
+
const WORKING_MEMORY_STATE_ID = "working-memory";
|
|
33744
|
+
const WORKING_MEMORY_STATE_PROCESSOR_ID = "working-memory-state";
|
|
33745
|
+
var WorkingMemoryStateProcessor = class {
|
|
33746
|
+
memory;
|
|
33747
|
+
memoryConfig;
|
|
33748
|
+
id = WORKING_MEMORY_STATE_PROCESSOR_ID;
|
|
33749
|
+
stateId = WORKING_MEMORY_STATE_ID;
|
|
33750
|
+
constructor(memory, memoryConfig) {
|
|
33751
|
+
this.memory = memory;
|
|
33752
|
+
this.memoryConfig = memoryConfig;
|
|
33753
|
+
}
|
|
33754
|
+
async computeStateSignal(args) {
|
|
33755
|
+
const template = await this.memory.getWorkingMemoryTemplate({ memoryConfig: this.memoryConfig });
|
|
33756
|
+
if (!template) return;
|
|
33757
|
+
const contents = (await this.memory.getWorkingMemory({
|
|
33758
|
+
threadId: args.threadId,
|
|
33759
|
+
resourceId: args.resourceId,
|
|
33760
|
+
memoryConfig: this.memoryConfig
|
|
33761
|
+
}))?.trim();
|
|
33762
|
+
if (!contents) return;
|
|
33763
|
+
const cacheKey = stableWorkingMemoryCacheKey({
|
|
33764
|
+
format: template.format,
|
|
33765
|
+
data: contents
|
|
33766
|
+
});
|
|
33767
|
+
const shouldMakeSnapshot = !args.contextWindow.hasSnapshot;
|
|
33768
|
+
if (args.tracking?.currentCacheKey === cacheKey && !shouldMakeSnapshot) return;
|
|
33769
|
+
const scope = this.memory.getMergedThreadConfig(this.memoryConfig).workingMemory?.scope ?? "resource";
|
|
33770
|
+
const deltaCandidate = template.format === "markdown" && !shouldMakeSnapshot ? buildMarkdownDelta({
|
|
33771
|
+
lastSnapshot: args.lastSnapshot,
|
|
33772
|
+
deltasSinceSnapshot: args.deltasSinceSnapshot,
|
|
33773
|
+
nextContents: contents
|
|
33774
|
+
}) : void 0;
|
|
33775
|
+
if (deltaCandidate) return {
|
|
33776
|
+
id: WORKING_MEMORY_STATE_ID,
|
|
33777
|
+
mode: "delta",
|
|
33778
|
+
cacheKey,
|
|
33779
|
+
tagName: "working-memory",
|
|
33780
|
+
contents: deltaCandidate.contents,
|
|
33781
|
+
delta: deltaCandidate.contents,
|
|
33782
|
+
value: contents,
|
|
33783
|
+
attributes: {
|
|
33784
|
+
format: template.format,
|
|
33785
|
+
scope,
|
|
33786
|
+
patch: "unified-diff"
|
|
33787
|
+
}
|
|
33788
|
+
};
|
|
33789
|
+
return {
|
|
33790
|
+
id: WORKING_MEMORY_STATE_ID,
|
|
33791
|
+
mode: "snapshot",
|
|
33792
|
+
cacheKey,
|
|
33793
|
+
tagName: "working-memory",
|
|
33794
|
+
contents,
|
|
33795
|
+
value: contents,
|
|
33796
|
+
attributes: {
|
|
33797
|
+
format: template.format,
|
|
33798
|
+
scope
|
|
33799
|
+
}
|
|
33800
|
+
};
|
|
33801
|
+
}
|
|
33802
|
+
};
|
|
33803
|
+
/**
|
|
33804
|
+
* Stable cache key for the rendered working memory payload. Returns a SHA-256
|
|
33805
|
+
* digest so dedup metadata stays compact regardless of payload size (working
|
|
33806
|
+
* memory blobs can grow arbitrarily long).
|
|
33807
|
+
*/
|
|
33808
|
+
function stableWorkingMemoryCacheKey(input) {
|
|
33809
|
+
const hash = createHash("sha256");
|
|
33810
|
+
hash.update(input.format);
|
|
33811
|
+
hash.update("\0");
|
|
33812
|
+
hash.update(input.data ?? "");
|
|
33813
|
+
return `sha256:${hash.digest("hex")}`;
|
|
33814
|
+
}
|
|
33815
|
+
/**
|
|
33816
|
+
* Build a unified-diff delta against the most recently emitted state. Prefers
|
|
33817
|
+
* the latest delta's `value` (the post-edit full text) when available, falling
|
|
33818
|
+
* back to the snapshot's `value` and finally the snapshot's `contents`. This
|
|
33819
|
+
* keeps deltas incremental (B→C) instead of cumulative against a stale
|
|
33820
|
+
* snapshot (A→C), which matters when many small edits land between snapshots.
|
|
33821
|
+
*
|
|
33822
|
+
* Returns undefined when:
|
|
33823
|
+
* - there's no prior state to diff against
|
|
33824
|
+
* - the prior state isn't a plain string (multimodal signal)
|
|
33825
|
+
*
|
|
33826
|
+
* In either case the caller falls back to emitting a full snapshot.
|
|
33827
|
+
*/
|
|
33828
|
+
function buildMarkdownDelta(args) {
|
|
33829
|
+
const { lastSnapshot, deltasSinceSnapshot, nextContents } = args;
|
|
33830
|
+
const prior = pickStringValue(readSignalValue(deltasSinceSnapshot.at(-1))) ?? pickStringValue(readSignalValue(lastSnapshot)) ?? (typeof lastSnapshot?.contents === "string" ? lastSnapshot.contents : void 0);
|
|
33831
|
+
if (!prior) return;
|
|
33832
|
+
return { contents: renderHunksOnly(prior, nextContents) };
|
|
33833
|
+
}
|
|
33834
|
+
function pickStringValue(value) {
|
|
33835
|
+
return typeof value === "string" ? value : void 0;
|
|
33836
|
+
}
|
|
33837
|
+
function readSignalValue(signal) {
|
|
33838
|
+
return (signal?.metadata)?.value;
|
|
33839
|
+
}
|
|
33840
|
+
/**
|
|
33841
|
+
* Render a unified-diff-style patch body containing only `@@` hunks and their
|
|
33842
|
+
* lines — dropping the filename preamble (`Index:` / `===` / `---` / `+++`)
|
|
33843
|
+
* that `createPatch` emits and the `` trailer.
|
|
33844
|
+
* The preamble exists for tooling like `patch -p1` to know which file to
|
|
33845
|
+
* apply to; we only ever diff a single working-memory blob. The newline
|
|
33846
|
+
* trailer is semantically meaningless to the model and adds noise to the
|
|
33847
|
+
* state signal.
|
|
33848
|
+
*/
|
|
33849
|
+
function renderHunksOnly(prior, next) {
|
|
33850
|
+
const { hunks } = structuredPatch("", "", prior, next, "", "", { context: 0 });
|
|
33851
|
+
return hunks.map((hunk) => {
|
|
33852
|
+
return [`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`, ...hunk.lines.filter((line) => !line.startsWith("\"))].join("\n");
|
|
33853
|
+
}).join("\n");
|
|
33854
|
+
}
|
|
33978
33855
|
var working_memory_state_exports = /* @__PURE__ */ __exportAll({
|
|
33979
33856
|
WORKING_MEMORY_STATE_ID: () => WORKING_MEMORY_STATE_ID,
|
|
33980
33857
|
WORKING_MEMORY_STATE_PROCESSOR_ID: () => WORKING_MEMORY_STATE_PROCESSOR_ID,
|
|
@@ -35055,7 +34932,6 @@ ${workingMemory}`;
|
|
|
35055
34932
|
instruction: omConfig.observation.instruction,
|
|
35056
34933
|
threadTitle: omConfig.observation.threadTitle,
|
|
35057
34934
|
observeAttachments: omConfig.observation.observeAttachments,
|
|
35058
|
-
continuationHints: omConfig.observation.continuationHints,
|
|
35059
34935
|
extract: omConfig.observation.extract
|
|
35060
34936
|
} : void 0,
|
|
35061
34937
|
reflection: omConfig.reflection ? {
|
|
@@ -35066,7 +34942,6 @@ ${workingMemory}`;
|
|
|
35066
34942
|
bufferActivation: omConfig.reflection.bufferActivation,
|
|
35067
34943
|
blockAfter: omConfig.reflection.blockAfter,
|
|
35068
34944
|
instruction: omConfig.reflection.instruction,
|
|
35069
|
-
continuationHints: omConfig.reflection.continuationHints,
|
|
35070
34945
|
extract: omConfig.reflection.extract
|
|
35071
34946
|
} : void 0
|
|
35072
34947
|
});
|
|
@@ -41234,7 +41109,6 @@ async function cancelResponseBody(response) {
|
|
|
41234
41109
|
var initialGlobalFetch = globalThis.fetch;
|
|
41235
41110
|
isNodeDefaultFetch(initialGlobalFetch);
|
|
41236
41111
|
function isNodeDefaultFetch(fetch) {
|
|
41237
|
-
if (typeof fetch !== "function") return false;
|
|
41238
41112
|
const source = Function.prototype.toString.call(fetch);
|
|
41239
41113
|
return source.includes("internal/deps/undici") || source.includes("lazy loading of undici");
|
|
41240
41114
|
}
|
|
@@ -46361,4 +46235,4 @@ const agentBuilderWorkflows = {
|
|
|
46361
46235
|
//#endregion
|
|
46362
46236
|
export { agentBuilderWorkflows };
|
|
46363
46237
|
|
|
46364
|
-
//# sourceMappingURL=dist-
|
|
46238
|
+
//# sourceMappingURL=dist-HzWDFjPH.js.map
|