@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
|
@@ -14856,6 +14856,7 @@ var Extractor = class Extractor {
|
|
|
14856
14856
|
includePreviousExtraction;
|
|
14857
14857
|
metadataKeyPath;
|
|
14858
14858
|
onExtracted;
|
|
14859
|
+
retryStructuredExtractionOnEmptyObject;
|
|
14859
14860
|
/** @internal */
|
|
14860
14861
|
internal;
|
|
14861
14862
|
instructionsConfig;
|
|
@@ -14878,6 +14879,7 @@ var Extractor = class Extractor {
|
|
|
14878
14879
|
this.includePreviousExtraction = config.includePreviousExtraction ?? true;
|
|
14879
14880
|
this.metadataKeyPath = config.metadataKeyPath ?? `extracted.${slug}`;
|
|
14880
14881
|
this.onExtracted = config.onExtracted;
|
|
14882
|
+
this.retryStructuredExtractionOnEmptyObject = config.retryStructuredExtractionOnEmptyObject ?? false;
|
|
14881
14883
|
this.internal = internal;
|
|
14882
14884
|
}
|
|
14883
14885
|
async resolve(context) {
|
|
@@ -14890,7 +14892,8 @@ var Extractor = class Extractor {
|
|
|
14890
14892
|
...schema ? { schema } : {},
|
|
14891
14893
|
includePreviousExtraction: this.includePreviousExtraction,
|
|
14892
14894
|
metadataKeyPath: this.metadataKeyPath,
|
|
14893
|
-
onExtracted: this.onExtracted
|
|
14895
|
+
onExtracted: this.onExtracted,
|
|
14896
|
+
retryStructuredExtractionOnEmptyObject: this.retryStructuredExtractionOnEmptyObject
|
|
14894
14897
|
}, this.internal);
|
|
14895
14898
|
}
|
|
14896
14899
|
};
|
|
@@ -15215,6 +15218,9 @@ if (OM_DEBUG_LOG) {
|
|
|
15215
15218
|
function isAbortError$1(error, abortSignal) {
|
|
15216
15219
|
return abortSignal?.aborted === true || error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
|
|
15217
15220
|
}
|
|
15221
|
+
function shouldRetryEmptyStructuredObject(object, extractors) {
|
|
15222
|
+
return Object.keys(object).length === 0 && extractors.some((extractor) => extractor.retryStructuredExtractionOnEmptyObject);
|
|
15223
|
+
}
|
|
15218
15224
|
async function extractStructuredValues(opts) {
|
|
15219
15225
|
const structuredExtractors = (opts.extractors ?? []).filter((extractor) => extractor.mode === "structured");
|
|
15220
15226
|
if (structuredExtractors.length === 0) return {
|
|
@@ -15251,8 +15257,10 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
|
|
|
15251
15257
|
return output.object;
|
|
15252
15258
|
};
|
|
15253
15259
|
let object;
|
|
15260
|
+
let retryEmptyObject = false;
|
|
15254
15261
|
try {
|
|
15255
15262
|
object = await generateWithStructuredOutput();
|
|
15263
|
+
retryEmptyObject = shouldRetryEmptyStructuredObject(object, structuredExtractors);
|
|
15256
15264
|
} catch (error) {
|
|
15257
15265
|
if (isAbortError$1(error, opts.abortSignal)) throw error;
|
|
15258
15266
|
try {
|
|
@@ -15269,6 +15277,19 @@ ${extractorInstructions}${priorLines.length > 0 ? `\n\n## Prior Extracted Values
|
|
|
15269
15277
|
};
|
|
15270
15278
|
}
|
|
15271
15279
|
}
|
|
15280
|
+
if (retryEmptyObject) try {
|
|
15281
|
+
object = await generateWithStructuredOutput(_mastra_core_features.coreFeatures.has("json-prompt-injection:inline") ? "inline" : true);
|
|
15282
|
+
} catch (fallbackError) {
|
|
15283
|
+
if (isAbortError$1(fallbackError, opts.abortSignal)) throw fallbackError;
|
|
15284
|
+
const message = fallbackError instanceof Error ? fallbackError.message : String(fallbackError);
|
|
15285
|
+
return {
|
|
15286
|
+
values,
|
|
15287
|
+
failures: structuredExtractors.map((extractor) => ({
|
|
15288
|
+
slug: extractor.slug,
|
|
15289
|
+
error: message
|
|
15290
|
+
}))
|
|
15291
|
+
};
|
|
15292
|
+
}
|
|
15272
15293
|
for (const extractor of structuredExtractors) {
|
|
15273
15294
|
const value = object[extractor.slug];
|
|
15274
15295
|
if (value === void 0 || value === null || value === "") continue;
|
|
@@ -18574,6 +18595,17 @@ var TokenCounter = class TokenCounter {
|
|
|
18574
18595
|
toolResultDelta
|
|
18575
18596
|
};
|
|
18576
18597
|
}
|
|
18598
|
+
if (invocation.state === "output-error") {
|
|
18599
|
+
toolResultDelta++;
|
|
18600
|
+
const errorText = invocation.errorText;
|
|
18601
|
+
const errorMessage = typeof errorText === "string" ? errorText : "Tool execution failed";
|
|
18602
|
+
tokens += this.readOrPersistPartEstimate(part, "tool-result-error", errorMessage);
|
|
18603
|
+
return {
|
|
18604
|
+
tokens,
|
|
18605
|
+
overheadDelta,
|
|
18606
|
+
toolResultDelta
|
|
18607
|
+
};
|
|
18608
|
+
}
|
|
18577
18609
|
throw new Error(`Unhandled tool-invocation state '${part.toolInvocation?.state}' in token counting for part type '${part.type}'`);
|
|
18578
18610
|
}
|
|
18579
18611
|
if (typeof part.type === "string" && part.type.startsWith("data-")) return {
|
|
@@ -18799,6 +18831,7 @@ var WorkingMemoryExtractor = class extends Extractor {
|
|
|
18799
18831
|
name: "Working Memory",
|
|
18800
18832
|
includePreviousExtraction: false,
|
|
18801
18833
|
metadataKeyPath: false,
|
|
18834
|
+
retryStructuredExtractionOnEmptyObject: true,
|
|
18802
18835
|
instructions: async (context) => buildWorkingMemoryInstructions(await getWorkingMemoryDetails(context)),
|
|
18803
18836
|
schema: async (context) => {
|
|
18804
18837
|
return (await getWorkingMemoryDetails(context)).usesSchema ? zod.z.union([zod.z.record(zod.z.string(), zod.z.unknown()), zod.z.null()]) : void 0;
|
|
@@ -18947,9 +18980,10 @@ async function listThreadsForResource({ memory, resourceId, currentThreadId, pag
|
|
|
18947
18980
|
hasMore
|
|
18948
18981
|
};
|
|
18949
18982
|
}
|
|
18983
|
+
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.";
|
|
18950
18984
|
async function searchMessagesForResource({ memory, resourceId, currentThreadId, query, topK = 10, maxTokens = DEFAULT_MAX_RESULT_TOKENS, before, after, threadScope }) {
|
|
18951
18985
|
if (!memory.searchMessages) return {
|
|
18952
|
-
results:
|
|
18986
|
+
results: SEARCH_NOT_CONFIGURED_MESSAGE,
|
|
18953
18987
|
count: 0
|
|
18954
18988
|
};
|
|
18955
18989
|
const MAX_TOPK = 20;
|
|
@@ -19495,9 +19529,16 @@ async function recallThreadFromStart({ memory, threadId, resourceId, page = 1, l
|
|
|
19495
19529
|
}
|
|
19496
19530
|
const recallTool = (_memoryConfig, options) => {
|
|
19497
19531
|
const isResourceScope = (options?.retrievalScope ?? "thread") === "resource";
|
|
19532
|
+
const searchEnabled = options?.searchEnabled ?? true;
|
|
19533
|
+
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.`;
|
|
19534
|
+
const modeEnum = searchEnabled ? [
|
|
19535
|
+
"messages",
|
|
19536
|
+
"threads",
|
|
19537
|
+
"search"
|
|
19538
|
+
] : ["messages", "threads"];
|
|
19498
19539
|
return (0, _mastra_core_tools.createTool)({
|
|
19499
19540
|
id: "recall",
|
|
19500
|
-
description
|
|
19541
|
+
description,
|
|
19501
19542
|
inputSchema: {
|
|
19502
19543
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
19503
19544
|
type: "object",
|
|
@@ -19505,12 +19546,8 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19505
19546
|
...isResourceScope ? {
|
|
19506
19547
|
mode: {
|
|
19507
19548
|
type: "string",
|
|
19508
|
-
enum:
|
|
19509
|
-
|
|
19510
|
-
"threads",
|
|
19511
|
-
"search"
|
|
19512
|
-
],
|
|
19513
|
-
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."
|
|
19549
|
+
enum: modeEnum,
|
|
19550
|
+
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." : ""}`
|
|
19514
19551
|
},
|
|
19515
19552
|
threadId: {
|
|
19516
19553
|
type: "string",
|
|
@@ -19527,18 +19564,14 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19527
19564
|
}
|
|
19528
19565
|
} : { mode: {
|
|
19529
19566
|
type: "string",
|
|
19530
|
-
enum:
|
|
19531
|
-
|
|
19532
|
-
"threads",
|
|
19533
|
-
"search"
|
|
19534
|
-
],
|
|
19535
|
-
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."
|
|
19567
|
+
enum: modeEnum,
|
|
19568
|
+
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." : ""}`
|
|
19536
19569
|
} },
|
|
19537
|
-
query: {
|
|
19570
|
+
...searchEnabled ? { query: {
|
|
19538
19571
|
type: "string",
|
|
19539
19572
|
minLength: 1,
|
|
19540
19573
|
description: "Search query for mode=\"search\". Finds messages semantically similar to this text."
|
|
19541
|
-
},
|
|
19574
|
+
} } : {},
|
|
19542
19575
|
cursor: {
|
|
19543
19576
|
type: "string",
|
|
19544
19577
|
minLength: 1,
|
|
@@ -19599,6 +19632,10 @@ const recallTool = (_memoryConfig, options) => {
|
|
|
19599
19632
|
if (!memory) throw new Error("Memory instance is required for recall");
|
|
19600
19633
|
if (explicitThreadId === "current" && !currentThreadId) throw new Error("Could not resolve current thread.");
|
|
19601
19634
|
if (mode === "search") {
|
|
19635
|
+
if (!searchEnabled) return {
|
|
19636
|
+
results: SEARCH_NOT_CONFIGURED_MESSAGE,
|
|
19637
|
+
count: 0
|
|
19638
|
+
};
|
|
19602
19639
|
if (!query) throw new Error("query is required for mode=\"search\"");
|
|
19603
19640
|
if (!resourceId) throw new Error("Resource ID is required for recall");
|
|
19604
19641
|
return searchMessagesForResource({
|
|
@@ -20560,6 +20597,24 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
|
|
|
20560
20597
|
return preservedCalls.length > 0 ? [...preservedCalls, ...unobservedParts] : unobservedParts;
|
|
20561
20598
|
}
|
|
20562
20599
|
/**
|
|
20600
|
+
* Get the messages Observational Memory is allowed to work with.
|
|
20601
|
+
*
|
|
20602
|
+
* Messages supplied through the `context` option are per-run ephemeral input. Core's
|
|
20603
|
+
* persistence contract already treats them as never-persist: `MessageStateManager` routes
|
|
20604
|
+
* them into `userContextMessages`, and `drainUnsavedMessages` only drains input/response.
|
|
20605
|
+
*
|
|
20606
|
+
* OM builds its windows from `get.all.db()`, which includes context messages, and then
|
|
20607
|
+
* seals and persists candidates directly — turning ephemeral context into durable user
|
|
20608
|
+
* messages. Excluding them here keeps OM's window, sealing, persistence and token
|
|
20609
|
+
* accounting consistent with that contract.
|
|
20610
|
+
*/
|
|
20611
|
+
function getObservableMessages(messageList) {
|
|
20612
|
+
const allMessages = messageList.get.all.db();
|
|
20613
|
+
const contextMessageIds = messageList.makeMessageSourceChecker().context;
|
|
20614
|
+
if (contextMessageIds.size === 0) return allMessages;
|
|
20615
|
+
return allMessages.filter((message) => !contextMessageIds.has(message.id));
|
|
20616
|
+
}
|
|
20617
|
+
/**
|
|
20563
20618
|
* Safely extract buffered observation chunks from a record.
|
|
20564
20619
|
* Handles both array and JSON-string formats, returning empty array if malformed.
|
|
20565
20620
|
*/
|
|
@@ -20572,7 +20627,7 @@ function getUnobservedPartsPreservingToolCallPairs(message) {
|
|
|
20572
20627
|
*/
|
|
20573
20628
|
function filterObservedMessages(opts) {
|
|
20574
20629
|
const { messageList, record } = opts;
|
|
20575
|
-
const allMessages = messageList
|
|
20630
|
+
const allMessages = getObservableMessages(messageList);
|
|
20576
20631
|
const useMarkerBoundaryPruning = opts.useMarkerBoundaryPruning ?? true;
|
|
20577
20632
|
const preserveMessageIds = opts.preserveMessageIds ?? /* @__PURE__ */ new Set();
|
|
20578
20633
|
const observedIds = new Set(Array.isArray(record?.observedMessageIds) ? record.observedMessageIds : []);
|
|
@@ -20990,7 +21045,7 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
20990
21045
|
transient: true
|
|
20991
21046
|
}).catch(() => {});
|
|
20992
21047
|
const markerThreadId = marker.data?.threadId ?? this.opts.threadId;
|
|
20993
|
-
await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
|
|
21048
|
+
if (!await this.persistMarkerToMessage(marker, this.opts.messageList, markerThreadId, this.opts.resourceId)) await this.persistMarkerToStorage(marker, markerThreadId, this.opts.resourceId);
|
|
20994
21049
|
}
|
|
20995
21050
|
getObservationMarkerConfig() {
|
|
20996
21051
|
return {
|
|
@@ -21118,10 +21173,14 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
21118
21173
|
/**
|
|
21119
21174
|
* Persist a marker part on the last assistant message in a MessageList
|
|
21120
21175
|
* AND save the updated message to the DB.
|
|
21176
|
+
*
|
|
21177
|
+
* @returns true when a marker was placed on an assistant message, false when
|
|
21178
|
+
* no list was provided or the list contains no assistant message (caller
|
|
21179
|
+
* should fall back to `persistMarkerToStorage`).
|
|
21121
21180
|
*/
|
|
21122
21181
|
async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
|
|
21123
|
-
if (!messageList) return;
|
|
21124
|
-
const allMsgs = messageList
|
|
21182
|
+
if (!messageList) return false;
|
|
21183
|
+
const allMsgs = getObservableMessages(messageList);
|
|
21125
21184
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
21126
21185
|
const msg = allMsgs[i];
|
|
21127
21186
|
if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
|
|
@@ -21136,9 +21195,10 @@ var ObservationStrategy = class ObservationStrategy {
|
|
|
21136
21195
|
} catch (e) {
|
|
21137
21196
|
omDebug(`[OM:persistMarker] failed to save marker to DB: ${e}`);
|
|
21138
21197
|
}
|
|
21139
|
-
return;
|
|
21198
|
+
return true;
|
|
21140
21199
|
}
|
|
21141
21200
|
}
|
|
21201
|
+
return false;
|
|
21142
21202
|
}
|
|
21143
21203
|
};
|
|
21144
21204
|
//#endregion
|
|
@@ -21947,6 +22007,12 @@ var ObservationStep = class {
|
|
|
21947
22007
|
stepNumber;
|
|
21948
22008
|
_prepared = false;
|
|
21949
22009
|
_context;
|
|
22010
|
+
/**
|
|
22011
|
+
* True when this step seeded an empty assistant response message for a step-0
|
|
22012
|
+
* observation. While set, the response-id rotation hook must NOT run — rotating
|
|
22013
|
+
* would orphan the seed (markers would sit on a message the agent never streams into).
|
|
22014
|
+
*/
|
|
22015
|
+
seededResponseMessage = false;
|
|
21950
22016
|
constructor(turn, stepNumber) {
|
|
21951
22017
|
this.turn = turn;
|
|
21952
22018
|
this.stepNumber = stepNumber;
|
|
@@ -21993,7 +22059,7 @@ var ObservationStep = class {
|
|
|
21993
22059
|
let didThresholdCleanup = false;
|
|
21994
22060
|
let observerExchange;
|
|
21995
22061
|
if (this.stepNumber === 0) {
|
|
21996
|
-
const step0Messages = messageList
|
|
22062
|
+
const step0Messages = getObservableMessages(messageList);
|
|
21997
22063
|
const activation = await om.activate({
|
|
21998
22064
|
threadId,
|
|
21999
22065
|
resourceId,
|
|
@@ -22025,7 +22091,7 @@ var ObservationStep = class {
|
|
|
22025
22091
|
currentModel: this.turn.actorModelContext,
|
|
22026
22092
|
requestContext: this.turn.requestContext,
|
|
22027
22093
|
observabilityContext: this.turn.observabilityContext,
|
|
22028
|
-
lastActivityAt: getLastActivityFromMessages(messageList
|
|
22094
|
+
lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
|
|
22029
22095
|
reflectionHooks: om.composeHooks(void 0, {
|
|
22030
22096
|
threadId,
|
|
22031
22097
|
resourceId,
|
|
@@ -22035,7 +22101,7 @@ var ObservationStep = class {
|
|
|
22035
22101
|
await this.turn.refreshRecord();
|
|
22036
22102
|
if (this.turn.record.generationCount > preReflectGeneration) reflected = true;
|
|
22037
22103
|
}
|
|
22038
|
-
const allMsgsForToolCheck = messageList
|
|
22104
|
+
const allMsgsForToolCheck = getObservableMessages(messageList);
|
|
22039
22105
|
const lastMessage = allMsgsForToolCheck[allMsgsForToolCheck.length - 1];
|
|
22040
22106
|
const pendingStepMessages = [...messageList.get.input.db(), ...messageList.get.response.db()];
|
|
22041
22107
|
const latestStepParts = [...getLatestStepParts(lastMessage?.content?.parts ?? []), ...pendingStepMessages.flatMap((msg) => getLatestStepParts(msg.content?.parts ?? []))];
|
|
@@ -22044,10 +22110,10 @@ var ObservationStep = class {
|
|
|
22044
22110
|
let statusSnapshot = await om.getStatus({
|
|
22045
22111
|
threadId,
|
|
22046
22112
|
resourceId,
|
|
22047
|
-
messages: messageList
|
|
22113
|
+
messages: getObservableMessages(messageList)
|
|
22048
22114
|
});
|
|
22049
22115
|
if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
|
|
22050
|
-
const allMessages = messageList
|
|
22116
|
+
const allMessages = getObservableMessages(messageList);
|
|
22051
22117
|
const unobservedMessages = om.getUnobservedMessages(allMessages, statusSnapshot.record);
|
|
22052
22118
|
const candidates = om.getUnobservedMessages(unobservedMessages, statusSnapshot.record, { excludeBuffered: true });
|
|
22053
22119
|
if (candidates.length > 0) {
|
|
@@ -22075,15 +22141,41 @@ var ObservationStep = class {
|
|
|
22075
22141
|
});
|
|
22076
22142
|
buffered = true;
|
|
22077
22143
|
}
|
|
22078
|
-
|
|
22079
|
-
|
|
22080
|
-
|
|
22081
|
-
|
|
22082
|
-
if (
|
|
22083
|
-
|
|
22084
|
-
|
|
22144
|
+
const willObserveNow = statusSnapshot.shouldObserve && !hasIncompleteToolCalls;
|
|
22145
|
+
/** In-flight message ids the step-0 cleanup must never remove from live context. */
|
|
22146
|
+
let step0PreserveIds;
|
|
22147
|
+
if (this.stepNumber > 0 || willObserveNow) {
|
|
22148
|
+
if (this.stepNumber > 0) {
|
|
22149
|
+
const newInput = messageList.clear.input.db();
|
|
22150
|
+
const newOutput = messageList.clear.response.db();
|
|
22151
|
+
const messagesToSave = [...newInput, ...newOutput];
|
|
22152
|
+
if (messagesToSave.length > 0) {
|
|
22153
|
+
await om.persistMessages(messagesToSave, threadId, resourceId);
|
|
22154
|
+
for (const msg of messagesToSave) messageList.add(msg, "memory");
|
|
22155
|
+
}
|
|
22156
|
+
} else {
|
|
22157
|
+
const pending = [...messageList.get.input.db(), ...messageList.get.response.db()];
|
|
22158
|
+
if (pending.length > 0) await om.persistMessages(pending, threadId, resourceId);
|
|
22159
|
+
step0PreserveIds = pending.map((msg) => msg.id);
|
|
22085
22160
|
}
|
|
22086
|
-
if (
|
|
22161
|
+
if (this.stepNumber === 0 && willObserveNow && this.turn.responseMessageId) {
|
|
22162
|
+
const seed = {
|
|
22163
|
+
id: this.turn.responseMessageId,
|
|
22164
|
+
role: "assistant",
|
|
22165
|
+
content: {
|
|
22166
|
+
format: 2,
|
|
22167
|
+
parts: []
|
|
22168
|
+
},
|
|
22169
|
+
type: "text",
|
|
22170
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
22171
|
+
threadId,
|
|
22172
|
+
resourceId
|
|
22173
|
+
};
|
|
22174
|
+
messageList.add(seed, "response");
|
|
22175
|
+
this.seededResponseMessage = true;
|
|
22176
|
+
omDebug(`[OM:step0] seeded response message ${seed.id} for step-0 observation markers`);
|
|
22177
|
+
}
|
|
22178
|
+
if (willObserveNow) {
|
|
22087
22179
|
const preObsGeneration = this.turn.record.generationCount;
|
|
22088
22180
|
const obsResult = await this.runThresholdObservation();
|
|
22089
22181
|
observerExchange = obsResult.observerExchange;
|
|
@@ -22097,7 +22189,8 @@ var ObservationStep = class {
|
|
|
22097
22189
|
resourceId,
|
|
22098
22190
|
messages: messageList,
|
|
22099
22191
|
observedMessageIds: observedIds,
|
|
22100
|
-
retentionFloor: minRemaining
|
|
22192
|
+
retentionFloor: minRemaining,
|
|
22193
|
+
preserveMessageIds: step0PreserveIds
|
|
22101
22194
|
});
|
|
22102
22195
|
if (statusSnapshot.asyncObservationEnabled) await om.resetBufferingState({
|
|
22103
22196
|
threadId,
|
|
@@ -22112,7 +22205,7 @@ var ObservationStep = class {
|
|
|
22112
22205
|
statusSnapshot = await om.getStatus({
|
|
22113
22206
|
threadId,
|
|
22114
22207
|
resourceId,
|
|
22115
|
-
messages: messageList
|
|
22208
|
+
messages: getObservableMessages(messageList)
|
|
22116
22209
|
});
|
|
22117
22210
|
}
|
|
22118
22211
|
const otherThreadsContext = await this.turn.refreshOtherThreadsContext();
|
|
@@ -22161,10 +22254,11 @@ var ObservationStep = class {
|
|
|
22161
22254
|
const { threadId, resourceId, messageList } = this.turn;
|
|
22162
22255
|
const om = this.turn.om;
|
|
22163
22256
|
await om.waitForBuffering(threadId, resourceId);
|
|
22257
|
+
const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
|
|
22164
22258
|
const freshStatus = await om.getStatus({
|
|
22165
22259
|
threadId,
|
|
22166
22260
|
resourceId,
|
|
22167
|
-
messages:
|
|
22261
|
+
messages: observableMessages
|
|
22168
22262
|
});
|
|
22169
22263
|
if (!freshStatus.shouldObserve) return {
|
|
22170
22264
|
succeeded: false,
|
|
@@ -22174,7 +22268,7 @@ var ObservationStep = class {
|
|
|
22174
22268
|
const activation = await om.activate({
|
|
22175
22269
|
threadId,
|
|
22176
22270
|
resourceId,
|
|
22177
|
-
messages:
|
|
22271
|
+
messages: observableMessages,
|
|
22178
22272
|
currentModel: this.turn.actorModelContext,
|
|
22179
22273
|
writer: this.turn.writer,
|
|
22180
22274
|
messageList
|
|
@@ -22190,7 +22284,7 @@ var ObservationStep = class {
|
|
|
22190
22284
|
currentModel: this.turn.actorModelContext,
|
|
22191
22285
|
requestContext: this.turn.requestContext,
|
|
22192
22286
|
observabilityContext: this.turn.observabilityContext,
|
|
22193
|
-
lastActivityAt: getLastActivityFromMessages(messageList
|
|
22287
|
+
lastActivityAt: getLastActivityFromMessages(getObservableMessages(messageList)),
|
|
22194
22288
|
reflectionHooks: om.composeHooks(void 0, {
|
|
22195
22289
|
threadId,
|
|
22196
22290
|
resourceId,
|
|
@@ -22207,7 +22301,8 @@ var ObservationStep = class {
|
|
|
22207
22301
|
const obsResult = await om.observe({
|
|
22208
22302
|
threadId,
|
|
22209
22303
|
resourceId,
|
|
22210
|
-
messages:
|
|
22304
|
+
messages: observableMessages,
|
|
22305
|
+
messageList,
|
|
22211
22306
|
trigger: "turn-sync",
|
|
22212
22307
|
requestContext: this.turn.requestContext,
|
|
22213
22308
|
writer: this.turn.writer,
|
|
@@ -22215,7 +22310,7 @@ var ObservationStep = class {
|
|
|
22215
22310
|
});
|
|
22216
22311
|
if (obsResult.observed) {
|
|
22217
22312
|
const observedMessageIds = new Set(obsResult.record.observedMessageIds ?? []);
|
|
22218
|
-
const liveMessages = messageList
|
|
22313
|
+
const liveMessages = getObservableMessages(messageList);
|
|
22219
22314
|
let latestObservedIndex = -1;
|
|
22220
22315
|
for (let i = liveMessages.length - 1; i >= 0; i--) {
|
|
22221
22316
|
const message = liveMessages[i];
|
|
@@ -22224,10 +22319,12 @@ var ObservationStep = class {
|
|
|
22224
22319
|
break;
|
|
22225
22320
|
}
|
|
22226
22321
|
}
|
|
22227
|
-
|
|
22322
|
+
let messageToSeal = latestObservedIndex >= 0 ? liveMessages[latestObservedIndex] : void 0;
|
|
22323
|
+
if (this.stepNumber === 0 && messageToSeal?.role !== "assistant") messageToSeal = void 0;
|
|
22228
22324
|
const messagesToSeal = messageToSeal ? [messageToSeal] : [];
|
|
22229
22325
|
om.sealMessagesForBuffering(messagesToSeal);
|
|
22230
|
-
|
|
22326
|
+
if (this.seededResponseMessage) omDebug("[OM:observe] skipping response-id rotation — step-0 seeded response message holds the active id");
|
|
22327
|
+
else try {
|
|
22231
22328
|
await this.turn.hooks?.onSyncObservationComplete?.();
|
|
22232
22329
|
} catch (error) {
|
|
22233
22330
|
omDebug(`[OM:observe] onSyncObservationComplete hook failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -22288,6 +22385,8 @@ var ObservationTurn = class {
|
|
|
22288
22385
|
sendSignal;
|
|
22289
22386
|
/** Current actor model for this step. Updated by the processor before prepare(). */
|
|
22290
22387
|
actorModelContext;
|
|
22388
|
+
/** The active assistant response message ID for this step. Updated by the processor before prepare(). */
|
|
22389
|
+
responseMessageId;
|
|
22291
22390
|
/** Processor-provided hooks for turn/step lifecycle integration. */
|
|
22292
22391
|
hooks;
|
|
22293
22392
|
constructor(opts) {
|
|
@@ -22386,7 +22485,7 @@ var ObservationTurn = class {
|
|
|
22386
22485
|
const asyncObservationEnabled = this.om.buffering.isAsyncObservationEnabled();
|
|
22387
22486
|
const bufferOnIdle = this.om.getObservationConfig().bufferOnIdle;
|
|
22388
22487
|
if (asyncObservationEnabled && bufferOnIdle) {
|
|
22389
|
-
const allMessages = this.messageList
|
|
22488
|
+
const allMessages = getObservableMessages(this.messageList);
|
|
22390
22489
|
const record = this._record;
|
|
22391
22490
|
const unobservedMessages = this.om.getUnobservedMessages(allMessages, record);
|
|
22392
22491
|
if (unobservedMessages.length > 0) this.om.buffer({
|
|
@@ -22756,7 +22855,7 @@ function getCurrentModel$1(model) {
|
|
|
22756
22855
|
return formatModelContext$1(model?.provider, model?.modelId);
|
|
22757
22856
|
}
|
|
22758
22857
|
function getLastModelFromMessageList(messageList) {
|
|
22759
|
-
const messages = messageList
|
|
22858
|
+
const messages = messageList ? getObservableMessages(messageList) : void 0;
|
|
22760
22859
|
if (!messages) return void 0;
|
|
22761
22860
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
22762
22861
|
const message = messages[i];
|
|
@@ -24340,7 +24439,7 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
24340
24439
|
*/
|
|
24341
24440
|
async persistMarkerToMessage(marker, messageList, threadId, resourceId) {
|
|
24342
24441
|
if (!messageList) return;
|
|
24343
|
-
const allMsgs = messageList
|
|
24442
|
+
const allMsgs = getObservableMessages(messageList);
|
|
24344
24443
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
24345
24444
|
const msg = allMsgs[i];
|
|
24346
24445
|
if (msg?.role === "assistant" && msg.content?.parts && Array.isArray(msg.content.parts)) {
|
|
@@ -24956,6 +25055,7 @@ ${formattedMessages}
|
|
|
24956
25055
|
*/
|
|
24957
25056
|
async getObservedMessageIdsForCleanup(opts) {
|
|
24958
25057
|
const { threadId, resourceId, messages, observedMessageIds, retentionFloor } = opts;
|
|
25058
|
+
const preserveSet = opts.preserveMessageIds?.length ? new Set(opts.preserveMessageIds) : null;
|
|
24959
25059
|
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
24960
25060
|
const effectiveObservedIds = observedMessageIds && observedMessageIds.length > 0 ? observedMessageIds : Array.isArray(record.observedMessageIds) ? record.observedMessageIds : [];
|
|
24961
25061
|
if (effectiveObservedIds.length === 0) return [];
|
|
@@ -24967,6 +25067,10 @@ ${formattedMessages}
|
|
|
24967
25067
|
const retentionCounter = typeof retentionFloor === "number" ? new TokenCounter() : null;
|
|
24968
25068
|
for (const msg of messages) {
|
|
24969
25069
|
if (!msg?.id || msg.id === "om-continuation" || !observedSet.has(msg.id)) continue;
|
|
25070
|
+
if (preserveSet?.has(msg.id)) {
|
|
25071
|
+
skipped += 1;
|
|
25072
|
+
continue;
|
|
25073
|
+
}
|
|
24970
25074
|
const unobservedParts = getUnobservedParts(msg);
|
|
24971
25075
|
const totalParts = msg.content?.parts?.length ?? 0;
|
|
24972
25076
|
if (unobservedParts.length > 0 && unobservedParts.length < totalParts) {
|
|
@@ -25011,9 +25115,9 @@ ${formattedMessages}
|
|
|
25011
25115
|
*/
|
|
25012
25116
|
/** @internal Used by ObservationStep. */
|
|
25013
25117
|
async cleanupMessages(opts) {
|
|
25014
|
-
const { threadId, resourceId, observedMessageIds, retentionFloor } = opts;
|
|
25118
|
+
const { threadId, resourceId, observedMessageIds, retentionFloor, preserveMessageIds } = opts;
|
|
25015
25119
|
const messageList = this.isMessageList(opts.messages) ? opts.messages : void 0;
|
|
25016
|
-
const allMsgs = messageList ? messageList
|
|
25120
|
+
const allMsgs = messageList ? getObservableMessages(messageList) : opts.messages;
|
|
25017
25121
|
let markerIdx = -1;
|
|
25018
25122
|
let markerMsg = null;
|
|
25019
25123
|
for (let i = allMsgs.length - 1; i >= 0; i--) {
|
|
@@ -25032,7 +25136,8 @@ ${formattedMessages}
|
|
|
25032
25136
|
resourceId,
|
|
25033
25137
|
messages: allMsgs,
|
|
25034
25138
|
observedMessageIds,
|
|
25035
|
-
retentionFloor
|
|
25139
|
+
retentionFloor,
|
|
25140
|
+
preserveMessageIds
|
|
25036
25141
|
});
|
|
25037
25142
|
if (messageList) {
|
|
25038
25143
|
if (idsToRemoveList.length > 0) messageList.removeByIds(idsToRemoveList);
|
|
@@ -25044,18 +25149,21 @@ ${formattedMessages}
|
|
|
25044
25149
|
if (markerMsg && markerIdx !== -1) {
|
|
25045
25150
|
const idsToRemove = [];
|
|
25046
25151
|
const messagesToSave = [];
|
|
25152
|
+
const preserveSet = preserveMessageIds?.length ? new Set(preserveMessageIds) : null;
|
|
25047
25153
|
for (let i = 0; i < markerIdx; i++) {
|
|
25048
25154
|
const msg = allMsgs[i];
|
|
25049
|
-
if (msg?.id && msg.id !== "om-continuation") {
|
|
25155
|
+
if (msg?.id && msg.id !== "om-continuation" && !preserveSet?.has(msg.id)) {
|
|
25050
25156
|
idsToRemove.push(msg.id);
|
|
25051
25157
|
messagesToSave.push(msg);
|
|
25052
25158
|
}
|
|
25053
25159
|
}
|
|
25054
25160
|
messagesToSave.push(markerMsg);
|
|
25055
|
-
|
|
25056
|
-
|
|
25057
|
-
if (
|
|
25058
|
-
|
|
25161
|
+
if (!Boolean(markerMsg.id && preserveSet?.has(markerMsg.id))) {
|
|
25162
|
+
const unobservedParts = getUnobservedParts(markerMsg);
|
|
25163
|
+
if (unobservedParts.length === 0) {
|
|
25164
|
+
if (markerMsg.id) idsToRemove.push(markerMsg.id);
|
|
25165
|
+
} else if (unobservedParts.length < (markerMsg.content?.parts?.length ?? 0)) markerMsg.content.parts = unobservedParts;
|
|
25166
|
+
}
|
|
25059
25167
|
if (messageList) {
|
|
25060
25168
|
if (idsToRemove.length > 0) messageList.removeByIds(idsToRemove);
|
|
25061
25169
|
if (messagesToSave.length > 0) await this.persistMessages(messagesToSave, threadId, resourceId);
|
|
@@ -25842,6 +25950,7 @@ ${formattedMessages}
|
|
|
25842
25950
|
threadId,
|
|
25843
25951
|
resourceId,
|
|
25844
25952
|
messages: unobservedMessages,
|
|
25953
|
+
messageList: opts.messageList,
|
|
25845
25954
|
reflectionHooks,
|
|
25846
25955
|
agent: opts.agent,
|
|
25847
25956
|
requestContext,
|
|
@@ -26124,7 +26233,7 @@ function isTemporalGapMarkerForMessage(message, targetMessageId) {
|
|
|
26124
26233
|
async function insertTemporalGapMarkers({ messageList, sendSignal }) {
|
|
26125
26234
|
const latestInputMessage = messageList.get.input.db().filter((message) => Boolean(message)).at(-1);
|
|
26126
26235
|
if (!latestInputMessage || isTemporalGapMarker(latestInputMessage)) return;
|
|
26127
|
-
const allMessages = messageList
|
|
26236
|
+
const allMessages = getObservableMessages(messageList).filter((message) => Boolean(message));
|
|
26128
26237
|
const latestInputIndex = allMessages.findIndex((message) => message.id === latestInputMessage.id);
|
|
26129
26238
|
if (latestInputIndex <= 0) return;
|
|
26130
26239
|
if (allMessages.some((message) => isTemporalGapMarkerForMessage(message, latestInputMessage.id))) return;
|
|
@@ -26231,7 +26340,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26231
26340
|
this.temporalMarkers = options?.temporalMarkers ?? false;
|
|
26232
26341
|
}
|
|
26233
26342
|
async processInputStep(args) {
|
|
26234
|
-
const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, rotateResponseMessageId } = args;
|
|
26343
|
+
const { messageList, requestContext, stepNumber, state: _state, writer, model, abortSignal, abort, messageId, rotateResponseMessageId } = args;
|
|
26235
26344
|
const state = _state ?? {};
|
|
26236
26345
|
omDebug(`[OM:processInputStep:ENTER] step=${stepNumber}, hasMastraMemory=${!!requestContext?.get("MastraMemory")}, hasMemoryInfo=${!!messageList?.serialize()?.memoryInfo?.threadId}`);
|
|
26237
26346
|
const context = this.engine.getThreadContext(requestContext, messageList);
|
|
@@ -26317,6 +26426,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26317
26426
|
state.__omObservabilityContext = observabilityContext;
|
|
26318
26427
|
this.turn.observabilityContext = observabilityContext;
|
|
26319
26428
|
this.turn.actorModelContext = actorModelContext;
|
|
26429
|
+
this.turn.responseMessageId = messageId;
|
|
26320
26430
|
{
|
|
26321
26431
|
const step = this.turn.step(stepNumber);
|
|
26322
26432
|
let ctx;
|
|
@@ -26347,7 +26457,7 @@ var ObservationalMemoryProcessor = class {
|
|
|
26347
26457
|
threadId,
|
|
26348
26458
|
resourceId
|
|
26349
26459
|
});
|
|
26350
|
-
const allDbMsgs = messageList
|
|
26460
|
+
const allDbMsgs = getObservableMessages(messageList);
|
|
26351
26461
|
const tokenCounter = this.engine.getTokenCounter();
|
|
26352
26462
|
const contextTokens = await tokenCounter.countMessagesAsync(allDbMsgs);
|
|
26353
26463
|
const otherThreadsContext = this.turn.context.otherThreadsContext;
|
|
@@ -26717,6 +26827,18 @@ var Memory = class extends _mastra_core_memory.MastraMemory {
|
|
|
26717
26827
|
_omEngine;
|
|
26718
26828
|
_omEngineInstance;
|
|
26719
26829
|
_mastraInstance;
|
|
26830
|
+
/**
|
|
26831
|
+
* Every vector cleanup that deleteThread or deleteMessages started in the background.
|
|
26832
|
+
* Callers do not wait for the cleanup, so this handle is the only join point.
|
|
26833
|
+
*/
|
|
26834
|
+
pendingVectorCleanup = Promise.resolve();
|
|
26835
|
+
/**
|
|
26836
|
+
* Adds a background vector cleanup to the join handle.
|
|
26837
|
+
* The handle keeps the earlier cleanups, so it settles only after all of them end.
|
|
26838
|
+
*/
|
|
26839
|
+
trackVectorCleanup(cleanup) {
|
|
26840
|
+
this.pendingVectorCleanup = Promise.allSettled([this.pendingVectorCleanup, cleanup]).then(() => void 0);
|
|
26841
|
+
}
|
|
26720
26842
|
/** The shared ObservationalMemory engine. Lazily created on first access. */
|
|
26721
26843
|
get omEngine() {
|
|
26722
26844
|
if (!this._omEngine) this._omEngine = this._initOMEngine().then((engine) => {
|
|
@@ -26981,26 +27103,40 @@ var Memory = class extends _mastra_core_memory.MastraMemory {
|
|
|
26981
27103
|
const thread = await memoryStore.getThreadById({ threadId });
|
|
26982
27104
|
await memoryStore.deleteThread({ threadId });
|
|
26983
27105
|
if (thread?.resourceId && memoryStore.supportsObservationalMemory) await memoryStore.clearObservationalMemory(threadId, thread.resourceId);
|
|
26984
|
-
if (this.vector) this.deleteThreadVectors(threadId);
|
|
27106
|
+
if (this.vector) this.trackVectorCleanup(this.deleteThreadVectors(threadId));
|
|
26985
27107
|
}
|
|
26986
27108
|
/**
|
|
26987
|
-
*
|
|
26988
|
-
*
|
|
27109
|
+
* Prefix shared by every message index. The index for the default embedding
|
|
27110
|
+
* dimension is named with the bare prefix; other dimensions add a suffix.
|
|
26989
27111
|
*/
|
|
26990
|
-
|
|
27112
|
+
get messageIndexPrefix() {
|
|
27113
|
+
return this.getEmbeddingIndexName();
|
|
27114
|
+
}
|
|
27115
|
+
/**
|
|
27116
|
+
* Prefix shared by every observation index. Each observation index adds a dimension suffix.
|
|
27117
|
+
*/
|
|
27118
|
+
get observationIndexPrefix() {
|
|
27119
|
+
return `memory${this.vector?.indexSeparator ?? "_"}observations`;
|
|
27120
|
+
}
|
|
27121
|
+
/**
|
|
27122
|
+
* Lists the vector indexes whose name starts with one of the given prefixes.
|
|
27123
|
+
* Index names can carry a dimension suffix, so discovery matches on the prefix.
|
|
27124
|
+
*/
|
|
27125
|
+
async getMemoryVectorIndexes(prefixes) {
|
|
26991
27126
|
if (!this.vector) return [];
|
|
26992
|
-
|
|
26993
|
-
return (await this.vector.listIndexes()).filter((name) => name.startsWith(prefix));
|
|
27127
|
+
return (await this.vector.listIndexes()).filter((name) => prefixes.some((prefix) => name.startsWith(prefix)));
|
|
26994
27128
|
}
|
|
26995
27129
|
/**
|
|
26996
27130
|
* Deletes all vector embeddings associated with a thread.
|
|
26997
27131
|
* This is called internally by deleteThread to clean up orphaned vectors.
|
|
27132
|
+
* Both message and observation vectors are removed, so no text of the deleted
|
|
27133
|
+
* thread stays reachable through resource-scoped retrieval.
|
|
26998
27134
|
*
|
|
26999
27135
|
* @param threadId - The ID of the thread whose vectors should be deleted
|
|
27000
27136
|
*/
|
|
27001
27137
|
async deleteThreadVectors(threadId) {
|
|
27002
27138
|
try {
|
|
27003
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
27139
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix, this.observationIndexPrefix]);
|
|
27004
27140
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
27005
27141
|
try {
|
|
27006
27142
|
await this.vector.deleteVectors({
|
|
@@ -27008,14 +27144,14 @@ var Memory = class extends _mastra_core_memory.MastraMemory {
|
|
|
27008
27144
|
filter: { thread_id: threadId }
|
|
27009
27145
|
});
|
|
27010
27146
|
} catch {
|
|
27011
|
-
this.logger.
|
|
27147
|
+
this.logger.warn("Failed to delete vectors of the deleted thread from index", {
|
|
27012
27148
|
threadId,
|
|
27013
27149
|
indexName
|
|
27014
27150
|
});
|
|
27015
27151
|
}
|
|
27016
27152
|
}));
|
|
27017
27153
|
} catch {
|
|
27018
|
-
this.logger.
|
|
27154
|
+
this.logger.warn("Failed to clean up vectors of the deleted thread", { threadId });
|
|
27019
27155
|
}
|
|
27020
27156
|
}
|
|
27021
27157
|
async updateWorkingMemory({ threadId, resourceId, workingMemory, memoryConfig, observabilityContext }) {
|
|
@@ -27688,7 +27824,7 @@ Notes:
|
|
|
27688
27824
|
getObservationEmbeddingIndexName(dimensions) {
|
|
27689
27825
|
const usedDimensions = dimensions ?? 384;
|
|
27690
27826
|
const separator = this.vector?.indexSeparator ?? "_";
|
|
27691
|
-
return
|
|
27827
|
+
return `${this.observationIndexPrefix}${separator}${usedDimensions}`;
|
|
27692
27828
|
}
|
|
27693
27829
|
async createObservationEmbeddingIndex(dimensions) {
|
|
27694
27830
|
const usedDimensions = dimensions ?? 384;
|
|
@@ -27934,7 +28070,10 @@ Notes:
|
|
|
27934
28070
|
tools[name] = tool;
|
|
27935
28071
|
}
|
|
27936
28072
|
const omConfig = normalizeObservationalMemoryConfig(mergedConfig.observationalMemory);
|
|
27937
|
-
if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
|
|
28073
|
+
if (omConfig?.retrieval) tools.recall = recallTool(mergedConfig, {
|
|
28074
|
+
retrievalScope: typeof omConfig.retrieval === "object" ? omConfig.retrieval.scope ?? "resource" : "resource",
|
|
28075
|
+
searchEnabled: this.hasRetrievalSearch(omConfig.retrieval)
|
|
28076
|
+
});
|
|
27938
28077
|
return tools;
|
|
27939
28078
|
}
|
|
27940
28079
|
/**
|
|
@@ -27990,7 +28129,7 @@ Notes:
|
|
|
27990
28129
|
}));
|
|
27991
28130
|
const messageIdsNeedingDeletion = /* @__PURE__ */ new Set([...messageIdsWithClearedContent, ...messageIdsWithNewEmbeddings]);
|
|
27992
28131
|
if (messageIdsNeedingDeletion.size > 0) try {
|
|
27993
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
28132
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
27994
28133
|
const idsToDelete = [...messageIdsNeedingDeletion];
|
|
27995
28134
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
27996
28135
|
for (let i = 0; i < idsToDelete.length; i += VECTOR_DELETE_BATCH_SIZE) {
|
|
@@ -28049,7 +28188,7 @@ Notes:
|
|
|
28049
28188
|
const span = this.createMemorySpan("delete", observabilityContext, void 0, { messageCount: messageIds.length });
|
|
28050
28189
|
try {
|
|
28051
28190
|
await (await this.getMemoryStore()).deleteMessages(messageIds);
|
|
28052
|
-
if (this.vector) this.deleteMessageVectors(messageIds);
|
|
28191
|
+
if (this.vector) this.trackVectorCleanup(this.deleteMessageVectors(messageIds));
|
|
28053
28192
|
span?.end({
|
|
28054
28193
|
output: { success: true },
|
|
28055
28194
|
attributes: { messageCount: messageIds.length }
|
|
@@ -28065,12 +28204,14 @@ Notes:
|
|
|
28065
28204
|
/**
|
|
28066
28205
|
* Deletes vector embeddings for specific messages.
|
|
28067
28206
|
* This is called internally by deleteMessages to clean up orphaned vectors.
|
|
28207
|
+
* Only the message indexes are touched, because observation vectors can hold
|
|
28208
|
+
* text of other messages of the thread.
|
|
28068
28209
|
*
|
|
28069
28210
|
* @param messageIds - The IDs of the messages whose vectors should be deleted
|
|
28070
28211
|
*/
|
|
28071
28212
|
async deleteMessageVectors(messageIds) {
|
|
28072
28213
|
try {
|
|
28073
|
-
const memoryIndexes = await this.getMemoryVectorIndexes();
|
|
28214
|
+
const memoryIndexes = await this.getMemoryVectorIndexes([this.messageIndexPrefix]);
|
|
28074
28215
|
await Promise.all(memoryIndexes.map(async (indexName) => {
|
|
28075
28216
|
for (let i = 0; i < messageIds.length; i += VECTOR_DELETE_BATCH_SIZE) {
|
|
28076
28217
|
const batch = messageIds.slice(i, i + VECTOR_DELETE_BATCH_SIZE);
|
|
@@ -28697,4 +28838,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
28697
28838
|
}
|
|
28698
28839
|
});
|
|
28699
28840
|
|
|
28700
|
-
//# sourceMappingURL=src-
|
|
28841
|
+
//# sourceMappingURL=src-DY9-_lul.cjs.map
|