@mastra/memory 1.10.1-alpha.0 → 1.10.1-alpha.1
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 +92 -0
- package/dist/{chunk-K2NLYL2O.js → chunk-2QSOQQPM.js} +6817 -6615
- package/dist/chunk-2QSOQQPM.js.map +1 -0
- package/dist/chunk-D4J4XPGM.cjs +111 -0
- package/dist/chunk-D4J4XPGM.cjs.map +1 -0
- package/dist/chunk-LSJJAJAF.js +105 -0
- package/dist/chunk-LSJJAJAF.js.map +1 -0
- package/dist/{chunk-HSOEY7M2.cjs → chunk-NS47X3OB.cjs} +6807 -6608
- package/dist/chunk-NS47X3OB.cjs.map +1 -0
- package/dist/constants-BDOITAO3.js +3 -0
- package/dist/constants-BDOITAO3.js.map +1 -0
- package/dist/constants-HXOCZPB7.cjs +28 -0
- package/dist/constants-HXOCZPB7.cjs.map +1 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +67 -61
- package/dist/docs/references/docs-memory-observational-memory.md +7 -5
- package/dist/docs/references/reference-memory-observational-memory.md +2 -2
- package/dist/index.cjs +207 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +52 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +200 -71
- package/dist/index.js.map +1 -1
- package/dist/{observational-memory-DJMF2UNC.cjs → observational-memory-I5UTOG63.cjs} +46 -41
- package/dist/{observational-memory-DJMF2UNC.cjs.map → observational-memory-I5UTOG63.cjs.map} +1 -1
- package/dist/observational-memory-WMCWT577.js +4 -0
- package/dist/{observational-memory-NMQ7URIP.js.map → observational-memory-WMCWT577.js.map} +1 -1
- package/dist/processors/index.cjs +44 -39
- package/dist/processors/index.js +2 -1
- package/dist/processors/observational-memory/buffering-coordinator.d.ts +61 -0
- package/dist/processors/observational-memory/buffering-coordinator.d.ts.map +1 -0
- package/dist/processors/observational-memory/constants.d.ts +62 -0
- package/dist/processors/observational-memory/constants.d.ts.map +1 -0
- package/dist/processors/observational-memory/debug.d.ts +3 -0
- package/dist/processors/observational-memory/debug.d.ts.map +1 -0
- package/dist/processors/observational-memory/index.d.ts +5 -2
- package/dist/processors/observational-memory/index.d.ts.map +1 -1
- package/dist/processors/observational-memory/message-utils.d.ts +69 -0
- package/dist/processors/observational-memory/message-utils.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts +33 -0
- package/dist/processors/observational-memory/observation-strategies/async-buffer.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/base.d.ts +102 -0
- package/dist/processors/observational-memory/observation-strategies/base.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/index.d.ts +7 -0
- package/dist/processors/observational-memory/observation-strategies/index.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts +39 -0
- package/dist/processors/observational-memory/observation-strategies/resource-scoped.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts +35 -0
- package/dist/processors/observational-memory/observation-strategies/sync.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts +55 -0
- package/dist/processors/observational-memory/observation-strategies/types.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/index.d.ts +4 -0
- package/dist/processors/observational-memory/observation-turn/index.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts +34 -0
- package/dist/processors/observational-memory/observation-turn/step.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts +84 -0
- package/dist/processors/observational-memory/observation-turn/turn.d.ts.map +1 -0
- package/dist/processors/observational-memory/observation-turn/types.d.ts +38 -0
- package/dist/processors/observational-memory/observation-turn/types.d.ts.map +1 -0
- package/dist/processors/observational-memory/observational-memory.d.ts +388 -553
- package/dist/processors/observational-memory/observational-memory.d.ts.map +1 -1
- package/dist/processors/observational-memory/observer-runner.d.ts +65 -0
- package/dist/processors/observational-memory/observer-runner.d.ts.map +1 -0
- package/dist/processors/observational-memory/processor.d.ts +70 -0
- package/dist/processors/observational-memory/processor.d.ts.map +1 -0
- package/dist/processors/observational-memory/reflector-runner.d.ts +95 -0
- package/dist/processors/observational-memory/reflector-runner.d.ts.map +1 -0
- package/dist/processors/observational-memory/types.d.ts +157 -0
- package/dist/processors/observational-memory/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-HSOEY7M2.cjs.map +0 -1
- package/dist/chunk-K2NLYL2O.js.map +0 -1
- package/dist/observational-memory-NMQ7URIP.js +0 -3
|
@@ -1,217 +1,25 @@
|
|
|
1
1
|
import type { MastraDBMessage, MessageList } from '@mastra/core/agent';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ProcessorStreamWriter } from '@mastra/core/processors';
|
|
3
|
+
import { MessageHistory } from '@mastra/core/processors';
|
|
3
4
|
import type { RequestContext } from '@mastra/core/request-context';
|
|
4
5
|
import type { MemoryStorage, ObservationalMemoryRecord } from '@mastra/core/storage';
|
|
5
|
-
import {
|
|
6
|
-
import type { ObservationConfig, ReflectionConfig, ThresholdRange, ModelSettings, ProviderOptions, ObservationalMemoryModel } from './types.js';
|
|
7
|
-
/**
|
|
8
|
-
* Debug event emitted when observation-related events occur.
|
|
9
|
-
* Useful for understanding what the Observer is doing.
|
|
10
|
-
*/
|
|
11
|
-
export interface ObservationDebugEvent {
|
|
12
|
-
type: 'observation_triggered' | 'observation_complete' | 'reflection_triggered' | 'reflection_complete' | 'tokens_accumulated' | 'step_progress';
|
|
13
|
-
timestamp: Date;
|
|
14
|
-
threadId: string;
|
|
15
|
-
resourceId: string;
|
|
16
|
-
/** Messages that were sent to the Observer */
|
|
17
|
-
messages?: Array<{
|
|
18
|
-
role: string;
|
|
19
|
-
content: string;
|
|
20
|
-
}>;
|
|
21
|
-
/** Token counts */
|
|
22
|
-
pendingTokens?: number;
|
|
23
|
-
sessionTokens?: number;
|
|
24
|
-
totalPendingTokens?: number;
|
|
25
|
-
threshold?: number;
|
|
26
|
-
/** Input token count (for reflection events) */
|
|
27
|
-
inputTokens?: number;
|
|
28
|
-
/** Number of active observations (for reflection events) */
|
|
29
|
-
activeObservationsLength?: number;
|
|
30
|
-
/** Output token count after reflection */
|
|
31
|
-
outputTokens?: number;
|
|
32
|
-
/** The observations that were generated */
|
|
33
|
-
observations?: string;
|
|
34
|
-
/** Previous observations (before this event) */
|
|
35
|
-
previousObservations?: string;
|
|
36
|
-
/** Observer's raw output */
|
|
37
|
-
rawObserverOutput?: string;
|
|
38
|
-
/** LLM usage from Observer/Reflector calls */
|
|
39
|
-
usage?: {
|
|
40
|
-
inputTokens?: number;
|
|
41
|
-
outputTokens?: number;
|
|
42
|
-
totalTokens?: number;
|
|
43
|
-
};
|
|
44
|
-
/** Step progress fields (for step_progress events) */
|
|
45
|
-
stepNumber?: number;
|
|
46
|
-
finishReason?: string;
|
|
47
|
-
thresholdPercent?: number;
|
|
48
|
-
willSave?: boolean;
|
|
49
|
-
willObserve?: boolean;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Configuration for ObservationalMemory
|
|
53
|
-
*/
|
|
54
|
-
export interface ObservationalMemoryConfig {
|
|
55
|
-
/**
|
|
56
|
-
* Storage adapter for persisting observations.
|
|
57
|
-
* Must be a MemoryStorage instance (from MastraStorage.stores.memory).
|
|
58
|
-
*/
|
|
59
|
-
storage: MemoryStorage;
|
|
60
|
-
/**
|
|
61
|
-
* **Experimental.** Enable retrieval-mode observation group metadata.
|
|
62
|
-
* When true, observation groups are treated as durable pointers to raw
|
|
63
|
-
* message history and a `recall` tool is registered so the actor can
|
|
64
|
-
* inspect raw messages behind a stored observation summary.
|
|
65
|
-
*
|
|
66
|
-
* @experimental
|
|
67
|
-
* @default false
|
|
68
|
-
*/
|
|
69
|
-
retrieval?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Model for both Observer and Reflector agents.
|
|
72
|
-
* Sets the model for both agents at once. Cannot be used together with
|
|
73
|
-
* `observation.model` or `reflection.model` — an error will be thrown.
|
|
74
|
-
*
|
|
75
|
-
* @default 'google/gemini-2.5-flash'
|
|
76
|
-
*/
|
|
77
|
-
model?: ObservationalMemoryModel;
|
|
78
|
-
/**
|
|
79
|
-
* Observation step configuration.
|
|
80
|
-
*/
|
|
81
|
-
observation?: ObservationConfig;
|
|
82
|
-
/**
|
|
83
|
-
* Reflection step configuration.
|
|
84
|
-
*/
|
|
85
|
-
reflection?: ReflectionConfig;
|
|
86
|
-
/**
|
|
87
|
-
* Memory scope for observations.
|
|
88
|
-
* - 'resource': Observations span all threads for a resource (cross-thread memory)
|
|
89
|
-
* - 'thread': Observations are per-thread (default)
|
|
90
|
-
*/
|
|
91
|
-
scope?: 'resource' | 'thread';
|
|
92
|
-
/**
|
|
93
|
-
* Debug callback for observation events.
|
|
94
|
-
* Called whenever observation-related events occur.
|
|
95
|
-
* Useful for debugging and understanding the observation flow.
|
|
96
|
-
*/
|
|
97
|
-
onDebugEvent?: (event: ObservationDebugEvent) => void;
|
|
98
|
-
obscureThreadIds?: boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Share the token budget between messages and observations.
|
|
101
|
-
* When true, the total budget = observation.messageTokens + reflection.observationTokens.
|
|
102
|
-
* - Messages can use more space when observations are small
|
|
103
|
-
* - Observations can use more space when messages are small
|
|
104
|
-
*
|
|
105
|
-
* This helps maximize context usage by allowing flexible allocation.
|
|
106
|
-
*
|
|
107
|
-
* @default false
|
|
108
|
-
*/
|
|
109
|
-
shareTokenBudget?: boolean;
|
|
110
|
-
}
|
|
6
|
+
import { BufferingCoordinator } from './buffering-coordinator.js';
|
|
111
7
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* even when user provides a simple number (converted based on shareTokenBudget).
|
|
8
|
+
* Returns the parts from the latest step of a message (after the last step-start marker).
|
|
9
|
+
* If no step-start marker exists, returns all parts.
|
|
115
10
|
*/
|
|
116
|
-
|
|
117
|
-
model: ObservationalMemoryModel;
|
|
118
|
-
/** Internal threshold - always stored as ThresholdRange for dynamic calculation */
|
|
119
|
-
messageTokens: number | ThresholdRange;
|
|
120
|
-
/** Whether shared token budget is enabled */
|
|
121
|
-
shareTokenBudget: boolean;
|
|
122
|
-
/** Model settings - merged with user config and defaults */
|
|
123
|
-
modelSettings: ModelSettings;
|
|
124
|
-
providerOptions: ProviderOptions;
|
|
125
|
-
maxTokensPerBatch: number;
|
|
126
|
-
/** Token interval for async background observation buffering (resolved from config) */
|
|
127
|
-
bufferTokens?: number;
|
|
128
|
-
/** Ratio of buffered observations to activate (0-1 float) */
|
|
129
|
-
bufferActivation?: number;
|
|
130
|
-
/** Token threshold above which synchronous observation is forced */
|
|
131
|
-
blockAfter?: number;
|
|
132
|
-
/** Optional token budget for observer context optimization (0 = full truncation, false = disabled) */
|
|
133
|
-
previousObserverTokens?: number | false;
|
|
134
|
-
/** Custom instructions to append to the Observer's system prompt */
|
|
135
|
-
instruction?: string;
|
|
136
|
-
/** Whether the Observer should suggest thread titles */
|
|
137
|
-
threadTitle?: boolean;
|
|
138
|
-
}
|
|
139
|
-
interface ResolvedReflectionConfig {
|
|
140
|
-
model: ObservationalMemoryModel;
|
|
141
|
-
/** Internal threshold - always stored as ThresholdRange for dynamic calculation */
|
|
142
|
-
observationTokens: number | ThresholdRange;
|
|
143
|
-
/** Whether shared token budget is enabled */
|
|
144
|
-
shareTokenBudget: boolean;
|
|
145
|
-
/** Model settings - merged with user config and defaults */
|
|
146
|
-
modelSettings: ModelSettings;
|
|
147
|
-
providerOptions: ProviderOptions;
|
|
148
|
-
/** Ratio (0-1) controlling when async reflection buffering starts */
|
|
149
|
-
bufferActivation?: number;
|
|
150
|
-
/** Token threshold above which synchronous reflection is forced */
|
|
151
|
-
blockAfter?: number;
|
|
152
|
-
/** Custom instructions to append to the Reflector's system prompt */
|
|
153
|
-
instruction?: string;
|
|
154
|
-
}
|
|
11
|
+
export declare function getLatestStepParts(parts: MastraDBMessage['content']['parts']): MastraDBMessage['content']['parts'];
|
|
155
12
|
/**
|
|
156
|
-
*
|
|
13
|
+
* Build a messageRange string from the first and last messages that have visible
|
|
14
|
+
* content. Falls back to the full array boundaries when every message is data-only.
|
|
157
15
|
*/
|
|
158
|
-
export declare
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
readonly maxOutputTokens: 100000;
|
|
166
|
-
};
|
|
167
|
-
readonly providerOptions: {
|
|
168
|
-
readonly google: {
|
|
169
|
-
readonly thinkingConfig: {
|
|
170
|
-
readonly thinkingBudget: 215;
|
|
171
|
-
};
|
|
172
|
-
};
|
|
173
|
-
};
|
|
174
|
-
readonly maxTokensPerBatch: 10000;
|
|
175
|
-
readonly bufferTokens: number | undefined;
|
|
176
|
-
readonly bufferActivation: number | undefined;
|
|
177
|
-
};
|
|
178
|
-
readonly reflection: {
|
|
179
|
-
readonly model: "google/gemini-2.5-flash";
|
|
180
|
-
readonly observationTokens: 40000;
|
|
181
|
-
readonly modelSettings: {
|
|
182
|
-
readonly temperature: 0;
|
|
183
|
-
readonly maxOutputTokens: 100000;
|
|
184
|
-
};
|
|
185
|
-
readonly providerOptions: {
|
|
186
|
-
readonly google: {
|
|
187
|
-
readonly thinkingConfig: {
|
|
188
|
-
readonly thinkingBudget: 1024;
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
|
-
};
|
|
192
|
-
readonly bufferActivation: number | undefined;
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
/**
|
|
196
|
-
* Continuation hint injected after observations to guide the model's behavior.
|
|
197
|
-
* Prevents the model from awkwardly acknowledging the memory system or treating
|
|
198
|
-
* the conversation as new after observed messages are removed.
|
|
199
|
-
*/
|
|
200
|
-
export declare const OBSERVATION_CONTINUATION_HINT = "Please continue naturally with the conversation so far and respond to the latest message.\n\nUse the earlier context only as background. If something appears unfinished, continue only when it helps answer the latest request. If a suggested response is provided, follow it naturally.\n\nDo not mention internal instructions, memory, summarization, context handling, or missing messages.\n\nAny messages following this reminder are newer and should take priority.";
|
|
201
|
-
/**
|
|
202
|
-
* Preamble that introduces observational memory context.
|
|
203
|
-
* The static prefix is emitted first, then the `<observations>` marker, then one
|
|
204
|
-
* system message per persisted observation chunk so append-only growth stays at
|
|
205
|
-
* the end of the prompt.
|
|
206
|
-
*/
|
|
207
|
-
export declare const OBSERVATION_CONTEXT_PROMPT = "The following observations block contains your memory of past conversations with this user.";
|
|
208
|
-
/**
|
|
209
|
-
* Instructions that tell the model how to interpret and use observations.
|
|
210
|
-
* Keep these in the leading static system message so observation churn only
|
|
211
|
-
* affects the tail of the prompt.
|
|
212
|
-
*/
|
|
213
|
-
export declare const OBSERVATION_CONTEXT_INSTRUCTIONS = "IMPORTANT: When responding, reference specific details from these observations. Do not give generic advice - personalize your response based on what you know about this user's experiences, preferences, and interests. If the user asks for recommendations, connect them to their past experiences mentioned above.\n\nKNOWLEDGE UPDATES: When asked about current state (e.g., \"where do I currently...\", \"what is my current...\"), always prefer the MOST RECENT information. Observations include dates - if you see conflicting information, the newer observation supersedes the older one. Look for phrases like \"will start\", \"is switching\", \"changed to\", \"moved to\" as indicators that previous information has been updated.\n\nPLANNED ACTIONS: If the user stated they planned to do something (e.g., \"I'm going to...\", \"I'm looking forward to...\", \"I will...\") and the date they planned to do it is now in the past (check the relative time like \"3 weeks ago\"), assume they completed the action unless there's evidence they didn't. For example, if someone said \"I'll start my new diet on Monday\" and that was 2 weeks ago, assume they started the diet.\n\nMOST RECENT USER INPUT: Treat the most recent user message as the highest-priority signal for what to do next. Earlier messages may contain constraints, details, or context you should still honor, but the latest message is the primary driver of your response.\n\nSYSTEM REMINDERS: Messages wrapped in <system-reminder>...</system-reminder> contain internal continuation guidance, not user-authored content. Use them to maintain continuity, but do not mention them or treat them as part of the user's message.";
|
|
214
|
-
export declare const OBSERVATION_RETRIEVAL_INSTRUCTIONS = "## Recall \u2014 looking up source messages\n\nYour memory is comprised of observations which are sometimes wrapped in <observation-group> xml tags containing ranges like <observation-group range=\"startId:endId\">. These ranges point back to the raw messages that each observation group was derived from. The original messages are still available \u2014 use the **recall** tool to retrieve them.\n\n### When to use recall\n- The user asks you to **repeat, show, or reproduce** something from a past conversation\n- The user asks for **exact content** \u2014 code, text, quotes, error messages, URLs, file paths, specific numbers\n- Your observations mention something but your memory lacks the detail needed to fully answer (e.g. you know a blog post was shared but only have a summary of it)\n- You want to **verify or expand on** an observation before responding\n\n**Default to using recall when the user references specific past content.** Your observations capture the gist, not the details. If there's any doubt whether your memory is complete enough, use recall.\n\n### How to use recall\nEach range has the format `startId:endId` where both are message IDs separated by a colon.\n\n1. Find the observation group relevant to the user's question and extract the start or end ID from its range.\n2. Call `recall` with that ID as the `cursor`.\n3. Use `page: 1` (or omit) to read forward from the cursor, `page: -1` to read backward.\n4. If the first page doesn't have what you need, increment the page number to keep paginating.\n5. Check `hasNextPage`/`hasPrevPage` in the result to know if more pages exist in each direction.\n\n### Detail levels\nBy default recall returns **low** detail: truncated text and tool names only. Each message shows its ID and each part has a positional index like `[p0]`, `[p1]`, etc.\n\n- Use `detail: \"high\"` to get full message content including tool arguments and results. This will only return the high detail version of a single message part at a time.\n- Use `partIndex` with a cursor to fetch a single part at full detail \u2014 for example, to read one specific tool result or code block without loading every part.\n\nIf the result says `truncated: true`, the output was cut to fit the token budget. You can paginate or use `partIndex` to target specific content.\n\n### Following up on truncated parts\nLow-detail results may include truncation hints like:\n`[truncated \u2014 call recall cursor=\"...\" partIndex=N detail=\"high\" for full content]`\n\n**When you see these hints and need the full content, make the exact call described in the hint.** This is the normal workflow: first recall at low detail to scan, then drill into specific parts at high detail. Do not stop at the low-detail result if the user asked for exact content.\n\n### When recall is NOT needed\n- The user is asking for a high-level summary and your observations already cover it\n- The question is about general preferences or facts that don't require source text\n- There is no relevant range in your observations for the topic\n\nObservation groups with range IDs and your recall tool allows you to think back and remember details you're fuzzy on.";
|
|
16
|
+
export declare function buildMessageRange(messages: MastraDBMessage[]): string;
|
|
17
|
+
import { ObservationTurn } from './observation-turn/index.js';
|
|
18
|
+
import { ObserverRunner } from './observer-runner.js';
|
|
19
|
+
import type { CompressionLevel } from './reflector-agent.js';
|
|
20
|
+
import { ReflectorRunner } from './reflector-runner.js';
|
|
21
|
+
import { TokenCounter } from './token-counter.js';
|
|
22
|
+
import type { ObservationDebugEvent, ObservationalMemoryConfig, ObserveHooks, ResolvedObservationConfig, ResolvedReflectionConfig, ThresholdRange } from './types.js';
|
|
215
23
|
/**
|
|
216
24
|
* ObservationalMemory - A three-agent memory system for long conversations.
|
|
217
25
|
*
|
|
@@ -251,37 +59,30 @@ export declare const OBSERVATION_RETRIEVAL_INSTRUCTIONS = "## Recall \u2014 look
|
|
|
251
59
|
* });
|
|
252
60
|
* ```
|
|
253
61
|
*/
|
|
254
|
-
export
|
|
255
|
-
onObservationStart?: () => void;
|
|
256
|
-
onObservationEnd?: () => void;
|
|
257
|
-
onReflectionStart?: () => void;
|
|
258
|
-
onReflectionEnd?: () => void;
|
|
259
|
-
}
|
|
260
|
-
export declare class ObservationalMemory implements Processor<'observational-memory'> {
|
|
261
|
-
readonly id: "observational-memory";
|
|
262
|
-
readonly name = "Observational Memory";
|
|
62
|
+
export declare class ObservationalMemory {
|
|
263
63
|
private storage;
|
|
264
64
|
private tokenCounter;
|
|
265
|
-
|
|
266
|
-
|
|
65
|
+
readonly scope: 'resource' | 'thread';
|
|
66
|
+
/** Whether retrieval-mode observation groups are enabled (thread scope only). */
|
|
67
|
+
readonly retrieval: boolean;
|
|
267
68
|
private observationConfig;
|
|
268
69
|
private reflectionConfig;
|
|
269
70
|
private onDebugEvent?;
|
|
270
|
-
/**
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
71
|
+
/** Observer agent runner — handles LLM calls for extracting observations. */
|
|
72
|
+
readonly observer: ObserverRunner;
|
|
73
|
+
/** Reflector agent runner — handles LLM calls for compressing observations. */
|
|
74
|
+
readonly reflector: ReflectorRunner;
|
|
75
|
+
/** Buffering state coordinator — manages static maps and buffering lifecycle. */
|
|
76
|
+
readonly buffering: BufferingCoordinator;
|
|
276
77
|
private shouldObscureThreadIds;
|
|
277
78
|
private hasher;
|
|
278
|
-
private threadIdCache;
|
|
279
79
|
/**
|
|
280
80
|
* Track message IDs observed during this instance's lifetime.
|
|
281
81
|
* Prevents re-observing messages when per-thread lastObservedAt cursors
|
|
282
82
|
* haven't fully advanced past messages observed in a prior cycle.
|
|
83
|
+
* @internal Used by observation strategies. Do not call directly.
|
|
283
84
|
*/
|
|
284
|
-
|
|
85
|
+
observedMessageIds: Set<string>;
|
|
285
86
|
/** Internal MessageHistory for message persistence */
|
|
286
87
|
private messageHistory;
|
|
287
88
|
/**
|
|
@@ -297,116 +98,11 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
297
98
|
* accept eventual consistency (acceptable for v1).
|
|
298
99
|
*/
|
|
299
100
|
private locks;
|
|
300
|
-
/**
|
|
301
|
-
* Track in-flight async buffering operations per resource/thread.
|
|
302
|
-
* STATIC: Shared across all ObservationalMemory instances in this process.
|
|
303
|
-
* This is critical because multiple OM instances are created per agent loop step,
|
|
304
|
-
* and we need them to share knowledge of in-flight operations.
|
|
305
|
-
* Key format: "obs:{lockKey}" or "refl:{lockKey}"
|
|
306
|
-
* Value: Promise that resolves when buffering completes
|
|
307
|
-
*/
|
|
308
|
-
private static asyncBufferingOps;
|
|
309
|
-
/**
|
|
310
|
-
* Track the last token boundary at which we started buffering.
|
|
311
|
-
* STATIC: Shared across all instances so boundary tracking persists across OM recreations.
|
|
312
|
-
* Key format: "obs:{lockKey}" or "refl:{lockKey}"
|
|
313
|
-
*/
|
|
314
|
-
private static lastBufferedBoundary;
|
|
315
|
-
/**
|
|
316
|
-
* Track the timestamp cursor for buffered messages.
|
|
317
|
-
* STATIC: Shared across all instances so each buffer only observes messages
|
|
318
|
-
* newer than the previous buffer's boundary.
|
|
319
|
-
* Key format: "obs:{lockKey}"
|
|
320
|
-
*/
|
|
321
|
-
private static lastBufferedAtTime;
|
|
322
|
-
/**
|
|
323
|
-
* Tracks cycleId for in-flight buffered reflections.
|
|
324
|
-
* STATIC: Shared across instances so we can match cycleId at activation time.
|
|
325
|
-
* Key format: "refl:{lockKey}"
|
|
326
|
-
*/
|
|
327
|
-
private static reflectionBufferCycleIds;
|
|
328
|
-
/**
|
|
329
|
-
* Track message IDs that have been sealed during async buffering.
|
|
330
|
-
* STATIC: Shared across all instances so saveMessagesWithSealedIdTracking
|
|
331
|
-
* generates new IDs when re-saving messages that were sealed in a previous step.
|
|
332
|
-
* Key format: threadId
|
|
333
|
-
* Value: Set of sealed message IDs
|
|
334
|
-
*/
|
|
335
|
-
private static sealedMessageIds;
|
|
336
|
-
/**
|
|
337
|
-
* Check if async buffering is enabled for observations.
|
|
338
|
-
*/
|
|
339
|
-
private isAsyncObservationEnabled;
|
|
340
|
-
/**
|
|
341
|
-
* Check if async buffering is enabled for reflections.
|
|
342
|
-
* Reflection buffering is enabled when bufferActivation is set (triggers at threshold * bufferActivation).
|
|
343
|
-
*/
|
|
344
|
-
private isAsyncReflectionEnabled;
|
|
345
|
-
/**
|
|
346
|
-
* Get the buffer interval boundary key for observations.
|
|
347
|
-
*/
|
|
348
|
-
private getObservationBufferKey;
|
|
349
|
-
/**
|
|
350
|
-
* Get the buffer interval boundary key for reflections.
|
|
351
|
-
*/
|
|
352
|
-
private getReflectionBufferKey;
|
|
353
|
-
/**
|
|
354
|
-
* Clean up static maps for a thread/resource to prevent memory leaks.
|
|
355
|
-
* Called after activation (to remove activated message IDs from sealedMessageIds)
|
|
356
|
-
* and from clear() (to fully remove all static state for a thread).
|
|
357
|
-
*/
|
|
358
|
-
private cleanupStaticMaps;
|
|
359
|
-
/**
|
|
360
|
-
* Await any in-flight async buffering operations for a given thread/resource.
|
|
361
|
-
* Returns once all buffering promises have settled (or after timeout).
|
|
362
|
-
*/
|
|
363
|
-
static awaitBuffering(threadId: string | null | undefined, resourceId: string | null | undefined, scope: 'thread' | 'resource', timeoutMs?: number): Promise<void>;
|
|
364
|
-
/**
|
|
365
|
-
* Safely get bufferedObservationChunks as an array.
|
|
366
|
-
* Handles cases where it might be a JSON string or undefined.
|
|
367
|
-
*/
|
|
368
|
-
private getBufferedChunks;
|
|
369
|
-
/**
|
|
370
|
-
* Refresh per-chunk messageTokens from the current in-memory message list.
|
|
371
|
-
*
|
|
372
|
-
* Buffered chunks store a messageTokens snapshot from when they were created,
|
|
373
|
-
* but messages can be edited/sealed between buffering and activation, changing
|
|
374
|
-
* their token weight. Using stale weights causes projected-removal math to
|
|
375
|
-
* over- or under-estimate, leading to skipped activations or over-activation.
|
|
376
|
-
*
|
|
377
|
-
* Token recount only runs when the full chunk is present in the message list.
|
|
378
|
-
* Partial recount is skipped because it would undercount and could cause
|
|
379
|
-
* over-activation of buffered chunks.
|
|
380
|
-
*/
|
|
381
|
-
private refreshBufferedChunkMessageTokens;
|
|
382
|
-
/**
|
|
383
|
-
* Check if we've crossed a new bufferTokens interval boundary.
|
|
384
|
-
* Returns true if async buffering should be triggered.
|
|
385
|
-
*
|
|
386
|
-
* When pending tokens are within ~1 bufferTokens of the observation threshold,
|
|
387
|
-
* the buffer interval is halved to produce finer-grained chunks right before
|
|
388
|
-
* activation. This improves chunk boundary selection, reducing overshoot.
|
|
389
|
-
*/
|
|
390
|
-
private shouldTriggerAsyncObservation;
|
|
391
|
-
/**
|
|
392
|
-
* Check if async reflection buffering should be triggered.
|
|
393
|
-
* Triggers once when observation tokens reach `threshold * bufferActivation`.
|
|
394
|
-
* Only allows one buffered reflection at a time.
|
|
395
|
-
*/
|
|
396
|
-
private shouldTriggerAsyncReflection;
|
|
397
|
-
/**
|
|
398
|
-
* Check if an async buffering operation is already in progress.
|
|
399
|
-
*/
|
|
400
|
-
private isAsyncBufferingInProgress;
|
|
401
101
|
/**
|
|
402
102
|
* Acquire a lock for the given key, execute the callback, then release.
|
|
403
103
|
* If a lock is already held, waits for it to be released before acquiring.
|
|
404
104
|
*/
|
|
405
105
|
private withLock;
|
|
406
|
-
/**
|
|
407
|
-
* Get the lock key for the current scope
|
|
408
|
-
*/
|
|
409
|
-
private getLockKey;
|
|
410
106
|
constructor(config: ObservationalMemoryConfig);
|
|
411
107
|
/**
|
|
412
108
|
* Get the current configuration for this OM instance.
|
|
@@ -436,40 +132,28 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
436
132
|
* Get the default compression start level based on model behavior.
|
|
437
133
|
* gemini-2.5-flash is a faithful transcriber that needs explicit pressure to compress effectively.
|
|
438
134
|
*/
|
|
439
|
-
|
|
440
|
-
private getRuntimeModelContext;
|
|
441
|
-
private runWithTokenCounterModelContext;
|
|
442
|
-
private formatRoutingModel;
|
|
443
|
-
private withOmTracingSpan;
|
|
135
|
+
getCompressionStartLevel(requestContext?: RequestContext): Promise<CompressionLevel>;
|
|
444
136
|
/**
|
|
445
137
|
* Get the full config including resolved model names.
|
|
446
138
|
* This is async because it needs to resolve the model configs.
|
|
447
139
|
*/
|
|
448
140
|
getResolvedConfig(requestContext?: RequestContext): Promise<{
|
|
449
141
|
scope: 'resource' | 'thread';
|
|
450
|
-
shareTokenBudget: boolean;
|
|
451
142
|
observation: {
|
|
452
143
|
messageTokens: number | ThresholdRange;
|
|
453
144
|
model: string;
|
|
454
145
|
previousObserverTokens: number | false | undefined;
|
|
455
|
-
routing?: Array<{
|
|
456
|
-
upTo: number;
|
|
457
|
-
model: string;
|
|
458
|
-
}>;
|
|
459
146
|
};
|
|
460
147
|
reflection: {
|
|
461
148
|
observationTokens: number | ThresholdRange;
|
|
462
149
|
model: string;
|
|
463
|
-
routing?: Array<{
|
|
464
|
-
upTo: number;
|
|
465
|
-
model: string;
|
|
466
|
-
}>;
|
|
467
150
|
};
|
|
468
151
|
}>;
|
|
469
152
|
/**
|
|
470
|
-
* Emit a debug event if the callback is configured
|
|
153
|
+
* Emit a debug event if the callback is configured.
|
|
154
|
+
* @internal Used by observation strategies. Do not call directly.
|
|
471
155
|
*/
|
|
472
|
-
|
|
156
|
+
emitDebugEvent(event: ObservationDebugEvent): void;
|
|
473
157
|
/**
|
|
474
158
|
* Validate buffer configuration on first use.
|
|
475
159
|
* Ensures bufferTokens is less than the threshold and bufferActivation is valid.
|
|
@@ -479,14 +163,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
479
163
|
* Check whether the unobserved message tokens meet the observation threshold.
|
|
480
164
|
*/
|
|
481
165
|
private meetsObservationThreshold;
|
|
482
|
-
/**
|
|
483
|
-
* Get or create the Observer agent
|
|
484
|
-
*/
|
|
485
|
-
private getObserverAgent;
|
|
486
|
-
/**
|
|
487
|
-
* Get or create the Reflector agent
|
|
488
|
-
*/
|
|
489
|
-
private getReflectorAgent;
|
|
490
166
|
/**
|
|
491
167
|
* Get thread/resource IDs for storage lookup
|
|
492
168
|
*/
|
|
@@ -496,10 +172,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
496
172
|
* Returns the existing record if one exists, otherwise initializes a new one.
|
|
497
173
|
*/
|
|
498
174
|
getOrCreateRecord(threadId: string, resourceId?: string): Promise<ObservationalMemoryRecord>;
|
|
499
|
-
/**
|
|
500
|
-
* Check if we need to trigger reflection.
|
|
501
|
-
*/
|
|
502
|
-
private shouldReflect;
|
|
503
175
|
/**
|
|
504
176
|
* Get current config snapshot for observation markers.
|
|
505
177
|
*/
|
|
@@ -508,14 +180,22 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
508
180
|
* Persist a data-om-* marker part on the last assistant message in messageList
|
|
509
181
|
* AND save the updated message to the DB so it survives page reload.
|
|
510
182
|
* (data-* parts are filtered out before sending to the LLM, so they don't affect model calls.)
|
|
183
|
+
* @internal Used by ReflectorRunner. Do not call directly.
|
|
511
184
|
*/
|
|
512
|
-
|
|
185
|
+
persistMarkerToMessage(marker: {
|
|
186
|
+
type: string;
|
|
187
|
+
data: unknown;
|
|
188
|
+
}, messageList: MessageList | undefined, threadId: string, resourceId?: string): Promise<void>;
|
|
513
189
|
/**
|
|
514
190
|
* Persist a marker to the last assistant message in storage.
|
|
515
191
|
* Unlike persistMarkerToMessage, this fetches messages directly from the DB
|
|
516
192
|
* so it works even when no MessageList is available (e.g. async buffering ops).
|
|
193
|
+
* @internal Used by observation strategies. Do not call directly.
|
|
517
194
|
*/
|
|
518
|
-
|
|
195
|
+
persistMarkerToStorage(marker: {
|
|
196
|
+
type: string;
|
|
197
|
+
data: unknown;
|
|
198
|
+
}, threadId: string, resourceId?: string): Promise<void>;
|
|
519
199
|
/**
|
|
520
200
|
* Find the last completed observation boundary in a message's parts.
|
|
521
201
|
* A completed observation is a start marker followed by an end marker.
|
|
@@ -523,7 +203,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
523
203
|
* Returns the index of the END marker (which is the observation boundary),
|
|
524
204
|
* or -1 if no completed observation is found.
|
|
525
205
|
*/
|
|
526
|
-
private findLastCompletedObservationBoundary;
|
|
527
206
|
/**
|
|
528
207
|
* Check if a message has an in-progress observation (start without end).
|
|
529
208
|
*/
|
|
@@ -544,7 +223,8 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
544
223
|
*
|
|
545
224
|
* @param messages - Messages to seal (mutated in place)
|
|
546
225
|
*/
|
|
547
|
-
|
|
226
|
+
/** @internal Used by ObservationStep. */
|
|
227
|
+
sealMessagesForBuffering(messages: MastraDBMessage[]): void;
|
|
548
228
|
/**
|
|
549
229
|
* Insert an observation marker into a message.
|
|
550
230
|
* The marker is appended directly to the message's parts array (mutating in place).
|
|
@@ -559,17 +239,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
559
239
|
* For end/failed markers, this should be called AFTER writer.custom() has added the part,
|
|
560
240
|
* so we just find the part and add sealing metadata.
|
|
561
241
|
*/
|
|
562
|
-
/**
|
|
563
|
-
* Get unobserved parts from a message.
|
|
564
|
-
* If the message has a completed observation (start + end), only return parts after the end.
|
|
565
|
-
* If observation is in progress (start without end), include parts before the start.
|
|
566
|
-
* Otherwise, return all parts.
|
|
567
|
-
*/
|
|
568
|
-
private getUnobservedParts;
|
|
569
|
-
/**
|
|
570
|
-
* Check if a message has any unobserved parts.
|
|
571
|
-
*/
|
|
572
|
-
private hasUnobservedParts;
|
|
573
242
|
/**
|
|
574
243
|
* Create a virtual message containing only the unobserved parts.
|
|
575
244
|
* This is used for token counting and observation.
|
|
@@ -585,21 +254,20 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
585
254
|
* This handles the case where a single message accumulates many parts
|
|
586
255
|
* (like tool calls) during an agentic loop - we only observe the new parts.
|
|
587
256
|
*/
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
* so we must check the signal before and after the call.
|
|
593
|
-
* Retries are handled by Mastra's built-in p-retry at the model execution layer.
|
|
594
|
-
*/
|
|
595
|
-
private withAbortCheck;
|
|
257
|
+
/** @internal Used by ObservationStep. */
|
|
258
|
+
getUnobservedMessages(allMessages: MastraDBMessage[], record: ObservationalMemoryRecord, opts?: {
|
|
259
|
+
excludeBuffered?: boolean;
|
|
260
|
+
}): MastraDBMessage[];
|
|
596
261
|
/**
|
|
597
262
|
* Prepare optimized observer context by applying truncation and buffered-reflection inclusion.
|
|
598
263
|
*
|
|
599
264
|
* Returns the (possibly optimized) observations string to pass as "Previous Observations"
|
|
600
265
|
* to the observer prompt. When no optimization options are set, returns the input unchanged.
|
|
601
266
|
*/
|
|
602
|
-
|
|
267
|
+
prepareObserverContext(existingObservations: string | undefined, record?: ObservationalMemoryRecord | null): {
|
|
268
|
+
context: string | undefined;
|
|
269
|
+
wasTruncated: boolean;
|
|
270
|
+
};
|
|
603
271
|
/**
|
|
604
272
|
* Truncate observations to fit within a token budget.
|
|
605
273
|
*
|
|
@@ -610,22 +278,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
610
278
|
* 4. Enforce that at least 50% of kept observations remain raw tail observations.
|
|
611
279
|
*/
|
|
612
280
|
private truncateObservationsToTokenBudget;
|
|
613
|
-
/**
|
|
614
|
-
* Call the Observer agent to extract observations.
|
|
615
|
-
*/
|
|
616
|
-
private callObserver;
|
|
617
|
-
/**
|
|
618
|
-
* Call the Observer agent for multiple threads in a single batched request.
|
|
619
|
-
* This is more efficient than calling the Observer for each thread individually.
|
|
620
|
-
* Returns per-thread results with observations, currentTask, and suggestedContinuation,
|
|
621
|
-
* plus the total usage for the batch.
|
|
622
|
-
*/
|
|
623
|
-
private callMultiThreadObserver;
|
|
624
|
-
/**
|
|
625
|
-
* Call the Reflector agent to condense observations.
|
|
626
|
-
* Includes compression validation and retry logic.
|
|
627
|
-
*/
|
|
628
|
-
private callReflector;
|
|
629
281
|
/**
|
|
630
282
|
* Format observations for injection into context.
|
|
631
283
|
* Applies token optimization before presenting to the Actor.
|
|
@@ -633,12 +285,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
633
285
|
* In resource scope mode, filters continuity messages to only show
|
|
634
286
|
* the message for the current thread.
|
|
635
287
|
*/
|
|
636
|
-
/**
|
|
637
|
-
* Format observations for injection into the Actor's context.
|
|
638
|
-
* @param observations - The observations to inject
|
|
639
|
-
* @param suggestedResponse - Thread-specific suggested response (from thread metadata)
|
|
640
|
-
* @param unobservedContextBlocks - Formatted <unobserved-context> blocks from other threads
|
|
641
|
-
*/
|
|
642
288
|
private formatObservationsForContext;
|
|
643
289
|
private splitObservationContextChunks;
|
|
644
290
|
/**
|
|
@@ -650,77 +296,19 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
650
296
|
/**
|
|
651
297
|
* Get threadId and resourceId from either RequestContext or MessageList
|
|
652
298
|
*/
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
* In thread scope, loads all unobserved messages for the thread.
|
|
658
|
-
*/
|
|
659
|
-
private loadHistoricalMessagesIfNeeded;
|
|
660
|
-
/**
|
|
661
|
-
* Calculate all threshold-related values for observation decision making.
|
|
662
|
-
*/
|
|
663
|
-
private calculateObservationThresholds;
|
|
664
|
-
/**
|
|
665
|
-
* Emit debug event and stream progress part for UI feedback.
|
|
666
|
-
*/
|
|
667
|
-
private emitStepProgress;
|
|
668
|
-
/**
|
|
669
|
-
* Handle observation when threshold is reached.
|
|
670
|
-
* Tries async activation first if enabled, then falls back to sync observation.
|
|
671
|
-
* Returns whether observation succeeded.
|
|
672
|
-
*/
|
|
673
|
-
private handleThresholdReached;
|
|
674
|
-
/**
|
|
675
|
-
* Remove observed messages from message list after successful observation.
|
|
676
|
-
* Accepts optional observedMessageIds for activation-based cleanup (when no markers are present).
|
|
677
|
-
*/
|
|
678
|
-
private cleanupAfterObservation;
|
|
679
|
-
/**
|
|
680
|
-
* Handle per-step save when threshold is not reached.
|
|
681
|
-
* Persists messages incrementally to prevent data loss on interruption.
|
|
682
|
-
*/
|
|
683
|
-
private handlePerStepSave;
|
|
684
|
-
/**
|
|
685
|
-
* Inject observations as system message and add continuation reminder.
|
|
686
|
-
*/
|
|
687
|
-
private injectObservationsIntoContext;
|
|
688
|
-
/**
|
|
689
|
-
* Filter out already-observed messages from the in-memory context.
|
|
690
|
-
*
|
|
691
|
-
* Marker-boundary pruning is safest at step 0 (historical resume/rebuild), where
|
|
692
|
-
* list ordering mirrors persisted history.
|
|
693
|
-
* For step > 0, the list may include mid-loop mutations (sealing/splitting/trim),
|
|
694
|
-
* so we prefer record-based fallback pruning over position-based marker pruning.
|
|
695
|
-
*/
|
|
696
|
-
private filterAlreadyObservedMessages;
|
|
697
|
-
/**
|
|
698
|
-
* Process input at each step - check threshold, observe if needed, save, inject observations.
|
|
699
|
-
* This is the ONLY processor method - all OM logic happens here.
|
|
700
|
-
*
|
|
701
|
-
* Flow:
|
|
702
|
-
* 1. Load historical messages (step 0 only)
|
|
703
|
-
* 2. Check if observation threshold is reached
|
|
704
|
-
* 3. If threshold reached: observe, save messages with markers
|
|
705
|
-
* 4. Inject observations into context
|
|
706
|
-
* 5. Filter out already-observed messages
|
|
707
|
-
*/
|
|
708
|
-
processInputStep(args: ProcessInputStepArgs): Promise<MessageList | MastraDBMessage[]>;
|
|
709
|
-
/**
|
|
710
|
-
* Save any unsaved messages at the end of the agent turn.
|
|
711
|
-
*
|
|
712
|
-
* This is the "final save" that catches messages that processInputStep didn't save
|
|
713
|
-
* (e.g., when the observation threshold was never reached, or on single-step execution).
|
|
714
|
-
* Without this, messages would be lost because MessageHistory is disabled when OM is active.
|
|
715
|
-
*/
|
|
716
|
-
processOutputResult(args: ProcessOutputResultArgs): Promise<MessageList | MastraDBMessage[]>;
|
|
299
|
+
getThreadContext(requestContext: RequestContext | undefined, messageList: MessageList): {
|
|
300
|
+
threadId: string;
|
|
301
|
+
resourceId?: string;
|
|
302
|
+
} | null;
|
|
717
303
|
/**
|
|
718
|
-
* Save messages to storage
|
|
304
|
+
* Save messages to storage, skipping messages that were already persisted by
|
|
305
|
+
* async buffering. Uses the message-level sealed flag (metadata.mastra.sealed)
|
|
306
|
+
* to detect already-persisted messages, avoiding redundant DB operations.
|
|
719
307
|
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
308
|
+
* Messages with observation markers are always saved (upserted) even if sealed,
|
|
309
|
+
* because the markers need to be persisted to storage.
|
|
722
310
|
*/
|
|
723
|
-
|
|
311
|
+
persistMessages(messagesToSave: MastraDBMessage[], threadId: string, resourceId: string | undefined): Promise<void>;
|
|
724
312
|
/**
|
|
725
313
|
* Load messages from storage that haven't been observed yet.
|
|
726
314
|
* Uses cursor-based query with lastObservedAt timestamp for efficiency.
|
|
@@ -729,12 +317,6 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
729
317
|
* In thread scope mode, loads messages for just the current thread.
|
|
730
318
|
*/
|
|
731
319
|
private loadUnobservedMessages;
|
|
732
|
-
/**
|
|
733
|
-
* Load unobserved messages from other threads (not the current thread) for a resource.
|
|
734
|
-
* Called fresh each step so it reflects the latest lastObservedAt cursors
|
|
735
|
-
* after observations complete.
|
|
736
|
-
*/
|
|
737
|
-
private loadOtherThreadsContext;
|
|
738
320
|
/**
|
|
739
321
|
* Format unobserved messages from other threads as <unobserved-context> blocks.
|
|
740
322
|
* These are injected into the Actor's context so it has awareness of activity
|
|
@@ -742,32 +324,18 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
742
324
|
*/
|
|
743
325
|
private formatUnobservedContextBlocks;
|
|
744
326
|
private representThreadIDInContext;
|
|
745
|
-
/**
|
|
746
|
-
* Strip any thread tags that the Observer might have added.
|
|
747
|
-
* Thread attribution is handled externally by the system, not by the Observer.
|
|
748
|
-
* This is a defense-in-depth measure.
|
|
749
|
-
*/
|
|
750
|
-
private stripThreadTags;
|
|
751
327
|
/**
|
|
752
328
|
* Get the maximum createdAt timestamp from a list of messages.
|
|
753
329
|
* Used to set lastObservedAt to the most recent message timestamp instead of current time.
|
|
754
330
|
* This ensures historical data (like LongMemEval fixtures) works correctly.
|
|
755
331
|
*/
|
|
756
332
|
private getMaxMessageTimestamp;
|
|
757
|
-
/**
|
|
758
|
-
* Compute a cursor pointing at the latest message by createdAt.
|
|
759
|
-
* Used to derive a stable observation boundary for replay pruning.
|
|
760
|
-
*/
|
|
761
|
-
private getLastObservedMessageCursor;
|
|
762
|
-
/**
|
|
763
|
-
* Check if a message is at or before a cursor (by createdAt then id).
|
|
764
|
-
*/
|
|
765
|
-
private isMessageAtOrBeforeCursor;
|
|
766
333
|
/**
|
|
767
334
|
* Wrap observations in a thread attribution tag.
|
|
768
335
|
* Used in resource scope to track which thread observations came from.
|
|
336
|
+
* @internal Used by observation strategies. Do not call directly.
|
|
769
337
|
*/
|
|
770
|
-
|
|
338
|
+
wrapWithThreadTag(threadId: string, observations: string, messageRange?: string): Promise<string>;
|
|
771
339
|
/**
|
|
772
340
|
* Append or merge new thread sections.
|
|
773
341
|
* If the new section has the same thread ID and date as an existing section,
|
|
@@ -776,15 +344,9 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
776
344
|
*/
|
|
777
345
|
private replaceOrAppendThreadSection;
|
|
778
346
|
/**
|
|
779
|
-
*
|
|
780
|
-
* Returns thread IDs in order from oldest to most recent.
|
|
781
|
-
* This ensures no thread's messages get "stuck" unobserved.
|
|
782
|
-
*/
|
|
783
|
-
private sortThreadsByOldestMessage;
|
|
784
|
-
/**
|
|
785
|
-
* Do synchronous observation (fallback when no buffering)
|
|
347
|
+
* @internal Used by observation strategies. Do not call directly.
|
|
786
348
|
*/
|
|
787
|
-
|
|
349
|
+
wrapObservations(rawObservations: string, existingObservations: string, threadId: string, lastObservedAt?: Date, messageRange?: string): Promise<string> | string;
|
|
788
350
|
/**
|
|
789
351
|
* Start an async background observation that stores results to bufferedObservations.
|
|
790
352
|
* This is a fire-and-forget operation that runs in the background.
|
|
@@ -806,81 +368,318 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
806
368
|
*/
|
|
807
369
|
private runAsyncBufferedObservation;
|
|
808
370
|
/**
|
|
809
|
-
*
|
|
810
|
-
* Does NOT update activeObservations or trigger reflection.
|
|
371
|
+
* Trigger async buffered observation if the token count has crossed a new interval.
|
|
811
372
|
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
373
|
+
* Encapsulates the shouldTrigger check + startAsyncBufferedObservation call.
|
|
374
|
+
* Returns whether buffering was actually triggered.
|
|
814
375
|
*/
|
|
815
|
-
|
|
376
|
+
triggerAsyncBuffering(opts: {
|
|
377
|
+
threadId: string;
|
|
378
|
+
resourceId?: string;
|
|
379
|
+
record: ObservationalMemoryRecord;
|
|
380
|
+
pendingTokens: number;
|
|
381
|
+
unbufferedPendingTokens: number;
|
|
382
|
+
unobservedMessages: MastraDBMessage[];
|
|
383
|
+
threshold: number;
|
|
384
|
+
writer?: ProcessorStreamWriter;
|
|
385
|
+
requestContext?: RequestContext;
|
|
386
|
+
}): Promise<boolean>;
|
|
387
|
+
private isMessageList;
|
|
388
|
+
private removeIdsFromArray;
|
|
816
389
|
/**
|
|
817
|
-
*
|
|
818
|
-
*
|
|
390
|
+
* Mutate partially observed messages in place and return the fully observed
|
|
391
|
+
* message IDs that should be removed from the live context.
|
|
392
|
+
*
|
|
393
|
+
* This is the shared activation-cleanup primitive used by both the processor
|
|
394
|
+
* and AI SDK integrations: callers pass the current live messages, OM trims
|
|
395
|
+
* any partially observed messages down to their unobserved parts, and OM
|
|
396
|
+
* returns only the IDs that are safe to remove entirely.
|
|
819
397
|
*/
|
|
820
|
-
|
|
398
|
+
getObservedMessageIdsForCleanup(opts: {
|
|
399
|
+
threadId: string;
|
|
400
|
+
resourceId?: string;
|
|
401
|
+
messages: MastraDBMessage[];
|
|
402
|
+
observedMessageIds?: string[];
|
|
403
|
+
retentionFloor?: number;
|
|
404
|
+
}): Promise<string[]>;
|
|
821
405
|
/**
|
|
822
|
-
*
|
|
823
|
-
* Returns true if activation succeeded, false if no buffered content or activation failed.
|
|
406
|
+
* Clean up observed content from either a live MessageList or a plain message array.
|
|
824
407
|
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
408
|
+
* - MessageList input: mutates the live container in place and returns the remaining messages
|
|
409
|
+
* - Array input: mutates the array in place and returns it
|
|
410
|
+
*
|
|
411
|
+
* This is the shared cleanup primitive intended for both processor and non-processor
|
|
412
|
+
* integrations. The processor may still pass sealedIds/state so marker/fallback cleanup
|
|
413
|
+
* can persist messages safely, but callers that do not need that bookkeeping can omit it.
|
|
828
414
|
*/
|
|
829
|
-
|
|
415
|
+
/** @internal Used by ObservationStep. */
|
|
416
|
+
cleanupMessages(opts: {
|
|
417
|
+
threadId: string;
|
|
418
|
+
resourceId?: string;
|
|
419
|
+
messages: MessageList | MastraDBMessage[];
|
|
420
|
+
observedMessageIds?: string[];
|
|
421
|
+
retentionFloor?: number;
|
|
422
|
+
}): Promise<MastraDBMessage[]>;
|
|
830
423
|
/**
|
|
831
|
-
*
|
|
832
|
-
* This is a fire-and-forget operation that runs in the background.
|
|
833
|
-
* The results will be swapped to active when the main reflection threshold is reached.
|
|
424
|
+
* Clean up the message context after a successful observation.
|
|
834
425
|
*
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
*
|
|
426
|
+
* Handles both activation-based cleanup (using observedMessageIds) and
|
|
427
|
+
* marker-based cleanup (using observation boundary markers). Respects
|
|
428
|
+
* retention floors to prevent removing too many messages.
|
|
429
|
+
*/
|
|
430
|
+
cleanupObservedContext(opts: {
|
|
431
|
+
messageList: MessageList;
|
|
432
|
+
threadId: string;
|
|
433
|
+
resourceId?: string;
|
|
434
|
+
observedMessageIds?: string[];
|
|
435
|
+
retentionFloor?: number;
|
|
436
|
+
}): Promise<void>;
|
|
437
|
+
/**
|
|
438
|
+
* Reset buffering state after a successful observation activation.
|
|
439
|
+
*
|
|
440
|
+
* Clears the lastBufferedBoundary, buffering flag, and optionally cleans up
|
|
441
|
+
* static maps for activated message IDs.
|
|
838
442
|
*/
|
|
839
|
-
|
|
443
|
+
/** @internal Used by ObservationStep. */
|
|
444
|
+
resetBufferingState(opts: {
|
|
445
|
+
threadId: string;
|
|
446
|
+
resourceId?: string;
|
|
447
|
+
recordId: string;
|
|
448
|
+
activatedMessageIds?: string[];
|
|
449
|
+
}): Promise<void>;
|
|
840
450
|
/**
|
|
841
|
-
*
|
|
842
|
-
*
|
|
451
|
+
* Build the observation system message string for injection into an LLM prompt.
|
|
452
|
+
*
|
|
453
|
+
* Loads thread metadata (currentTask, suggestedResponse), formats observations
|
|
454
|
+
* with context prompts and instructions, and returns the fully-formed string.
|
|
455
|
+
* Returns undefined if no observations exist.
|
|
456
|
+
*
|
|
457
|
+
* This is the public entry point for context formatting — used by both
|
|
458
|
+
* Memory.getContext() (standalone) and the processor (via injectObservationsIntoMessages).
|
|
459
|
+
*
|
|
460
|
+
* @example
|
|
461
|
+
* ```ts
|
|
462
|
+
* const systemMsg = await om.buildContextSystemMessage({ threadId: 'thread-1' });
|
|
463
|
+
* if (systemMsg) {
|
|
464
|
+
* const result = await generateText({ system: systemMsg, messages });
|
|
465
|
+
* }
|
|
466
|
+
* ```
|
|
843
467
|
*/
|
|
844
|
-
|
|
468
|
+
buildContextSystemMessage(opts: {
|
|
469
|
+
threadId: string;
|
|
470
|
+
resourceId?: string;
|
|
471
|
+
record?: ObservationalMemoryRecord;
|
|
472
|
+
unobservedContextBlocks?: string;
|
|
473
|
+
currentDate?: Date;
|
|
474
|
+
}): Promise<string | undefined>;
|
|
845
475
|
/**
|
|
846
|
-
*
|
|
847
|
-
*
|
|
476
|
+
* Build observation context as an array of system message chunks.
|
|
477
|
+
* Each chunk is a separate system message for better LLM cache hit rates.
|
|
478
|
+
* Used by the processor to inject multiple system messages.
|
|
479
|
+
* @internal
|
|
480
|
+
*/
|
|
481
|
+
buildContextSystemMessages(opts: {
|
|
482
|
+
threadId: string;
|
|
483
|
+
resourceId?: string;
|
|
484
|
+
record?: ObservationalMemoryRecord;
|
|
485
|
+
unobservedContextBlocks?: string;
|
|
486
|
+
currentDate?: Date;
|
|
487
|
+
}): Promise<string[] | undefined>;
|
|
488
|
+
/**
|
|
489
|
+
* Get unobserved messages from other threads for resource-scoped observation.
|
|
848
490
|
*
|
|
849
|
-
*
|
|
850
|
-
*
|
|
491
|
+
* Lists all threads for the resource, filters to unobserved messages,
|
|
492
|
+
* and formats them as context blocks.
|
|
493
|
+
*/
|
|
494
|
+
/** @internal Used by ObservationTurn. */
|
|
495
|
+
getOtherThreadsContext(resourceId: string, currentThreadId: string): Promise<string | undefined>;
|
|
496
|
+
/**
|
|
497
|
+
* Emit debug event and stream progress for UI feedback.
|
|
498
|
+
*/
|
|
499
|
+
emitProgress(opts: {
|
|
500
|
+
record: ObservationalMemoryRecord;
|
|
501
|
+
pendingTokens: number;
|
|
502
|
+
threshold: number;
|
|
503
|
+
effectiveObservationTokensThreshold: number;
|
|
504
|
+
currentObservationTokens: number;
|
|
505
|
+
writer?: ProcessorStreamWriter;
|
|
506
|
+
stepNumber: number;
|
|
507
|
+
threadId: string;
|
|
508
|
+
resourceId?: string;
|
|
509
|
+
}): Promise<void>;
|
|
510
|
+
/**
|
|
511
|
+
* Get the current observation status for a thread/resource.
|
|
512
|
+
*
|
|
513
|
+
* Loads unobserved messages from storage, counts tokens, and checks against
|
|
514
|
+
* configured thresholds. Returns a comprehensive status object that tells the
|
|
515
|
+
* caller what actions are needed.
|
|
516
|
+
*
|
|
517
|
+
* This is a pure read operation with no side effects.
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```ts
|
|
521
|
+
* const status = await om.getStatus({ threadId });
|
|
522
|
+
* if (status.shouldObserve) {
|
|
523
|
+
* await om.observe({ threadId });
|
|
524
|
+
* } else if (status.shouldBuffer) {
|
|
525
|
+
* await om.buffer({ threadId });
|
|
526
|
+
* }
|
|
527
|
+
* if (status.shouldReflect) {
|
|
528
|
+
* await om.reflect(threadId);
|
|
529
|
+
* }
|
|
530
|
+
* ```
|
|
851
531
|
*/
|
|
852
|
-
|
|
532
|
+
getStatus(opts: {
|
|
533
|
+
threadId: string;
|
|
534
|
+
resourceId?: string;
|
|
535
|
+
messages?: MastraDBMessage[];
|
|
536
|
+
}): Promise<{
|
|
537
|
+
record: ObservationalMemoryRecord;
|
|
538
|
+
pendingTokens: number;
|
|
539
|
+
threshold: number;
|
|
540
|
+
effectiveObservationTokensThreshold: number;
|
|
541
|
+
unbufferedPendingTokens: number;
|
|
542
|
+
shouldObserve: boolean;
|
|
543
|
+
shouldBuffer: boolean;
|
|
544
|
+
shouldReflect: boolean;
|
|
545
|
+
bufferedChunkCount: number;
|
|
546
|
+
bufferedChunkTokens: number;
|
|
547
|
+
canActivate: boolean;
|
|
548
|
+
asyncObservationEnabled: boolean;
|
|
549
|
+
asyncReflectionEnabled: boolean;
|
|
550
|
+
scope: 'resource' | 'thread';
|
|
551
|
+
}>;
|
|
853
552
|
/**
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
* get "stuck" unobserved forever.
|
|
553
|
+
* Finalize the observation lifecycle: activate any remaining buffered chunks,
|
|
554
|
+
* then observe if the threshold is crossed.
|
|
857
555
|
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
*
|
|
861
|
-
*
|
|
862
|
-
*
|
|
556
|
+
* Call this at the end of a conversation, session, or turn sequence to ensure
|
|
557
|
+
* no buffered observations are left orphaned and the observation cursor is
|
|
558
|
+
* advanced. Produces a clean terminal state (no pending chunks, cursor up to date).
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* ```ts
|
|
562
|
+
* // After all turns are complete
|
|
563
|
+
* const result = await om.finalize({ threadId });
|
|
564
|
+
* // result.activated: true if buffered chunks were promoted
|
|
565
|
+
* // result.observed: true if a full observation pass ran
|
|
566
|
+
* ```
|
|
863
567
|
*/
|
|
864
|
-
|
|
568
|
+
finalize(opts: {
|
|
569
|
+
threadId: string;
|
|
570
|
+
resourceId?: string;
|
|
571
|
+
messages?: MastraDBMessage[];
|
|
572
|
+
}): Promise<{
|
|
573
|
+
activated: boolean;
|
|
574
|
+
observed: boolean;
|
|
575
|
+
reflected: boolean;
|
|
576
|
+
record: ObservationalMemoryRecord;
|
|
577
|
+
}>;
|
|
865
578
|
/**
|
|
866
|
-
*
|
|
867
|
-
*
|
|
868
|
-
*
|
|
579
|
+
* Return only the messages that haven't been fully observed yet.
|
|
580
|
+
*
|
|
581
|
+
* Use this to prune observed messages from an in-memory message array,
|
|
582
|
+
* preventing unbounded context growth across steps in a multi-step loop.
|
|
583
|
+
* This is the array-based equivalent of the processor's `cleanupObservedContext()`.
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```ts
|
|
587
|
+
* // In a prepareStep hook, prune before sending to the model
|
|
588
|
+
* messages = await om.pruneObserved({ threadId, messages });
|
|
589
|
+
* ```
|
|
869
590
|
*/
|
|
870
|
-
|
|
591
|
+
pruneObserved(opts: {
|
|
592
|
+
threadId: string;
|
|
593
|
+
resourceId?: string;
|
|
594
|
+
messages: MastraDBMessage[];
|
|
595
|
+
}): Promise<MastraDBMessage[]>;
|
|
596
|
+
/**
|
|
597
|
+
* Create a buffered observation chunk without merging into active observations.
|
|
598
|
+
*
|
|
599
|
+
* Loads unobserved messages from storage (filtered by the buffer cursor to avoid
|
|
600
|
+
* re-buffering), calls the observer LLM, and stores the result as a pending
|
|
601
|
+
* buffered chunk in the DB. The chunk can later be merged into active observations
|
|
602
|
+
* via `activate()`.
|
|
603
|
+
*
|
|
604
|
+
* This is a synchronous (awaited) operation — the caller decides whether to
|
|
605
|
+
* `await` it or fire-and-forget. All state lives in storage; no in-process
|
|
606
|
+
* coordination is needed.
|
|
607
|
+
*
|
|
608
|
+
* @example
|
|
609
|
+
* ```ts
|
|
610
|
+
* const status = await om.getStatus({ threadId });
|
|
611
|
+
* if (status.shouldBuffer) {
|
|
612
|
+
* await om.buffer({ threadId });
|
|
613
|
+
* }
|
|
614
|
+
* ```
|
|
615
|
+
*/
|
|
616
|
+
/** @internal Used by ObservationStep. */
|
|
617
|
+
buffer(opts: {
|
|
618
|
+
threadId: string;
|
|
619
|
+
resourceId?: string;
|
|
620
|
+
messages?: MastraDBMessage[];
|
|
621
|
+
/** The freshly-counted pending token count from the caller. If not provided,
|
|
622
|
+
* falls back to record.pendingMessageTokens (which may be stale). */
|
|
623
|
+
pendingTokens?: number;
|
|
624
|
+
/** Pre-loaded record to skip the initial getOrCreateRecord() fetch.
|
|
625
|
+
* When called fire-and-forget, passing the record avoids an async gap
|
|
626
|
+
* before lastBufferedBoundary is set. */
|
|
627
|
+
record?: ObservationalMemoryRecord;
|
|
628
|
+
writer?: ProcessorStreamWriter;
|
|
629
|
+
requestContext?: RequestContext;
|
|
630
|
+
/** Called with the final candidate messages after cursor filtering, before the observer runs.
|
|
631
|
+
* Use this to seal messages in a live MessageList and persist them to storage. */
|
|
632
|
+
beforeBuffer?: (candidates: MastraDBMessage[]) => Promise<void>;
|
|
633
|
+
}): Promise<{
|
|
634
|
+
buffered: boolean;
|
|
635
|
+
record: ObservationalMemoryRecord;
|
|
636
|
+
}>;
|
|
871
637
|
/**
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
638
|
+
* Activate buffered observation chunks by merging them into active observations.
|
|
639
|
+
*
|
|
640
|
+
* This is a pure storage operation — no LLM call. It reads buffered chunks from
|
|
641
|
+
* the DB and swaps them into active observations via `storage.swapBufferedToActive()`.
|
|
642
|
+
*
|
|
643
|
+
* Call this after `buffer()` has created chunks, typically at the start of a new
|
|
644
|
+
* turn or when `getStatus().canActivate` is true.
|
|
645
|
+
*
|
|
646
|
+
* @example
|
|
647
|
+
* ```ts
|
|
648
|
+
* const status = await om.getStatus({ threadId });
|
|
649
|
+
* if (status.canActivate) {
|
|
650
|
+
* const result = await om.activate({ threadId });
|
|
651
|
+
* if (result.activated) {
|
|
652
|
+
* console.log('Activated', result.activatedMessageIds?.length, 'message observations');
|
|
653
|
+
* }
|
|
654
|
+
* }
|
|
655
|
+
* ```
|
|
876
656
|
*/
|
|
877
|
-
|
|
657
|
+
/** @internal Used by ObservationStep. */
|
|
658
|
+
activate(opts: {
|
|
659
|
+
threadId: string;
|
|
660
|
+
resourceId?: string;
|
|
661
|
+
/** When true, skip activation if pending tokens are below the observation threshold. */
|
|
662
|
+
checkThreshold?: boolean;
|
|
663
|
+
/** Messages to use for threshold check (in-memory). If omitted, loads from storage. */
|
|
664
|
+
messages?: MastraDBMessage[];
|
|
665
|
+
/** Stream writer for emitting activation markers to the UI. */
|
|
666
|
+
writer?: ProcessorStreamWriter;
|
|
667
|
+
/** MessageList for persisting activation markers on the last assistant message. */
|
|
668
|
+
messageList?: MessageList;
|
|
669
|
+
}): Promise<{
|
|
670
|
+
activated: boolean;
|
|
671
|
+
record: ObservationalMemoryRecord;
|
|
672
|
+
activatedMessageIds?: string[];
|
|
673
|
+
}>;
|
|
878
674
|
/**
|
|
879
675
|
* Manually trigger observation.
|
|
880
676
|
*
|
|
881
677
|
* When `messages` is provided, those are used directly (filtered for unobserved)
|
|
882
678
|
* instead of reading from storage. This allows external systems (e.g., opencode)
|
|
883
679
|
* to pass conversation messages without duplicating them into Mastra's DB.
|
|
680
|
+
*
|
|
681
|
+
* Returns a result indicating whether observation and/or reflection occurred,
|
|
682
|
+
* along with the updated record.
|
|
884
683
|
*/
|
|
885
684
|
observe(opts: {
|
|
886
685
|
threadId: string;
|
|
@@ -888,7 +687,12 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
888
687
|
messages?: MastraDBMessage[];
|
|
889
688
|
hooks?: ObserveHooks;
|
|
890
689
|
requestContext?: RequestContext;
|
|
891
|
-
|
|
690
|
+
writer?: ProcessorStreamWriter;
|
|
691
|
+
}): Promise<{
|
|
692
|
+
observed: boolean;
|
|
693
|
+
reflected: boolean;
|
|
694
|
+
record: ObservationalMemoryRecord;
|
|
695
|
+
}>;
|
|
892
696
|
/**
|
|
893
697
|
* Manually trigger reflection with optional guidance prompt.
|
|
894
698
|
*
|
|
@@ -900,7 +704,10 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
900
704
|
* );
|
|
901
705
|
* ```
|
|
902
706
|
*/
|
|
903
|
-
reflect(threadId: string, resourceId?: string, prompt?: string, requestContext?: RequestContext): Promise<
|
|
707
|
+
reflect(threadId: string, resourceId?: string, prompt?: string, requestContext?: RequestContext): Promise<{
|
|
708
|
+
reflected: boolean;
|
|
709
|
+
record: ObservationalMemoryRecord;
|
|
710
|
+
}>;
|
|
904
711
|
/**
|
|
905
712
|
* Get current observations for a thread/resource
|
|
906
713
|
*/
|
|
@@ -933,6 +740,34 @@ export declare class ObservationalMemory implements Processor<'observational-mem
|
|
|
933
740
|
* Get current reflection configuration
|
|
934
741
|
*/
|
|
935
742
|
getReflectionConfig(): ResolvedReflectionConfig;
|
|
743
|
+
/**
|
|
744
|
+
* Get the message history instance for marker persistence.
|
|
745
|
+
*/
|
|
746
|
+
getMessageHistory(): MessageHistory;
|
|
747
|
+
/**
|
|
748
|
+
* Get whether thread IDs should be obscured in observations.
|
|
749
|
+
*/
|
|
750
|
+
getObscureThreadIds(): boolean;
|
|
751
|
+
/**
|
|
752
|
+
* Begin a new observation turn — the high-level API for managing the
|
|
753
|
+
* observe/buffer/activate/reflect lifecycle across agentic loop steps.
|
|
754
|
+
*
|
|
755
|
+
* @example
|
|
756
|
+
* ```ts
|
|
757
|
+
* const turn = om.beginTurn({ threadId, resourceId, messageList });
|
|
758
|
+
* await turn.start(memory);
|
|
759
|
+
*
|
|
760
|
+
* const step0 = turn.step(0);
|
|
761
|
+
* const ctx = await step0.prepare();
|
|
762
|
+
* // ... agent generates ...
|
|
763
|
+
*
|
|
764
|
+
* await turn.end();
|
|
765
|
+
* ```
|
|
766
|
+
*/
|
|
767
|
+
beginTurn(opts: {
|
|
768
|
+
threadId: string;
|
|
769
|
+
resourceId?: string;
|
|
770
|
+
messageList: MessageList;
|
|
771
|
+
}): ObservationTurn;
|
|
936
772
|
}
|
|
937
|
-
export {};
|
|
938
773
|
//# sourceMappingURL=observational-memory.d.ts.map
|