@mastra/memory 1.26.0 → 1.26.1-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 +61 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-capabilities-subagents.md +23 -5
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +25 -2
- 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/extraction-runner.d.ts.map +1 -1
- package/dist/processors/observational-memory/extractor.d.ts +3 -0
- package/dist/processors/observational-memory/extractor.d.ts.map +1 -1
- package/dist/processors/observational-memory/message-utils.d.ts +13 -0
- package/dist/processors/observational-memory/message-utils.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/base.d.ts +5 -1
- package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +7 -1
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/step.d.ts +6 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +2 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +6 -0
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- 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/temporal-markers.d.ts.map +1 -1
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/dist/processors/observational-memory/working-memory-extractor.d.ts.map +1 -1
- package/dist/{src-Cwt9gefz.js → src-CdqJP57F.js} +214 -73
- package/dist/{src-Cwt9gefz.js.map → src-CdqJP57F.js.map} +1 -1
- package/dist/{src-CjTEWCUF.cjs → src-DY9-_lul.cjs} +214 -73
- package/dist/{src-CjTEWCUF.cjs.map → src-DY9-_lul.cjs.map} +1 -1
- package/dist/tools/om-tools.d.ts +2 -0
- package/dist/tools/om-tools.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -14835,6 +14835,7 @@ var Extractor = class Extractor {
|
|
|
14835
14835
|
includePreviousExtraction;
|
|
14836
14836
|
metadataKeyPath;
|
|
14837
14837
|
onExtracted;
|
|
14838
|
+
retryStructuredExtractionOnEmptyObject;
|
|
14838
14839
|
/** @internal */
|
|
14839
14840
|
internal;
|
|
14840
14841
|
instructionsConfig;
|
|
@@ -14857,6 +14858,7 @@ var Extractor = class Extractor {
|
|
|
14857
14858
|
this.includePreviousExtraction = config.includePreviousExtraction ?? true;
|
|
14858
14859
|
this.metadataKeyPath = config.metadataKeyPath ?? `extracted.${slug}`;
|
|
14859
14860
|
this.onExtracted = config.onExtracted;
|
|
14861
|
+
this.retryStructuredExtractionOnEmptyObject = config.retryStructuredExtractionOnEmptyObject ?? false;
|
|
14860
14862
|
this.internal = internal;
|
|
14861
14863
|
}
|
|
14862
14864
|
async resolve(context) {
|
|
@@ -14869,7 +14871,8 @@ var Extractor = class Extractor {
|
|
|
14869
14871
|
...schema ? { schema } : {},
|
|
14870
14872
|
includePreviousExtraction: this.includePreviousExtraction,
|
|
14871
14873
|
metadataKeyPath: this.metadataKeyPath,
|
|
14872
|
-
onExtracted: this.onExtracted
|
|
14874
|
+
onExtracted: this.onExtracted,
|
|
14875
|
+
retryStructuredExtractionOnEmptyObject: this.retryStructuredExtractionOnEmptyObject
|
|
14873
14876
|
}, this.internal);
|
|
14874
14877
|
}
|
|
14875
14878
|
};
|
|
@@ -15194,6 +15197,9 @@ if (OM_DEBUG_LOG) {
|
|
|
15194
15197
|
function isAbortError$1(error, abortSignal) {
|
|
15195
15198
|
return abortSignal?.aborted === true || error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
|
|
15196
15199
|
}
|
|
15200
|
+
function shouldRetryEmptyStructuredObject(object, extractors) {
|
|
15201
|
+
return Object.keys(object).length === 0 && extractors.some((extractor) => extractor.retryStructuredExtractionOnEmptyObject);
|
|
15202
|
+
}
|
|
15197
15203
|
async function extractStructuredValues(opts) {
|
|
15198
15204
|
const structuredExtractors = (opts.extractors ?? []).filter((extractor) => extractor.mode === "structured");
|
|
15199
15205
|
if (structuredExtractors.length === 0) return {
|
|
@@ -15230,8 +15236,10 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
|
|
|
15230
15236
|
return output.object;
|
|
15231
15237
|
};
|
|
15232
15238
|
let object;
|
|
15239
|
+
let retryEmptyObject = false;
|
|
15233
15240
|
try {
|
|
15234
15241
|
object = await generateWithStructuredOutput();
|
|
15242
|
+
retryEmptyObject = shouldRetryEmptyStructuredObject(object, structuredExtractors);
|
|
15235
15243
|
} catch (error) {
|
|
15236
15244
|
if (isAbortError$1(error, opts.abortSignal)) throw error;
|
|
15237
15245
|
try {
|
|
@@ -15248,6 +15256,19 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
|
|
|
15248
15256
|
};
|
|
15249
15257
|
}
|
|
15250
15258
|
}
|
|
15259
|
+
if (retryEmptyObject) try {
|
|
15260
|
+
object = await generateWithStructuredOutput(coreFeatures.has("json-prompt-injection:inline") ? "inline" : true);
|
|
15261
|
+
} catch (fallbackError) {
|
|
15262
|
+
if (isAbortError$1(fallbackError, opts.abortSignal)) throw fallbackError;
|
|
15263
|
+
const message = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
15264
|
+
return {
|
|
15265
|
+
values,
|
|
15266
|
+
failures: structuredExtractors.map((extractor) => ({
|
|
15267
|
+
slug: extractor.slug,
|
|
15268
|
+
error: message
|
|
15269
|
+
}))
|
|
15270
|
+
};
|
|
15271
|
+
}
|
|
15251
15272
|
for (const extractor of structuredExtractors) {
|
|
15252
15273
|
const value = object[extractor.slug];
|
|
15253
15274
|
if (value === void 0 || value === null || value === "") continue;
|
|
@@ -18553,6 +18574,17 @@ var TokenCounter = class TokenCounter {
|
|
|
18553
18574
|
toolResultDelta
|
|
18554
18575
|
};
|
|
18555
18576
|
}
|
|
18577
|
+
if (invocation.state === "output-error") {
|
|
18578
|
+
toolResultDelta++;
|
|
18579
|
+
const errorText = invocation.errorText;
|
|
18580
|
+
const errorMessage = typeof errorText === "string" ? errorText : "Tool execution failed";
|
|
18581
|
+
tokens += this.readOrPersistPartEstimate(part, "tool-result-error", errorMessage);
|
|
18582
|
+
return {
|
|
18583
|
+
tokens,
|
|
18584
|
+
overheadDelta,
|
|
18585
|
+
toolResultDelta
|
|
18586
|
+
};
|
|
18587
|
+
}
|
|
18556
18588
|
throw new Error(`Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`);
|
|
18557
18589
|
}
|
|
18558
18590
|
if (typeof part.type === "string" && part.type.startsWith("data-")) return {
|
|
@@ -18778,6 +18810,7 @@ var WorkingMemoryExtractor = class extends Extractor {
|
|
|
18778
18810
|
name: "Working Memory",
|
|
18779
18811
|
includePreviousExtraction: false,
|
|
18780
18812
|
metadataKeyPath: false,
|
|
18813
|
+
retryStructuredExtractionOnEmptyObject: true,
|
|
18781
18814
|
instructions: async (context) => buildWorkingMemoryInstructions(await getWorkingMemoryDetails(context)),
|
|
18782
18815
|
schema: async (context) => {
|
|
18783
18816
|
return (await getWorkingMemoryDetails(context)).usesSchema ? z.union([z.record(z.string(), z.unknown()), z.null()]) : void 0;
|
|
@@ -18926,9 +18959,10 @@ async function listThreadsForResource({ memory, resourceId, currentThreadId, pag
|
|
|
18926
18959
|
hasMore
|
|
18927
18960
|
};
|
|
18928
18961
|
}
|
|
18962
|
+
const SEARCH_NOT_CONFIGURED_MESSAGE = "Search is not configured. Enable it with `retrieval: { vector: true }` and configure a vector store and embedder on your Memory instance.";
|
|
18929
18963
|
async function searchMessagesForResource({ memory, resourceId, currentThreadId, query, topK = 10, maxTokens = DEFAULT_MAX_RESULT_TOKENS, before, after, threadScope }) {
|
|
18930
18964
|
if (!memory.searchMessages) return {
|
|
18931
|
-
results:
|
|
18965
|
+
results: SEARCH_NOT_CONFIGURED_MESSAGE,
|
|
18932
18966
|
count: 0
|
|
18933
18967
|
};
|
|
18934
18968
|
const MAX_TOPK = 20;
|
|
@@ -19474,9 +19508,16 @@ async function recallThreadFromStart({ memory, threadId, resourceId, page = 1, l
|
|
|
19474
19508
|
}
|
|
19475
19509
|
const recallTool = (_memoryConfig, options) => {
|
|
19476
19510
|
const isResourceScope = (options?.retrievalScope ?? "thread") === "resource";
|
|
19511
|
+
const searchEnabled = options?.searchEnabled ?? true;
|
|
19512
|
+
const description = isResourceScope ? `Browse conversation history. Use mode="threads" to list all threads for the current user. Use mode="messages" (default) to browse messages in the current thread or pass threadId to browse another thread in the active resource. When mode="messages" has no cursor or threadId, it defaults to the current thread and says so at the top of the result. If you pass only a cursor, it must belong to the current thread.${searchEnabled ? " Use mode=\"search\" to find messages by content across all threads." : ""}` : `Browse conversation history in the current thread. Use mode="messages" (default) to page through messages near a cursor.${searchEnabled ? " Use mode=\"search\" to find messages by content in this thread." : ""} Use mode="threads" to get the current thread's ID and title.`;
|
|
19513
|
+
const modeEnum = searchEnabled ? [
|
|
19514
|
+
"messages",
|
|
19515
|
+
"threads",
|
|
19516
|
+
"search"
|
|
19517
|
+
] : ["messages", "threads"];
|
|
19477
19518
|
return createTool({
|
|
19478
19519
|
id: "recall",
|
|
19479
|
-
description
|
|
19520
|
+
description,
|
|
19480
19521
|
inputSchema: {
|
|
19481
19522
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
19482
19523
|
type: "object",
|
|
@@ -19484,12 +19525,8 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19484
19525
|
...isResourceScope ? {
|
|
19485
19526
|
mode: {
|
|
19486
19527
|
type: "string",
|
|
19487
|
-
enum:
|
|
19488
|
-
|
|
19489
|
-
"threads",
|
|
19490
|
-
"search"
|
|
19491
|
-
],
|
|
19492
|
-
description: "What to retrieve. \"messages\" (default) pages through message history. \"threads\" lists all threads for the current user. \"search\" finds messages by semantic similarity across all threads."
|
|
19528
|
+
enum: modeEnum,
|
|
19529
|
+
description: `What to retrieve. "messages" (default) pages through message history. "threads" lists all threads for the current user.${searchEnabled ? " \"search\" finds messages by semantic similarity across all threads." : ""}`
|
|
19493
19530
|
},
|
|
19494
19531
|
threadId: {
|
|
19495
19532
|
type: "string",
|
|
@@ -19506,18 +19543,14 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19506
19543
|
}
|
|
19507
19544
|
} : { mode: {
|
|
19508
19545
|
type: "string",
|
|
19509
|
-
enum:
|
|
19510
|
-
|
|
19511
|
-
"threads",
|
|
19512
|
-
"search"
|
|
19513
|
-
],
|
|
19514
|
-
description: "What to retrieve. \"messages\" (default) pages through message history. \"threads\" returns info about the current thread. \"search\" finds messages by semantic similarity in this thread."
|
|
19546
|
+
enum: modeEnum,
|
|
19547
|
+
description: `What to retrieve. "messages" (default) pages through message history. "threads" returns info about the current thread.${searchEnabled ? " \"search\" finds messages by semantic similarity in this thread." : ""}`
|
|
19515
19548
|
} },
|
|
19516
|
-
query: {
|
|
19549
|
+
...searchEnabled ? { query: {
|
|
19517
19550
|
type: "string",
|
|
19518
19551
|
minLength: 1,
|
|
19519
19552
|
description: "Search query for mode=\"search\". Finds messages semantically similar to this text."
|
|
19520
|
-
},
|
|
19553
|
+
} } : {},
|
|
19521
19554
|
cursor: {
|
|
19522
19555
|
type: "string",
|
|
19523
19556
|
minLength: 1,
|
|
@@ -19578,6 +19611,10 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19578
19611
|
if (!memory) throw new Error("Memory instance is required for recall");
|
|
19579
19612
|
if (explicitThreadId === "current" && !currentThreadId) throw new Error("Could not resolve current thread.");
|
|
19580
19613
|
if (mode === "search") {
|
|
19614
|
+
if (!searchEnabled) return {
|
|
19615
|
+
results: SEARCH_NOT_CONFIGURED_MESSAGE,
|
|
19616
|
+
count: 0
|
|
19617
|
+
};
|
|
19581
19618
|
if (!query) throw new Error("query is required for mode=\"search\"");
|
|
19582
19619
|
if (!resourceId) throw new Error("Resource ID is required for recall");
|
|
19583
19620
|
return searchMessagesForResource({
|
|
@@ -20539,6 +20576,24 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
|
|
|
20539
20576
|
return preservedCalls.length > 0 ? [...preservedCalls, ...unobservedParts] : unobservedParts;
|
|
20540
20577
|
}
|
|
20541
20578
|
/**
|
|
20579
|
+
* Get the messages Observational Memory is allowed to work with.
|
|
20580
|
+
*
|
|
20581
|
+
* Messages supplied through the `context` option are per-run ephemeral input. Core's
|
|
20582
|
+
* persistence contract already treats them as never-persist: `MessageStateManager` routes
|
|
20583
|
+
* them into `userContextMessages`, and `drainUnsavedMessages` only drains input/response.
|
|
20584
|
+
*
|
|
20585
|
+
* OM builds its windows from `get.all.db()`, which includes context messages, and then
|
|
20586
|
+
* seals and persists candidates directly — turning ephemeral context into durable user
|
|
20587
|
+
* messages. Excluding them here keeps OM's window, sealing, persistence and token
|
|
20588
|
+
* accounting consistent with that contract.
|
|
20589
|
+
*/
|
|
20590
|
+
function getObservableMessages(messageList) {
|
|
20591
|
+
const allMessages = messageList.get.all.db();
|
|
20592
|
+
const contextMessageIds = messageList.makeMessageSourceChecker().context;
|
|
20593
|
+
if (contextMessageIds.size === 0) return allMessages;
|
|
20594
|
+
return allMessages.filter((message) => !contextMessageIds.has(message.id));
|
|
20595
|
+
}
|
|
20596
|
+
/**
|
|
20542
20597
|
* Safely extract buffered observation chunks from a record.
|
|
20543
20598
|
* Handles both array and JSON-string formats, returning empty array if malformed.
|
|
20544
20599
|
*/
|
|
@@ -20551,7 +20606,7 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
|
|
|
20551
20606
|
*/
|
|
20552
20607
|
function filterObservedMessages(opts) {
|
|
20553
20608
|
const { messageList, record } = opts;
|
|
20554
|
-
const allMessages = messageList
|
|
20609
|
+
const allMessages = getObservableMessages(messageList);
|
|
20555
20610
|
const useMarkerBoundaryPruning = opts.useMarkerBoundaryPruning ?? true;
|
|
20556
20611
|
const preserveMessageIds = opts.preserveMessageIds ?? /* @__PURE__ */ new Set();
|
|
20557
20612
|
const observedIds = new Set(Array.isArray(record?.observedMessageIds) ? record.observedMessageIds : []);
|
|
@@ -20969,7 +21024,7 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
20969
21024
|
transient: true
|
|
20970
21025
|
}).catch(() => {});
|
|
20971
21026
|
const markerThreadId = marker.data?.threadId ?? this.opts.threadId;
|
|
20972
|
-
await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
|
|
21027
|
+
if (!await this.persistMarkerToMessage(marker, this.opts.messageList, markerThreadId, this.opts.resourceId)) await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
|
|
20973
21028
|
}
|
|
20974
21029
|
getObservationMarkerConfig() {
|
|
20975
21030
|
return {
|
|
@@ -21097,10 +21152,14 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
21097
21152
|
/**
|
|
21098
21153
|
* Persist a marker part on the last assistant message in a MessageList
|
|
21099
21154
|
* AND save the updated message to the DB.
|
|
21155
|
+
*
|
|
21156
|
+
* @returns true when a marker was placed on an assistant message, false when
|
|
21157
|
+
* no list was provided or the list contains no assistant message (caller
|
|
21158
|
+
* should fall back to `persistMarkerToStorage`).
|
|
21100
21159
|
*/
|
|
21101
21160
|
async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
|
|
21102
|
-
if (!messageList) return;
|
|
21103
|
-
const allMsgs = messageList
|
|
21161
|
+
if (!messageList) return false;
|
|
21162
|
+
const allMsgs = getObservableMessages(messageList);
|
|
21104
21163
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
21105
21164
|
const msg = allMsgs[i];
|
|
21106
21165
|
if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
|
|
@@ -21115,9 +21174,10 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
21115
21174
|
} catch (e) {
|
|
21116
21175
|
omDebug(`[OM:persistMarker] failed to save marker to DB: ${e}`);
|
|
21117
21176
|
}
|
|
21118
|
-
return;
|
|
21177
|
+
return true;
|
|
21119
21178
|
}
|
|
21120
21179
|
}
|
|
21180
|
+
return false;
|
|
21121
21181
|
}
|
|
21122
21182
|
};
|
|
21123
21183
|
//#endregion
|
|
@@ -21926,6 +21986,12 @@ var ObservationStep = class {
|
|
|
21926
21986
|
stepNumber;
|
|
21927
21987
|
_prepared = false;
|
|
21928
21988
|
_context;
|
|
21989
|
+
/**
|
|
21990
|
+
* True when this step seeded an empty assistant response message for a step-0
|
|
21991
|
+
* observation. While set, the response-id rotation hook must NOT run — rotating
|
|
21992
|
+
* would orphan the seed (markers would sit on a message the agent never streams into).
|
|
21993
|
+
*/
|
|
21994
|
+
seededResponseMessage = false;
|
|
21929
21995
|
constructor(turn, stepNumber) {
|
|
21930
21996
|
this.turn = turn;
|
|
21931
21997
|
this.stepNumber = stepNumber;
|
|
@@ -21972,7 +22038,7 @@ var ObservationStep = class {
|
|
|
21972
22038
|
let didThresholdCleanup = false;
|
|
21973
22039
|
let observerExchange;
|
|
21974
22040
|
if (this.stepNumber === 0) {
|
|
21975
|
-
const step0Messages = messageList
|
|
22041
|
+
const step0Messages = getObservableMessages(messageList);
|
|
21976
22042
|
const activation = await om.activate({
|
|
21977
22043
|
threadId,
|
|
21978
22044
|
resourceId,
|
|
@@ -22004,7 +22070,7 @@ var ObservationStep = class {
|
|
|
22004
22070
|
currentModel: this.turn.actorModelContext,
|
|
22005
22071
|
requestContext: this.turn.requestContext,
|
|
22006
22072
|
observabilityContext: this.turn.observabilityContext,
|
|
22007
|
-
lastActivityAt: getLastActivityFromMessages(messageList
|
|
22073
|
+
lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
|
|
22008
22074
|
reflectionHooks: om.composeHooks(void 0, {
|
|
22009
22075
|
threadId,
|
|
22010
22076
|
resourceId,
|
|
@@ -22014,7 +22080,7 @@ var ObservationStep = class {
|
|
|
22014
22080
|
await this.turn.refreshRecord();
|
|
22015
22081
|
if (this.turn.record.generationCount > preReflectGeneration) reflected = true;
|
|
22016
22082
|
}
|
|
22017
|
-
const allMsgsForToolCheck = messageList
|
|
22083
|
+
const allMsgsForToolCheck = getObservableMessages(messageList);
|
|
22018
22084
|
const lastMessage = allMsgsForToolCheck[allMsgsForToolCheck.length - 1];
|
|
22019
22085
|
const pendingStepMessages = [...messageList.get.input.db(), ...messageList.get.response.db()];
|
|
22020
22086
|
const latestStepParts = [...getLatestStepParts(lastMessage?.content?.parts ?? []), ...pendingStepMessages.flatMap((msg) => getLatestStepParts(msg.content?.parts ?? []))];
|
|
@@ -22023,10 +22089,10 @@ var ObservationStep = class {
|
|
|
22023
22089
|
let statusSnapshot = await om.getStatus({
|
|
22024
22090
|
threadId,
|
|
22025
22091
|
resourceId,
|
|
22026
|
-
messages: messageList
|
|
22092
|
+
messages: getObservableMessages(messageList)
|
|
22027
22093
|
});
|
|
22028
22094
|
if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
|
|
22029
|
-
const allMessages = messageList
|
|
22095
|
+
const allMessages = getObservableMessages(messageList);
|
|
22030
22096
|
const unobservedMessages = om.getUnobservedMessages(allMessages, statusSnapshot.record);
|
|
22031
22097
|
const candidates = om.getUnobservedMessages(unobservedMessages, statusSnapshot.record, { excludeBuffered: true });
|
|
22032
22098
|
if (candidates.length > 0) {
|
|
@@ -22054,15 +22120,41 @@ var ObservationStep = class {
|
|
|
22054
22120
|
});
|
|
22055
22121
|
buffered = true;
|
|
22056
22122
|
}
|
|
22057
|
-
|
|
22058
|
-
|
|
22059
|
-
|
|
22060
|
-
|
|
22061
|
-
if (
|
|
22062
|
-
|
|
22063
|
-
|
|
22123
|
+
const willObserveNow = statusSnapshot.shouldObserve && !hasIncompleteToolCalls;
|
|
22124
|
+
/** In-flight message ids the step-0 cleanup must never remove from live context. */
|
|
22125
|
+
let step0PreserveIds;
|
|
22126
|
+
if (this.stepNumber > 0 || willObserveNow) {
|
|
22127
|
+
if (this.stepNumber > 0) {
|
|
22128
|
+
const newInput = messageList.clear.input.db();
|
|
22129
|
+
const newOutput = messageList.clear.response.db();
|
|
22130
|
+
const messagesToSave = [...newInput, ...newOutput];
|
|
22131
|
+
if (messagesToSave.length > 0) {
|
|
22132
|
+
await om.persistMessages(messagesToSave, threadId, resourceId);
|
|
22133
|
+
for (const msg of messagesToSave) messageList.add(msg, "memory");
|
|
22134
|
+
}
|
|
22135
|
+
} else {
|
|
22136
|
+
const pending = [...messageList.get.input.db(), ...messageList.get.response.db()];
|
|
22137
|
+
if (pending.length > 0) await om.persistMessages(pending, threadId, resourceId);
|
|
22138
|
+
step0PreserveIds = pending.map((msg) => msg.id);
|
|
22064
22139
|
}
|
|
22065
|
-
if (
|
|
22140
|
+
if (this.stepNumber === 0 && willObserveNow && this.turn.responseMessageId) {
|
|
22141
|
+
const seed = {
|
|
22142
|
+
id: this.turn.responseMessageId,
|
|
22143
|
+
role: "assistant",
|
|
22144
|
+
content: {
|
|
22145
|
+
format: 2,
|
|
22146
|
+
parts: []
|
|
22147
|
+
},
|
|
22148
|
+
type: "text",
|
|
22149
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
22150
|
+
threadId,
|
|
22151
|
+
resourceId
|
|
22152
|
+
};
|
|
22153
|
+
messageList.add(seed, "response");
|
|
22154
|
+
this.seededResponseMessage = true;
|
|
22155
|
+
omDebug(`[OM:step0] seeded response message ${seed.id} for step-0 observation markers`);
|
|
22156
|
+
}
|
|
22157
|
+
if (willObserveNow) {
|
|
22066
22158
|
const preObsGeneration = this.turn.record.generationCount;
|
|
22067
22159
|
const obsResult = await this.runThresholdObservation();
|
|
22068
22160
|
observerExchange = obsResult.observerExchange;
|
|
@@ -22076,7 +22168,8 @@ var ObservationStep = class {
|
|
|
22076
22168
|
resourceId,
|
|
22077
22169
|
messages: messageList,
|
|
22078
22170
|
observedMessageIds: observedIds,
|
|
22079
|
-
retentionFloor: minRemaining
|
|
22171
|
+
retentionFloor: minRemaining,
|
|
22172
|
+
preserveMessageIds: step0PreserveIds
|
|
22080
22173
|
});
|
|
22081
22174
|
if (statusSnapshot.asyncObservationEnabled) await om.resetBufferingState({
|
|
22082
22175
|
threadId,
|
|
@@ -22091,7 +22184,7 @@ var ObservationStep = class {
|
|
|
22091
22184
|
statusSnapshot = await om.getStatus({
|
|
22092
22185
|
threadId,
|
|
22093
22186
|
resourceId,
|
|
22094
|
-
messages: messageList
|
|
22187
|
+
messages: getObservableMessages(messageList)
|
|
22095
22188
|
});
|
|
22096
22189
|
}
|
|
22097
22190
|
const otherThreadsContext = await this.turn.refreshOtherThreadsContext();
|
|
@@ -22140,10 +22233,11 @@ var ObservationStep = class {
|
|
|
22140
22233
|
const { threadId, resourceId, messageList } = this.turn;
|
|
22141
22234
|
const om = this.turn.om;
|
|
22142
22235
|
await om.waitForBuffering(threadId, resourceId);
|
|
22236
|
+
const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
|
|
22143
22237
|
const freshStatus = await om.getStatus({
|
|
22144
22238
|
threadId,
|
|
22145
22239
|
resourceId,
|
|
22146
|
-
messages:
|
|
22240
|
+
messages: observableMessages
|
|
22147
22241
|
});
|
|
22148
22242
|
if (!freshStatus.shouldObserve) return {
|
|
22149
22243
|
succeeded: false,
|
|
@@ -22153,7 +22247,7 @@ var ObservationStep = class {
|
|
|
22153
22247
|
const activation = await om.activate({
|
|
22154
22248
|
threadId,
|
|
22155
22249
|
resourceId,
|
|
22156
|
-
messages:
|
|
22250
|
+
messages: observableMessages,
|
|
22157
22251
|
currentModel: this.turn.actorModelContext,
|
|
22158
22252
|
writer: this.turn.writer,
|
|
22159
22253
|
messageList
|
|
@@ -22169,7 +22263,7 @@ var ObservationStep = class {
|
|
|
22169
22263
|
currentModel: this.turn.actorModelContext,
|
|
22170
22264
|
requestContext: this.turn.requestContext,
|
|
22171
22265
|
observabilityContext: this.turn.observabilityContext,
|
|
22172
|
-
lastActivityAt: getLastActivityFromMessages(messageList
|
|
22266
|
+
lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
|
|
22173
22267
|
reflectionHooks: om.composeHooks(void 0, {
|
|
22174
22268
|
threadId,
|
|
22175
22269
|
resourceId,
|
|
@@ -22186,7 +22280,8 @@ var ObservationStep = class {
|
|
|
22186
22280
|
const obsResult = await om.observe({
|
|
22187
22281
|
threadId,
|
|
22188
22282
|
resourceId,
|
|
22189
|
-
messages:
|
|
22283
|
+
messages: observableMessages,
|
|
22284
|
+
messageList,
|
|
22190
22285
|
trigger: "turn-sync",
|
|
22191
22286
|
requestContext: this.turn.requestContext,
|
|
22192
22287
|
writer: this.turn.writer,
|
|
@@ -22194,7 +22289,7 @@ var ObservationStep = class {
|
|
|
22194
22289
|
});
|
|
22195
22290
|
if (obsResult.observed) {
|
|
22196
22291
|
const observedMessageIds = new Set(obsResult.record.observedMessageIds ?? []);
|
|
22197
|
-
const liveMessages = messageList
|
|
22292
|
+
const liveMessages = getObservableMessages(messageList);
|
|
22198
22293
|
let latestObservedIndex = -1;
|
|
22199
22294
|
for (let i = liveMessages.length - 1; i >= 0; i--) {
|
|
22200
22295
|
const message = liveMessages[i];
|
|
@@ -22203,10 +22298,12 @@ var ObservationStep = class {
|
|
|
22203
22298
|
break;
|
|
22204
22299
|
}
|
|
22205
22300
|
}
|
|
22206
|
-
|
|
22301
|
+
let messageToSeal = latestObservedIndex >= 0 ? liveMessages[latestObservedIndex] : void 0;
|
|
22302
|
+
if (this.stepNumber === 0 && messageToSeal?.role !== "assistant") messageToSeal = void 0;
|
|
22207
22303
|
const messagesToSeal = messageToSeal ? [messageToSeal] : [];
|
|
22208
22304
|
om.sealMessagesForBuffering(messagesToSeal);
|
|
22209
|
-
|
|
22305
|
+
if (this.seededResponseMessage) omDebug("[OM:observe] skipping response-id rotation — step-0 seeded response message holds the active id");
|
|
22306
|
+
else try {
|
|
22210
22307
|
await this.turn.hooks?.onSyncObservationComplete?.();
|
|
22211
22308
|
} catch (error) {
|
|
22212
22309
|
omDebug(`[OM:observe] onSyncObservationComplete hook failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -22267,6 +22364,8 @@ var ObservationTurn = class {
|
|
|
22267
22364
|
sendSignal;
|
|
22268
22365
|
/** Current actor model for this step. Updated by the processor before prepare(). */
|
|
22269
22366
|
actorModelContext;
|
|
22367
|
+
/** The active assistant response message ID for this step. Updated by the processor before prepare(). */
|
|
22368
|
+
responseMessageId;
|
|
22270
22369
|
/** Processor-provided hooks for turn/step lifecycle integration. */
|
|
22271
22370
|
hooks;
|
|
22272
22371
|
constructor(opts) {
|
|
@@ -22365,7 +22464,7 @@ var ObservationTurn = class {
|
|
|
22365
22464
|
const asyncObservationEnabled = this.om.buffering.isAsyncObservationEnabled();
|
|
22366
22465
|
const bufferOnIdle = this.om.getObservationConfig().bufferOnIdle;
|
|
22367
22466
|
if (asyncObservationEnabled && bufferOnIdle) {
|
|
22368
|
-
const allMessages = this.messageList
|
|
22467
|
+
const allMessages = getObservableMessages(this.messageList);
|
|
22369
22468
|
const record = this._record;
|
|
22370
22469
|
const unobservedMessages = this.om.getUnobservedMessages(allMessages, record);
|
|
22371
22470
|
if (unobservedMessages.length > 0) this.om.buffer({
|
|
@@ -22735,7 +22834,7 @@ function getCurrentModel$1(model) {
|
|
|
22735
22834
|
return formatModelContext$1(model?.provider, model?.modelId);
|
|
22736
22835
|
}
|
|
22737
22836
|
function getLastModelFromMessageList(messageList) {
|
|
22738
|
-
const messages = messageList
|
|
22837
|
+
const messages = messageList ? getObservableMessages(messageList) : void 0;
|
|
22739
22838
|
if (!messages) return void 0;
|
|
22740
22839
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
22741
22840
|
const message = messages[i];
|
|
@@ -24319,7 +24418,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
24319
24418
|
*/
|
|
24320
24419
|
async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
|
|
24321
24420
|
if (!messageList) return;
|
|
24322
|
-
const allMsgs = messageList
|
|
24421
|
+
const allMsgs = getObservableMessages(messageList);
|
|
24323
24422
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
24324
24423
|
const msg = allMsgs[i];
|
|
24325
24424
|
if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
|
|
@@ -24935,6 +25034,7 @@ ${formattedMessages}
|
|
|
24935
25034
|
*/
|
|
24936
25035
|
async getObservedMessageIdsForCleanup(opts) {
|
|
24937
25036
|
const { threadId, resourceId, messages, observedMessageIds, retentionFloor } = opts;
|
|
25037
|
+
const preserveSet = opts.preserveMessageIds?.length ? new Set(opts.preserveMessageIds) : null;
|
|
24938
25038
|
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
24939
25039
|
const effectiveObservedIds = observedMessageIds && observedMessageIds.length > 0 ? observedMessageIds : Array.isArray(record.observedMessageIds) ? record.observedMessageIds : [];
|
|
24940
25040
|
if (effectiveObservedIds.length === 0) return [];
|
|
@@ -24946,6 +25046,10 @@ ${formattedMessages}
|
|
|
24946
25046
|
const retentionCounter = typeof retentionFloor === "number" ? new TokenCounter() : null;
|
|
24947
25047
|
for (const msg of messages) {
|
|
24948
25048
|
if (!msg?.id || msg.id === "om-continuation" || !observedSet.has(msg.id)) continue;
|
|
25049
|
+
if (preserveSet?.has(msg.id)) {
|
|
25050
|
+
skipped += 1;
|
|
25051
|
+
continue;
|
|
25052
|
+
}
|
|
24949
25053
|
const unobservedParts = getUnobservedParts(msg);
|
|
24950
25054
|
const totalParts = msg.content?.parts?.length ?? 0;
|
|
24951
25055
|
if (unobservedParts.length > 0 && unobservedParts.length < totalParts) {
|
|
@@ -24990,9 +25094,9 @@ ${formattedMessages}
|
|
|
24990
25094
|
*/
|
|
24991
25095
|
/** @internal Used by ObservationStep. */
|
|
24992
25096
|
async cleanupMessages(opts) {
|
|
24993
|
-
const { threadId, resourceId, observedMessageIds, retentionFloor } = opts;
|
|
25097
|
+
const { threadId, resourceId, observedMessageIds, retentionFloor, preserveMessageIds } = opts;
|
|
24994
25098
|
const messageList = this.isMessageList(opts.messages) ? opts.messages : void 0;
|
|
24995
|
-
const allMsgs = messageList ? messageList
|
|
25099
|
+
const allMsgs = messageList ? getObservableMessages(messageList) : opts.messages;
|
|
24996
25100
|
let markerIdx = -1;
|
|
24997
25101
|
let markerMsg = null;
|
|
24998
25102
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
@@ -25011,7 +25115,8 @@ ${formattedMessages}
|
|
|
25011
25115
|
resourceId,
|
|
25012
25116
|
messages: allMsgs,
|
|
25013
25117
|
observedMessageIds,
|
|
25014
|
-
retentionFloor
|
|
25118
|
+
retentionFloor,
|
|
25119
|
+
preserveMessageIds
|
|
25015
25120
|
});
|
|
25016
25121
|
if (messageList) {
|
|
25017
25122
|
if (idsToRemoveList.length > 0) messageList.removeByIds(idsToRemoveList);
|
|
@@ -25023,18 +25128,21 @@ ${formattedMessages}
|
|
|
25023
25128
|
if (markerMsg && markerIdx !== -1) {
|
|
25024
25129
|
const idsToRemove = [];
|
|
25025
25130
|
const messagesToSave = [];
|
|
25131
|
+
const preserveSet = preserveMessageIds?.length ? new Set(preserveMessageIds) : null;
|
|
25026
25132
|
for (let i = 0; i < markerIdx; i++) {
|
|
25027
25133
|
const msg = allMsgs[i];
|
|
25028
|
-
if (msg?.id && msg.id !== "om-continuation") {
|
|
25134
|
+
if (msg?.id && msg.id !== "om-continuation" && !preserveSet?.has(msg.id)) {
|
|
25029
25135
|
idsToRemove.push(msg.id);
|
|
25030
25136
|
messagesToSave.push(msg);
|
|
25031
25137
|
}
|
|
25032
25138
|
}
|
|
25033
25139
|
messagesToSave.push(markerMsg);
|
|
25034
|
-
|
|
25035
|
-
|
|
25036
|
-
if (
|
|
25037
|
-
|
|
25140
|
+
if (!Boolean(markerMsg.id && preserveSet?.has(markerMsg.id))) {
|
|
25141
|
+
const unobservedParts = getUnobservedParts(markerMsg);
|
|
25142
|
+
if (unobservedParts.length === 0) {
|
|
25143
|
+
if (markerMsg.id) idsToRemove.push(markerMsg.id);
|
|
25144
|
+
} else if (unobservedParts.length < (markerMsg.content?.parts?.length ?? 0)) markerMsg.content.parts = unobservedParts;
|
|
25145
|
+
}
|
|
25038
25146
|
if (messageList) {
|
|
25039
25147
|
if (idsToRemove.length > 0) messageList.removeByIds(idsToRemove);
|
|
25040
25148
|
if (messagesToSave.length > 0) await this.persistMessages(messagesToSave, threadId, resourceId);
|
|
@@ -25821,6 +25929,7 @@ ${formattedMessages}
|
|
|
25821
25929
|
threadId,
|
|
25822
25930
|
resourceId,
|
|
25823
25931
|
messages: unobservedMessages,
|
|
25932
|
+
messageList: opts.messageList,
|
|
25824
25933
|
reflectionHooks,
|
|
25825
25934
|
agent: opts.agent,
|
|
25826
25935
|
requestContext,
|
|
@@ -26103,7 +26212,7 @@ function isTemporalGapMarkerForMessage(message, targetMessageId) {
|
|
|
26103
26212
|
async function insertTemporalGapMarkers({ messageList, sendSignal }) {
|
|
26104
26213
|
const latestInputMessage = messageList.get.input.db().filter((message) => Boolean(message)).at(-1);
|
|
26105
26214
|
if (!latestInputMessage || isTemporalGapMarker(latestInputMessage)) return;
|
|
26106
|
-
const allMessages = messageList
|
|
26215
|
+
const allMessages = getObservableMessages(messageList).filter((message) => Boolean(message));
|
|
26107
26216
|
const latestInputIndex = allMessages.findIndex((message) => message.id === latestInputMessage.id);
|
|
26108
26217
|
if (latestInputIndex <= 0) return;
|
|
26109
26218
|
if (allMessages.some((message) => isTemporalGapMarkerForMessage(message, latestInputMessage.id))) return;
|
|
@@ -26210,7 +26319,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26210
26319
|
this.temporalMarkers = options?.temporalMarkers ?? false;
|
|
26211
26320
|
}
|
|
26212
26321
|
async processInputStep(args) {
|
|
26213
|
-
const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, rotateResponseMessageId } = args;
|
|
26322
|
+
const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, messageId, rotateResponseMessageId } = args;
|
|
26214
26323
|
const state = _state ?? {};
|
|
26215
26324
|
omDebug(`[OM:processInputStep:ENTER] step=${stepNumber}, hasMastraMemory=${!!requestContext?.get("MastraMemory")}, hasMemoryInfo=${!!messageList?.serialize()?.memoryInfo?.threadId}`);
|
|
26216
26325
|
const context = this.engine.getThreadContext(requestContext, messageList);
|
|
@@ -26296,6 +26405,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26296
26405
|
state.__omObservabilityContext = observabilityContext;
|
|
26297
26406
|
this.turn.observabilityContext = observabilityContext;
|
|
26298
26407
|
this.turn.actorModelContext = actorModelContext;
|
|
26408
|
+
this.turn.responseMessageId = messageId;
|
|
26299
26409
|
{
|
|
26300
26410
|
const step = this.turn.step(stepNumber);
|
|
26301
26411
|
let ctx;
|
|
@@ -26326,7 +26436,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26326
26436
|
threadId,
|
|
26327
26437
|
resourceId
|
|
26328
26438
|
});
|
|
26329
|
-
const allDbMsgs = messageList
|
|
26439
|
+
const allDbMsgs = getObservableMessages(messageList);
|
|
26330
26440
|
const tokenCounter = this.engine.getTokenCounter();
|
|
26331
26441
|
const contextTokens = await tokenCounter.countMessagesAsync(allDbMsgs);
|
|
26332
26442
|
const otherThreadsContext = this.turn.context.otherThreadsContext;
|
|
@@ -26696,6 +26806,18 @@ var Memory = class extends MastraMemory {
|
|
|
26696
26806
|
_omEngine;
|
|
26697
26807
|
_omEngineInstance;
|
|
26698
26808
|
_mastraInstance;
|
|
26809
|
+
/**
|
|
26810
|
+
* Every vector cleanup that deleteThread or deleteMessages started in the background.
|
|
26811
|
+
* Callers do not wait for the cleanup, so this handle is the only join point.
|
|
26812
|
+
*/
|
|
26813
|
+
pendingVectorCleanup = Promise.resolve();
|
|
26814
|
+
/**
|
|
26815
|
+
* Adds a background vector cleanup to the join handle.
|
|
26816
|
+
* The handle keeps the earlier cleanups, so it settles only after all of them end.
|
|
26817
|
+
*/
|
|
26818
|
+
trackVectorCleanup(cleanup) {
|
|
26819
|
+
this.pendingVectorCleanup = Promise.allSettled([this.pendingVectorCleanup, cleanup]).then(() => void 0);
|
|
26820
|
+
}
|
|
26699
26821
|
/** The shared ObservationalMemory engine. Lazily created on first access. */
|
|
26700
26822
|
get omEngine() {
|
|
26701
26823
|
if (!this._omEngine) this._omEngine = this._initOMEngine().then((engine) => {
|
|
@@ -26960,26 +27082,40 @@ var Memory = class extends MastraMemory {
|
|
|
26960
27082
|
const thread = await memoryStore.getThreadById({ threadId });
|
|
26961
27083
|
await memoryStore.deleteThread({ threadId });
|
|
26962
27084
|
if (thread?.resourceId && memoryStore.supportsObservationalMemory) await memoryStore.clearObservationalMemory(threadId, thread.resourceId);
|
|
26963
|
-
if (this.vector) this.deleteThreadVectors(threadId);
|
|
27085
|
+
if (this.vector) this.trackVectorCleanup(this.deleteThreadVectors(threadId));
|
|
26964
27086
|
}
|
|
26965
27087
|
/**
|
|
26966
|
-
*
|
|
26967
|
-
*
|
|
27088
|
+
* Prefix shared by every message index. The index for the default embedding
|
|
27089
|
+
* dimension is named with the bare prefix; other dimensions add a suffix.
|
|
26968
27090
|
*/
|
|
26969
|
-
|
|
27091
|
+
get messageIndexPrefix() {
|
|
27092
|
+
return this.getEmbeddingIndexName();
|
|
27093
|
+
}
|
|
27094
|
+
/**
|
|
27095
|
+
* Prefix shared by every observation index. Each observation index adds a dimension suffix.
|
|
27096
|
+
*/
|
|
27097
|
+
get observationIndexPrefix() {
|
|
27098
|
+
return `memory${this.vector?.indexSeparator ?? "_"}observations`;
|
|
27099
|
+
}
|
|
27100
|
+
/**
|
|
27101
|
+
* Lists the vector indexes whose name starts with one of the given prefixes.
|
|
27102
|
+
* Index names can carry a dimension suffix, so discovery matches on the prefix.
|
|
27103
|
+
*/
|
|
27104
|
+
async getMemoryVectorIndexes(prefixes) {
|
|
26970
27105
|
if (!this.vector) return [];
|
|
26971
|
-
|
|
26972
|
-
return (await this.vector.listIndexes()).filter((name) => name.startsWith(prefix));
|
|
27106
|
+
return (await this.vector.listIndexes()).filter((name) => prefixes.some((prefix) => name.startsWith(prefix)));
|
|
26973
27107
|
}
|
|
26974
27108
|
/**
|
|
26975
27109
|
* Deletes all vector embeddings associated with a thread.
|
|
26976
27110
|
* This is called internally by deleteThread to clean up orphaned vectors.
|
|
27111
|
+
* Both message and observation vectors are removed, so no text of the deleted
|
|
27112
|
+
* thread stays reachable through resource-scoped retrieval.
|
|
26977
27113
|
*
|
|
26978
27114
|
* @param threadId - The ID of the thread whose vectors should be deleted
|
|
26979
27115
|
*/
|
|
26980
27116
|
async deleteThreadVectors(threadId) {
|
|
26981
27117
|
try {
|
|
26982
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
27118
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix, this.observationIndexPrefix]);
|
|
26983
27119
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
26984
27120
|
try {
|
|
26985
27121
|
await this.vector.deleteVectors({
|
|
@@ -26987,14 +27123,14 @@ var Memory = class extends MastraMemory {
|
|
|
26987
27123
|
filter: { thread_id: threadId }
|
|
26988
27124
|
});
|
|
26989
27125
|
} catch {
|
|
26990
|
-
this.logger.
|
|
27126
|
+
this.logger.warn("Failed to delete vectors of the deleted thread from index", {
|
|
26991
27127
|
threadId,
|
|
26992
27128
|
indexName
|
|
26993
27129
|
});
|
|
26994
27130
|
}
|
|
26995
27131
|
}));
|
|
26996
27132
|
} catch {
|
|
26997
|
-
this.logger.
|
|
27133
|
+
this.logger.warn("Failed to clean up vectors of the deleted thread", { threadId });
|
|
26998
27134
|
}
|
|
26999
27135
|
}
|
|
27000
27136
|
async updateWorkingMemory({ threadId, resourceId, workingMemory, memoryConfig, observabilityContext }) {
|
|
@@ -27667,7 +27803,7 @@ Notes:
|
|
|
27667
27803
|
getObservationEmbeddingIndexName(dimensions) {
|
|
27668
27804
|
const usedDimensions = dimensions ?? 384;
|
|
27669
27805
|
const separator = this.vector?.indexSeparator ?? "_";
|
|
27670
|
-
return
|
|
27806
|
+
return `${this.observationIndexPrefix}${separator}${usedDimensions}`;
|
|
27671
27807
|
}
|
|
27672
27808
|
async createObservationEmbeddingIndex(dimensions) {
|
|
27673
27809
|
const usedDimensions = dimensions ?? 384;
|
|
@@ -27913,7 +28049,10 @@ Notes:
|
|
|
27913
28049
|
tools[name] = tool;
|
|
27914
28050
|
}
|
|
27915
28051
|
const omConfig = normalizeObservationalMemoryConfig(mergedConfig.observationalMemory);
|
|
27916
|
-
if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
|
|
28052
|
+
if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
|
|
28053
|
+
retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource",
|
|
28054
|
+
searchEnabled: this.hasRetrievalSearch(omConfig.retrieval)
|
|
28055
|
+
});
|
|
27917
28056
|
return tools;
|
|
27918
28057
|
}
|
|
27919
28058
|
/**
|
|
@@ -27969,7 +28108,7 @@ Notes:
|
|
|
27969
28108
|
}));
|
|
27970
28109
|
const messageIdsNeedingDeletion = /* @__PURE__ */ new Set([...messageIdsWithClearedContent, ...messageIdsWithNewEmbeddings]);
|
|
27971
28110
|
if (messageIdsNeedingDeletion.size > 0) try {
|
|
27972
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
28111
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
27973
28112
|
const idsToDelete = [...messageIdsNeedingDeletion];
|
|
27974
28113
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
27975
28114
|
for (let i = 0; i < idsToDelete.length; i += VECTOR_DELETE_BATCH_SIZE) {
|
|
@@ -28028,7 +28167,7 @@ Notes:
|
|
|
28028
28167
|
const span = this.createMemorySpan("delete", observabilityContext, void 0, { messageCount: messageIds.length });
|
|
28029
28168
|
try {
|
|
28030
28169
|
await (await this.getMemoryStore()).deleteMessages(messageIds);
|
|
28031
|
-
if (this.vector) this.deleteMessageVectors(messageIds);
|
|
28170
|
+
if (this.vector) this.trackVectorCleanup(this.deleteMessageVectors(messageIds));
|
|
28032
28171
|
span?.end({
|
|
28033
28172
|
output: { success: true },
|
|
28034
28173
|
attributes: { messageCount: messageIds.length }
|
|
@@ -28044,12 +28183,14 @@ Notes:
|
|
|
28044
28183
|
/**
|
|
28045
28184
|
* Deletes vector embeddings for specific messages.
|
|
28046
28185
|
* This is called internally by deleteMessages to clean up orphaned vectors.
|
|
28186
|
+
* Only the message indexes are touched, because observation vectors can hold
|
|
28187
|
+
* text of other messages of the thread.
|
|
28047
28188
|
*
|
|
28048
28189
|
* @param messageIds - The IDs of the messages whose vectors should be deleted
|
|
28049
28190
|
*/
|
|
28050
28191
|
async deleteMessageVectors(messageIds) {
|
|
28051
28192
|
try {
|
|
28052
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
28193
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
28053
28194
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
28054
28195
|
for (let i = 0; i < messageIds.length; i += VECTOR_DELETE_BATCH_SIZE) {
|
|
28055
28196
|
const batch = messageIds.slice(i, i + VECTOR_DELETE_BATCH_SIZE);
|
|
@@ -28443,4 +28584,4 @@ Notes:
|
|
|
28443
28584
|
//#endregion
|
|
28444
28585
|
export { extractCurrentTask as A, OBSERVATION_CONTEXT_INSTRUCTIONS as B, WorkingMemoryExtractor as C, OBSERVER_SYSTEM_PROMPT as D, TokenCounter as E, injectAnchorIds as F, OBSERVATION_CONTINUATION_HINT as H, parseAnchorId as I, stripEphemeralAnchorIds as L, hasCurrentTaskSection as M, optimizeObservationsForContext as N, buildObserverPrompt as O, parseObserverOutput as P, Extractor as R, deepMergeWorkingMemory as S, summarizeConversation as T, OBSERVATION_CONTEXT_PROMPT as V, reconcileObservationGroupsFromReflection as _, extractWorkingMemoryContent as a, wrapInObservationGroup as b, WORKING_MEMORY_STATE_ID as c, getObservationsAsOf as d, ObservationalMemoryProcessor as f, parseObservationGroups as g, deriveObservationGroupProvenance as h, WorkingMemory as i, formatMessagesForObserver as j, buildObserverSystemPrompt as k, WORKING_MEMORY_STATE_PROCESSOR_ID as l, combineObservationGroupRanges as m, MessageHistory$1 as n, extractWorkingMemoryTags as o, ObservationalMemory as p, SemanticRecall as r, removeWorkingMemoryTags as s, Memory as t, WorkingMemoryStateProcessor as u, renderObservationGroupsForReflection as v, SUMMARIZE_THREAD_DEFAULTS as w, ModelByInputTokens as x, stripObservationGroups as y, OBSERVATIONAL_MEMORY_DEFAULTS as z };
|
|
28445
28586
|
|
|
28446
|
-
//# sourceMappingURL=src-
|
|
28587
|
+
//# sourceMappingURL=src-CdqJP57F.js.map
|