indusagi 0.12.13 → 0.12.15
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/dist/agent/tools/registry.d.ts +1 -1
- package/dist/agent/tools/registry.d.ts.map +1 -1
- package/dist/agent/types.d.ts +1 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/ai/models.generated.d.ts +621 -53
- package/dist/ai/models.generated.d.ts.map +1 -1
- package/dist/ai/models.generated.js +548 -0
- package/dist/ai/models.generated.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/client-pool.d.ts +106 -0
- package/dist/mcp/client-pool.d.ts.map +1 -0
- package/dist/mcp/client-pool.js +233 -0
- package/dist/mcp/client-pool.js.map +1 -0
- package/dist/mcp/client.d.ts +158 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +586 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config.d.ts +61 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +250 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/errors.d.ts +104 -0
- package/dist/mcp/errors.d.ts.map +1 -0
- package/dist/mcp/errors.js +138 -0
- package/dist/mcp/errors.js.map +1 -0
- package/dist/mcp/index.d.ts +56 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +83 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/schema-converter.d.ts +68 -0
- package/dist/mcp/schema-converter.d.ts.map +1 -0
- package/dist/mcp/schema-converter.js +230 -0
- package/dist/mcp/schema-converter.js.map +1 -0
- package/dist/mcp/server.d.ts +111 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +300 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tool-factory.d.ts +63 -0
- package/dist/mcp/tool-factory.d.ts.map +1 -0
- package/dist/mcp/tool-factory.js +228 -0
- package/dist/mcp/tool-factory.js.map +1 -0
- package/dist/mcp/types.d.ts +289 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +8 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +6 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory/embedder/base.d.ts +41 -0
- package/dist/memory/embedder/base.d.ts.map +1 -0
- package/dist/memory/embedder/base.js +10 -0
- package/dist/memory/embedder/base.js.map +1 -0
- package/dist/memory/embedder/index.d.ts +8 -0
- package/dist/memory/embedder/index.d.ts.map +1 -0
- package/dist/memory/embedder/index.js +6 -0
- package/dist/memory/embedder/index.js.map +1 -0
- package/dist/memory/embedder/openai.d.ts +35 -0
- package/dist/memory/embedder/openai.d.ts.map +1 -0
- package/dist/memory/embedder/openai.js +103 -0
- package/dist/memory/embedder/openai.js.map +1 -0
- package/dist/memory/index.d.ts +33 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +31 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/memory.d.ts +126 -0
- package/dist/memory/memory.d.ts.map +1 -0
- package/dist/memory/memory.js +280 -0
- package/dist/memory/memory.js.map +1 -0
- package/dist/memory/processors/base.d.ts +42 -0
- package/dist/memory/processors/base.d.ts.map +1 -0
- package/dist/memory/processors/base.js +6 -0
- package/dist/memory/processors/base.js.map +1 -0
- package/dist/memory/processors/index.d.ts +16 -0
- package/dist/memory/processors/index.d.ts.map +1 -0
- package/dist/memory/processors/index.js +18 -0
- package/dist/memory/processors/index.js.map +1 -0
- package/dist/memory/processors/message-history.d.ts +35 -0
- package/dist/memory/processors/message-history.d.ts.map +1 -0
- package/dist/memory/processors/message-history.js +51 -0
- package/dist/memory/processors/message-history.js.map +1 -0
- package/dist/memory/processors/observational-memory/index.d.ts +82 -0
- package/dist/memory/processors/observational-memory/index.d.ts.map +1 -0
- package/dist/memory/processors/observational-memory/index.js +234 -0
- package/dist/memory/processors/observational-memory/index.js.map +1 -0
- package/dist/memory/processors/observational-memory/observer-agent.d.ts +64 -0
- package/dist/memory/processors/observational-memory/observer-agent.d.ts.map +1 -0
- package/dist/memory/processors/observational-memory/observer-agent.js +362 -0
- package/dist/memory/processors/observational-memory/observer-agent.js.map +1 -0
- package/dist/memory/processors/observational-memory/reflector-agent.d.ts +38 -0
- package/dist/memory/processors/observational-memory/reflector-agent.d.ts.map +1 -0
- package/dist/memory/processors/observational-memory/reflector-agent.js +213 -0
- package/dist/memory/processors/observational-memory/reflector-agent.js.map +1 -0
- package/dist/memory/processors/observational-memory/token-counter.d.ts +35 -0
- package/dist/memory/processors/observational-memory/token-counter.d.ts.map +1 -0
- package/dist/memory/processors/observational-memory/token-counter.js +90 -0
- package/dist/memory/processors/observational-memory/token-counter.js.map +1 -0
- package/dist/memory/processors/semantic-recall.d.ts +55 -0
- package/dist/memory/processors/semantic-recall.d.ts.map +1 -0
- package/dist/memory/processors/semantic-recall.js +143 -0
- package/dist/memory/processors/semantic-recall.js.map +1 -0
- package/dist/memory/processors/working-memory.d.ts +41 -0
- package/dist/memory/processors/working-memory.d.ts.map +1 -0
- package/dist/memory/processors/working-memory.js +82 -0
- package/dist/memory/processors/working-memory.js.map +1 -0
- package/dist/memory/storage/base.d.ts +288 -0
- package/dist/memory/storage/base.d.ts.map +1 -0
- package/dist/memory/storage/base.js +211 -0
- package/dist/memory/storage/base.js.map +1 -0
- package/dist/memory/storage/index.d.ts +9 -0
- package/dist/memory/storage/index.d.ts.map +1 -0
- package/dist/memory/storage/index.js +7 -0
- package/dist/memory/storage/index.js.map +1 -0
- package/dist/memory/storage/inmemory.d.ts +93 -0
- package/dist/memory/storage/inmemory.d.ts.map +1 -0
- package/dist/memory/storage/inmemory.js +646 -0
- package/dist/memory/storage/inmemory.js.map +1 -0
- package/dist/memory/tools/working-memory.d.ts +100 -0
- package/dist/memory/tools/working-memory.d.ts.map +1 -0
- package/dist/memory/tools/working-memory.js +237 -0
- package/dist/memory/tools/working-memory.js.map +1 -0
- package/dist/memory/types.d.ts +386 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +58 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/memory/vector/base.d.ts +145 -0
- package/dist/memory/vector/base.d.ts.map +1 -0
- package/dist/memory/vector/base.js +83 -0
- package/dist/memory/vector/base.js.map +1 -0
- package/dist/memory/vector/index.d.ts +8 -0
- package/dist/memory/vector/index.d.ts.map +1 -0
- package/dist/memory/vector/index.js +7 -0
- package/dist/memory/vector/index.js.map +1 -0
- package/dist/memory/vector/inmemory.d.ts +47 -0
- package/dist/memory/vector/inmemory.d.ts.map +1 -0
- package/dist/memory/vector/inmemory.js +234 -0
- package/dist/memory/vector/inmemory.js.map +1 -0
- package/package.json +32 -2
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observer Agent - Prompts and Parsing
|
|
3
|
+
* Based on Mastra ObserverAgent
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Core extraction instructions for the Observer
|
|
7
|
+
*/
|
|
8
|
+
export const OBSERVER_EXTRACTION_INSTRUCTIONS = `CRITICAL: DISTINGUISH USER ASSERTIONS FROM QUESTIONS
|
|
9
|
+
|
|
10
|
+
When the user TELLS you something about themselves, mark it as an assertion:
|
|
11
|
+
- "I have two kids" → 🔴 (14:30) User stated has two kids
|
|
12
|
+
- "I work at Acme Corp" → 🔴 (14:31) User stated works at Acme Corp
|
|
13
|
+
|
|
14
|
+
When the user ASKS about something, mark it as a question/request:
|
|
15
|
+
- "Can you help me with X?" → 🔴 (15:00) User asked help with X
|
|
16
|
+
- "What's the best way to do Y?" → 🔴 (15:01) User asked best way to do Y
|
|
17
|
+
|
|
18
|
+
STATE CHANGES AND UPDATES:
|
|
19
|
+
When a user indicates they are changing something, frame it as a state change:
|
|
20
|
+
- "I'm going to start doing X instead of Y" → "User will start doing X (changing from Y)"
|
|
21
|
+
- "I'm switching from A to B" → "User is switching from A to B"
|
|
22
|
+
|
|
23
|
+
TEMPORAL ANCHORING:
|
|
24
|
+
Each observation has TWO potential timestamps:
|
|
25
|
+
1. BEGINNING: The time the statement was made - ALWAYS include this
|
|
26
|
+
2. END: The time being REFERENCED, if different - ONLY when there's a relative time reference
|
|
27
|
+
|
|
28
|
+
FORMAT:
|
|
29
|
+
- With time reference: (TIME) [observation]. (meaning/estimated DATE)
|
|
30
|
+
- Without time reference: (TIME) [observation].
|
|
31
|
+
|
|
32
|
+
CONVERSATION CONTEXT:
|
|
33
|
+
- What the user is working on or asking about
|
|
34
|
+
- Previous topics and their outcomes
|
|
35
|
+
- User preferences (likes, dislikes, etc.)
|
|
36
|
+
- Any specifically formatted text that needs to be reproduced later
|
|
37
|
+
- When who/what/where/when is mentioned, note all details
|
|
38
|
+
|
|
39
|
+
USER MESSAGE CAPTURE:
|
|
40
|
+
- Short and medium-length user messages should be captured nearly verbatim
|
|
41
|
+
- For very long user messages, summarize but quote key phrases
|
|
42
|
+
|
|
43
|
+
AVOIDING REPETITIVE OBSERVATIONS:
|
|
44
|
+
- Do NOT repeat the same observation across multiple turns
|
|
45
|
+
- Group repeated similar actions into a single parent observation`;
|
|
46
|
+
/**
|
|
47
|
+
* Output format for Observer
|
|
48
|
+
*/
|
|
49
|
+
export const OBSERVER_OUTPUT_FORMAT_BASE = `Use priority levels:
|
|
50
|
+
- 🔴 High: explicit user facts, preferences, goals achieved, critical context
|
|
51
|
+
- 🟡 Medium: project details, learned information, tool results
|
|
52
|
+
- 🟢 Low: minor details, uncertain observations
|
|
53
|
+
|
|
54
|
+
Group related observations by indenting:
|
|
55
|
+
* 🔴 (14:33) Agent debugging auth issue
|
|
56
|
+
* -> ran git status, found 3 modified files
|
|
57
|
+
* -> viewed auth.ts, found missing null check
|
|
58
|
+
|
|
59
|
+
Group observations by date, then list each with 24-hour time.
|
|
60
|
+
|
|
61
|
+
<observations>
|
|
62
|
+
Date: Dec 4, 2025
|
|
63
|
+
* 🔴 (14:30) User prefers direct answers
|
|
64
|
+
* 🔴 (14:31) Working on feature X
|
|
65
|
+
* 🟡 (14:32) User might prefer dark mode
|
|
66
|
+
|
|
67
|
+
Date: Dec 5, 2025
|
|
68
|
+
* 🔴 (09:15) Continued work on feature X
|
|
69
|
+
</observations>
|
|
70
|
+
|
|
71
|
+
<current-task>
|
|
72
|
+
State the current task(s) explicitly.
|
|
73
|
+
</current-task>
|
|
74
|
+
|
|
75
|
+
<suggested-response>
|
|
76
|
+
Hint for the agent's immediate next message.
|
|
77
|
+
</suggested-response>`;
|
|
78
|
+
/**
|
|
79
|
+
* Observer guidelines
|
|
80
|
+
*/
|
|
81
|
+
export const OBSERVER_GUIDELINES = `- Be specific enough for the assistant to act on
|
|
82
|
+
- Add 1 to 5 observations per exchange
|
|
83
|
+
- Use terse language to save tokens
|
|
84
|
+
- Do not add repetitive observations
|
|
85
|
+
- If the agent calls tools, observe what was called and what was learned
|
|
86
|
+
- Make sure you start each observation with a priority emoji (🔴, 🟡, 🟢)
|
|
87
|
+
- User messages are always 🔴 priority`;
|
|
88
|
+
/**
|
|
89
|
+
* Build the Observer system prompt
|
|
90
|
+
*/
|
|
91
|
+
export function buildObserverSystemPrompt(multiThread = false, instruction) {
|
|
92
|
+
const outputFormat = OBSERVER_OUTPUT_FORMAT_BASE;
|
|
93
|
+
if (multiThread) {
|
|
94
|
+
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.
|
|
95
|
+
|
|
96
|
+
Extract observations that will help the assistant remember:
|
|
97
|
+
|
|
98
|
+
${OBSERVER_EXTRACTION_INSTRUCTIONS}
|
|
99
|
+
|
|
100
|
+
=== MULTI-THREAD INPUT ===
|
|
101
|
+
|
|
102
|
+
You will receive messages from MULTIPLE conversation threads, each wrapped in <thread id="..."> tags.
|
|
103
|
+
Process each thread separately and output observations for each thread.
|
|
104
|
+
|
|
105
|
+
=== OUTPUT FORMAT ===
|
|
106
|
+
|
|
107
|
+
<observations>
|
|
108
|
+
<thread id="thread_id_1">
|
|
109
|
+
Date: Dec 4, 2025
|
|
110
|
+
* 🔴 (14:30) User prefers direct answers
|
|
111
|
+
|
|
112
|
+
<current-task>
|
|
113
|
+
What the agent is currently working on
|
|
114
|
+
</current-task>
|
|
115
|
+
|
|
116
|
+
<suggested-response>
|
|
117
|
+
Hint for the agent's next message
|
|
118
|
+
</suggested-response>
|
|
119
|
+
</thread>
|
|
120
|
+
</observations>
|
|
121
|
+
|
|
122
|
+
Use priority levels: 🔴 High, 🟡 Medium, 🟢 Low
|
|
123
|
+
|
|
124
|
+
=== GUIDELINES ===
|
|
125
|
+
|
|
126
|
+
${OBSERVER_GUIDELINES}
|
|
127
|
+
|
|
128
|
+
Remember: These observations are the assistant's ONLY memory. Make them count.${instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : ""}`;
|
|
129
|
+
}
|
|
130
|
+
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.
|
|
131
|
+
|
|
132
|
+
Extract observations that will help the assistant remember:
|
|
133
|
+
|
|
134
|
+
${OBSERVER_EXTRACTION_INSTRUCTIONS}
|
|
135
|
+
|
|
136
|
+
=== OUTPUT FORMAT ===
|
|
137
|
+
|
|
138
|
+
Your output MUST use XML tags to structure the response.
|
|
139
|
+
|
|
140
|
+
${outputFormat}
|
|
141
|
+
|
|
142
|
+
=== GUIDELINES ===
|
|
143
|
+
|
|
144
|
+
${OBSERVER_GUIDELINES}
|
|
145
|
+
|
|
146
|
+
Remember: These observations are the assistant's ONLY memory. Make them count.${instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : ""}`;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Default Observer system prompt
|
|
150
|
+
*/
|
|
151
|
+
export const OBSERVER_SYSTEM_PROMPT = buildObserverSystemPrompt();
|
|
152
|
+
/**
|
|
153
|
+
* Format messages for Observer input
|
|
154
|
+
*/
|
|
155
|
+
export function formatMessagesForObserver(messages, options) {
|
|
156
|
+
const maxLen = options?.maxPartLength;
|
|
157
|
+
return messages
|
|
158
|
+
.map(msg => {
|
|
159
|
+
const timestamp = msg.createdAt
|
|
160
|
+
? new Date(msg.createdAt).toLocaleString("en-US", {
|
|
161
|
+
year: "numeric",
|
|
162
|
+
month: "short",
|
|
163
|
+
day: "numeric",
|
|
164
|
+
hour: "numeric",
|
|
165
|
+
minute: "2-digit",
|
|
166
|
+
hour12: true,
|
|
167
|
+
})
|
|
168
|
+
: "";
|
|
169
|
+
const role = msg.role.charAt(0).toUpperCase() + msg.role.slice(1);
|
|
170
|
+
const timestampStr = timestamp ? ` (${timestamp})` : "";
|
|
171
|
+
let content = "";
|
|
172
|
+
if (typeof msg.content === "string") {
|
|
173
|
+
content = maybeTruncate(msg.content, maxLen);
|
|
174
|
+
}
|
|
175
|
+
else if (msg.content && typeof msg.content === "object") {
|
|
176
|
+
const contentObj = msg.content;
|
|
177
|
+
if (contentObj.parts && Array.isArray(contentObj.parts) && contentObj.parts.length > 0) {
|
|
178
|
+
content = contentObj.parts
|
|
179
|
+
.map(part => {
|
|
180
|
+
if (part.type === "text")
|
|
181
|
+
return maybeTruncate(part.text, maxLen);
|
|
182
|
+
if (part.type === "tool-call") {
|
|
183
|
+
return `[Tool Call: ${part.toolName}]\n${maybeTruncate(JSON.stringify(part.args, null, 2), maxLen)}`;
|
|
184
|
+
}
|
|
185
|
+
if (part.type === "tool-result") {
|
|
186
|
+
return `[Tool Result: ${part.toolName}]\n${maybeTruncate(JSON.stringify(part.result, null, 2), maxLen)}`;
|
|
187
|
+
}
|
|
188
|
+
return "";
|
|
189
|
+
})
|
|
190
|
+
.filter(Boolean)
|
|
191
|
+
.join("\n");
|
|
192
|
+
}
|
|
193
|
+
else if (contentObj.content) {
|
|
194
|
+
content = maybeTruncate(contentObj.content, maxLen);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return `**${role}${timestampStr}:**\n${content}`;
|
|
198
|
+
})
|
|
199
|
+
.join("\n\n---\n\n");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Truncate string if needed
|
|
203
|
+
*/
|
|
204
|
+
function maybeTruncate(str, maxLen) {
|
|
205
|
+
if (!maxLen || str.length <= maxLen)
|
|
206
|
+
return str;
|
|
207
|
+
return `${str.slice(0, maxLen)}\n... [truncated ${str.length - maxLen} characters]`;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Build the Observer prompt
|
|
211
|
+
*/
|
|
212
|
+
export function buildObserverPrompt(existingObservations, messagesToObserve, options) {
|
|
213
|
+
const formattedMessages = formatMessagesForObserver(messagesToObserve);
|
|
214
|
+
let prompt = "";
|
|
215
|
+
if (existingObservations) {
|
|
216
|
+
prompt += `## Previous Observations\n\n${existingObservations}\n\n---\n\n`;
|
|
217
|
+
prompt += "Do not repeat these existing observations. Your new observations will be appended.\n\n";
|
|
218
|
+
}
|
|
219
|
+
prompt += `## New Message History to Observe\n\n${formattedMessages}\n\n---\n\n`;
|
|
220
|
+
prompt += `## Your Task\n\n`;
|
|
221
|
+
prompt += `Extract new observations from the message history above. Do not repeat observations already in previous observations.`;
|
|
222
|
+
if (options?.skipContinuationHints) {
|
|
223
|
+
prompt += `\n\nIMPORTANT: Do NOT include <current-task> or <suggested-response> sections. Only output <observations>.`;
|
|
224
|
+
}
|
|
225
|
+
return prompt;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Parse Observer output
|
|
229
|
+
*/
|
|
230
|
+
export function parseObserverOutput(output) {
|
|
231
|
+
// Check for degenerate repetition
|
|
232
|
+
if (detectDegenerateRepetition(output)) {
|
|
233
|
+
return {
|
|
234
|
+
observations: "",
|
|
235
|
+
rawOutput: output,
|
|
236
|
+
degenerate: true,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const parsed = parseMemorySectionXml(output);
|
|
240
|
+
const observations = sanitizeObservationLines(parsed.observations || "");
|
|
241
|
+
return {
|
|
242
|
+
observations,
|
|
243
|
+
currentTask: parsed.currentTask || undefined,
|
|
244
|
+
suggestedContinuation: parsed.suggestedResponse || undefined,
|
|
245
|
+
rawOutput: output,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Parse XML tags from observer/reflector output
|
|
250
|
+
*/
|
|
251
|
+
function parseMemorySectionXml(content) {
|
|
252
|
+
const result = {
|
|
253
|
+
observations: "",
|
|
254
|
+
currentTask: "",
|
|
255
|
+
suggestedResponse: "",
|
|
256
|
+
};
|
|
257
|
+
// Extract <observations> content
|
|
258
|
+
const observationsRegex = /^[ \t]*<observations>([\s\S]*?)^[ \t]*<\/observations>/gim;
|
|
259
|
+
const observationsMatches = [...content.matchAll(observationsRegex)];
|
|
260
|
+
if (observationsMatches.length > 0) {
|
|
261
|
+
result.observations = observationsMatches
|
|
262
|
+
.map(m => m[1]?.trim() ?? "")
|
|
263
|
+
.filter(Boolean)
|
|
264
|
+
.join("\n");
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
result.observations = extractListItemsOnly(content);
|
|
268
|
+
}
|
|
269
|
+
// Extract <current-task> content
|
|
270
|
+
const currentTaskMatch = content.match(/^[ \t]*<current-task>([\s\S]*?)^[ \t]*<\/current-task>/im);
|
|
271
|
+
if (currentTaskMatch?.[1]) {
|
|
272
|
+
result.currentTask = currentTaskMatch[1].trim();
|
|
273
|
+
}
|
|
274
|
+
// Extract <suggested-response> content
|
|
275
|
+
const suggestedResponseMatch = content.match(/^[ \t]*<suggested-response>([\s\S]*?)^[ \t]*<\/suggested-response>/im);
|
|
276
|
+
if (suggestedResponseMatch?.[1]) {
|
|
277
|
+
result.suggestedResponse = suggestedResponseMatch[1].trim();
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Extract only list items from content
|
|
283
|
+
*/
|
|
284
|
+
function extractListItemsOnly(content) {
|
|
285
|
+
const lines = content.split("\n");
|
|
286
|
+
const listLines = [];
|
|
287
|
+
for (const line of lines) {
|
|
288
|
+
if (/^\s*[-*]\s/.test(line) || /^\s*\d+\.\s/.test(line)) {
|
|
289
|
+
listLines.push(line);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return listLines.join("\n").trim();
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Maximum length for a single observation line
|
|
296
|
+
*/
|
|
297
|
+
const MAX_OBSERVATION_LINE_CHARS = 10_000;
|
|
298
|
+
/**
|
|
299
|
+
* Truncate observation lines that exceed max length
|
|
300
|
+
*/
|
|
301
|
+
export function sanitizeObservationLines(observations) {
|
|
302
|
+
if (!observations)
|
|
303
|
+
return observations;
|
|
304
|
+
const lines = observations.split("\n");
|
|
305
|
+
let changed = false;
|
|
306
|
+
for (let i = 0; i < lines.length; i++) {
|
|
307
|
+
if (lines[i].length > MAX_OBSERVATION_LINE_CHARS) {
|
|
308
|
+
lines[i] = lines[i].slice(0, MAX_OBSERVATION_LINE_CHARS) + " … [truncated]";
|
|
309
|
+
changed = true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return changed ? lines.join("\n") : observations;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Detect degenerate repetition in output
|
|
316
|
+
*/
|
|
317
|
+
export function detectDegenerateRepetition(text) {
|
|
318
|
+
if (!text || text.length < 2000)
|
|
319
|
+
return false;
|
|
320
|
+
const windowSize = 200;
|
|
321
|
+
const step = Math.max(1, Math.floor(text.length / 50));
|
|
322
|
+
const seen = new Map();
|
|
323
|
+
let duplicateWindows = 0;
|
|
324
|
+
let totalWindows = 0;
|
|
325
|
+
for (let i = 0; i + windowSize <= text.length; i += step) {
|
|
326
|
+
const window = text.slice(i, i + windowSize);
|
|
327
|
+
totalWindows++;
|
|
328
|
+
const count = (seen.get(window) ?? 0) + 1;
|
|
329
|
+
seen.set(window, count);
|
|
330
|
+
if (count > 1)
|
|
331
|
+
duplicateWindows++;
|
|
332
|
+
}
|
|
333
|
+
if (totalWindows > 5 && duplicateWindows / totalWindows > 0.4) {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
// Check for extremely long lines
|
|
337
|
+
const lines = text.split("\n");
|
|
338
|
+
for (const line of lines) {
|
|
339
|
+
if (line.length > 50_000)
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Optimize observations for token efficiency
|
|
346
|
+
*/
|
|
347
|
+
export function optimizeObservationsForContext(observations) {
|
|
348
|
+
let optimized = observations;
|
|
349
|
+
// Remove 🟡 and 🟢 emojis (keep 🔴)
|
|
350
|
+
optimized = optimized.replace(/🟡\s*/g, "");
|
|
351
|
+
optimized = optimized.replace(/🟢\s*/g, "");
|
|
352
|
+
// Remove semantic tags
|
|
353
|
+
optimized = optimized.replace(/\[(?![\d\s]*items collapsed)[^\]]+\]/g, "");
|
|
354
|
+
// Remove arrow indicators
|
|
355
|
+
optimized = optimized.replace(/\s*->\s*/g, " ");
|
|
356
|
+
// Clean up multiple spaces
|
|
357
|
+
optimized = optimized.replace(/ +/g, " ");
|
|
358
|
+
// Clean up multiple newlines
|
|
359
|
+
optimized = optimized.replace(/\n{3,}/g, "\n\n");
|
|
360
|
+
return optimized.trim();
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=observer-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer-agent.js","sourceRoot":"","sources":["../../../../src/memory/processors/observational-memory/observer-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflector Agent - Prompts and Parsing
|
|
3
|
+
* Based on Mastra ReflectorAgent
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Result from Reflector agent
|
|
7
|
+
*/
|
|
8
|
+
export interface ReflectorResult {
|
|
9
|
+
observations: string;
|
|
10
|
+
suggestedContinuation?: string;
|
|
11
|
+
degenerate?: boolean;
|
|
12
|
+
tokenCount?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the Reflector system prompt
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildReflectorSystemPrompt(instruction?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Default Reflector system prompt
|
|
20
|
+
*/
|
|
21
|
+
export declare const REFLECTOR_SYSTEM_PROMPT: string;
|
|
22
|
+
/**
|
|
23
|
+
* Compression guidance by level
|
|
24
|
+
*/
|
|
25
|
+
export declare const COMPRESSION_GUIDANCE: Record<0 | 1 | 2 | 3, string>;
|
|
26
|
+
/**
|
|
27
|
+
* Build the Reflector prompt
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildReflectorPrompt(observations: string, manualPrompt?: string, compressionLevel?: boolean | 0 | 1 | 2 | 3, skipContinuationHints?: boolean): string;
|
|
30
|
+
/**
|
|
31
|
+
* Parse Reflector output
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseReflectorOutput(output: string): ReflectorResult;
|
|
34
|
+
/**
|
|
35
|
+
* Validate that reflection compressed below target threshold
|
|
36
|
+
*/
|
|
37
|
+
export declare function validateCompression(reflectedTokens: number, targetThreshold: number): boolean;
|
|
38
|
+
//# sourceMappingURL=reflector-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflector-agent.d.ts","sourceRoot":"","sources":["../../../../src/memory/processors/observational-memory/reflector-agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAqDvE;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,QAA+B,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAyC9D,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,EACrB,gBAAgB,CAAC,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAC1C,qBAAqB,CAAC,EAAE,OAAO,GAC9B,MAAM,CA+BR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAgBpE;AAiED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAE7F"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflector Agent - Prompts and Parsing
|
|
3
|
+
* Based on Mastra ReflectorAgent
|
|
4
|
+
*/
|
|
5
|
+
import { OBSERVER_EXTRACTION_INSTRUCTIONS, OBSERVER_OUTPUT_FORMAT_BASE, OBSERVER_GUIDELINES, sanitizeObservationLines, detectDegenerateRepetition, } from "./observer-agent.js";
|
|
6
|
+
/**
|
|
7
|
+
* Build the Reflector system prompt
|
|
8
|
+
*/
|
|
9
|
+
export function buildReflectorSystemPrompt(instruction) {
|
|
10
|
+
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.
|
|
11
|
+
|
|
12
|
+
The following instructions were given to another part of your psyche (the observer) to create memories.
|
|
13
|
+
Use this to understand how your observational memories were created.
|
|
14
|
+
|
|
15
|
+
<observational-memory-instruction>
|
|
16
|
+
${OBSERVER_EXTRACTION_INSTRUCTIONS}
|
|
17
|
+
|
|
18
|
+
=== OUTPUT FORMAT ===
|
|
19
|
+
|
|
20
|
+
${OBSERVER_OUTPUT_FORMAT_BASE}
|
|
21
|
+
|
|
22
|
+
=== GUIDELINES ===
|
|
23
|
+
|
|
24
|
+
${OBSERVER_GUIDELINES}
|
|
25
|
+
</observational-memory-instruction>
|
|
26
|
+
|
|
27
|
+
You are another part of the same psyche, the observation reflector.
|
|
28
|
+
Your reason for existing is to reflect on all the observations, re-organize and streamline them, and draw connections and conclusions between observations.
|
|
29
|
+
|
|
30
|
+
You are a much greater and broader aspect of the psyche. Understand that other parts of your mind may get off track in details or side quests, make sure you think hard about what the observed goal at hand is, and observe if we got off track, and why, and how to get back on track.
|
|
31
|
+
|
|
32
|
+
Take the existing observations and rewrite them to make it easier to continue into the future with this knowledge!
|
|
33
|
+
|
|
34
|
+
IMPORTANT: your reflections are THE ENTIRETY of the assistant's memory. Any information you do not add to your reflections will be immediately forgotten. Make sure you do not leave out anything.
|
|
35
|
+
|
|
36
|
+
When consolidating observations:
|
|
37
|
+
- Preserve and include dates/times when present (temporal context is critical)
|
|
38
|
+
- Combine related items where it makes sense
|
|
39
|
+
- Condense older observations more aggressively, retain more detail for recent ones
|
|
40
|
+
|
|
41
|
+
CRITICAL: USER ASSERTIONS vs QUESTIONS
|
|
42
|
+
- "User stated: X" = authoritative assertion
|
|
43
|
+
- "User asked: X" = question/request
|
|
44
|
+
|
|
45
|
+
When consolidating, USER ASSERTIONS TAKE PRECEDENCE.
|
|
46
|
+
|
|
47
|
+
=== OUTPUT FORMAT ===
|
|
48
|
+
|
|
49
|
+
Your output MUST use XML tags to structure the response:
|
|
50
|
+
|
|
51
|
+
<observations>
|
|
52
|
+
Put all consolidated observations here using the date-grouped format with priority emojis.
|
|
53
|
+
</observations>
|
|
54
|
+
|
|
55
|
+
<current-task>
|
|
56
|
+
State the current task(s) explicitly.
|
|
57
|
+
</current-task>
|
|
58
|
+
|
|
59
|
+
<suggested-response>
|
|
60
|
+
Hint for the agent's immediate next message.
|
|
61
|
+
</suggested-response>${instruction ? `\n\n=== CUSTOM INSTRUCTIONS ===\n\n${instruction}` : ""}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Default Reflector system prompt
|
|
65
|
+
*/
|
|
66
|
+
export const REFLECTOR_SYSTEM_PROMPT = buildReflectorSystemPrompt();
|
|
67
|
+
/**
|
|
68
|
+
* Compression guidance by level
|
|
69
|
+
*/
|
|
70
|
+
export const COMPRESSION_GUIDANCE = {
|
|
71
|
+
0: "",
|
|
72
|
+
1: `
|
|
73
|
+
## COMPRESSION REQUIRED
|
|
74
|
+
|
|
75
|
+
Your previous reflection was the same size or larger than the original observations.
|
|
76
|
+
|
|
77
|
+
Please re-process with slightly more compression:
|
|
78
|
+
- Towards the beginning, condense more observations into higher-level reflections
|
|
79
|
+
- Closer to the end, retain more fine details (recent context matters more)
|
|
80
|
+
- Combine related items more aggressively but do not lose important details
|
|
81
|
+
|
|
82
|
+
Your current detail level was a 10/10, lets aim for a 8/10 detail level.
|
|
83
|
+
`,
|
|
84
|
+
2: `
|
|
85
|
+
## AGGRESSIVE COMPRESSION REQUIRED
|
|
86
|
+
|
|
87
|
+
Your previous reflection was still too large after compression guidance.
|
|
88
|
+
|
|
89
|
+
Please re-process with much more aggressive compression:
|
|
90
|
+
- Towards the beginning, heavily condense observations into high-level summaries
|
|
91
|
+
- Closer to the end, retain fine details
|
|
92
|
+
- Combine related items aggressively
|
|
93
|
+
- Remove redundant information and merge overlapping observations
|
|
94
|
+
|
|
95
|
+
Your current detail level was a 10/10, lets aim for a 6/10 detail level.
|
|
96
|
+
`,
|
|
97
|
+
3: `
|
|
98
|
+
## CRITICAL COMPRESSION REQUIRED
|
|
99
|
+
|
|
100
|
+
Your previous reflections have failed to compress sufficiently after multiple attempts.
|
|
101
|
+
|
|
102
|
+
Please re-process with maximum compression:
|
|
103
|
+
- Summarize the oldest observations into brief high-level paragraphs
|
|
104
|
+
- For the most recent observations, retain important details but still use condensed style
|
|
105
|
+
- Ruthlessly merge related observations
|
|
106
|
+
- Drop procedural details, keep only final outcomes
|
|
107
|
+
- Preserve: names, dates, decisions, errors, user preferences
|
|
108
|
+
|
|
109
|
+
Your current detail level was a 10/10, lets aim for a 4/10 detail level.
|
|
110
|
+
`,
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Build the Reflector prompt
|
|
114
|
+
*/
|
|
115
|
+
export function buildReflectorPrompt(observations, manualPrompt, compressionLevel, skipContinuationHints) {
|
|
116
|
+
const level = typeof compressionLevel === "number" ? compressionLevel : compressionLevel ? 1 : 0;
|
|
117
|
+
let prompt = `## OBSERVATIONS TO REFLECT ON
|
|
118
|
+
|
|
119
|
+
${observations}
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
Please analyze these observations and produce a refined, condensed version that will become the assistant's entire memory going forward.`;
|
|
124
|
+
if (manualPrompt) {
|
|
125
|
+
prompt += `
|
|
126
|
+
|
|
127
|
+
## SPECIFIC GUIDANCE
|
|
128
|
+
|
|
129
|
+
${manualPrompt}`;
|
|
130
|
+
}
|
|
131
|
+
const guidance = COMPRESSION_GUIDANCE[level];
|
|
132
|
+
if (guidance) {
|
|
133
|
+
prompt += `
|
|
134
|
+
|
|
135
|
+
${guidance}`;
|
|
136
|
+
}
|
|
137
|
+
if (skipContinuationHints) {
|
|
138
|
+
prompt += `\n\nIMPORTANT: Do NOT include <current-task> or <suggested-response> sections. Only output <observations>.`;
|
|
139
|
+
}
|
|
140
|
+
return prompt;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Parse Reflector output
|
|
144
|
+
*/
|
|
145
|
+
export function parseReflectorOutput(output) {
|
|
146
|
+
// Check for degenerate repetition
|
|
147
|
+
if (detectDegenerateRepetition(output)) {
|
|
148
|
+
return {
|
|
149
|
+
observations: "",
|
|
150
|
+
degenerate: true,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const parsed = parseReflectorSectionXml(output);
|
|
154
|
+
const observations = sanitizeObservationLines(parsed.observations || "");
|
|
155
|
+
return {
|
|
156
|
+
observations,
|
|
157
|
+
suggestedContinuation: parsed.suggestedResponse || undefined,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Parse XML tags from reflector output
|
|
162
|
+
*/
|
|
163
|
+
function parseReflectorSectionXml(content) {
|
|
164
|
+
const result = {
|
|
165
|
+
observations: "",
|
|
166
|
+
currentTask: "",
|
|
167
|
+
suggestedResponse: "",
|
|
168
|
+
};
|
|
169
|
+
// Extract <observations> content
|
|
170
|
+
const observationsRegex = /^[ \t]*<observations>([\s\S]*?)^[ \t]*<\/observations>/gim;
|
|
171
|
+
const observationsMatches = [...content.matchAll(observationsRegex)];
|
|
172
|
+
if (observationsMatches.length > 0) {
|
|
173
|
+
result.observations = observationsMatches
|
|
174
|
+
.map(m => m[1]?.trim() ?? "")
|
|
175
|
+
.filter(Boolean)
|
|
176
|
+
.join("\n");
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const listItems = extractReflectorListItems(content);
|
|
180
|
+
result.observations = listItems || content.trim();
|
|
181
|
+
}
|
|
182
|
+
// Extract <current-task> content
|
|
183
|
+
const currentTaskMatch = content.match(/<current-task>([\s\S]*?)<\/current-task>/i);
|
|
184
|
+
if (currentTaskMatch?.[1]) {
|
|
185
|
+
result.currentTask = currentTaskMatch[1].trim();
|
|
186
|
+
}
|
|
187
|
+
// Extract <suggested-response> content
|
|
188
|
+
const suggestedResponseMatch = content.match(/<suggested-response>([\s\S]*?)<\/suggested-response>/i);
|
|
189
|
+
if (suggestedResponseMatch?.[1]) {
|
|
190
|
+
result.suggestedResponse = suggestedResponseMatch[1].trim();
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Extract only list items from content
|
|
196
|
+
*/
|
|
197
|
+
function extractReflectorListItems(content) {
|
|
198
|
+
const lines = content.split("\n");
|
|
199
|
+
const listLines = [];
|
|
200
|
+
for (const line of lines) {
|
|
201
|
+
if (/^\s*[-*]\s/.test(line) || /^\s*\d+\.\s/.test(line)) {
|
|
202
|
+
listLines.push(line);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return listLines.join("\n").trim();
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Validate that reflection compressed below target threshold
|
|
209
|
+
*/
|
|
210
|
+
export function validateCompression(reflectedTokens, targetThreshold) {
|
|
211
|
+
return reflectedTokens < targetThreshold;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=reflector-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflector-agent.js","sourceRoot":"","sources":["../../../../src/memory/processors/observational-memory/reflector-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Counter Utility
|
|
3
|
+
* Based on Mastra TokenCounter
|
|
4
|
+
*/
|
|
5
|
+
import type { CoreMessage } from "../../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Simple token counter using character-based estimation.
|
|
8
|
+
* For production, integrate with js-tiktoken for accurate counting.
|
|
9
|
+
*/
|
|
10
|
+
export declare class TokenCounter {
|
|
11
|
+
private static readonly CHARS_PER_TOKEN;
|
|
12
|
+
private static readonly TOKENS_PER_MESSAGE;
|
|
13
|
+
private static readonly TOKENS_PER_CONVERSATION;
|
|
14
|
+
/**
|
|
15
|
+
* Count tokens in a plain string
|
|
16
|
+
*/
|
|
17
|
+
countString(text: string): number;
|
|
18
|
+
/**
|
|
19
|
+
* Count tokens in a single message
|
|
20
|
+
*/
|
|
21
|
+
countMessage(message: CoreMessage): number;
|
|
22
|
+
/**
|
|
23
|
+
* Count tokens in an array of messages
|
|
24
|
+
*/
|
|
25
|
+
countMessages(messages: CoreMessage[]): number;
|
|
26
|
+
/**
|
|
27
|
+
* Count tokens in observations string
|
|
28
|
+
*/
|
|
29
|
+
countObservations(observations: string): number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a default token counter instance
|
|
33
|
+
*/
|
|
34
|
+
export declare function createTokenCounter(): TokenCounter;
|
|
35
|
+
//# sourceMappingURL=token-counter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-counter.d.ts","sourceRoot":"","sources":["../../../../src/memory/processors/observational-memory/token-counter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,gBAAgB,CAAC;AAEpE;;;GAGG;AACH,qBAAa,YAAY;IAEvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAK;IAG5C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAGjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IAErD;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOjC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM;IAoC1C;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM;IAU9C;;OAEG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;CAGhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD"}
|