sensorium-mcp 2.16.97 → 2.16.98
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/data/memory/index.d.ts +4 -0
- package/dist/data/memory/index.d.ts.map +1 -1
- package/dist/data/memory/index.js +4 -0
- package/dist/data/memory/index.js.map +1 -1
- package/dist/data/memory/reflection.d.ts +37 -0
- package/dist/data/memory/reflection.d.ts.map +1 -0
- package/dist/data/memory/reflection.js +407 -0
- package/dist/data/memory/reflection.js.map +1 -0
- package/dist/tools/wait/drive-handler.d.ts.map +1 -1
- package/dist/tools/wait/drive-handler.js +24 -5
- package/dist/tools/wait/drive-handler.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* All memory modules are re-exported here so consumers can import from
|
|
5
5
|
* a single path: `./data/memory/index.js`.
|
|
6
|
+
*
|
|
7
|
+
* Modules: utils, schema, episodes, semantic, procedures, voice-sig,
|
|
8
|
+
* consolidation, reflection (causal/pattern/counterfactual insights), bootstrap.
|
|
6
9
|
*/
|
|
7
10
|
export * from './utils.js';
|
|
8
11
|
export * from './schema.js';
|
|
@@ -11,5 +14,6 @@ export * from './semantic.js';
|
|
|
11
14
|
export * from './procedures.js';
|
|
12
15
|
export * from './voice-sig.js';
|
|
13
16
|
export * from './consolidation.js';
|
|
17
|
+
export * from './reflection.js';
|
|
14
18
|
export * from './bootstrap.js';
|
|
15
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* All memory modules are re-exported here so consumers can import from
|
|
5
5
|
* a single path: `./data/memory/index.js`.
|
|
6
|
+
*
|
|
7
|
+
* Modules: utils, schema, episodes, semantic, procedures, voice-sig,
|
|
8
|
+
* consolidation, reflection (causal/pattern/counterfactual insights), bootstrap.
|
|
6
9
|
*/
|
|
7
10
|
export * from './utils.js';
|
|
8
11
|
export * from './schema.js';
|
|
@@ -11,5 +14,6 @@ export * from './semantic.js';
|
|
|
11
14
|
export * from './procedures.js';
|
|
12
15
|
export * from './voice-sig.js';
|
|
13
16
|
export * from './consolidation.js';
|
|
17
|
+
export * from './reflection.js';
|
|
14
18
|
export * from './bootstrap.js';
|
|
15
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflection pipeline — the "dreaming" phase that generates deeper insights
|
|
3
|
+
* from episodic memories after consolidation.
|
|
4
|
+
*
|
|
5
|
+
* Unlike consolidation (which extracts facts and preferences), reflection
|
|
6
|
+
* finds causal chains, recurring patterns, counterfactuals, and
|
|
7
|
+
* self-assessments across episodes. It runs post-consolidation when
|
|
8
|
+
* enough episodes exist, rate-limited to once per 4 hours.
|
|
9
|
+
*/
|
|
10
|
+
import type { Database } from "./schema.js";
|
|
11
|
+
export interface ReflectionInsight {
|
|
12
|
+
type: "causal" | "pattern" | "self_assessment" | "counterfactual";
|
|
13
|
+
content: string;
|
|
14
|
+
confidence: number;
|
|
15
|
+
relatedEpisodeIds: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface ReflectionResult {
|
|
18
|
+
insights: ReflectionInsight[];
|
|
19
|
+
processedEpisodeCount: number;
|
|
20
|
+
duration: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Run the reflection pipeline on recent consolidated episodes.
|
|
24
|
+
* Generates deeper insights beyond simple fact/preference extraction.
|
|
25
|
+
*
|
|
26
|
+
* Pipeline:
|
|
27
|
+
* 1. Gate check — enough episodes, rate limit, API key present
|
|
28
|
+
* 2. Gather episodes — recent + random sample of older ones
|
|
29
|
+
* 3. Build a narrative from episode content
|
|
30
|
+
* 4. Send to OpenAI with the reflection prompt
|
|
31
|
+
* 5. Parse insights, de-duplicate, and save as semantic notes
|
|
32
|
+
*/
|
|
33
|
+
export declare function runReflection(db: Database, threadId: number, options?: {
|
|
34
|
+
maxEpisodes?: number;
|
|
35
|
+
includeOldSample?: boolean;
|
|
36
|
+
}): Promise<ReflectionResult>;
|
|
37
|
+
//# sourceMappingURL=reflection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.d.ts","sourceRoot":"","sources":["../../../src/data/memory/reflection.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAc5C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8ND;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D,OAAO,CAAC,gBAAgB,CAAC,CAkJ3B"}
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reflection pipeline — the "dreaming" phase that generates deeper insights
|
|
3
|
+
* from episodic memories after consolidation.
|
|
4
|
+
*
|
|
5
|
+
* Unlike consolidation (which extracts facts and preferences), reflection
|
|
6
|
+
* finds causal chains, recurring patterns, counterfactuals, and
|
|
7
|
+
* self-assessments across episodes. It runs post-consolidation when
|
|
8
|
+
* enough episodes exist, rate-limited to once per 4 hours.
|
|
9
|
+
*/
|
|
10
|
+
import { saveSemanticNote, searchByEmbedding, saveNoteEmbedding } from "./semantic.js";
|
|
11
|
+
import { nowISO } from "./utils.js";
|
|
12
|
+
import { log } from "../../logger.js";
|
|
13
|
+
import { chatCompletion, generateEmbedding, } from "../../integrations/openai/chat.js";
|
|
14
|
+
// ─── Rate-limiting ───────────────────────────────────────────────────────────
|
|
15
|
+
const REFLECTION_COOLDOWN_MS = 4 * 60 * 60 * 1000; // 4 hours
|
|
16
|
+
const MIN_EPISODES_FOR_REFLECTION = 20;
|
|
17
|
+
/** Per-thread timestamp of the last successful reflection run. */
|
|
18
|
+
const lastReflectionAt = new Map();
|
|
19
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
20
|
+
/** Extract text from an episode's content object. */
|
|
21
|
+
function episodeText(ep) {
|
|
22
|
+
const c = ep.content;
|
|
23
|
+
if (typeof c === "string")
|
|
24
|
+
return c;
|
|
25
|
+
return c.text ?? c.caption ?? JSON.stringify(c);
|
|
26
|
+
}
|
|
27
|
+
/** Build a time-ordered narrative from a list of episodes. */
|
|
28
|
+
function buildNarrative(episodes) {
|
|
29
|
+
return episodes
|
|
30
|
+
.sort((a, b) => a.timestamp.localeCompare(b.timestamp))
|
|
31
|
+
.map((ep) => `[${ep.episodeId}] (${ep.type}/${ep.modality}, ${ep.timestamp}) ${episodeText(ep)}`)
|
|
32
|
+
.join("\n");
|
|
33
|
+
}
|
|
34
|
+
/** Gather consolidated episodes: last N recent + random sample of older ones. */
|
|
35
|
+
function gatherEpisodes(db, threadId, maxRecent, oldSampleSize) {
|
|
36
|
+
// Recent consolidated episodes
|
|
37
|
+
const recentRows = db
|
|
38
|
+
.prepare(`SELECT * FROM episodes
|
|
39
|
+
WHERE thread_id = ? AND consolidated = 1
|
|
40
|
+
ORDER BY timestamp DESC
|
|
41
|
+
LIMIT ?`)
|
|
42
|
+
.all(threadId, maxRecent);
|
|
43
|
+
const recentIds = new Set(recentRows.map((r) => r.episode_id));
|
|
44
|
+
// Random sample of older consolidated episodes from the past 7 days
|
|
45
|
+
// (excluding the ones already in the recent set)
|
|
46
|
+
const olderRows = db
|
|
47
|
+
.prepare(`SELECT * FROM episodes
|
|
48
|
+
WHERE thread_id = ? AND consolidated = 1
|
|
49
|
+
AND timestamp >= datetime('now', '-7 days')
|
|
50
|
+
ORDER BY RANDOM()
|
|
51
|
+
LIMIT ?`)
|
|
52
|
+
.all(threadId, oldSampleSize + recentRows.length);
|
|
53
|
+
const olderFiltered = olderRows
|
|
54
|
+
.filter((r) => !recentIds.has(r.episode_id))
|
|
55
|
+
.slice(0, oldSampleSize);
|
|
56
|
+
const allRows = [...recentRows, ...olderFiltered];
|
|
57
|
+
return allRows.map(rowToEpisode);
|
|
58
|
+
}
|
|
59
|
+
/** Map a raw DB row to an Episode (mirrors episodes.ts but avoids circular import). */
|
|
60
|
+
function rowToEpisode(row) {
|
|
61
|
+
return {
|
|
62
|
+
episodeId: row.episode_id,
|
|
63
|
+
sessionId: row.session_id,
|
|
64
|
+
threadId: row.thread_id,
|
|
65
|
+
timestamp: row.timestamp,
|
|
66
|
+
type: row.type,
|
|
67
|
+
modality: row.modality,
|
|
68
|
+
content: safeParseJson(row.content),
|
|
69
|
+
topicTags: safeParseArray(row.topic_tags),
|
|
70
|
+
importance: row.importance,
|
|
71
|
+
consolidated: row.consolidated === 1,
|
|
72
|
+
accessedCount: row.accessed_count,
|
|
73
|
+
lastAccessed: row.last_accessed ?? null,
|
|
74
|
+
createdAt: row.created_at,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function safeParseJson(val) {
|
|
78
|
+
if (!val)
|
|
79
|
+
return {};
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(val);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return {};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function safeParseArray(val) {
|
|
88
|
+
if (!val)
|
|
89
|
+
return [];
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(val);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// ─── JSON repair (minimal — shared pattern with consolidation.ts) ────────────
|
|
98
|
+
/** Return true if the character at `pos` is preceded by an odd number of backslashes (i.e. it is escaped). */
|
|
99
|
+
function isEscaped(text, pos) {
|
|
100
|
+
let count = 0;
|
|
101
|
+
let i = pos - 1;
|
|
102
|
+
while (i >= 0 && text[i] === "\\") {
|
|
103
|
+
count++;
|
|
104
|
+
i--;
|
|
105
|
+
}
|
|
106
|
+
return count % 2 !== 0;
|
|
107
|
+
}
|
|
108
|
+
function repairAndParseJSON(raw) {
|
|
109
|
+
try {
|
|
110
|
+
return JSON.parse(raw);
|
|
111
|
+
}
|
|
112
|
+
catch { /* continue */ }
|
|
113
|
+
let text = raw.trim();
|
|
114
|
+
// Strip markdown fences
|
|
115
|
+
if (text.startsWith("```")) {
|
|
116
|
+
text = text.replace(/^```(?:json)?\s*\n?/, "").replace(/\n?```\s*$/, "");
|
|
117
|
+
try {
|
|
118
|
+
return JSON.parse(text);
|
|
119
|
+
}
|
|
120
|
+
catch { /* continue */ }
|
|
121
|
+
}
|
|
122
|
+
// Fix unescaped control characters inside strings
|
|
123
|
+
const chars = [];
|
|
124
|
+
let inStr = false;
|
|
125
|
+
for (let i = 0; i < text.length; i++) {
|
|
126
|
+
const ch = text[i];
|
|
127
|
+
if (ch === '"' && !isEscaped(text, i)) {
|
|
128
|
+
inStr = !inStr;
|
|
129
|
+
chars.push(ch);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (inStr) {
|
|
133
|
+
if (ch === "\n") {
|
|
134
|
+
chars.push("\\n");
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (ch === "\r") {
|
|
138
|
+
chars.push("\\r");
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (ch === "\t") {
|
|
142
|
+
chars.push("\\t");
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
chars.push(ch);
|
|
147
|
+
}
|
|
148
|
+
text = chars.join("");
|
|
149
|
+
try {
|
|
150
|
+
return JSON.parse(text);
|
|
151
|
+
}
|
|
152
|
+
catch { /* continue */ }
|
|
153
|
+
// Close truncated structures
|
|
154
|
+
let quoteCount = 0;
|
|
155
|
+
for (let i = 0; i < text.length; i++) {
|
|
156
|
+
if (text[i] === '"' && !isEscaped(text, i))
|
|
157
|
+
quoteCount++;
|
|
158
|
+
}
|
|
159
|
+
if (quoteCount % 2 !== 0)
|
|
160
|
+
text += '"';
|
|
161
|
+
text = text.replace(/,\s*"[^"]*"\s*:\s*$/, "");
|
|
162
|
+
text = text.replace(/,\s*$/, "");
|
|
163
|
+
const opens = [];
|
|
164
|
+
let scanning = false;
|
|
165
|
+
for (let i = 0; i < text.length; i++) {
|
|
166
|
+
const c = text[i];
|
|
167
|
+
if (c === '"' && !isEscaped(text, i)) {
|
|
168
|
+
scanning = !scanning;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (scanning)
|
|
172
|
+
continue;
|
|
173
|
+
if (c === "{" || c === "[")
|
|
174
|
+
opens.push(c);
|
|
175
|
+
else if (c === "}" || c === "]")
|
|
176
|
+
opens.pop();
|
|
177
|
+
}
|
|
178
|
+
for (let i = opens.length - 1; i >= 0; i--) {
|
|
179
|
+
text += opens[i] === "{" ? "}" : "]";
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
return JSON.parse(text);
|
|
183
|
+
}
|
|
184
|
+
catch { /* continue */ }
|
|
185
|
+
throw new SyntaxError(`Unable to repair reflection JSON (length=${raw.length}): ${raw.slice(0, 200)}…`);
|
|
186
|
+
}
|
|
187
|
+
// ─── Prompt ──────────────────────────────────────────────────────────────────
|
|
188
|
+
const REFLECTION_SYSTEM_PROMPT = `You are a reflective reasoning system analyzing an agent's recent experiences. Your job is to extract DEEP insights — not surface-level summaries.
|
|
189
|
+
|
|
190
|
+
## Analysis tasks:
|
|
191
|
+
|
|
192
|
+
1. CAUSAL CHAINS: What caused what? Find cause-effect relationships. "When [X happened], it led to [Y] because [Z]." Be specific — cite episode IDs.
|
|
193
|
+
|
|
194
|
+
2. RECURRING PATTERNS: What behaviors, problems, or situations keep repeating? "The operator tends to [X] when [Y]." or "The agent fails at [X] in [Y] conditions."
|
|
195
|
+
|
|
196
|
+
3. COUNTERFACTUALS: For any negative outcomes or frustrations, what could have been done differently? "Instead of [X], the agent could have [Y], which would have [Z]."
|
|
197
|
+
|
|
198
|
+
4. SELF-ASSESSMENT: What does the agent do well? What are its weaknesses? "The agent is strong at [X] but struggles with [Y]."
|
|
199
|
+
|
|
200
|
+
Respond in JSON format:
|
|
201
|
+
{
|
|
202
|
+
"insights": [
|
|
203
|
+
{
|
|
204
|
+
"type": "causal" | "pattern" | "self_assessment" | "counterfactual",
|
|
205
|
+
"content": "Specific, actionable insight with references to specific events",
|
|
206
|
+
"confidence": 0.0-1.0,
|
|
207
|
+
"episode_refs": ["ep_xxx", "ep_yyy"]
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Rules:
|
|
213
|
+
- Minimum 3, maximum 10 insights
|
|
214
|
+
- Each insight must reference specific episodes by their ID
|
|
215
|
+
- Avoid generic statements — be specific to the actual events
|
|
216
|
+
- Confidence should reflect how well-supported the insight is by evidence
|
|
217
|
+
- Causal and pattern insights are most valuable`;
|
|
218
|
+
// ─── De-duplication ──────────────────────────────────────────────────────────
|
|
219
|
+
const DEDUP_SIMILARITY_THRESHOLD = 0.85;
|
|
220
|
+
async function checkDuplicate(db, content, apiKey, threadId) {
|
|
221
|
+
try {
|
|
222
|
+
const embedding = await generateEmbedding(content, apiKey);
|
|
223
|
+
const matches = searchByEmbedding(db, embedding, {
|
|
224
|
+
maxResults: 3,
|
|
225
|
+
minSimilarity: DEDUP_SIMILARITY_THRESHOLD,
|
|
226
|
+
skipAccessTracking: true,
|
|
227
|
+
threadId,
|
|
228
|
+
});
|
|
229
|
+
const isDuplicate = matches.some((m) => m.similarity >= DEDUP_SIMILARITY_THRESHOLD && m.content.startsWith("[REFLECTION]"));
|
|
230
|
+
return { isDuplicate, embedding };
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// Embedding lookup failed — allow the insight through to avoid data loss
|
|
234
|
+
return { isDuplicate: false, embedding: null };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// ─── Core Pipeline ───────────────────────────────────────────────────────────
|
|
238
|
+
/**
|
|
239
|
+
* Run the reflection pipeline on recent consolidated episodes.
|
|
240
|
+
* Generates deeper insights beyond simple fact/preference extraction.
|
|
241
|
+
*
|
|
242
|
+
* Pipeline:
|
|
243
|
+
* 1. Gate check — enough episodes, rate limit, API key present
|
|
244
|
+
* 2. Gather episodes — recent + random sample of older ones
|
|
245
|
+
* 3. Build a narrative from episode content
|
|
246
|
+
* 4. Send to OpenAI with the reflection prompt
|
|
247
|
+
* 5. Parse insights, de-duplicate, and save as semantic notes
|
|
248
|
+
*/
|
|
249
|
+
export async function runReflection(db, threadId, options) {
|
|
250
|
+
const startMs = Date.now();
|
|
251
|
+
const maxRecent = options?.maxEpisodes ?? 30;
|
|
252
|
+
const oldSampleSize = options?.includeOldSample !== false ? 10 : 0;
|
|
253
|
+
// ── Gate: rate limit ──────────────────────────────────────────────────────
|
|
254
|
+
const lastRun = lastReflectionAt.get(threadId) ?? 0;
|
|
255
|
+
if (Date.now() - lastRun < REFLECTION_COOLDOWN_MS) {
|
|
256
|
+
log.info("[reflection] Skipped — cooldown not elapsed");
|
|
257
|
+
return { insights: [], processedEpisodeCount: 0, duration: Date.now() - startMs };
|
|
258
|
+
}
|
|
259
|
+
// ── Gate: environment ─────────────────────────────────────────────────────
|
|
260
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
261
|
+
if (!apiKey) {
|
|
262
|
+
log.warn("[reflection] Skipped — OPENAI_API_KEY not set");
|
|
263
|
+
return { insights: [], processedEpisodeCount: 0, duration: Date.now() - startMs };
|
|
264
|
+
}
|
|
265
|
+
const reflectionEnabled = process.env.REFLECTION_ENABLED;
|
|
266
|
+
if (reflectionEnabled === "false" || reflectionEnabled === "0") {
|
|
267
|
+
return { insights: [], processedEpisodeCount: 0, duration: Date.now() - startMs };
|
|
268
|
+
}
|
|
269
|
+
// ── Gate: episode count ───────────────────────────────────────────────────
|
|
270
|
+
const countRow = db
|
|
271
|
+
.prepare("SELECT COUNT(*) as c FROM episodes WHERE thread_id = ? AND consolidated = 1")
|
|
272
|
+
.get(threadId);
|
|
273
|
+
if (countRow.c < MIN_EPISODES_FOR_REFLECTION) {
|
|
274
|
+
log.info(`[reflection] Skipped — only ${countRow.c} consolidated episodes (need ${MIN_EPISODES_FOR_REFLECTION})`);
|
|
275
|
+
return { insights: [], processedEpisodeCount: 0, duration: Date.now() - startMs };
|
|
276
|
+
}
|
|
277
|
+
// ── Step 1: Gather episodes ───────────────────────────────────────────────
|
|
278
|
+
const episodes = gatherEpisodes(db, threadId, maxRecent, oldSampleSize);
|
|
279
|
+
if (episodes.length === 0) {
|
|
280
|
+
return { insights: [], processedEpisodeCount: 0, duration: Date.now() - startMs };
|
|
281
|
+
}
|
|
282
|
+
// ── Step 2: Build narrative ───────────────────────────────────────────────
|
|
283
|
+
const narrative = buildNarrative(episodes);
|
|
284
|
+
// ── Step 3: LLM call ─────────────────────────────────────────────────────
|
|
285
|
+
const messages = [
|
|
286
|
+
{ role: "system", content: REFLECTION_SYSTEM_PROMPT },
|
|
287
|
+
{ role: "user", content: `## Episodes to reflect on:\n${narrative}\n\nAnalyze the episodes above and produce deep reflective insights.` },
|
|
288
|
+
];
|
|
289
|
+
let raw;
|
|
290
|
+
try {
|
|
291
|
+
raw = await chatCompletion(messages, apiKey, {
|
|
292
|
+
model: process.env.REFLECTION_MODEL ?? process.env.CONSOLIDATION_MODEL ?? "gpt-4o-mini",
|
|
293
|
+
maxTokens: 4096,
|
|
294
|
+
temperature: 0.4, // slightly creative for deeper reasoning
|
|
295
|
+
responseFormat: { type: "json_object" },
|
|
296
|
+
timeoutMs: 90_000,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
301
|
+
log.error(`[reflection] LLM call failed: ${msg}`);
|
|
302
|
+
return { insights: [], processedEpisodeCount: episodes.length, duration: Date.now() - startMs };
|
|
303
|
+
}
|
|
304
|
+
// ── Step 4: Parse response ────────────────────────────────────────────────
|
|
305
|
+
let parsed;
|
|
306
|
+
try {
|
|
307
|
+
parsed = repairAndParseJSON(raw);
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
log.error(`[reflection] JSON parse failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
311
|
+
return { insights: [], processedEpisodeCount: episodes.length, duration: Date.now() - startMs };
|
|
312
|
+
}
|
|
313
|
+
const rawInsights = parsed.insights ?? [];
|
|
314
|
+
const validTypes = new Set(["causal", "pattern", "self_assessment", "counterfactual"]);
|
|
315
|
+
// ── Step 5: Save insights ─────────────────────────────────────────────────
|
|
316
|
+
const savedInsights = [];
|
|
317
|
+
const episodeIdSet = new Set(episodes.map((e) => e.episodeId));
|
|
318
|
+
for (const ins of rawInsights) {
|
|
319
|
+
if (!ins.content || typeof ins.content !== "string")
|
|
320
|
+
continue;
|
|
321
|
+
const insightType = validTypes.has(ins.type) ? ins.type : "pattern";
|
|
322
|
+
const confidence = Math.max(0, Math.min(1, ins.confidence ?? 0.5));
|
|
323
|
+
const refs = (ins.episode_refs ?? []).filter((id) => typeof id === "string" && episodeIdSet.has(id));
|
|
324
|
+
// De-duplicate against existing reflections (embedding is cached for reuse)
|
|
325
|
+
const prefixedContent = `[REFLECTION] [${insightType.toUpperCase()}] ${ins.content}`;
|
|
326
|
+
const { isDuplicate: duplicate, embedding: cachedEmbedding } = await checkDuplicate(db, prefixedContent, apiKey, threadId);
|
|
327
|
+
if (duplicate) {
|
|
328
|
+
log.info(`[reflection] Skipped duplicate insight: ${ins.content.slice(0, 60)}…`);
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// Generate keywords from content
|
|
332
|
+
const keywords = extractKeywords(ins.content);
|
|
333
|
+
// Save as a semantic note of type "pattern" (reflection insights are patterns)
|
|
334
|
+
const noteId = saveSemanticNote(db, {
|
|
335
|
+
type: "pattern",
|
|
336
|
+
content: prefixedContent,
|
|
337
|
+
keywords: ["reflection", insightType, ...keywords],
|
|
338
|
+
confidence,
|
|
339
|
+
priority: confidence >= 0.8 ? 1 : 0,
|
|
340
|
+
threadId,
|
|
341
|
+
sourceEpisodes: refs,
|
|
342
|
+
});
|
|
343
|
+
// Reuse the embedding from dedup check — avoids a second API call
|
|
344
|
+
if (cachedEmbedding) {
|
|
345
|
+
saveNoteEmbedding(db, noteId, cachedEmbedding);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
try {
|
|
349
|
+
const embedding = await generateEmbedding(prefixedContent, apiKey);
|
|
350
|
+
saveNoteEmbedding(db, noteId, embedding);
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Non-fatal — backfill will catch it later
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
savedInsights.push({
|
|
357
|
+
type: insightType,
|
|
358
|
+
content: ins.content,
|
|
359
|
+
confidence,
|
|
360
|
+
relatedEpisodeIds: refs,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
// ── Log result ────────────────────────────────────────────────────────────
|
|
364
|
+
logReflection(db, {
|
|
365
|
+
episodesProcessed: episodes.length,
|
|
366
|
+
insightsCreated: savedInsights.length,
|
|
367
|
+
durationMs: Date.now() - startMs,
|
|
368
|
+
});
|
|
369
|
+
lastReflectionAt.set(threadId, Date.now());
|
|
370
|
+
log.info(`[reflection] Completed: ${episodes.length} episodes → ${savedInsights.length} insights (${Date.now() - startMs}ms)`);
|
|
371
|
+
return {
|
|
372
|
+
insights: savedInsights,
|
|
373
|
+
processedEpisodeCount: episodes.length,
|
|
374
|
+
duration: Date.now() - startMs,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
// ─── Keyword extraction ──────────────────────────────────────────────────────
|
|
378
|
+
const STOP_WORDS = new Set([
|
|
379
|
+
"this", "that", "with", "from", "have", "been", "will", "would", "could",
|
|
380
|
+
"should", "about", "there", "their", "which", "when", "what", "were",
|
|
381
|
+
"they", "than", "then", "also", "just", "more", "some", "into", "over",
|
|
382
|
+
"after", "before", "other", "very", "your", "here", "does", "because",
|
|
383
|
+
"instead", "agent", "operator", "the", "and", "for", "are", "but", "not",
|
|
384
|
+
"you", "all", "can", "had", "her", "was", "one", "our", "out",
|
|
385
|
+
]);
|
|
386
|
+
/** Extract up to 5 meaningful keywords from free-text content. */
|
|
387
|
+
function extractKeywords(text) {
|
|
388
|
+
const words = text
|
|
389
|
+
.toLowerCase()
|
|
390
|
+
.replace(/[^a-z0-9\s]/g, " ")
|
|
391
|
+
.split(/\s+/)
|
|
392
|
+
.filter((w) => w.length > 3 && !STOP_WORDS.has(w));
|
|
393
|
+
const freq = new Map();
|
|
394
|
+
for (const w of words)
|
|
395
|
+
freq.set(w, (freq.get(w) ?? 0) + 1);
|
|
396
|
+
return [...freq.entries()]
|
|
397
|
+
.sort((a, b) => b[1] - a[1])
|
|
398
|
+
.slice(0, 5)
|
|
399
|
+
.map(([w]) => w);
|
|
400
|
+
}
|
|
401
|
+
// ─── Consolidation log ───────────────────────────────────────────────────────
|
|
402
|
+
function logReflection(db, entry) {
|
|
403
|
+
db.prepare(`INSERT INTO meta_consolidation_log
|
|
404
|
+
(run_at, episodes_processed, notes_created, duration_ms)
|
|
405
|
+
VALUES (?, ?, ?, ?)`).run(nowISO(), entry.episodesProcessed, entry.insightsCreated, entry.durationMs);
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=reflection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reflection.js","sourceRoot":"","sources":["../../../src/data/memory/reflection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drive-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/wait/drive-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,
|
|
1
|
+
{"version":3,"file":"drive-handler.d.ts","sourceRoot":"","sources":["../../../src/tools/wait/drive-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAA8C,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGhG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMjD,UAAU,YAAY;IACpB,KAAK,EAAE;QACL,qBAAqB,EAAE,MAAM,CAAC;QAC9B,mBAAmB,EAAE,MAAM,CAAC;QAC5B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,EAAE,OAAO,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,WAAW,EAAE,MAAM,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACnD,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,EAAE;QACN,oBAAoB,EAAE,MAAM,CAAC;QAC7B,eAAe,EAAE,OAAO,CAAC;KAC1B,CAAC;IACF,uDAAuD;IACvD,aAAa,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;CACtB;AAkDD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAqC5D;AAQD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,UAAU,GAAG,IAAI,CA2CzE"}
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { formatDrivePrompt, PHASE3_APPROVAL_PROMPT } from "../../drive.js";
|
|
9
9
|
import { log } from "../../logger.js";
|
|
10
|
-
import { runIntelligentConsolidation } from "../../memory.js";
|
|
10
|
+
import { runIntelligentConsolidation, runReflection } from "../../memory.js";
|
|
11
11
|
import { getReminders } from "../../response-builders.js";
|
|
12
12
|
import { backfillEmbeddings } from "../memory-tools.js";
|
|
13
|
+
const EPISODE_COUNT_CONSOLIDATION_THRESHOLD = 15;
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// Auto-consolidation (3 strategies)
|
|
15
16
|
// ---------------------------------------------------------------------------
|
|
@@ -24,6 +25,18 @@ function fireConsolidation(db, threadId, label, apiKey) {
|
|
|
24
25
|
log.info(`[memory] ${label} consolidation: ${report.episodesProcessed} episodes \u2192 ${report.notesCreated} notes`);
|
|
25
26
|
}
|
|
26
27
|
await backfillEmbeddings(db, apiKey);
|
|
28
|
+
// Run reflection after consolidation if enough episodes exist
|
|
29
|
+
if (report.episodesProcessed > 0) {
|
|
30
|
+
try {
|
|
31
|
+
const reflectionResult = await runReflection(db, threadId);
|
|
32
|
+
if (reflectionResult.insights.length > 0) {
|
|
33
|
+
log.info(`[memory] ${label} reflection: ${reflectionResult.processedEpisodeCount} episodes → ${reflectionResult.insights.length} insights`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (reflErr) {
|
|
37
|
+
log.warn(`[memory] Reflection failed (non-fatal): ${reflErr instanceof Error ? reflErr.message : String(reflErr)}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
27
40
|
})
|
|
28
41
|
.catch((err) => {
|
|
29
42
|
log.error(`[memory] ${label} consolidation error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -48,7 +61,9 @@ export function runAutoConsolidation(ctx) {
|
|
|
48
61
|
fireConsolidation(getMemoryDb(), effectiveThreadId, "Idle-based", apiKey);
|
|
49
62
|
}
|
|
50
63
|
}
|
|
51
|
-
catch (
|
|
64
|
+
catch (err) {
|
|
65
|
+
log.debug(`[memory] Consolidation check failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
66
|
+
}
|
|
52
67
|
// Strategy 2: Episode-count consolidation — don't wait for idle.
|
|
53
68
|
// If many episodes accumulated during active use, consolidate now.
|
|
54
69
|
// This prevents stale/contradictory knowledge from persisting.
|
|
@@ -56,13 +71,15 @@ export function runAutoConsolidation(ctx) {
|
|
|
56
71
|
if (effectiveThreadId !== undefined && Date.now() - state.lastConsolidationAt > 30 * 60 * 1000) {
|
|
57
72
|
const db = getMemoryDb();
|
|
58
73
|
const uncons = db.prepare("SELECT COUNT(*) as c FROM episodes WHERE consolidated = 0 AND thread_id = ?").get(effectiveThreadId);
|
|
59
|
-
if (uncons.c >=
|
|
74
|
+
if (uncons.c >= EPISODE_COUNT_CONSOLIDATION_THRESHOLD) {
|
|
60
75
|
state.lastConsolidationAt = Date.now();
|
|
61
76
|
fireConsolidation(db, effectiveThreadId, "Episode-count", apiKey);
|
|
62
77
|
}
|
|
63
78
|
}
|
|
64
79
|
}
|
|
65
|
-
catch (
|
|
80
|
+
catch (err) {
|
|
81
|
+
log.debug(`[memory] Consolidation check failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
82
|
+
}
|
|
66
83
|
// Strategy 3: Time-based consolidation — every 4 hours regardless.
|
|
67
84
|
// Ensures stale knowledge gets cleaned up even during low-activity periods.
|
|
68
85
|
try {
|
|
@@ -74,7 +91,9 @@ export function runAutoConsolidation(ctx) {
|
|
|
74
91
|
fireConsolidation(db, effectiveThreadId, "Time-based", apiKey);
|
|
75
92
|
}
|
|
76
93
|
}
|
|
77
|
-
catch (
|
|
94
|
+
catch (err) {
|
|
95
|
+
log.debug(`[memory] Consolidation check failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
96
|
+
}
|
|
78
97
|
}
|
|
79
98
|
// ---------------------------------------------------------------------------
|
|
80
99
|
// 3-Phase Autonomous Drive
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drive-handler.js","sourceRoot":"","sources":["../../../src/tools/wait/drive-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,2BAA2B,EAAqB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"drive-handler.js","sourceRoot":"","sources":["../../../src/tools/wait/drive-handler.ts"],"names":[],"mappings":"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"}
|