@mastra/memory 1.26.2 → 1.27.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-agents-agent-approval.md +2 -0
- package/dist/docs/references/integrations-databases-postgresql.md +2 -1
- package/dist/docs/references/reference-memory-observational-memory.md +4 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/processors/index.cjs +1 -1
- package/dist/processors/index.js +1 -1
- package/dist/processors/observational-memory/built-in-extractors.d.ts +13 -4
- package/dist/processors/observational-memory/built-in-extractors.d.ts.map +1 -1
- package/dist/processors/observational-memory/index.d.ts +1 -1
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -1
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +4 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -1
- package/dist/processors/observational-memory/observational-memory.d.ts +5 -1
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-agent.d.ts +13 -0
- package/dist/processors/observational-memory/observer-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/processor.d.ts.map +1 -1
- package/dist/processors/observational-memory/reflector-agent.d.ts +1 -0
- package/dist/processors/observational-memory/reflector-agent.d.ts.map +1 -1
- package/dist/processors/observational-memory/token-counter.d.ts +1 -0
- package/dist/processors/observational-memory/token-counter.d.ts.map +1 -1
- package/dist/processors/observational-memory/types.d.ts +29 -0
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/dist/{src-BYD6Wp5m.js → src-BUlG9vaB.js} +155 -59
- package/dist/{src-BYD6Wp5m.js.map → src-BUlG9vaB.js.map} +1 -1
- package/dist/{src-b5E69E65.cjs → src-MvtBOFYO.cjs} +155 -59
- package/dist/{src-b5E69E65.cjs.map → src-MvtBOFYO.cjs.map} +1 -1
- package/package.json +3 -3
|
@@ -15946,21 +15946,17 @@ Or as a standalone observation when closing out a broader task:
|
|
|
15946
15946
|
Completion observations should be terse but specific about WHAT was completed.
|
|
15947
15947
|
Prefer concrete resolved outcomes over abstract workflow status so the assistant remembers what is already done.`;
|
|
15948
15948
|
buildObserverOutputFormat();
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
|
|
15959
|
-
|
|
15960
|
-
- "I've updated the navigation model. Let me walk you through the changes..."
|
|
15961
|
-
- "The assistant should wait for the user to respond before continuing."
|
|
15962
|
-
- Call the view tool on src/example.ts to continue debugging.
|
|
15963
|
-
</suggested-response>` : "";
|
|
15949
|
+
/**
|
|
15950
|
+
* Build the Observer's output format.
|
|
15951
|
+
*
|
|
15952
|
+
* `extractors` distinguishes two cases that both look empty:
|
|
15953
|
+
* - `undefined` — the no-arg call behind the exported defaults (OBSERVER_OUTPUT_FORMAT_BASE,
|
|
15954
|
+
* OBSERVER_SYSTEM_PROMPT, REFLECTOR_SYSTEM_PROMPT), which keep describing both built-in
|
|
15955
|
+
* sections with their historical text. Runtime callers always pass the composed list.
|
|
15956
|
+
* - `[]` — the caller composed extractors and every section was disabled, so no continuation
|
|
15957
|
+
* sections are described at all.
|
|
15958
|
+
*/
|
|
15959
|
+
function buildObserverOutputFormat(extractors) {
|
|
15964
15960
|
return `Use priority levels:
|
|
15965
15961
|
- 🔴 High: explicit user facts, preferences, unresolved goals, critical context
|
|
15966
15962
|
- 🟡 Medium: project details, learned information, tool results
|
|
@@ -15986,7 +15982,19 @@ Date: Dec 5, 2025
|
|
|
15986
15982
|
* 🔴 (09:15) Continued work on feature X
|
|
15987
15983
|
</observations>
|
|
15988
15984
|
|
|
15989
|
-
${
|
|
15985
|
+
${buildExtractorOutputSections(extractors ?? []) || (extractors === void 0 ? `
|
|
15986
|
+
<current-task>
|
|
15987
|
+
State the current task(s) explicitly:
|
|
15988
|
+
- Primary: What the agent is currently working on
|
|
15989
|
+
- Secondary: Other pending tasks (mark as "waiting for user" if appropriate)
|
|
15990
|
+
</current-task>
|
|
15991
|
+
|
|
15992
|
+
<suggested-response>
|
|
15993
|
+
Hint for the agent's immediate next message. Examples:
|
|
15994
|
+
- "I've updated the navigation model. Let me walk you through the changes..."
|
|
15995
|
+
- "The assistant should wait for the user to respond before continuing."
|
|
15996
|
+
- Call the view tool on src/example.ts to continue debugging.
|
|
15997
|
+
</suggested-response>` : "")}`;
|
|
15990
15998
|
}
|
|
15991
15999
|
/**
|
|
15992
16000
|
* The guidelines for the Observer.
|
|
@@ -16013,10 +16021,22 @@ const OBSERVER_GUIDELINES = `- Be specific enough for the assistant to act on
|
|
|
16013
16021
|
* Build the complete observer system prompt.
|
|
16014
16022
|
* @param multiThread - Whether this is for multi-thread batched observation (default: false)
|
|
16015
16023
|
* @param instruction - Optional custom instructions to append to the prompt
|
|
16024
|
+
* @param includeThreadTitle - Whether the Observer should also produce a thread title
|
|
16025
|
+
* @param extractors - Active extractors, used to decide which sections the prompt describes.
|
|
16026
|
+
* Omitted only by the exported no-arg defaults; pass `[]` to describe no continuation sections at all.
|
|
16016
16027
|
*/
|
|
16017
|
-
function buildObserverSystemPrompt(multiThread = false, instruction, includeThreadTitle = false, extractors
|
|
16028
|
+
function buildObserverSystemPrompt(multiThread = false, instruction, includeThreadTitle = false, extractors) {
|
|
16018
16029
|
const outputFormat = buildObserverOutputFormat(extractors);
|
|
16019
|
-
const
|
|
16030
|
+
const customInstructions = instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : "";
|
|
16031
|
+
const currentTaskEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "current-task");
|
|
16032
|
+
const suggestedResponseEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "suggested-response");
|
|
16033
|
+
const multiThreadSections = [
|
|
16034
|
+
"observations",
|
|
16035
|
+
...currentTaskEnabled ? ["current-task"] : [],
|
|
16036
|
+
...suggestedResponseEnabled ? ["suggested-response"] : [],
|
|
16037
|
+
...includeThreadTitle ? ["thread-title"] : []
|
|
16038
|
+
];
|
|
16039
|
+
const multiThreadTitleInstruction = ` Each thread's ${multiThreadSections.length <= 2 ? multiThreadSections.join(" and ") : `${multiThreadSections.slice(0, -1).join(", ")}, and ${multiThreadSections[multiThreadSections.length - 1]}`} should be nested inside a <thread id="..."> block within <observations>.`;
|
|
16020
16040
|
const multiThreadTitleExample = includeThreadTitle ? `
|
|
16021
16041
|
<thread-title>Feature X implementation</thread-title>` : "";
|
|
16022
16042
|
const multiThreadSecondTitleExample = includeThreadTitle ? `
|
|
@@ -16046,28 +16066,28 @@ For multi-thread output, wrap each thread's observations like this:
|
|
|
16046
16066
|
<thread id="thread_id_1">
|
|
16047
16067
|
Date: Dec 4, 2025
|
|
16048
16068
|
* 🔴 (14:30) User prefers direct answers
|
|
16049
|
-
* 🔴 (14:31) Working on feature X
|
|
16069
|
+
* 🔴 (14:31) Working on feature X${currentTaskEnabled ? `
|
|
16050
16070
|
|
|
16051
16071
|
<current-task>
|
|
16052
16072
|
What the agent is currently working on in this thread
|
|
16053
|
-
</current-task
|
|
16073
|
+
</current-task>` : ""}${suggestedResponseEnabled ? `
|
|
16054
16074
|
|
|
16055
16075
|
<suggested-response>
|
|
16056
16076
|
Hint for the agent's next message in this thread
|
|
16057
|
-
</suggested-response
|
|
16077
|
+
</suggested-response>` : ""}${multiThreadTitleExample}
|
|
16058
16078
|
</thread>
|
|
16059
16079
|
|
|
16060
16080
|
<thread id="thread_id_2">
|
|
16061
16081
|
Date: Dec 5, 2025
|
|
16062
|
-
* 🔴 (09:15) User asked about deployment
|
|
16082
|
+
* 🔴 (09:15) User asked about deployment${currentTaskEnabled ? `
|
|
16063
16083
|
|
|
16064
16084
|
<current-task>
|
|
16065
16085
|
Current task for this thread
|
|
16066
|
-
</current-task
|
|
16086
|
+
</current-task>` : ""}${suggestedResponseEnabled ? `
|
|
16067
16087
|
|
|
16068
16088
|
<suggested-response>
|
|
16069
16089
|
Suggested response for this thread
|
|
16070
|
-
</suggested-response
|
|
16090
|
+
</suggested-response>` : ""}${multiThreadSecondTitleExample}
|
|
16071
16091
|
</thread>
|
|
16072
16092
|
</observations>
|
|
16073
16093
|
|
|
@@ -16077,7 +16097,7 @@ ${OBSERVER_GUIDELINES}
|
|
|
16077
16097
|
|
|
16078
16098
|
Remember: These observations are the assistant's ONLY memory. Make them count.
|
|
16079
16099
|
|
|
16080
|
-
User messages are extremely important
|
|
16100
|
+
User messages are extremely important.${currentTaskEnabled ? " If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority." : ""}${customInstructions}`;
|
|
16081
16101
|
return `You are the memory consciousness of an AI assistant. Your observations will be the ONLY information the assistant has about past interactions with this user.
|
|
16082
16102
|
|
|
16083
16103
|
Extract observations that will help the assistant remember:
|
|
@@ -16102,7 +16122,7 @@ Simply output your observations without any thread-related markup.
|
|
|
16102
16122
|
|
|
16103
16123
|
Remember: These observations are the assistant's ONLY memory. Make them count.
|
|
16104
16124
|
|
|
16105
|
-
User messages are extremely important
|
|
16125
|
+
User messages are extremely important.${currentTaskEnabled ? " If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority." : ""}${suggestedResponseEnabled ? " If the assistant needs to respond to the user, indicate in <suggested-response> that it should pause for user reply before continuing other tasks." : ""}${customInstructions}`;
|
|
16106
16126
|
}
|
|
16107
16127
|
/**
|
|
16108
16128
|
* Observer Agent System Prompt (default - for backwards compatibility)
|
|
@@ -16794,7 +16814,7 @@ function optimizeObservationsForContext(observations) {
|
|
|
16794
16814
|
let optimized = stripEphemeralAnchorIds(observations);
|
|
16795
16815
|
optimized = optimized.replace(/🟡\s*/g, "");
|
|
16796
16816
|
optimized = optimized.replace(/🟢\s*/g, "");
|
|
16797
|
-
optimized = optimized.replace(/\[(?![\d\s]*items collapsed)[^\]]+\]/g, "");
|
|
16817
|
+
optimized = optimized.replace(/\[(?![\d\s]*items collapsed)[^\]]+\](?!\()/g, "");
|
|
16798
16818
|
optimized = optimized.replace(/\s*->\s*/g, " ");
|
|
16799
16819
|
optimized = optimized.replace(/ +/g, " ");
|
|
16800
16820
|
optimized = optimized.replace(/\n{3,}/g, "\n\n");
|
|
@@ -18216,6 +18236,7 @@ var TokenCounter = class TokenCounter {
|
|
|
18216
18236
|
defaultModelContext;
|
|
18217
18237
|
modelContextStorage = new async_hooks.AsyncLocalStorage();
|
|
18218
18238
|
inFlightAttachmentCounts = /* @__PURE__ */ new Map();
|
|
18239
|
+
multimodalToolResultCounts = /* @__PURE__ */ new WeakMap();
|
|
18219
18240
|
static TOKENS_PER_MESSAGE = 3.8;
|
|
18220
18241
|
static TOKENS_PER_CONVERSATION = 24;
|
|
18221
18242
|
constructor(options) {
|
|
@@ -18278,6 +18299,9 @@ var TokenCounter = class TokenCounter {
|
|
|
18278
18299
|
}
|
|
18279
18300
|
countMultimodalToolResultContent(part, toolResult) {
|
|
18280
18301
|
if (!toolResult || typeof toolResult !== "object") return;
|
|
18302
|
+
const resultKey = buildEstimateKey("tool-result-multimodal-content-source", JSON.stringify(toolResult));
|
|
18303
|
+
const cached = this.multimodalToolResultCounts.get(part);
|
|
18304
|
+
if (cached?.resultKey === resultKey) return cached.tokens;
|
|
18281
18305
|
const output = toolResult;
|
|
18282
18306
|
const content = output.type === "content" && Array.isArray(output.value) ? output.value : output.content;
|
|
18283
18307
|
if (!Array.isArray(content)) return;
|
|
@@ -18389,10 +18413,15 @@ var TokenCounter = class TokenCounter {
|
|
|
18389
18413
|
countJsonContentPart(contentPart);
|
|
18390
18414
|
}
|
|
18391
18415
|
if (!hasAttachment) return;
|
|
18392
|
-
|
|
18416
|
+
const estimate = this.readOrPersistFixedPartEstimate(part, "tool-result-multimodal-content", JSON.stringify({
|
|
18393
18417
|
type: "content",
|
|
18394
18418
|
value: cacheParts
|
|
18395
18419
|
}), tokens);
|
|
18420
|
+
this.multimodalToolResultCounts.set(part, {
|
|
18421
|
+
resultKey,
|
|
18422
|
+
tokens: estimate
|
|
18423
|
+
});
|
|
18424
|
+
return estimate;
|
|
18396
18425
|
}
|
|
18397
18426
|
estimateImageAssetTokens(part, asset, kind) {
|
|
18398
18427
|
const modelContext = this.getModelContext();
|
|
@@ -20379,23 +20408,43 @@ function createThreadTitleExtractor() {
|
|
|
20379
20408
|
metadataKeyPath: "threadTitle"
|
|
20380
20409
|
}, true);
|
|
20381
20410
|
}
|
|
20411
|
+
/**
|
|
20412
|
+
* Normalize the user-facing `continuationHints` config into explicit per-section flags.
|
|
20413
|
+
* Both sections stay enabled unless the caller opts out, so omitting the config is a no-op.
|
|
20414
|
+
*/
|
|
20415
|
+
function resolveContinuationHints(config) {
|
|
20416
|
+
if (config === void 0 || config === true) return {
|
|
20417
|
+
currentTask: true,
|
|
20418
|
+
suggestedResponse: true
|
|
20419
|
+
};
|
|
20420
|
+
if (config === false) return {
|
|
20421
|
+
currentTask: false,
|
|
20422
|
+
suggestedResponse: false
|
|
20423
|
+
};
|
|
20424
|
+
return {
|
|
20425
|
+
currentTask: config.currentTask ?? true,
|
|
20426
|
+
suggestedResponse: config.suggestedResponse ?? true
|
|
20427
|
+
};
|
|
20428
|
+
}
|
|
20382
20429
|
function composeExtractors(options) {
|
|
20430
|
+
const continuationHints = resolveContinuationHints(options.continuationHints);
|
|
20383
20431
|
const extractors = [];
|
|
20384
|
-
if (
|
|
20432
|
+
if (continuationHints.currentTask) extractors.push(createCurrentTaskExtractor());
|
|
20433
|
+
if (continuationHints.suggestedResponse) extractors.push(createSuggestedResponseExtractor());
|
|
20385
20434
|
if (options.includeThreadTitle) extractors.push(createThreadTitleExtractor());
|
|
20386
20435
|
extractors.push(...options.userExtractors ?? []);
|
|
20387
20436
|
return validateExtractorList(extractors);
|
|
20388
20437
|
}
|
|
20389
20438
|
function composeObservationExtractors(config) {
|
|
20390
20439
|
return composeExtractors({
|
|
20391
|
-
|
|
20440
|
+
continuationHints: config.continuationHints,
|
|
20392
20441
|
includeThreadTitle: config.threadTitle,
|
|
20393
20442
|
userExtractors: config.extract
|
|
20394
20443
|
});
|
|
20395
20444
|
}
|
|
20396
20445
|
function composeReflectionExtractors(config) {
|
|
20397
20446
|
return composeExtractors({
|
|
20398
|
-
|
|
20447
|
+
continuationHints: config.continuationHints,
|
|
20399
20448
|
userExtractors: config.extract
|
|
20400
20449
|
});
|
|
20401
20450
|
}
|
|
@@ -22180,10 +22229,12 @@ var ObservationStep = class {
|
|
|
22180
22229
|
resourceId,
|
|
22181
22230
|
checkThreshold: true,
|
|
22182
22231
|
messages: step0Messages,
|
|
22232
|
+
record: this.turn.record,
|
|
22183
22233
|
currentModel: this.turn.actorModelContext,
|
|
22184
22234
|
writer: this.turn.writer,
|
|
22185
22235
|
messageList
|
|
22186
22236
|
});
|
|
22237
|
+
this.turn.setRecord(activation.record);
|
|
22187
22238
|
if (activation.activated) {
|
|
22188
22239
|
activated = true;
|
|
22189
22240
|
if (activation.activatedMessageIds?.length) messageList.removeByIds(activation.activatedMessageIds);
|
|
@@ -22225,6 +22276,7 @@ var ObservationStep = class {
|
|
|
22225
22276
|
let statusSnapshot = await om.getStatus({
|
|
22226
22277
|
threadId,
|
|
22227
22278
|
resourceId,
|
|
22279
|
+
record: this.turn.record,
|
|
22228
22280
|
messages: getObservableMessages(messageList)
|
|
22229
22281
|
});
|
|
22230
22282
|
if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
|
|
@@ -22320,6 +22372,7 @@ var ObservationStep = class {
|
|
|
22320
22372
|
statusSnapshot = await om.getStatus({
|
|
22321
22373
|
threadId,
|
|
22322
22374
|
resourceId,
|
|
22375
|
+
record: this.turn.record,
|
|
22323
22376
|
messages: getObservableMessages(messageList)
|
|
22324
22377
|
});
|
|
22325
22378
|
}
|
|
@@ -22370,10 +22423,12 @@ var ObservationStep = class {
|
|
|
22370
22423
|
const { threadId, resourceId, messageList } = this.turn;
|
|
22371
22424
|
const om = this.turn.om;
|
|
22372
22425
|
await om.waitForBuffering(threadId, resourceId);
|
|
22426
|
+
await this.turn.refreshRecord();
|
|
22373
22427
|
const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
|
|
22374
22428
|
const freshStatus = await om.getStatus({
|
|
22375
22429
|
threadId,
|
|
22376
22430
|
resourceId,
|
|
22431
|
+
record: this.turn.record,
|
|
22377
22432
|
messages: observableMessages
|
|
22378
22433
|
});
|
|
22379
22434
|
if (!freshStatus.shouldObserve) return {
|
|
@@ -22384,11 +22439,13 @@ var ObservationStep = class {
|
|
|
22384
22439
|
const activation = await om.activate({
|
|
22385
22440
|
threadId,
|
|
22386
22441
|
resourceId,
|
|
22442
|
+
record: this.turn.record,
|
|
22387
22443
|
messages: observableMessages,
|
|
22388
22444
|
currentModel: this.turn.actorModelContext,
|
|
22389
22445
|
writer: this.turn.writer,
|
|
22390
22446
|
messageList
|
|
22391
22447
|
});
|
|
22448
|
+
this.turn.setRecord(activation.record);
|
|
22392
22449
|
if (activation.activated) {
|
|
22393
22450
|
const postActivationRecord = activation.record;
|
|
22394
22451
|
await om.reflector.maybeReflect({
|
|
@@ -22573,6 +22630,18 @@ var ObservationTurn = class {
|
|
|
22573
22630
|
};
|
|
22574
22631
|
return this._context;
|
|
22575
22632
|
}
|
|
22633
|
+
/** Replace the cached turn record with a specific instance. */
|
|
22634
|
+
setRecord(record) {
|
|
22635
|
+
this._record = record;
|
|
22636
|
+
if (this._context) this._context.record = record;
|
|
22637
|
+
}
|
|
22638
|
+
/** Patch the cached turn record with merged fields. */
|
|
22639
|
+
patchRecord(patch) {
|
|
22640
|
+
this.setRecord({
|
|
22641
|
+
...this.record,
|
|
22642
|
+
...patch
|
|
22643
|
+
});
|
|
22644
|
+
}
|
|
22576
22645
|
/**
|
|
22577
22646
|
* Create a step handle. If a previous step exists, it is finalized
|
|
22578
22647
|
* (its output messages will be saved at the start of the new step's prepare()).
|
|
@@ -22627,7 +22696,7 @@ var ObservationTurn = class {
|
|
|
22627
22696
|
* @internal
|
|
22628
22697
|
*/
|
|
22629
22698
|
async refreshRecord() {
|
|
22630
|
-
this.
|
|
22699
|
+
this.setRecord(await this.om.getOrCreateRecord(this.threadId, this.resourceId));
|
|
22631
22700
|
}
|
|
22632
22701
|
/**
|
|
22633
22702
|
* Refresh cross-thread context for resource scope. Called per-step.
|
|
@@ -22682,9 +22751,13 @@ var ObservationTurn = class {
|
|
|
22682
22751
|
* - Preserving ALL important information (reflections become the ENTIRE memory)
|
|
22683
22752
|
*
|
|
22684
22753
|
* @param instruction - Optional custom instructions to append to the prompt
|
|
22754
|
+
* @param extractors - Active extractors, used to decide which sections the prompt describes
|
|
22685
22755
|
*/
|
|
22686
|
-
function buildReflectorSystemPrompt(instruction, extractors
|
|
22756
|
+
function buildReflectorSystemPrompt(instruction, extractors) {
|
|
22687
22757
|
const outputFormat = buildObserverOutputFormat(extractors);
|
|
22758
|
+
const customInstructions = instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : "";
|
|
22759
|
+
const currentTaskEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "current-task");
|
|
22760
|
+
const suggestedResponseEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "suggested-response");
|
|
22688
22761
|
return `You are the memory consciousness of an AI assistant. Your memory observation reflections will be the ONLY information the assistant has about past interactions with this user.
|
|
22689
22762
|
|
|
22690
22763
|
The following instructions were given to another part of your psyche (the observer) to create memories.
|
|
@@ -22761,7 +22834,7 @@ Date: Dec 4, 2025
|
|
|
22761
22834
|
|
|
22762
22835
|
${outputFormat}
|
|
22763
22836
|
|
|
22764
|
-
User messages are extremely important
|
|
22837
|
+
User messages are extremely important.${currentTaskEnabled ? " If the user asks a question or gives a new task, make it clear in <current-task> that this is the priority." : ""}${suggestedResponseEnabled ? " If the assistant needs to respond to the user, indicate in <suggested-response> that it should pause for user reply before continuing other tasks." : ""}${customInstructions}`;
|
|
22765
22838
|
}
|
|
22766
22839
|
buildReflectorSystemPrompt();
|
|
22767
22840
|
/**
|
|
@@ -24225,7 +24298,8 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
24225
24298
|
observeAttachments: config.observation?.observeAttachments ?? true,
|
|
24226
24299
|
extractors: composeObservationExtractors({
|
|
24227
24300
|
threadTitle: config.observation?.threadTitle ?? false,
|
|
24228
|
-
extract: config.observation?.extract
|
|
24301
|
+
extract: config.observation?.extract,
|
|
24302
|
+
continuationHints: config.observation?.continuationHints
|
|
24229
24303
|
})
|
|
24230
24304
|
};
|
|
24231
24305
|
this.reflectionConfig = {
|
|
@@ -24242,7 +24316,10 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
24242
24316
|
activateOnProviderChange: config.reflection?.activateOnProviderChange ?? false,
|
|
24243
24317
|
blockAfter: asyncBufferingDisabled ? void 0 : resolveBlockAfter(config.reflection?.blockAfter ?? (config.reflection?.bufferActivation ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.bufferActivation ? 1.2 : void 0), config.reflection?.observationTokens ?? OBSERVATIONAL_MEMORY_DEFAULTS.reflection.observationTokens),
|
|
24244
24318
|
instruction: config.reflection?.instruction,
|
|
24245
|
-
extractors: composeReflectionExtractors({
|
|
24319
|
+
extractors: composeReflectionExtractors({
|
|
24320
|
+
extract: config.reflection?.extract,
|
|
24321
|
+
continuationHints: config.reflection?.continuationHints
|
|
24322
|
+
})
|
|
24246
24323
|
};
|
|
24247
24324
|
this.tokenCounter = new TokenCounter({ model: typeof observationModel === "string" ? observationModel : void 0 });
|
|
24248
24325
|
this.onDebugEvent = config.onDebugEvent;
|
|
@@ -25357,8 +25434,9 @@ ${formattedMessages}
|
|
|
25357
25434
|
return;
|
|
25358
25435
|
}
|
|
25359
25436
|
const omMetadata = (0, _mastra_core_memory.getThreadOMMetadata)((await this.storage.getThreadById({ threadId }))?.metadata);
|
|
25360
|
-
const
|
|
25361
|
-
const
|
|
25437
|
+
const activeExtractors = [...this.observationConfig.extractors, ...this.reflectionConfig.extractors];
|
|
25438
|
+
const currentTask = activeExtractors.some((extractor) => extractor.slug === "current-task") ? omMetadata?.currentTask : void 0;
|
|
25439
|
+
const suggestedResponse = activeExtractors.some((extractor) => extractor.slug === "suggested-response") ? omMetadata?.suggestedResponse : void 0;
|
|
25362
25440
|
const currentDate = opts.currentDate ?? /* @__PURE__ */ new Date();
|
|
25363
25441
|
return this.formatObservationsForContext(record.activeObservations, currentTask, suggestedResponse, omMetadata?.extracted, unobservedContextBlocks, currentDate, this.retrieval);
|
|
25364
25442
|
}
|
|
@@ -25483,11 +25561,11 @@ ${formattedMessages}
|
|
|
25483
25561
|
* ```
|
|
25484
25562
|
*/
|
|
25485
25563
|
async getStatus(opts) {
|
|
25486
|
-
const { threadId, resourceId } = opts;
|
|
25487
|
-
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
25564
|
+
const { threadId, resourceId, record: providedRecord, messages } = opts;
|
|
25565
|
+
const record = providedRecord ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
25488
25566
|
const currentObservationTokens = record.observationTokenCount ?? 0;
|
|
25489
25567
|
let unobservedMessages;
|
|
25490
|
-
if (
|
|
25568
|
+
if (messages) unobservedMessages = this.getUnobservedMessages(messages, record);
|
|
25491
25569
|
else {
|
|
25492
25570
|
const rawMessages = await this.loadMessagesFromStorage(threadId, resourceId, record.lastObservedAt ? new Date(record.lastObservedAt) : void 0);
|
|
25493
25571
|
unobservedMessages = this.getUnobservedMessages(rawMessages, record);
|
|
@@ -25644,6 +25722,7 @@ ${formattedMessages}
|
|
|
25644
25722
|
async buffer(opts) {
|
|
25645
25723
|
const { threadId, resourceId, requestContext, observabilityContext } = opts;
|
|
25646
25724
|
let record = opts.record ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
25725
|
+
const inMemoryRecord = record;
|
|
25647
25726
|
if (!this.buffering.isAsyncObservationEnabled()) return {
|
|
25648
25727
|
buffered: false,
|
|
25649
25728
|
record
|
|
@@ -25662,6 +25741,8 @@ ${formattedMessages}
|
|
|
25662
25741
|
await existingOp;
|
|
25663
25742
|
} catch {}
|
|
25664
25743
|
registerOp(record.id, "bufferingObservation");
|
|
25744
|
+
inMemoryRecord.isBufferingObservation = true;
|
|
25745
|
+
inMemoryRecord.lastBufferedAtTokens = currentTokens;
|
|
25665
25746
|
this.storage.setBufferingObservationFlag(record.id, true, currentTokens).catch((err) => {
|
|
25666
25747
|
omError("[OM] Failed to set buffering observation flag", err);
|
|
25667
25748
|
});
|
|
@@ -25671,6 +25752,14 @@ ${formattedMessages}
|
|
|
25671
25752
|
});
|
|
25672
25753
|
BufferingCoordinator.asyncBufferingOps.set(bufferKey, opPromise);
|
|
25673
25754
|
record = await this.storage.getObservationalMemory(record.threadId, record.resourceId) ?? record;
|
|
25755
|
+
const setBufferingState = (isBufferingObservation, lastBufferedAtTokens) => {
|
|
25756
|
+
inMemoryRecord.isBufferingObservation = isBufferingObservation;
|
|
25757
|
+
record.isBufferingObservation = isBufferingObservation;
|
|
25758
|
+
if (lastBufferedAtTokens !== void 0) {
|
|
25759
|
+
inMemoryRecord.lastBufferedAtTokens = lastBufferedAtTokens;
|
|
25760
|
+
record.lastBufferedAtTokens = lastBufferedAtTokens;
|
|
25761
|
+
}
|
|
25762
|
+
};
|
|
25674
25763
|
let flagCleared = false;
|
|
25675
25764
|
try {
|
|
25676
25765
|
let candidateMessages;
|
|
@@ -25692,10 +25781,13 @@ ${formattedMessages}
|
|
|
25692
25781
|
}
|
|
25693
25782
|
const minNewTokens = (this.observationConfig.bufferTokens ?? 5e3) / 2;
|
|
25694
25783
|
const newTokens = await this.tokenCounter.countMessagesAsync(candidateMessages);
|
|
25695
|
-
if (candidateMessages.length === 0 || !opts.skipMinimumTokenCheck && newTokens < minNewTokens)
|
|
25696
|
-
|
|
25697
|
-
|
|
25698
|
-
|
|
25784
|
+
if (candidateMessages.length === 0 || !opts.skipMinimumTokenCheck && newTokens < minNewTokens) {
|
|
25785
|
+
setBufferingState(false);
|
|
25786
|
+
return {
|
|
25787
|
+
buffered: false,
|
|
25788
|
+
record
|
|
25789
|
+
};
|
|
25790
|
+
}
|
|
25699
25791
|
if (opts.beforeBuffer) await opts.beforeBuffer(candidateMessages);
|
|
25700
25792
|
else if (opts.messages) this.sealMessagesForBuffering(candidateMessages);
|
|
25701
25793
|
const cycleId = `buffer-obs-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
@@ -25750,13 +25842,14 @@ ${formattedMessages}
|
|
|
25750
25842
|
});
|
|
25751
25843
|
await this.storage.setBufferingObservationFlag(record.id, false, newTokens).catch(() => {});
|
|
25752
25844
|
flagCleared = true;
|
|
25845
|
+
setBufferingState(false, newTokens);
|
|
25753
25846
|
BufferingCoordinator.lastBufferedBoundary.set(bufferKey, newTokens);
|
|
25754
25847
|
const maxTimestamp = this.getMaxMessageTimestamp(candidateMessages);
|
|
25755
25848
|
const cursor = new Date(maxTimestamp.getTime() + 1);
|
|
25756
25849
|
BufferingCoordinator.lastBufferedAtTime.set(bufferKey, cursor);
|
|
25757
25850
|
return {
|
|
25758
25851
|
buffered: true,
|
|
25759
|
-
record: await this.
|
|
25852
|
+
record: await this.storage.getObservationalMemory(record.threadId, record.resourceId) ?? record
|
|
25760
25853
|
};
|
|
25761
25854
|
} catch (error) {
|
|
25762
25855
|
omError("[OM] buffer() failed", error);
|
|
@@ -25768,7 +25861,10 @@ ${formattedMessages}
|
|
|
25768
25861
|
unregisterOp(record.id, "bufferingObservation");
|
|
25769
25862
|
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
25770
25863
|
resolveOp();
|
|
25771
|
-
if (!flagCleared)
|
|
25864
|
+
if (!flagCleared) {
|
|
25865
|
+
setBufferingState(false);
|
|
25866
|
+
await this.storage.setBufferingObservationFlag(record.id, false).catch(() => {});
|
|
25867
|
+
}
|
|
25772
25868
|
}
|
|
25773
25869
|
}
|
|
25774
25870
|
/**
|
|
@@ -25794,7 +25890,7 @@ ${formattedMessages}
|
|
|
25794
25890
|
/** @internal Used by ObservationStep. */
|
|
25795
25891
|
async activate(opts) {
|
|
25796
25892
|
const { threadId, resourceId } = opts;
|
|
25797
|
-
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
25893
|
+
const record = opts.record ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
25798
25894
|
if (this.buffering.isAsyncObservationEnabled()) {
|
|
25799
25895
|
const lockKey = this.buffering.getLockKey(threadId, resourceId);
|
|
25800
25896
|
const bufKey = this.buffering.getObservationBufferKey(lockKey);
|
|
@@ -25840,6 +25936,7 @@ ${formattedMessages}
|
|
|
25840
25936
|
const status = await this.getStatus({
|
|
25841
25937
|
threadId,
|
|
25842
25938
|
resourceId,
|
|
25939
|
+
record,
|
|
25843
25940
|
messages: thresholdMessages
|
|
25844
25941
|
});
|
|
25845
25942
|
if (status.pendingTokens < status.threshold) return {
|
|
@@ -26559,31 +26656,30 @@ var ObservationalMemoryProcessor = class {
|
|
|
26559
26656
|
threadId,
|
|
26560
26657
|
resourceId
|
|
26561
26658
|
});
|
|
26562
|
-
const
|
|
26659
|
+
const turnRecord = this.turn.record;
|
|
26563
26660
|
await this.engine.emitProgress({
|
|
26564
|
-
record:
|
|
26661
|
+
record: turnRecord,
|
|
26565
26662
|
stepNumber,
|
|
26566
26663
|
pendingTokens: ctx.status.pendingTokens,
|
|
26567
26664
|
threshold: ctx.status.threshold,
|
|
26568
26665
|
effectiveObservationTokensThreshold: ctx.status.effectiveObservationTokensThreshold,
|
|
26569
|
-
currentObservationTokens:
|
|
26666
|
+
currentObservationTokens: turnRecord.observationTokenCount ?? 0,
|
|
26570
26667
|
writer,
|
|
26571
26668
|
threadId,
|
|
26572
26669
|
resourceId
|
|
26573
26670
|
});
|
|
26574
|
-
const
|
|
26575
|
-
|
|
26576
|
-
|
|
26577
|
-
|
|
26578
|
-
|
|
26579
|
-
await this.engine.getStorage().setPendingMessageTokens(freshRecord.id, finalTotalPending).catch(() => {});
|
|
26671
|
+
const finalTotalPending = ctx.status.pendingTokens;
|
|
26672
|
+
try {
|
|
26673
|
+
await this.engine.getStorage().setPendingMessageTokens(turnRecord.id, finalTotalPending);
|
|
26674
|
+
this.turn.patchRecord({ pendingMessageTokens: finalTotalPending });
|
|
26675
|
+
} catch {}
|
|
26580
26676
|
if (reproCaptureEnabled) writeProcessInputStepReproCapture({
|
|
26581
26677
|
threadId,
|
|
26582
26678
|
resourceId,
|
|
26583
26679
|
stepNumber,
|
|
26584
26680
|
args,
|
|
26585
26681
|
preRecord: preRecordSnapshot,
|
|
26586
|
-
postRecord: safeCaptureJson(
|
|
26682
|
+
postRecord: safeCaptureJson(turnRecord),
|
|
26587
26683
|
preMessages: preMessagesSnapshot,
|
|
26588
26684
|
preBufferedChunks: [],
|
|
26589
26685
|
preContextTokenCount: 0,
|
|
@@ -28950,4 +29046,4 @@ Object.defineProperty(exports, "wrapInObservationGroup", {
|
|
|
28950
29046
|
}
|
|
28951
29047
|
});
|
|
28952
29048
|
|
|
28953
|
-
//# sourceMappingURL=src-
|
|
29049
|
+
//# sourceMappingURL=src-MvtBOFYO.cjs.map
|