@mastra/memory 1.27.0 → 1.28.0-alpha.2
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 +50 -0
- package/dist/docs/SKILL.md +4 -2
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-guides-context-engineering.md +297 -0
- package/dist/docs/references/docs-storage.md +1 -0
- package/dist/docs/references/integrations-databases-mongodb.md +1 -1
- package/dist/docs/references/integrations-databases-postgresql.md +2 -0
- package/dist/docs/references/integrations-databases-valkey.md +99 -0
- package/dist/docs/references/reference-vectors-mongodb.md +11 -11
- package/dist/docs/references/reference-vectors-pg.md +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +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/observation-turn/load-memory-context.d.ts +3 -1
- package/dist/processors/observational-memory/observation-turn/load-memory-context.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +2 -1
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +6 -12
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts +2 -0
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/tracing.d.ts.map +1 -1
- package/dist/processors/observational-memory/types.d.ts +23 -13
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/dist/{src-CxkQ-ICG.cjs → src-CIBCjg2A.cjs} +272 -158
- package/dist/{src-CxkQ-ICG.cjs.map → src-CIBCjg2A.cjs.map} +1 -1
- package/dist/{src-aTfbkxBl.js → src-kLYHhPqh.js} +272 -158
- package/dist/{src-aTfbkxBl.js.map → src-kLYHhPqh.js.map} +1 -1
- package/package.json +7 -7
|
@@ -18926,6 +18926,12 @@ function extractListItemsOnly(content) {
|
|
|
18926
18926
|
*/
|
|
18927
18927
|
const MAX_OBSERVATION_LINE_CHARS = 1e4;
|
|
18928
18928
|
/**
|
|
18929
|
+
* Minimum trimmed line length considered by the duplicate-line degenerate
|
|
18930
|
+
* check. Short lines (blank lines, separators, terse bullets) legitimately
|
|
18931
|
+
* repeat; long identical lines almost never do.
|
|
18932
|
+
*/
|
|
18933
|
+
const MIN_DUPLICATE_LINE_CHARS = 24;
|
|
18934
|
+
/**
|
|
18929
18935
|
* Truncate individual observation lines that exceed the maximum length.
|
|
18930
18936
|
*/
|
|
18931
18937
|
function sanitizeObservationLines(observations) {
|
|
@@ -18963,6 +18969,18 @@ function detectDegenerateRepetition(text) {
|
|
|
18963
18969
|
if (totalWindows > 5 && duplicateWindows / totalWindows > .4) return true;
|
|
18964
18970
|
const lines = text.split("\n");
|
|
18965
18971
|
for (const line of lines) if (line.length > 5e4) return true;
|
|
18972
|
+
const seenLines = /* @__PURE__ */ new Map();
|
|
18973
|
+
let duplicateLines = 0;
|
|
18974
|
+
let totalCountedLines = 0;
|
|
18975
|
+
for (const line of lines) {
|
|
18976
|
+
const trimmed = line.trim();
|
|
18977
|
+
if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
|
|
18978
|
+
totalCountedLines++;
|
|
18979
|
+
const count = (seenLines.get(trimmed) ?? 0) + 1;
|
|
18980
|
+
seenLines.set(trimmed, count);
|
|
18981
|
+
if (count > 1) duplicateLines++;
|
|
18982
|
+
}
|
|
18983
|
+
if (totalCountedLines >= 20 && duplicateLines / totalCountedLines > .5) return true;
|
|
18966
18984
|
return false;
|
|
18967
18985
|
}
|
|
18968
18986
|
/**
|
|
@@ -18997,12 +19015,26 @@ function describeDegenerateOutput(text, snippetChars = 400) {
|
|
|
18997
19015
|
topWindow = window;
|
|
18998
19016
|
}
|
|
18999
19017
|
let longestLine = 0;
|
|
19000
|
-
|
|
19018
|
+
const seenLines = /* @__PURE__ */ new Map();
|
|
19019
|
+
let duplicateLines = 0;
|
|
19020
|
+
let totalCountedLines = 0;
|
|
19021
|
+
for (const line of text.split("\n")) {
|
|
19022
|
+
if (line.length > longestLine) longestLine = line.length;
|
|
19023
|
+
const trimmed = line.trim();
|
|
19024
|
+
if (trimmed.length < MIN_DUPLICATE_LINE_CHARS) continue;
|
|
19025
|
+
totalCountedLines++;
|
|
19026
|
+
const count = (seenLines.get(trimmed) ?? 0) + 1;
|
|
19027
|
+
seenLines.set(trimmed, count);
|
|
19028
|
+
if (count > 1) duplicateLines++;
|
|
19029
|
+
}
|
|
19001
19030
|
const duplicateRatio = totalWindows > 0 ? (duplicateWindows / totalWindows).toFixed(2) : "n/a";
|
|
19031
|
+
const duplicateLineRatio = totalCountedLines > 0 ? (duplicateLines / totalCountedLines).toFixed(2) : "n/a";
|
|
19002
19032
|
const parts = [
|
|
19003
19033
|
`length=${text.length}`,
|
|
19004
19034
|
`sampledWindows=${totalWindows}`,
|
|
19005
19035
|
`duplicateRatio=${duplicateRatio}`,
|
|
19036
|
+
`duplicateLineRatio=${duplicateLineRatio}`,
|
|
19037
|
+
`countedLines=${totalCountedLines}`,
|
|
19006
19038
|
`longestLine=${longestLine}`,
|
|
19007
19039
|
`topWindowCount=${topCount}`
|
|
19008
19040
|
];
|
|
@@ -19276,7 +19308,19 @@ async function withOmTracingSpan({ phase, model, inputTokens, requestContext, ob
|
|
|
19276
19308
|
});
|
|
19277
19309
|
const childObservabilityContext = (0, _mastra_core_observability.createObservabilityContext)({ currentSpan: span });
|
|
19278
19310
|
if (!span) return callback(childObservabilityContext);
|
|
19279
|
-
return span.executeInContext(() =>
|
|
19311
|
+
return span.executeInContext(async () => {
|
|
19312
|
+
try {
|
|
19313
|
+
const result = await callback(childObservabilityContext);
|
|
19314
|
+
span.end();
|
|
19315
|
+
return result;
|
|
19316
|
+
} catch (error) {
|
|
19317
|
+
span.error({
|
|
19318
|
+
error,
|
|
19319
|
+
endSpan: true
|
|
19320
|
+
});
|
|
19321
|
+
throw error;
|
|
19322
|
+
}
|
|
19323
|
+
});
|
|
19280
19324
|
}
|
|
19281
19325
|
//#endregion
|
|
19282
19326
|
//#region src/processors/observational-memory/observer-runner.ts
|
|
@@ -24413,10 +24457,11 @@ ObservationStrategy.create = ((om, opts) => {
|
|
|
24413
24457
|
});
|
|
24414
24458
|
//#endregion
|
|
24415
24459
|
//#region src/processors/observational-memory/observation-turn/load-memory-context.ts
|
|
24416
|
-
async function loadMemoryContextMessages({ memory, messageList, threadId, resourceId }) {
|
|
24460
|
+
async function loadMemoryContextMessages({ memory, messageList, threadId, resourceId, runState }) {
|
|
24417
24461
|
const ctx = await memory.getContext({
|
|
24418
24462
|
threadId,
|
|
24419
|
-
resourceId
|
|
24463
|
+
resourceId,
|
|
24464
|
+
runState
|
|
24420
24465
|
});
|
|
24421
24466
|
for (const msg of ctx.messages) if (msg.role !== "system") messageList.add(msg, "memory");
|
|
24422
24467
|
return ctx;
|
|
@@ -24874,10 +24919,11 @@ var ObservationTurn = class {
|
|
|
24874
24919
|
* If a MemoryContextProvider is passed, loads historical messages and adds
|
|
24875
24920
|
* them to the MessageList. Without a provider, only fetches/caches the record.
|
|
24876
24921
|
*/
|
|
24877
|
-
async start(memory) {
|
|
24922
|
+
async start(memory, runState) {
|
|
24878
24923
|
if (this._started) throw new Error("Turn already started");
|
|
24879
24924
|
this._started = true;
|
|
24880
24925
|
this._record = await this.om.getOrCreateRecord(this.threadId, this.resourceId);
|
|
24926
|
+
runState?.set(`observational-memory:record:${this.threadId}:${this.resourceId ?? ""}`, this._record);
|
|
24881
24927
|
this._generationCountAtStart = this._record.generationCount;
|
|
24882
24928
|
this.memory = memory;
|
|
24883
24929
|
if (memory) {
|
|
@@ -24885,7 +24931,8 @@ var ObservationTurn = class {
|
|
|
24885
24931
|
memory,
|
|
24886
24932
|
messageList: this.messageList,
|
|
24887
24933
|
threadId: this.threadId,
|
|
24888
|
-
resourceId: this.resourceId
|
|
24934
|
+
resourceId: this.resourceId,
|
|
24935
|
+
runState
|
|
24889
24936
|
});
|
|
24890
24937
|
this._context = {
|
|
24891
24938
|
messages: ctx.messages,
|
|
@@ -25447,8 +25494,6 @@ var ReflectorRunner = class {
|
|
|
25447
25494
|
};
|
|
25448
25495
|
let reflectedTokens = 0;
|
|
25449
25496
|
let attemptNumber = 0;
|
|
25450
|
-
/** Observations from the previous attempt, used to detect a no-progress ladder. */
|
|
25451
|
-
let previousObservations;
|
|
25452
25497
|
while (currentLevel <= maxLevel) {
|
|
25453
25498
|
attemptNumber++;
|
|
25454
25499
|
const isRetry = attemptNumber > 1;
|
|
@@ -25522,11 +25567,6 @@ var ReflectorRunner = class {
|
|
|
25522
25567
|
omDebug(`[OM:callReflector] degenerate output persists at maxLevel=${maxLevel}, breaking`);
|
|
25523
25568
|
break;
|
|
25524
25569
|
}
|
|
25525
|
-
if (!parsed.degenerate && previousObservations !== void 0 && parsed.observations === previousObservations) {
|
|
25526
|
-
omDebug(`[OM:callReflector] attempt #${attemptNumber} returned output identical to the previous attempt; escalating cannot help, stopping the ladder`);
|
|
25527
|
-
break;
|
|
25528
|
-
}
|
|
25529
|
-
previousObservations = parsed.observations;
|
|
25530
25570
|
if (streamContext?.writer) {
|
|
25531
25571
|
const failedMarker = createObservationFailedMarker({
|
|
25532
25572
|
cycleId: streamContext.cycleId,
|
|
@@ -25610,52 +25650,51 @@ var ReflectorRunner = class {
|
|
|
25610
25650
|
this.storage.setBufferingReflectionFlag(record.id, true).catch((err) => {
|
|
25611
25651
|
omError("[OM] Failed to set buffering reflection flag", err);
|
|
25612
25652
|
});
|
|
25613
|
-
|
|
25614
|
-
|
|
25653
|
+
const asyncOp = (async () => {
|
|
25654
|
+
let outcome;
|
|
25655
|
+
let reflectionError;
|
|
25615
25656
|
try {
|
|
25616
|
-
reflectionHooks?.
|
|
25617
|
-
|
|
25618
|
-
|
|
25619
|
-
|
|
25620
|
-
|
|
25621
|
-
|
|
25622
|
-
|
|
25623
|
-
|
|
25624
|
-
|
|
25625
|
-
|
|
25626
|
-
|
|
25627
|
-
|
|
25628
|
-
|
|
25629
|
-
|
|
25630
|
-
|
|
25631
|
-
|
|
25632
|
-
|
|
25633
|
-
|
|
25634
|
-
|
|
25635
|
-
|
|
25636
|
-
|
|
25637
|
-
}
|
|
25638
|
-
|
|
25639
|
-
|
|
25640
|
-
|
|
25641
|
-
|
|
25642
|
-
|
|
25643
|
-
|
|
25644
|
-
|
|
25645
|
-
|
|
25646
|
-
|
|
25657
|
+
await reflectionHooks?.onReflectionStart?.();
|
|
25658
|
+
outcome = await this.doAsyncBufferedReflection(record, bufferKey, writer, requestContext, observabilityContext, priorExtractedValues, mainAgent, sendSignal);
|
|
25659
|
+
} catch (error) {
|
|
25660
|
+
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
25661
|
+
if (writer) try {
|
|
25662
|
+
const failedMarker = createBufferingFailedMarker({
|
|
25663
|
+
cycleId: `reflect-buf-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`,
|
|
25664
|
+
operationType: "reflection",
|
|
25665
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25666
|
+
tokensAttempted: observationTokens,
|
|
25667
|
+
error: reflectionError.message,
|
|
25668
|
+
recordId: record.id,
|
|
25669
|
+
threadId: record.threadId ?? ""
|
|
25670
|
+
});
|
|
25671
|
+
writer.custom({
|
|
25672
|
+
...failedMarker,
|
|
25673
|
+
transient: true
|
|
25674
|
+
}).catch(() => {});
|
|
25675
|
+
await this.persistMarkerToStorage(failedMarker, record.threadId ?? "", record.resourceId ?? void 0);
|
|
25676
|
+
} catch (markerError) {
|
|
25677
|
+
omError("[OM] Failed to persist buffering-failed marker after async buffered reflection failure", markerError);
|
|
25678
|
+
}
|
|
25679
|
+
omError("[OM] Async buffered reflection failed", error);
|
|
25680
|
+
BufferingCoordinator.lastBufferedBoundary.delete(bufferKey);
|
|
25681
|
+
} finally {
|
|
25682
|
+
try {
|
|
25683
|
+
await reflectionHooks?.onReflectionEnd?.({
|
|
25684
|
+
usage: outcome?.usage,
|
|
25685
|
+
error: reflectionError,
|
|
25686
|
+
...outcome?.providerMetadata ? { providerMetadata: outcome.providerMetadata } : {}
|
|
25687
|
+
});
|
|
25688
|
+
} catch (hookError) {
|
|
25689
|
+
omError("[OM] onReflectionEnd hook failed after async buffered reflection", hookError);
|
|
25690
|
+
}
|
|
25691
|
+
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
25692
|
+
unregisterOp(record.id, "bufferingReflection");
|
|
25693
|
+
this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
|
|
25694
|
+
omError("[OM] Failed to clear buffering reflection flag", err);
|
|
25647
25695
|
});
|
|
25648
|
-
} catch (hookError) {
|
|
25649
|
-
omError("[OM] onReflectionEnd hook failed after async buffered reflection failure", hookError);
|
|
25650
25696
|
}
|
|
25651
|
-
|
|
25652
|
-
}).finally(() => {
|
|
25653
|
-
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
25654
|
-
unregisterOp(record.id, "bufferingReflection");
|
|
25655
|
-
this.storage.setBufferingReflectionFlag(record.id, false).catch((err) => {
|
|
25656
|
-
omError("[OM] Failed to clear buffering reflection flag", err);
|
|
25657
|
-
});
|
|
25658
|
-
});
|
|
25697
|
+
})();
|
|
25659
25698
|
BufferingCoordinator.asyncBufferingOps.set(bufferKey, asyncOp);
|
|
25660
25699
|
}
|
|
25661
25700
|
/**
|
|
@@ -25956,8 +25995,15 @@ var ReflectorRunner = class {
|
|
|
25956
25995
|
let reflectionUsage;
|
|
25957
25996
|
let reflectionProviderMetadata;
|
|
25958
25997
|
let reflectionError;
|
|
25959
|
-
|
|
25998
|
+
let lifecycleError;
|
|
25960
25999
|
try {
|
|
26000
|
+
try {
|
|
26001
|
+
await reflectionHooks?.onReflectionStart?.();
|
|
26002
|
+
} catch (error) {
|
|
26003
|
+
lifecycleError = error;
|
|
26004
|
+
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
26005
|
+
throw error;
|
|
26006
|
+
}
|
|
25961
26007
|
const compressionStartLevel = await this.getCompressionStartLevel(requestContext);
|
|
25962
26008
|
const reflectResult = await this.call(record.activeObservations, void 0, streamContext, reflectThreshold, abortSignal, void 0, compressionStartLevel, requestContext, priorExtractedValues, observabilityContext, void 0, mainAgent, sendSignal);
|
|
25963
26009
|
reflectionUsage = reflectResult.usage;
|
|
@@ -26027,18 +26073,27 @@ var ReflectorRunner = class {
|
|
|
26027
26073
|
await this.persistMarkerToStorage(failedMarker, threadId, record.resourceId ?? void 0);
|
|
26028
26074
|
}
|
|
26029
26075
|
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
26030
|
-
if (abortSignal?.aborted) throw error;
|
|
26076
|
+
if (lifecycleError !== void 0 || abortSignal?.aborted) throw error;
|
|
26031
26077
|
omError("[OM] Reflection failed", error);
|
|
26032
26078
|
} finally {
|
|
26033
|
-
await this.storage.setReflectingFlag(record.id, false);
|
|
26034
26079
|
try {
|
|
26035
|
-
|
|
26080
|
+
await this.storage.setReflectingFlag(record.id, false);
|
|
26081
|
+
} finally {
|
|
26082
|
+
unregisterOp(record.id, "reflecting");
|
|
26083
|
+
}
|
|
26084
|
+
let endHookError;
|
|
26085
|
+
try {
|
|
26086
|
+
await reflectionHooks?.onReflectionEnd?.({
|
|
26036
26087
|
usage: reflectionUsage,
|
|
26037
26088
|
error: reflectionError,
|
|
26038
26089
|
...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
|
|
26039
26090
|
});
|
|
26040
|
-
}
|
|
26041
|
-
|
|
26091
|
+
} catch (error) {
|
|
26092
|
+
endHookError = error;
|
|
26093
|
+
}
|
|
26094
|
+
if (endHookError !== void 0) {
|
|
26095
|
+
if (lifecycleError === void 0 && !abortSignal?.aborted) throw endHookError;
|
|
26096
|
+
omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
26042
26097
|
}
|
|
26043
26098
|
}
|
|
26044
26099
|
}
|
|
@@ -26499,6 +26554,8 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
26499
26554
|
onIndexObservations;
|
|
26500
26555
|
/** Config-level lifecycle hooks fired for every observation/reflection cycle. */
|
|
26501
26556
|
hooks;
|
|
26557
|
+
/** Execution policy for config-level hooks on manual and turn-synchronous cycles. */
|
|
26558
|
+
hookExecution;
|
|
26502
26559
|
/** Observer agent runner — handles LLM calls for extracting observations. */
|
|
26503
26560
|
observer;
|
|
26504
26561
|
/** Reflector agent runner — handles LLM calls for compressing observations. */
|
|
@@ -26605,6 +26662,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
26605
26662
|
this.retrievalSearch = typeof config.retrieval === "object" && Boolean(config.retrieval.vector);
|
|
26606
26663
|
this.onIndexObservations = config.onIndexObservations;
|
|
26607
26664
|
this.hooks = config.hooks;
|
|
26665
|
+
this.hookExecution = config.hookExecution ?? "non-blocking";
|
|
26608
26666
|
this.mastra = config.mastra;
|
|
26609
26667
|
this.memory = config.memory;
|
|
26610
26668
|
this.curationCadence = config.curationCadence;
|
|
@@ -28397,57 +28455,54 @@ ${formattedMessages}
|
|
|
28397
28455
|
};
|
|
28398
28456
|
}
|
|
28399
28457
|
/**
|
|
28400
|
-
* Compose
|
|
28401
|
-
*
|
|
28402
|
-
*
|
|
28403
|
-
* never fail an observation/reflection cycle; per-call hooks keep their
|
|
28404
|
-
* existing payloads and propagation semantics. Returns undefined when
|
|
28405
|
-
* neither is configured, so call sites stay zero-cost.
|
|
28406
|
-
*
|
|
28407
|
-
* Used internally by every pipeline path (manual observe/reflect,
|
|
28408
|
-
* turn-engine sync observation, async buffering); public only so the
|
|
28409
|
-
* observation turn engine can thread config-level reflection hooks into
|
|
28410
|
-
* reflector calls.
|
|
28458
|
+
* Compose config-level hooks with optional per-call hooks and bind context to
|
|
28459
|
+
* config-level callbacks. The configured policy applies unless a background
|
|
28460
|
+
* path explicitly requests non-blocking invocation.
|
|
28411
28461
|
*
|
|
28412
28462
|
* @internal
|
|
28413
28463
|
*/
|
|
28414
|
-
composeHooks(callHooks, context) {
|
|
28464
|
+
composeHooks(callHooks, context, execution = "configured") {
|
|
28415
28465
|
const configHooks = this.hooks;
|
|
28416
28466
|
if (!configHooks) return callHooks;
|
|
28417
28467
|
if (!callHooks && !Object.keys(configHooks).length) return void 0;
|
|
28418
|
-
const
|
|
28468
|
+
const shouldAwaitConfig = execution === "configured" && this.hookExecution === "await";
|
|
28469
|
+
const invokeConfigHook = async (name, arg) => {
|
|
28419
28470
|
const hook = configHooks[name];
|
|
28420
28471
|
if (!hook) return;
|
|
28472
|
+
if (shouldAwaitConfig) {
|
|
28473
|
+
await hook(arg);
|
|
28474
|
+
return;
|
|
28475
|
+
}
|
|
28421
28476
|
const logHookFailure = (error) => omDebug(`[OM:hooks] config-level ${name} hook failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
28422
28477
|
try {
|
|
28423
|
-
const
|
|
28424
|
-
if (
|
|
28478
|
+
const result = hook(arg);
|
|
28479
|
+
if (result && typeof result.then === "function") result.then(void 0, logHookFailure);
|
|
28425
28480
|
} catch (error) {
|
|
28426
28481
|
logHookFailure(error);
|
|
28427
28482
|
}
|
|
28428
28483
|
};
|
|
28429
28484
|
return {
|
|
28430
|
-
onObservationStart: () => {
|
|
28431
|
-
|
|
28432
|
-
callHooks?.onObservationStart?.();
|
|
28485
|
+
onObservationStart: async () => {
|
|
28486
|
+
await invokeConfigHook("onObservationStart", context);
|
|
28487
|
+
await callHooks?.onObservationStart?.();
|
|
28433
28488
|
},
|
|
28434
|
-
onObservationEnd: (result) => {
|
|
28435
|
-
|
|
28489
|
+
onObservationEnd: async (result) => {
|
|
28490
|
+
await invokeConfigHook("onObservationEnd", {
|
|
28436
28491
|
...context,
|
|
28437
28492
|
...result
|
|
28438
28493
|
});
|
|
28439
|
-
callHooks?.onObservationEnd?.(result);
|
|
28494
|
+
await callHooks?.onObservationEnd?.(result);
|
|
28440
28495
|
},
|
|
28441
|
-
onReflectionStart: () => {
|
|
28442
|
-
|
|
28443
|
-
callHooks?.onReflectionStart?.();
|
|
28496
|
+
onReflectionStart: async () => {
|
|
28497
|
+
await invokeConfigHook("onReflectionStart", context);
|
|
28498
|
+
await callHooks?.onReflectionStart?.();
|
|
28444
28499
|
},
|
|
28445
|
-
onReflectionEnd: (result) => {
|
|
28446
|
-
|
|
28500
|
+
onReflectionEnd: async (result) => {
|
|
28501
|
+
await invokeConfigHook("onReflectionEnd", {
|
|
28447
28502
|
...context,
|
|
28448
28503
|
...result
|
|
28449
28504
|
});
|
|
28450
|
-
callHooks?.onReflectionEnd?.(result);
|
|
28505
|
+
await callHooks?.onReflectionEnd?.(result);
|
|
28451
28506
|
}
|
|
28452
28507
|
};
|
|
28453
28508
|
}
|
|
@@ -28460,22 +28515,29 @@ ${formattedMessages}
|
|
|
28460
28515
|
* end hook reports `error` for failed cycles even though nothing throws.
|
|
28461
28516
|
*/
|
|
28462
28517
|
async runBufferedObservationCycle(context, run) {
|
|
28463
|
-
const hooks = this.composeHooks(void 0, context);
|
|
28464
|
-
hooks?.onObservationStart?.();
|
|
28518
|
+
const hooks = this.composeHooks(void 0, context, "non-blocking");
|
|
28465
28519
|
let runResult;
|
|
28466
28520
|
let runError;
|
|
28521
|
+
let lifecycleError;
|
|
28467
28522
|
try {
|
|
28523
|
+
await hooks?.onObservationStart?.();
|
|
28468
28524
|
runResult = await run();
|
|
28469
28525
|
return runResult;
|
|
28470
28526
|
} catch (error) {
|
|
28527
|
+
lifecycleError = error;
|
|
28471
28528
|
runError = error instanceof Error ? error : new Error(String(error));
|
|
28472
28529
|
throw error;
|
|
28473
28530
|
} finally {
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
|
|
28477
|
-
|
|
28478
|
-
|
|
28531
|
+
try {
|
|
28532
|
+
await hooks?.onObservationEnd?.({
|
|
28533
|
+
usage: runResult?.usage,
|
|
28534
|
+
error: runError ?? runResult?.error,
|
|
28535
|
+
...runResult?.providerMetadata ? { providerMetadata: runResult.providerMetadata } : {}
|
|
28536
|
+
});
|
|
28537
|
+
} catch (endHookError) {
|
|
28538
|
+
if (lifecycleError === void 0) throw endHookError;
|
|
28539
|
+
omDebug(`[OM:hooks] async-buffer onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
28540
|
+
}
|
|
28479
28541
|
}
|
|
28480
28542
|
}
|
|
28481
28543
|
/**
|
|
@@ -28503,18 +28565,21 @@ ${formattedMessages}
|
|
|
28503
28565
|
let observed = false;
|
|
28504
28566
|
let observationUsage;
|
|
28505
28567
|
let observationProviderMetadata;
|
|
28568
|
+
let observationError;
|
|
28569
|
+
let lifecycleError;
|
|
28570
|
+
let observationStarted = false;
|
|
28506
28571
|
let generationBefore = -1;
|
|
28507
|
-
|
|
28508
|
-
|
|
28509
|
-
|
|
28510
|
-
|
|
28511
|
-
|
|
28512
|
-
|
|
28513
|
-
|
|
28514
|
-
|
|
28515
|
-
|
|
28516
|
-
|
|
28517
|
-
|
|
28572
|
+
try {
|
|
28573
|
+
await this.withLock(lockKey, async () => {
|
|
28574
|
+
const freshRecord = await this.getOrCreateRecord(threadId, resourceId);
|
|
28575
|
+
generationBefore = freshRecord.generationCount;
|
|
28576
|
+
const unobservedMessages = messages ? this.getUnobservedMessages(messages, freshRecord) : await this.loadMessagesFromStorage(threadId, resourceId, freshRecord.lastObservedAt ? new Date(freshRecord.lastObservedAt) : void 0);
|
|
28577
|
+
if (!this.meetsObservationThreshold({
|
|
28578
|
+
record: freshRecord,
|
|
28579
|
+
unobservedTokens: await this.tokenCounter.countMessagesAsync(unobservedMessages)
|
|
28580
|
+
})) return;
|
|
28581
|
+
observationStarted = true;
|
|
28582
|
+
await hooks?.onObservationStart?.();
|
|
28518
28583
|
const result = await ObservationStrategy.create(this, {
|
|
28519
28584
|
record: freshRecord,
|
|
28520
28585
|
threadId,
|
|
@@ -28532,17 +28597,22 @@ ${formattedMessages}
|
|
|
28532
28597
|
observed = result.observed;
|
|
28533
28598
|
observationUsage = result.usage;
|
|
28534
28599
|
observationProviderMetadata = result.providerMetadata;
|
|
28535
|
-
}
|
|
28536
|
-
|
|
28537
|
-
|
|
28538
|
-
|
|
28539
|
-
|
|
28540
|
-
|
|
28541
|
-
|
|
28542
|
-
|
|
28543
|
-
|
|
28544
|
-
|
|
28545
|
-
|
|
28600
|
+
});
|
|
28601
|
+
} catch (error) {
|
|
28602
|
+
lifecycleError = error;
|
|
28603
|
+
observationError = error instanceof Error ? error : new Error(String(error));
|
|
28604
|
+
}
|
|
28605
|
+
if (observationStarted) try {
|
|
28606
|
+
await hooks?.onObservationEnd?.({
|
|
28607
|
+
usage: observationUsage,
|
|
28608
|
+
error: observationError,
|
|
28609
|
+
...observationProviderMetadata ? { providerMetadata: observationProviderMetadata } : {}
|
|
28610
|
+
});
|
|
28611
|
+
} catch (endHookError) {
|
|
28612
|
+
if (lifecycleError === void 0) throw endHookError;
|
|
28613
|
+
omDebug(`[OM:hooks] onObservationEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
28614
|
+
}
|
|
28615
|
+
if (lifecycleError !== void 0) throw lifecycleError;
|
|
28546
28616
|
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
28547
28617
|
const reflected = record.generationCount > generationBefore && generationBefore >= 0;
|
|
28548
28618
|
if (observed) this.maybeTriggerCadenceCuration(threadId, resourceId, record, requestContext).catch((error) => {
|
|
@@ -28616,11 +28686,18 @@ ${formattedMessages}
|
|
|
28616
28686
|
resourceId,
|
|
28617
28687
|
trigger: "manual"
|
|
28618
28688
|
});
|
|
28619
|
-
hooks?.onReflectionStart?.();
|
|
28620
28689
|
let reflectionUsage;
|
|
28621
28690
|
let reflectionProviderMetadata;
|
|
28622
28691
|
let reflectionError;
|
|
28692
|
+
let lifecycleError;
|
|
28623
28693
|
try {
|
|
28694
|
+
try {
|
|
28695
|
+
await hooks?.onReflectionStart?.();
|
|
28696
|
+
} catch (error) {
|
|
28697
|
+
lifecycleError = error;
|
|
28698
|
+
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
28699
|
+
throw error;
|
|
28700
|
+
}
|
|
28624
28701
|
const thread = await this.storage.getThreadById({ threadId });
|
|
28625
28702
|
const previousOmMetadata = (0, _mastra_core_memory.getThreadOMMetadata)(thread?.metadata);
|
|
28626
28703
|
const priorExtractedValues = getPriorExtractedValues(previousOmMetadata, this.reflectionConfig.extractors);
|
|
@@ -28658,6 +28735,7 @@ ${formattedMessages}
|
|
|
28658
28735
|
};
|
|
28659
28736
|
} catch (error) {
|
|
28660
28737
|
reflectionError = error instanceof Error ? error : new Error(String(error));
|
|
28738
|
+
if (lifecycleError !== void 0) throw error;
|
|
28661
28739
|
omError("[OM] reflect() failed", error);
|
|
28662
28740
|
return {
|
|
28663
28741
|
reflected: false,
|
|
@@ -28665,13 +28743,25 @@ ${formattedMessages}
|
|
|
28665
28743
|
usage: void 0
|
|
28666
28744
|
};
|
|
28667
28745
|
} finally {
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
}
|
|
28673
|
-
|
|
28674
|
-
|
|
28746
|
+
try {
|
|
28747
|
+
await this.storage.setReflectingFlag(record.id, false);
|
|
28748
|
+
} finally {
|
|
28749
|
+
unregisterOp(record.id, "reflecting");
|
|
28750
|
+
}
|
|
28751
|
+
let endHookError;
|
|
28752
|
+
try {
|
|
28753
|
+
await hooks?.onReflectionEnd?.({
|
|
28754
|
+
usage: reflectionUsage,
|
|
28755
|
+
error: reflectionError,
|
|
28756
|
+
...reflectionProviderMetadata ? { providerMetadata: reflectionProviderMetadata } : {}
|
|
28757
|
+
});
|
|
28758
|
+
} catch (error) {
|
|
28759
|
+
endHookError = error;
|
|
28760
|
+
}
|
|
28761
|
+
if (endHookError !== void 0) {
|
|
28762
|
+
if (lifecycleError === void 0) throw endHookError;
|
|
28763
|
+
omDebug(`[OM:hooks] onReflectionEnd hook failed after cycle failure: ${endHookError instanceof Error ? endHookError.message : String(endHookError)}`);
|
|
28764
|
+
}
|
|
28675
28765
|
}
|
|
28676
28766
|
}
|
|
28677
28767
|
/**
|
|
@@ -28967,7 +29057,9 @@ var ObservationalMemoryProcessor = class {
|
|
|
28967
29057
|
return messageList;
|
|
28968
29058
|
}
|
|
28969
29059
|
const { threadId, resourceId } = context;
|
|
28970
|
-
const
|
|
29060
|
+
const memoryContext = (0, _mastra_core_memory.parseMemoryRequestContext)(requestContext);
|
|
29061
|
+
const runState = memoryContext?.runState?.();
|
|
29062
|
+
const readOnly = memoryContext?.memoryConfig?.readOnly;
|
|
28971
29063
|
const actorModelContext = model?.modelId ? {
|
|
28972
29064
|
provider: model.provider,
|
|
28973
29065
|
modelId: model.modelId,
|
|
@@ -28984,7 +29076,8 @@ var ObservationalMemoryProcessor = class {
|
|
|
28984
29076
|
memory: this.memory,
|
|
28985
29077
|
messageList,
|
|
28986
29078
|
threadId,
|
|
28987
|
-
resourceId
|
|
29079
|
+
resourceId,
|
|
29080
|
+
runState
|
|
28988
29081
|
});
|
|
28989
29082
|
const systemMessages = ctx.omRecord ? await this.engine.buildContextSystemMessages({
|
|
28990
29083
|
threadId,
|
|
@@ -29025,7 +29118,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
29025
29118
|
this.turn.sendStateSignal = args.sendStateSignal;
|
|
29026
29119
|
this.turn.agent = args.agent;
|
|
29027
29120
|
this.turn.requestContext = requestContext;
|
|
29028
|
-
await this.turn.start(this.memory);
|
|
29121
|
+
await this.turn.start(this.memory, runState);
|
|
29029
29122
|
if (stepNumber === 0 && this.temporalMarkers) await insertTemporalGapMarkers({
|
|
29030
29123
|
messageList,
|
|
29031
29124
|
sendSignal: args.sendSignal
|
|
@@ -30195,14 +30288,18 @@ ${workingMemory}`;
|
|
|
30195
30288
|
if (!this.threadConfig.workingMemory?.enabled) return null;
|
|
30196
30289
|
return extractWorkingMemoryContent(text)?.trim() ?? null;
|
|
30197
30290
|
}
|
|
30198
|
-
async getWorkingMemory({ threadId, resourceId, memoryConfig }) {
|
|
30291
|
+
async getWorkingMemory({ threadId, resourceId, memoryConfig, runState }) {
|
|
30199
30292
|
const config = this.getMergedThreadConfig(memoryConfig || {});
|
|
30200
30293
|
if (!config.workingMemory?.enabled) return null;
|
|
30201
30294
|
const scope = config.workingMemory.scope || "resource";
|
|
30202
30295
|
let workingMemoryData = null;
|
|
30203
30296
|
if (scope === "resource" && !resourceId) throw new Error("Memory error: Resource-scoped working memory is enabled but no resourceId was provided. Either provide a resourceId or explicitly set workingMemory.scope to 'thread'.");
|
|
30204
|
-
if (scope === "resource" && resourceId)
|
|
30205
|
-
|
|
30297
|
+
if (scope === "resource" && resourceId) {
|
|
30298
|
+
const loadWorkingMemory = async () => {
|
|
30299
|
+
return (await (await this.getMemoryStore()).getResourceById({ resourceId }))?.workingMemory || null;
|
|
30300
|
+
};
|
|
30301
|
+
workingMemoryData = runState ? await runState.load(`working-memory:resource:${resourceId}`, loadWorkingMemory) : await loadWorkingMemory();
|
|
30302
|
+
} else workingMemoryData = (runState?.threadLoaded ? runState.thread : await this.getThreadById({ threadId }))?.metadata?.workingMemory;
|
|
30206
30303
|
if (!workingMemoryData) return null;
|
|
30207
30304
|
return workingMemoryData;
|
|
30208
30305
|
}
|
|
@@ -30234,16 +30331,18 @@ ${workingMemory}`;
|
|
|
30234
30331
|
content: (config.workingMemory.template || this.defaultWorkingMemoryTemplate).trim()
|
|
30235
30332
|
};
|
|
30236
30333
|
}
|
|
30237
|
-
async getSystemMessage({ threadId, resourceId, memoryConfig }) {
|
|
30334
|
+
async getSystemMessage({ threadId, resourceId, memoryConfig, runState }) {
|
|
30238
30335
|
const config = this.getMergedThreadConfig(memoryConfig);
|
|
30239
30336
|
this.assertWorkingMemoryStateSignalsCompatibility(config);
|
|
30240
30337
|
if (!config.workingMemory?.enabled) return null;
|
|
30241
30338
|
if (config.workingMemory?.useStateSignals) return null;
|
|
30242
|
-
const
|
|
30339
|
+
const loadTemplate = () => this.getWorkingMemoryTemplate({ memoryConfig });
|
|
30340
|
+
const workingMemoryTemplate = runState ? await runState.load("working-memory:template", loadTemplate) : await loadTemplate();
|
|
30243
30341
|
const workingMemoryData = await this.getWorkingMemory({
|
|
30244
30342
|
threadId,
|
|
30245
30343
|
resourceId,
|
|
30246
|
-
memoryConfig: config
|
|
30344
|
+
memoryConfig: config,
|
|
30345
|
+
runState
|
|
30247
30346
|
});
|
|
30248
30347
|
if (!workingMemoryTemplate) return null;
|
|
30249
30348
|
const workingMemoryConfig = config.workingMemory;
|
|
@@ -30276,7 +30375,7 @@ ${workingMemory}`;
|
|
|
30276
30375
|
* ```
|
|
30277
30376
|
*/
|
|
30278
30377
|
async getContext(opts) {
|
|
30279
|
-
const { threadId, resourceId, memoryConfig } = opts;
|
|
30378
|
+
const { threadId, resourceId, memoryConfig, runState } = opts;
|
|
30280
30379
|
const config = this.getMergedThreadConfig(memoryConfig);
|
|
30281
30380
|
const memoryStore = await this.getMemoryStore();
|
|
30282
30381
|
const systemParts = [];
|
|
@@ -30286,10 +30385,14 @@ ${workingMemory}`;
|
|
|
30286
30385
|
let otherThreadsContext;
|
|
30287
30386
|
const omEngine = await this.omEngine;
|
|
30288
30387
|
if (omEngine) {
|
|
30289
|
-
|
|
30388
|
+
const loadOmRecord = () => omEngine.getRecord(threadId, resourceId);
|
|
30389
|
+
omRecord = runState ? await runState.load(`observational-memory:record:${threadId}:${resourceId ?? ""}`, loadOmRecord) : await loadOmRecord();
|
|
30290
30390
|
if (omRecord?.activeObservations) {
|
|
30291
30391
|
hasObservations = true;
|
|
30292
|
-
if (omEngine.scope === "resource" && resourceId)
|
|
30392
|
+
if (omEngine.scope === "resource" && resourceId) {
|
|
30393
|
+
const loadOtherThreadsContext = () => omEngine.getOtherThreadsContext(resourceId, threadId);
|
|
30394
|
+
otherThreadsContext = runState ? await runState.load(`observational-memory:other-threads:${resourceId}:${threadId}:${omRecord.lastObservedAt ?? ""}`, loadOtherThreadsContext) : await loadOtherThreadsContext();
|
|
30395
|
+
}
|
|
30293
30396
|
const obsSystemMessage = await omEngine.buildContextSystemMessage({
|
|
30294
30397
|
threadId,
|
|
30295
30398
|
resourceId,
|
|
@@ -30317,30 +30420,41 @@ ${workingMemory}`;
|
|
|
30317
30420
|
const workingMemoryMessage = await this.getSystemMessage({
|
|
30318
30421
|
threadId,
|
|
30319
30422
|
resourceId,
|
|
30320
|
-
memoryConfig: config
|
|
30423
|
+
memoryConfig: config,
|
|
30424
|
+
runState
|
|
30321
30425
|
});
|
|
30322
30426
|
if (workingMemoryMessage) systemParts.push(workingMemoryMessage);
|
|
30323
30427
|
let messages;
|
|
30324
30428
|
if (omEngine && omRecord) {
|
|
30325
30429
|
const dateFilter = omRecord.lastObservedAt ? { dateRange: { start: new Date(new Date(omRecord.lastObservedAt).getTime() + 1) } } : void 0;
|
|
30326
|
-
|
|
30327
|
-
|
|
30328
|
-
|
|
30329
|
-
|
|
30330
|
-
|
|
30331
|
-
|
|
30332
|
-
|
|
30333
|
-
|
|
30334
|
-
|
|
30335
|
-
|
|
30336
|
-
|
|
30337
|
-
|
|
30338
|
-
|
|
30339
|
-
|
|
30340
|
-
|
|
30341
|
-
|
|
30342
|
-
|
|
30343
|
-
|
|
30430
|
+
const boundary = omRecord.lastObservedAt ? new Date(omRecord.lastObservedAt).toISOString() : "";
|
|
30431
|
+
if (omEngine.scope === "resource" && resourceId) {
|
|
30432
|
+
const loadMessages = async () => {
|
|
30433
|
+
return (await memoryStore.listMessagesByResourceId({
|
|
30434
|
+
resourceId,
|
|
30435
|
+
orderBy: {
|
|
30436
|
+
field: "createdAt",
|
|
30437
|
+
direction: "ASC"
|
|
30438
|
+
},
|
|
30439
|
+
perPage: false,
|
|
30440
|
+
filter: dateFilter
|
|
30441
|
+
})).messages;
|
|
30442
|
+
};
|
|
30443
|
+
messages = runState ? await runState.load(`observational-memory:messages:resource:${resourceId}:${boundary}`, loadMessages) : await loadMessages();
|
|
30444
|
+
} else {
|
|
30445
|
+
const loadMessages = async () => {
|
|
30446
|
+
return (await memoryStore.listMessages({
|
|
30447
|
+
threadId,
|
|
30448
|
+
orderBy: {
|
|
30449
|
+
field: "createdAt",
|
|
30450
|
+
direction: "ASC"
|
|
30451
|
+
},
|
|
30452
|
+
perPage: false,
|
|
30453
|
+
filter: dateFilter
|
|
30454
|
+
})).messages;
|
|
30455
|
+
};
|
|
30456
|
+
messages = runState ? await runState.load(`observational-memory:messages:thread:${threadId}:${boundary}`, loadMessages) : await loadMessages();
|
|
30457
|
+
}
|
|
30344
30458
|
} else {
|
|
30345
30459
|
const lastMessages = config.lastMessages;
|
|
30346
30460
|
if (lastMessages === false) messages = [];
|
|
@@ -31645,4 +31759,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
31645
31759
|
}
|
|
31646
31760
|
});
|
|
31647
31761
|
|
|
31648
|
-
//# sourceMappingURL=src-
|
|
31762
|
+
//# sourceMappingURL=src-CIBCjg2A.cjs.map
|