@mastra/server 1.60.0-alpha.2 → 1.60.0-alpha.4
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 +14 -0
- package/dist/{dist-RYanMda7.cjs → dist-BJ9n8vHL.cjs} +156 -60
- package/dist/dist-BJ9n8vHL.cjs.map +1 -0
- package/dist/{dist-ByXtFaHm.js → dist-Bpz9F_9G.js} +156 -60
- package/dist/dist-Bpz9F_9G.js.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/server/handlers/agent-builder.cjs +1 -1
- package/dist/server/handlers/agent-builder.js +1 -1
- package/dist/server/handlers/agent-controller.d.ts +2 -2
- package/package.json +5 -5
- package/dist/dist-ByXtFaHm.js.map +0 -1
- package/dist/dist-RYanMda7.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @mastra/server
|
|
2
2
|
|
|
3
|
+
## 1.60.0-alpha.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`d7e6745`](https://github.com/mastra-ai/mastra/commit/d7e67456954863c55440ea9c49bc6ceb9949972d), [`9acb50f`](https://github.com/mastra-ai/mastra/commit/9acb50f71cec9c362f06820033f90ae6b1f8282f), [`46e9e3f`](https://github.com/mastra-ai/mastra/commit/46e9e3f73babe1bc70080a596cf2ac0b9da48519), [`3f9a190`](https://github.com/mastra-ai/mastra/commit/3f9a19057c027155867b9317294ee4ca7bd0581a), [`e8808e3`](https://github.com/mastra-ai/mastra/commit/e8808e3d8eb585a2565be53e56a7e0e1477352a4), [`d4be8c1`](https://github.com/mastra-ai/mastra/commit/d4be8c1739d22d621e3f78790e1dd5eb5ecc3589), [`a5d2eb1`](https://github.com/mastra-ai/mastra/commit/a5d2eb10347eade1ae2816d88f466c25186c54a5), [`e81744c`](https://github.com/mastra-ai/mastra/commit/e81744cd13c46619c142dc521dc0baac47607a84)]:
|
|
8
|
+
- @mastra/core@1.60.0-alpha.4
|
|
9
|
+
|
|
10
|
+
## 1.60.0-alpha.3
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`d8308a2`](https://github.com/mastra-ai/mastra/commit/d8308a2be3c07e777393d1017a381dcae3890d30), [`7aad631`](https://github.com/mastra-ai/mastra/commit/7aad631b43bc10db77d5b8c66b200d7a49d18bf2), [`1794a79`](https://github.com/mastra-ai/mastra/commit/1794a79178c418004a7261b1ad9114066f7ef01d)]:
|
|
15
|
+
- @mastra/core@1.60.0-alpha.3
|
|
16
|
+
|
|
3
17
|
## 1.60.0-alpha.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -4693,7 +4693,7 @@ function splitLines(text) {
|
|
|
4693
4693
|
return result;
|
|
4694
4694
|
}
|
|
4695
4695
|
//#endregion
|
|
4696
|
-
//#region ../memory/dist/src-
|
|
4696
|
+
//#region ../memory/dist/src-BUlG9vaB.js
|
|
4697
4697
|
var __defProp$3 = Object.defineProperty;
|
|
4698
4698
|
var __exportAll = (all, no_symbols) => {
|
|
4699
4699
|
let target = {};
|
|
@@ -20528,21 +20528,17 @@ Or as a standalone observation when closing out a broader task:
|
|
|
20528
20528
|
Completion observations should be terse but specific about WHAT was completed.
|
|
20529
20529
|
Prefer concrete resolved outcomes over abstract workflow status so the assistant remembers what is already done.`;
|
|
20530
20530
|
buildObserverOutputFormat();
|
|
20531
|
-
|
|
20532
|
-
|
|
20533
|
-
|
|
20534
|
-
|
|
20535
|
-
|
|
20536
|
-
|
|
20537
|
-
|
|
20538
|
-
|
|
20539
|
-
|
|
20540
|
-
|
|
20541
|
-
|
|
20542
|
-
- "I've updated the navigation model. Let me walk you through the changes..."
|
|
20543
|
-
- "The assistant should wait for the user to respond before continuing."
|
|
20544
|
-
- Call the view tool on src/example.ts to continue debugging.
|
|
20545
|
-
</suggested-response>` : "";
|
|
20531
|
+
/**
|
|
20532
|
+
* Build the Observer's output format.
|
|
20533
|
+
*
|
|
20534
|
+
* `extractors` distinguishes two cases that both look empty:
|
|
20535
|
+
* - `undefined` — the no-arg call behind the exported defaults (OBSERVER_OUTPUT_FORMAT_BASE,
|
|
20536
|
+
* OBSERVER_SYSTEM_PROMPT, REFLECTOR_SYSTEM_PROMPT), which keep describing both built-in
|
|
20537
|
+
* sections with their historical text. Runtime callers always pass the composed list.
|
|
20538
|
+
* - `[]` — the caller composed extractors and every section was disabled, so no continuation
|
|
20539
|
+
* sections are described at all.
|
|
20540
|
+
*/
|
|
20541
|
+
function buildObserverOutputFormat(extractors) {
|
|
20546
20542
|
return `Use priority levels:
|
|
20547
20543
|
- 🔴 High: explicit user facts, preferences, unresolved goals, critical context
|
|
20548
20544
|
- 🟡 Medium: project details, learned information, tool results
|
|
@@ -20568,7 +20564,19 @@ Date: Dec 5, 2025
|
|
|
20568
20564
|
* 🔴 (09:15) Continued work on feature X
|
|
20569
20565
|
</observations>
|
|
20570
20566
|
|
|
20571
|
-
${
|
|
20567
|
+
${buildExtractorOutputSections(extractors ?? []) || (extractors === void 0 ? `
|
|
20568
|
+
<current-task>
|
|
20569
|
+
State the current task(s) explicitly:
|
|
20570
|
+
- Primary: What the agent is currently working on
|
|
20571
|
+
- Secondary: Other pending tasks (mark as "waiting for user" if appropriate)
|
|
20572
|
+
</current-task>
|
|
20573
|
+
|
|
20574
|
+
<suggested-response>
|
|
20575
|
+
Hint for the agent's immediate next message. Examples:
|
|
20576
|
+
- "I've updated the navigation model. Let me walk you through the changes..."
|
|
20577
|
+
- "The assistant should wait for the user to respond before continuing."
|
|
20578
|
+
- Call the view tool on src/example.ts to continue debugging.
|
|
20579
|
+
</suggested-response>` : "")}`;
|
|
20572
20580
|
}
|
|
20573
20581
|
/**
|
|
20574
20582
|
* The guidelines for the Observer.
|
|
@@ -20595,10 +20603,22 @@ const OBSERVER_GUIDELINES = `- Be specific enough for the assistant to act on
|
|
|
20595
20603
|
* Build the complete observer system prompt.
|
|
20596
20604
|
* @param multiThread - Whether this is for multi-thread batched observation (default: false)
|
|
20597
20605
|
* @param instruction - Optional custom instructions to append to the prompt
|
|
20606
|
+
* @param includeThreadTitle - Whether the Observer should also produce a thread title
|
|
20607
|
+
* @param extractors - Active extractors, used to decide which sections the prompt describes.
|
|
20608
|
+
* Omitted only by the exported no-arg defaults; pass `[]` to describe no continuation sections at all.
|
|
20598
20609
|
*/
|
|
20599
|
-
function buildObserverSystemPrompt(multiThread = false, instruction, includeThreadTitle = false, extractors
|
|
20610
|
+
function buildObserverSystemPrompt(multiThread = false, instruction, includeThreadTitle = false, extractors) {
|
|
20600
20611
|
const outputFormat = buildObserverOutputFormat(extractors);
|
|
20601
|
-
const
|
|
20612
|
+
const customInstructions = instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : "";
|
|
20613
|
+
const currentTaskEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "current-task");
|
|
20614
|
+
const suggestedResponseEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "suggested-response");
|
|
20615
|
+
const multiThreadSections = [
|
|
20616
|
+
"observations",
|
|
20617
|
+
...currentTaskEnabled ? ["current-task"] : [],
|
|
20618
|
+
...suggestedResponseEnabled ? ["suggested-response"] : [],
|
|
20619
|
+
...includeThreadTitle ? ["thread-title"] : []
|
|
20620
|
+
];
|
|
20621
|
+
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>.`;
|
|
20602
20622
|
const multiThreadTitleExample = includeThreadTitle ? `
|
|
20603
20623
|
<thread-title>Feature X implementation</thread-title>` : "";
|
|
20604
20624
|
const multiThreadSecondTitleExample = includeThreadTitle ? `
|
|
@@ -20628,28 +20648,28 @@ For multi-thread output, wrap each thread's observations like this:
|
|
|
20628
20648
|
<thread id="thread_id_1">
|
|
20629
20649
|
Date: Dec 4, 2025
|
|
20630
20650
|
* 🔴 (14:30) User prefers direct answers
|
|
20631
|
-
* 🔴 (14:31) Working on feature X
|
|
20651
|
+
* 🔴 (14:31) Working on feature X${currentTaskEnabled ? `
|
|
20632
20652
|
|
|
20633
20653
|
<current-task>
|
|
20634
20654
|
What the agent is currently working on in this thread
|
|
20635
|
-
</current-task
|
|
20655
|
+
</current-task>` : ""}${suggestedResponseEnabled ? `
|
|
20636
20656
|
|
|
20637
20657
|
<suggested-response>
|
|
20638
20658
|
Hint for the agent's next message in this thread
|
|
20639
|
-
</suggested-response
|
|
20659
|
+
</suggested-response>` : ""}${multiThreadTitleExample}
|
|
20640
20660
|
</thread>
|
|
20641
20661
|
|
|
20642
20662
|
<thread id="thread_id_2">
|
|
20643
20663
|
Date: Dec 5, 2025
|
|
20644
|
-
* 🔴 (09:15) User asked about deployment
|
|
20664
|
+
* 🔴 (09:15) User asked about deployment${currentTaskEnabled ? `
|
|
20645
20665
|
|
|
20646
20666
|
<current-task>
|
|
20647
20667
|
Current task for this thread
|
|
20648
|
-
</current-task
|
|
20668
|
+
</current-task>` : ""}${suggestedResponseEnabled ? `
|
|
20649
20669
|
|
|
20650
20670
|
<suggested-response>
|
|
20651
20671
|
Suggested response for this thread
|
|
20652
|
-
</suggested-response
|
|
20672
|
+
</suggested-response>` : ""}${multiThreadSecondTitleExample}
|
|
20653
20673
|
</thread>
|
|
20654
20674
|
</observations>
|
|
20655
20675
|
|
|
@@ -20659,7 +20679,7 @@ ${OBSERVER_GUIDELINES}
|
|
|
20659
20679
|
|
|
20660
20680
|
Remember: These observations are the assistant's ONLY memory. Make them count.
|
|
20661
20681
|
|
|
20662
|
-
User messages are extremely important
|
|
20682
|
+
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}`;
|
|
20663
20683
|
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.
|
|
20664
20684
|
|
|
20665
20685
|
Extract observations that will help the assistant remember:
|
|
@@ -20684,7 +20704,7 @@ Simply output your observations without any thread-related markup.
|
|
|
20684
20704
|
|
|
20685
20705
|
Remember: These observations are the assistant's ONLY memory. Make them count.
|
|
20686
20706
|
|
|
20687
|
-
User messages are extremely important
|
|
20707
|
+
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}`;
|
|
20688
20708
|
}
|
|
20689
20709
|
/**
|
|
20690
20710
|
* Observer Agent System Prompt (default - for backwards compatibility)
|
|
@@ -21376,7 +21396,7 @@ function optimizeObservationsForContext(observations) {
|
|
|
21376
21396
|
let optimized = stripEphemeralAnchorIds(observations);
|
|
21377
21397
|
optimized = optimized.replace(/🟡\s*/g, "");
|
|
21378
21398
|
optimized = optimized.replace(/🟢\s*/g, "");
|
|
21379
|
-
optimized = optimized.replace(/\[(?![\d\s]*items collapsed)[^\]]+\]/g, "");
|
|
21399
|
+
optimized = optimized.replace(/\[(?![\d\s]*items collapsed)[^\]]+\](?!\()/g, "");
|
|
21380
21400
|
optimized = optimized.replace(/\s*->\s*/g, " ");
|
|
21381
21401
|
optimized = optimized.replace(/ +/g, " ");
|
|
21382
21402
|
optimized = optimized.replace(/\n{3,}/g, "\n\n");
|
|
@@ -22786,6 +22806,7 @@ var TokenCounter = class TokenCounter {
|
|
|
22786
22806
|
defaultModelContext;
|
|
22787
22807
|
modelContextStorage = new async_hooks.AsyncLocalStorage();
|
|
22788
22808
|
inFlightAttachmentCounts = /* @__PURE__ */ new Map();
|
|
22809
|
+
multimodalToolResultCounts = /* @__PURE__ */ new WeakMap();
|
|
22789
22810
|
static TOKENS_PER_MESSAGE = 3.8;
|
|
22790
22811
|
static TOKENS_PER_CONVERSATION = 24;
|
|
22791
22812
|
constructor(options) {
|
|
@@ -22848,6 +22869,9 @@ var TokenCounter = class TokenCounter {
|
|
|
22848
22869
|
}
|
|
22849
22870
|
countMultimodalToolResultContent(part, toolResult) {
|
|
22850
22871
|
if (!toolResult || typeof toolResult !== "object") return;
|
|
22872
|
+
const resultKey = buildEstimateKey("tool-result-multimodal-content-source", JSON.stringify(toolResult));
|
|
22873
|
+
const cached = this.multimodalToolResultCounts.get(part);
|
|
22874
|
+
if (cached?.resultKey === resultKey) return cached.tokens;
|
|
22851
22875
|
const output = toolResult;
|
|
22852
22876
|
const content = output.type === "content" && Array.isArray(output.value) ? output.value : output.content;
|
|
22853
22877
|
if (!Array.isArray(content)) return;
|
|
@@ -22959,10 +22983,15 @@ var TokenCounter = class TokenCounter {
|
|
|
22959
22983
|
countJsonContentPart(contentPart);
|
|
22960
22984
|
}
|
|
22961
22985
|
if (!hasAttachment) return;
|
|
22962
|
-
|
|
22986
|
+
const estimate = this.readOrPersistFixedPartEstimate(part, "tool-result-multimodal-content", JSON.stringify({
|
|
22963
22987
|
type: "content",
|
|
22964
22988
|
value: cacheParts
|
|
22965
22989
|
}), tokens);
|
|
22990
|
+
this.multimodalToolResultCounts.set(part, {
|
|
22991
|
+
resultKey,
|
|
22992
|
+
tokens: estimate
|
|
22993
|
+
});
|
|
22994
|
+
return estimate;
|
|
22966
22995
|
}
|
|
22967
22996
|
estimateImageAssetTokens(part, asset, kind) {
|
|
22968
22997
|
const modelContext = this.getModelContext();
|
|
@@ -24931,23 +24960,43 @@ function createThreadTitleExtractor() {
|
|
|
24931
24960
|
metadataKeyPath: "threadTitle"
|
|
24932
24961
|
}, true);
|
|
24933
24962
|
}
|
|
24963
|
+
/**
|
|
24964
|
+
* Normalize the user-facing `continuationHints` config into explicit per-section flags.
|
|
24965
|
+
* Both sections stay enabled unless the caller opts out, so omitting the config is a no-op.
|
|
24966
|
+
*/
|
|
24967
|
+
function resolveContinuationHints(config) {
|
|
24968
|
+
if (config === void 0 || config === true) return {
|
|
24969
|
+
currentTask: true,
|
|
24970
|
+
suggestedResponse: true
|
|
24971
|
+
};
|
|
24972
|
+
if (config === false) return {
|
|
24973
|
+
currentTask: false,
|
|
24974
|
+
suggestedResponse: false
|
|
24975
|
+
};
|
|
24976
|
+
return {
|
|
24977
|
+
currentTask: config.currentTask ?? true,
|
|
24978
|
+
suggestedResponse: config.suggestedResponse ?? true
|
|
24979
|
+
};
|
|
24980
|
+
}
|
|
24934
24981
|
function composeExtractors(options) {
|
|
24982
|
+
const continuationHints = resolveContinuationHints(options.continuationHints);
|
|
24935
24983
|
const extractors = [];
|
|
24936
|
-
if (
|
|
24984
|
+
if (continuationHints.currentTask) extractors.push(createCurrentTaskExtractor());
|
|
24985
|
+
if (continuationHints.suggestedResponse) extractors.push(createSuggestedResponseExtractor());
|
|
24937
24986
|
if (options.includeThreadTitle) extractors.push(createThreadTitleExtractor());
|
|
24938
24987
|
extractors.push(...options.userExtractors ?? []);
|
|
24939
24988
|
return validateExtractorList(extractors);
|
|
24940
24989
|
}
|
|
24941
24990
|
function composeObservationExtractors(config) {
|
|
24942
24991
|
return composeExtractors({
|
|
24943
|
-
|
|
24992
|
+
continuationHints: config.continuationHints,
|
|
24944
24993
|
includeThreadTitle: config.threadTitle,
|
|
24945
24994
|
userExtractors: config.extract
|
|
24946
24995
|
});
|
|
24947
24996
|
}
|
|
24948
24997
|
function composeReflectionExtractors(config) {
|
|
24949
24998
|
return composeExtractors({
|
|
24950
|
-
|
|
24999
|
+
continuationHints: config.continuationHints,
|
|
24951
25000
|
userExtractors: config.extract
|
|
24952
25001
|
});
|
|
24953
25002
|
}
|
|
@@ -26708,10 +26757,12 @@ var ObservationStep = class {
|
|
|
26708
26757
|
resourceId,
|
|
26709
26758
|
checkThreshold: true,
|
|
26710
26759
|
messages: step0Messages,
|
|
26760
|
+
record: this.turn.record,
|
|
26711
26761
|
currentModel: this.turn.actorModelContext,
|
|
26712
26762
|
writer: this.turn.writer,
|
|
26713
26763
|
messageList
|
|
26714
26764
|
});
|
|
26765
|
+
this.turn.setRecord(activation.record);
|
|
26715
26766
|
if (activation.activated) {
|
|
26716
26767
|
activated = true;
|
|
26717
26768
|
if (activation.activatedMessageIds?.length) messageList.removeByIds(activation.activatedMessageIds);
|
|
@@ -26753,6 +26804,7 @@ var ObservationStep = class {
|
|
|
26753
26804
|
let statusSnapshot = await om.getStatus({
|
|
26754
26805
|
threadId,
|
|
26755
26806
|
resourceId,
|
|
26807
|
+
record: this.turn.record,
|
|
26756
26808
|
messages: getObservableMessages(messageList)
|
|
26757
26809
|
});
|
|
26758
26810
|
if (statusSnapshot.shouldBuffer && !hasIncompleteToolCalls) {
|
|
@@ -26848,6 +26900,7 @@ var ObservationStep = class {
|
|
|
26848
26900
|
statusSnapshot = await om.getStatus({
|
|
26849
26901
|
threadId,
|
|
26850
26902
|
resourceId,
|
|
26903
|
+
record: this.turn.record,
|
|
26851
26904
|
messages: getObservableMessages(messageList)
|
|
26852
26905
|
});
|
|
26853
26906
|
}
|
|
@@ -26898,10 +26951,12 @@ var ObservationStep = class {
|
|
|
26898
26951
|
const { threadId, resourceId, messageList } = this.turn;
|
|
26899
26952
|
const om = this.turn.om;
|
|
26900
26953
|
await om.waitForBuffering(threadId, resourceId);
|
|
26954
|
+
await this.turn.refreshRecord();
|
|
26901
26955
|
const observableMessages = this.seededResponseMessage ? getObservableMessages(messageList).filter((msg) => msg.id !== this.turn.responseMessageId) : getObservableMessages(messageList);
|
|
26902
26956
|
const freshStatus = await om.getStatus({
|
|
26903
26957
|
threadId,
|
|
26904
26958
|
resourceId,
|
|
26959
|
+
record: this.turn.record,
|
|
26905
26960
|
messages: observableMessages
|
|
26906
26961
|
});
|
|
26907
26962
|
if (!freshStatus.shouldObserve) return {
|
|
@@ -26912,11 +26967,13 @@ var ObservationStep = class {
|
|
|
26912
26967
|
const activation = await om.activate({
|
|
26913
26968
|
threadId,
|
|
26914
26969
|
resourceId,
|
|
26970
|
+
record: this.turn.record,
|
|
26915
26971
|
messages: observableMessages,
|
|
26916
26972
|
currentModel: this.turn.actorModelContext,
|
|
26917
26973
|
writer: this.turn.writer,
|
|
26918
26974
|
messageList
|
|
26919
26975
|
});
|
|
26976
|
+
this.turn.setRecord(activation.record);
|
|
26920
26977
|
if (activation.activated) {
|
|
26921
26978
|
const postActivationRecord = activation.record;
|
|
26922
26979
|
await om.reflector.maybeReflect({
|
|
@@ -27099,6 +27156,18 @@ var ObservationTurn = class {
|
|
|
27099
27156
|
};
|
|
27100
27157
|
return this._context;
|
|
27101
27158
|
}
|
|
27159
|
+
/** Replace the cached turn record with a specific instance. */
|
|
27160
|
+
setRecord(record) {
|
|
27161
|
+
this._record = record;
|
|
27162
|
+
if (this._context) this._context.record = record;
|
|
27163
|
+
}
|
|
27164
|
+
/** Patch the cached turn record with merged fields. */
|
|
27165
|
+
patchRecord(patch) {
|
|
27166
|
+
this.setRecord({
|
|
27167
|
+
...this.record,
|
|
27168
|
+
...patch
|
|
27169
|
+
});
|
|
27170
|
+
}
|
|
27102
27171
|
/**
|
|
27103
27172
|
* Create a step handle. If a previous step exists, it is finalized
|
|
27104
27173
|
* (its output messages will be saved at the start of the new step's prepare()).
|
|
@@ -27153,7 +27222,7 @@ var ObservationTurn = class {
|
|
|
27153
27222
|
* @internal
|
|
27154
27223
|
*/
|
|
27155
27224
|
async refreshRecord() {
|
|
27156
|
-
this.
|
|
27225
|
+
this.setRecord(await this.om.getOrCreateRecord(this.threadId, this.resourceId));
|
|
27157
27226
|
}
|
|
27158
27227
|
/**
|
|
27159
27228
|
* Refresh cross-thread context for resource scope. Called per-step.
|
|
@@ -27206,9 +27275,13 @@ var ObservationTurn = class {
|
|
|
27206
27275
|
* - Preserving ALL important information (reflections become the ENTIRE memory)
|
|
27207
27276
|
*
|
|
27208
27277
|
* @param instruction - Optional custom instructions to append to the prompt
|
|
27278
|
+
* @param extractors - Active extractors, used to decide which sections the prompt describes
|
|
27209
27279
|
*/
|
|
27210
|
-
function buildReflectorSystemPrompt(instruction, extractors
|
|
27280
|
+
function buildReflectorSystemPrompt(instruction, extractors) {
|
|
27211
27281
|
const outputFormat = buildObserverOutputFormat(extractors);
|
|
27282
|
+
const customInstructions = instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : "";
|
|
27283
|
+
const currentTaskEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "current-task");
|
|
27284
|
+
const suggestedResponseEnabled = extractors === void 0 || extractors.some((extractor) => extractor.slug === "suggested-response");
|
|
27212
27285
|
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.
|
|
27213
27286
|
|
|
27214
27287
|
The following instructions were given to another part of your psyche (the observer) to create memories.
|
|
@@ -27285,7 +27358,7 @@ Date: Dec 4, 2025
|
|
|
27285
27358
|
|
|
27286
27359
|
${outputFormat}
|
|
27287
27360
|
|
|
27288
|
-
User messages are extremely important
|
|
27361
|
+
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}`;
|
|
27289
27362
|
}
|
|
27290
27363
|
buildReflectorSystemPrompt();
|
|
27291
27364
|
/**
|
|
@@ -28743,7 +28816,8 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
28743
28816
|
observeAttachments: config.observation?.observeAttachments ?? true,
|
|
28744
28817
|
extractors: composeObservationExtractors({
|
|
28745
28818
|
threadTitle: config.observation?.threadTitle ?? false,
|
|
28746
|
-
extract: config.observation?.extract
|
|
28819
|
+
extract: config.observation?.extract,
|
|
28820
|
+
continuationHints: config.observation?.continuationHints
|
|
28747
28821
|
})
|
|
28748
28822
|
};
|
|
28749
28823
|
this.reflectionConfig = {
|
|
@@ -28760,7 +28834,10 @@ var ObservationalMemory = class ObservationalMemory {
|
|
|
28760
28834
|
activateOnProviderChange: config.reflection?.activateOnProviderChange ?? false,
|
|
28761
28835
|
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),
|
|
28762
28836
|
instruction: config.reflection?.instruction,
|
|
28763
|
-
extractors: composeReflectionExtractors({
|
|
28837
|
+
extractors: composeReflectionExtractors({
|
|
28838
|
+
extract: config.reflection?.extract,
|
|
28839
|
+
continuationHints: config.reflection?.continuationHints
|
|
28840
|
+
})
|
|
28764
28841
|
};
|
|
28765
28842
|
this.tokenCounter = new TokenCounter({ model: typeof observationModel === "string" ? observationModel : void 0 });
|
|
28766
28843
|
this.onDebugEvent = config.onDebugEvent;
|
|
@@ -29875,8 +29952,9 @@ ${formattedMessages}
|
|
|
29875
29952
|
return;
|
|
29876
29953
|
}
|
|
29877
29954
|
const omMetadata = (0, _mastra_core_memory.getThreadOMMetadata)((await this.storage.getThreadById({ threadId }))?.metadata);
|
|
29878
|
-
const
|
|
29879
|
-
const
|
|
29955
|
+
const activeExtractors = [...this.observationConfig.extractors, ...this.reflectionConfig.extractors];
|
|
29956
|
+
const currentTask = activeExtractors.some((extractor) => extractor.slug === "current-task") ? omMetadata?.currentTask : void 0;
|
|
29957
|
+
const suggestedResponse = activeExtractors.some((extractor) => extractor.slug === "suggested-response") ? omMetadata?.suggestedResponse : void 0;
|
|
29880
29958
|
const currentDate = opts.currentDate ?? /* @__PURE__ */ new Date();
|
|
29881
29959
|
return this.formatObservationsForContext(record.activeObservations, currentTask, suggestedResponse, omMetadata?.extracted, unobservedContextBlocks, currentDate, this.retrieval);
|
|
29882
29960
|
}
|
|
@@ -30001,11 +30079,11 @@ ${formattedMessages}
|
|
|
30001
30079
|
* ```
|
|
30002
30080
|
*/
|
|
30003
30081
|
async getStatus(opts) {
|
|
30004
|
-
const { threadId, resourceId } = opts;
|
|
30005
|
-
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
30082
|
+
const { threadId, resourceId, record: providedRecord, messages } = opts;
|
|
30083
|
+
const record = providedRecord ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
30006
30084
|
const currentObservationTokens = record.observationTokenCount ?? 0;
|
|
30007
30085
|
let unobservedMessages;
|
|
30008
|
-
if (
|
|
30086
|
+
if (messages) unobservedMessages = this.getUnobservedMessages(messages, record);
|
|
30009
30087
|
else {
|
|
30010
30088
|
const rawMessages = await this.loadMessagesFromStorage(threadId, resourceId, record.lastObservedAt ? new Date(record.lastObservedAt) : void 0);
|
|
30011
30089
|
unobservedMessages = this.getUnobservedMessages(rawMessages, record);
|
|
@@ -30162,6 +30240,7 @@ ${formattedMessages}
|
|
|
30162
30240
|
async buffer(opts) {
|
|
30163
30241
|
const { threadId, resourceId, requestContext, observabilityContext } = opts;
|
|
30164
30242
|
let record = opts.record ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
30243
|
+
const inMemoryRecord = record;
|
|
30165
30244
|
if (!this.buffering.isAsyncObservationEnabled()) return {
|
|
30166
30245
|
buffered: false,
|
|
30167
30246
|
record
|
|
@@ -30180,6 +30259,8 @@ ${formattedMessages}
|
|
|
30180
30259
|
await existingOp;
|
|
30181
30260
|
} catch {}
|
|
30182
30261
|
registerOp(record.id, "bufferingObservation");
|
|
30262
|
+
inMemoryRecord.isBufferingObservation = true;
|
|
30263
|
+
inMemoryRecord.lastBufferedAtTokens = currentTokens;
|
|
30183
30264
|
this.storage.setBufferingObservationFlag(record.id, true, currentTokens).catch((err) => {
|
|
30184
30265
|
omError("[OM] Failed to set buffering observation flag", err);
|
|
30185
30266
|
});
|
|
@@ -30189,6 +30270,14 @@ ${formattedMessages}
|
|
|
30189
30270
|
});
|
|
30190
30271
|
BufferingCoordinator.asyncBufferingOps.set(bufferKey, opPromise);
|
|
30191
30272
|
record = await this.storage.getObservationalMemory(record.threadId, record.resourceId) ?? record;
|
|
30273
|
+
const setBufferingState = (isBufferingObservation, lastBufferedAtTokens) => {
|
|
30274
|
+
inMemoryRecord.isBufferingObservation = isBufferingObservation;
|
|
30275
|
+
record.isBufferingObservation = isBufferingObservation;
|
|
30276
|
+
if (lastBufferedAtTokens !== void 0) {
|
|
30277
|
+
inMemoryRecord.lastBufferedAtTokens = lastBufferedAtTokens;
|
|
30278
|
+
record.lastBufferedAtTokens = lastBufferedAtTokens;
|
|
30279
|
+
}
|
|
30280
|
+
};
|
|
30192
30281
|
let flagCleared = false;
|
|
30193
30282
|
try {
|
|
30194
30283
|
let candidateMessages;
|
|
@@ -30210,10 +30299,13 @@ ${formattedMessages}
|
|
|
30210
30299
|
}
|
|
30211
30300
|
const minNewTokens = (this.observationConfig.bufferTokens ?? 5e3) / 2;
|
|
30212
30301
|
const newTokens = await this.tokenCounter.countMessagesAsync(candidateMessages);
|
|
30213
|
-
if (candidateMessages.length === 0 || !opts.skipMinimumTokenCheck && newTokens < minNewTokens)
|
|
30214
|
-
|
|
30215
|
-
|
|
30216
|
-
|
|
30302
|
+
if (candidateMessages.length === 0 || !opts.skipMinimumTokenCheck && newTokens < minNewTokens) {
|
|
30303
|
+
setBufferingState(false);
|
|
30304
|
+
return {
|
|
30305
|
+
buffered: false,
|
|
30306
|
+
record
|
|
30307
|
+
};
|
|
30308
|
+
}
|
|
30217
30309
|
if (opts.beforeBuffer) await opts.beforeBuffer(candidateMessages);
|
|
30218
30310
|
else if (opts.messages) this.sealMessagesForBuffering(candidateMessages);
|
|
30219
30311
|
const cycleId = `buffer-obs-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
@@ -30268,13 +30360,14 @@ ${formattedMessages}
|
|
|
30268
30360
|
});
|
|
30269
30361
|
await this.storage.setBufferingObservationFlag(record.id, false, newTokens).catch(() => {});
|
|
30270
30362
|
flagCleared = true;
|
|
30363
|
+
setBufferingState(false, newTokens);
|
|
30271
30364
|
BufferingCoordinator.lastBufferedBoundary.set(bufferKey, newTokens);
|
|
30272
30365
|
const maxTimestamp = this.getMaxMessageTimestamp(candidateMessages);
|
|
30273
30366
|
const cursor = new Date(maxTimestamp.getTime() + 1);
|
|
30274
30367
|
BufferingCoordinator.lastBufferedAtTime.set(bufferKey, cursor);
|
|
30275
30368
|
return {
|
|
30276
30369
|
buffered: true,
|
|
30277
|
-
record: await this.
|
|
30370
|
+
record: await this.storage.getObservationalMemory(record.threadId, record.resourceId) ?? record
|
|
30278
30371
|
};
|
|
30279
30372
|
} catch (error) {
|
|
30280
30373
|
omError("[OM] buffer() failed", error);
|
|
@@ -30286,7 +30379,10 @@ ${formattedMessages}
|
|
|
30286
30379
|
unregisterOp(record.id, "bufferingObservation");
|
|
30287
30380
|
BufferingCoordinator.asyncBufferingOps.delete(bufferKey);
|
|
30288
30381
|
resolveOp();
|
|
30289
|
-
if (!flagCleared)
|
|
30382
|
+
if (!flagCleared) {
|
|
30383
|
+
setBufferingState(false);
|
|
30384
|
+
await this.storage.setBufferingObservationFlag(record.id, false).catch(() => {});
|
|
30385
|
+
}
|
|
30290
30386
|
}
|
|
30291
30387
|
}
|
|
30292
30388
|
/**
|
|
@@ -30312,7 +30408,7 @@ ${formattedMessages}
|
|
|
30312
30408
|
/** @internal Used by ObservationStep. */
|
|
30313
30409
|
async activate(opts) {
|
|
30314
30410
|
const { threadId, resourceId } = opts;
|
|
30315
|
-
const record = await this.getOrCreateRecord(threadId, resourceId);
|
|
30411
|
+
const record = opts.record ?? await this.getOrCreateRecord(threadId, resourceId);
|
|
30316
30412
|
if (this.buffering.isAsyncObservationEnabled()) {
|
|
30317
30413
|
const lockKey = this.buffering.getLockKey(threadId, resourceId);
|
|
30318
30414
|
const bufKey = this.buffering.getObservationBufferKey(lockKey);
|
|
@@ -30358,6 +30454,7 @@ ${formattedMessages}
|
|
|
30358
30454
|
const status = await this.getStatus({
|
|
30359
30455
|
threadId,
|
|
30360
30456
|
resourceId,
|
|
30457
|
+
record,
|
|
30361
30458
|
messages: thresholdMessages
|
|
30362
30459
|
});
|
|
30363
30460
|
if (status.pendingTokens < status.threshold) return {
|
|
@@ -31073,31 +31170,30 @@ var ObservationalMemoryProcessor = class {
|
|
|
31073
31170
|
threadId,
|
|
31074
31171
|
resourceId
|
|
31075
31172
|
});
|
|
31076
|
-
const
|
|
31173
|
+
const turnRecord = this.turn.record;
|
|
31077
31174
|
await this.engine.emitProgress({
|
|
31078
|
-
record:
|
|
31175
|
+
record: turnRecord,
|
|
31079
31176
|
stepNumber,
|
|
31080
31177
|
pendingTokens: ctx.status.pendingTokens,
|
|
31081
31178
|
threshold: ctx.status.threshold,
|
|
31082
31179
|
effectiveObservationTokensThreshold: ctx.status.effectiveObservationTokensThreshold,
|
|
31083
|
-
currentObservationTokens:
|
|
31180
|
+
currentObservationTokens: turnRecord.observationTokenCount ?? 0,
|
|
31084
31181
|
writer,
|
|
31085
31182
|
threadId,
|
|
31086
31183
|
resourceId
|
|
31087
31184
|
});
|
|
31088
|
-
const
|
|
31089
|
-
|
|
31090
|
-
|
|
31091
|
-
|
|
31092
|
-
|
|
31093
|
-
await this.engine.getStorage().setPendingMessageTokens(freshRecord.id, finalTotalPending).catch(() => {});
|
|
31185
|
+
const finalTotalPending = ctx.status.pendingTokens;
|
|
31186
|
+
try {
|
|
31187
|
+
await this.engine.getStorage().setPendingMessageTokens(turnRecord.id, finalTotalPending);
|
|
31188
|
+
this.turn.patchRecord({ pendingMessageTokens: finalTotalPending });
|
|
31189
|
+
} catch {}
|
|
31094
31190
|
if (reproCaptureEnabled) writeProcessInputStepReproCapture({
|
|
31095
31191
|
threadId,
|
|
31096
31192
|
resourceId,
|
|
31097
31193
|
stepNumber,
|
|
31098
31194
|
args,
|
|
31099
31195
|
preRecord: preRecordSnapshot,
|
|
31100
|
-
postRecord: safeCaptureJson(
|
|
31196
|
+
postRecord: safeCaptureJson(turnRecord),
|
|
31101
31197
|
preMessages: preMessagesSnapshot,
|
|
31102
31198
|
preBufferedChunks: [],
|
|
31103
31199
|
preContextTokenCount: 0,
|
|
@@ -43590,4 +43686,4 @@ const agentBuilderWorkflows = {
|
|
|
43590
43686
|
//#endregion
|
|
43591
43687
|
exports.agentBuilderWorkflows = agentBuilderWorkflows;
|
|
43592
43688
|
|
|
43593
|
-
//# sourceMappingURL=dist-
|
|
43689
|
+
//# sourceMappingURL=dist-BJ9n8vHL.cjs.map
|