@timmeck/brain-core 2.36.79 → 2.36.81
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/browser/browser-agent.d.ts +188 -0
- package/dist/browser/browser-agent.js +787 -0
- package/dist/browser/browser-agent.js.map +1 -0
- package/dist/chat/brain-bot.d.ts +75 -0
- package/dist/chat/brain-bot.js +246 -0
- package/dist/chat/brain-bot.js.map +1 -0
- package/dist/chat/chat-engine.d.ts +3 -0
- package/dist/chat/chat-engine.js +17 -0
- package/dist/chat/chat-engine.js.map +1 -1
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +1 -0
- package/dist/chat/index.js.map +1 -1
- package/dist/debate/debate-engine.js +18 -2
- package/dist/debate/debate-engine.js.map +1 -1
- package/dist/hypothesis/engine.d.ts +34 -0
- package/dist/hypothesis/engine.js +82 -0
- package/dist/hypothesis/engine.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/conversation-memory.d.ts +141 -0
- package/dist/memory/conversation-memory.js +470 -0
- package/dist/memory/conversation-memory.js.map +1 -0
- package/dist/research/autonomous-research-loop.d.ts +104 -0
- package/dist/research/autonomous-research-loop.js +246 -0
- package/dist/research/autonomous-research-loop.js.map +1 -0
- package/dist/research/research-orchestrator.d.ts +3 -0
- package/dist/research/research-orchestrator.js +28 -0
- package/dist/research/research-orchestrator.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { ThoughtStream } from '../consciousness/thought-stream.js';
|
|
3
|
+
import type { ResearchJournal } from './journal.js';
|
|
4
|
+
export interface AutonomousResearchConfig {
|
|
5
|
+
/** Max autonomous missions per day. Default: 5 */
|
|
6
|
+
maxMissionsPerDay?: number;
|
|
7
|
+
/** Cooldown between research cycles in ms. Default: 30min */
|
|
8
|
+
cycleCooldownMs?: number;
|
|
9
|
+
/** Minimum gap score to trigger research. Default: 0.5 */
|
|
10
|
+
minGapScore?: number;
|
|
11
|
+
/** Minimum desire priority to trigger research. Default: 5 */
|
|
12
|
+
minDesirePriority?: number;
|
|
13
|
+
/** Mission depth for autonomous missions. Default: 'standard' */
|
|
14
|
+
missionDepth?: 'quick' | 'standard' | 'deep';
|
|
15
|
+
/** Enable/disable the loop. Default: false (opt-in) */
|
|
16
|
+
enabled?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface AutonomousResearchStatus {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
running: boolean;
|
|
21
|
+
cyclesCompleted: number;
|
|
22
|
+
missionsLaunchedToday: number;
|
|
23
|
+
maxMissionsPerDay: number;
|
|
24
|
+
lastCycleAt: number | null;
|
|
25
|
+
nextCycleAt: number | null;
|
|
26
|
+
lastTopic: string | null;
|
|
27
|
+
recentTopics: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface AutonomousResearchResult {
|
|
30
|
+
action: 'mission_launched' | 'skipped_no_target' | 'skipped_budget' | 'skipped_cooldown' | 'skipped_disabled';
|
|
31
|
+
topic?: string;
|
|
32
|
+
missionId?: number;
|
|
33
|
+
reason?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface AutonomousResearchSources {
|
|
36
|
+
getCuriosityGaps?: (limit: number) => Array<{
|
|
37
|
+
topic: string;
|
|
38
|
+
gapScore: number;
|
|
39
|
+
gapType: string;
|
|
40
|
+
questions: string[];
|
|
41
|
+
}>;
|
|
42
|
+
getDesires?: () => Array<{
|
|
43
|
+
key: string;
|
|
44
|
+
suggestion: string;
|
|
45
|
+
priority: number;
|
|
46
|
+
}>;
|
|
47
|
+
createMission?: (topic: string, depth: 'quick' | 'standard' | 'deep') => {
|
|
48
|
+
id?: number;
|
|
49
|
+
topic: string;
|
|
50
|
+
status: string;
|
|
51
|
+
};
|
|
52
|
+
getMissionStatus?: () => {
|
|
53
|
+
activeMissions: number;
|
|
54
|
+
completedMissions: number;
|
|
55
|
+
totalMissions: number;
|
|
56
|
+
};
|
|
57
|
+
observeHypothesis?: (obs: {
|
|
58
|
+
source: string;
|
|
59
|
+
type: string;
|
|
60
|
+
value: number;
|
|
61
|
+
timestamp: number;
|
|
62
|
+
}) => void;
|
|
63
|
+
checkBudget?: (engineId: string) => {
|
|
64
|
+
allowed: boolean;
|
|
65
|
+
reason?: string;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export declare function runAutonomousResearchMigration(db: Database.Database): void;
|
|
69
|
+
export declare class AutonomousResearchLoop {
|
|
70
|
+
private readonly db;
|
|
71
|
+
private readonly config;
|
|
72
|
+
private readonly log;
|
|
73
|
+
private ts;
|
|
74
|
+
private journal;
|
|
75
|
+
private sources;
|
|
76
|
+
private timer;
|
|
77
|
+
private cyclesCompleted;
|
|
78
|
+
private lastCycleAt;
|
|
79
|
+
private lastTopic;
|
|
80
|
+
private recentTopics;
|
|
81
|
+
private readonly stmtLogAction;
|
|
82
|
+
private readonly stmtCountToday;
|
|
83
|
+
private readonly stmtRecentTopics;
|
|
84
|
+
constructor(db: Database.Database, config?: AutonomousResearchConfig);
|
|
85
|
+
setThoughtStream(stream: ThoughtStream): void;
|
|
86
|
+
setJournal(journal: ResearchJournal): void;
|
|
87
|
+
setSources(sources: AutonomousResearchSources): void;
|
|
88
|
+
/** Update config at runtime. */
|
|
89
|
+
updateConfig(partial: Partial<AutonomousResearchConfig>): void;
|
|
90
|
+
/** Start the autonomous research timer. */
|
|
91
|
+
start(): void;
|
|
92
|
+
/** Stop the timer. */
|
|
93
|
+
stop(): void;
|
|
94
|
+
/** Run one autonomous research cycle. Can be called manually or by timer. */
|
|
95
|
+
cycle(): Promise<AutonomousResearchResult>;
|
|
96
|
+
/** Select the best research target from curiosity gaps and desires. */
|
|
97
|
+
private selectTarget;
|
|
98
|
+
/** Extract a researchable topic from a desire suggestion string. */
|
|
99
|
+
private extractTopicFromDesire;
|
|
100
|
+
/** Simple topic overlap check (Jaccard on words). */
|
|
101
|
+
private topicOverlap;
|
|
102
|
+
getStatus(): AutonomousResearchStatus;
|
|
103
|
+
getConfig(): Readonly<Required<AutonomousResearchConfig>>;
|
|
104
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
// ── Autonomous Research Loop ─────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Brain gibt sich selbst Forschungsaufträge. Kein Mensch nötig.
|
|
4
|
+
//
|
|
5
|
+
// Loop: CuriosityEngine → DesireEngine → MissionEngine
|
|
6
|
+
// → Brave Search + Playwright → Insight → Hypothese → Test
|
|
7
|
+
//
|
|
8
|
+
// Guards: max missions/day, budget check, cooldown between cycles.
|
|
9
|
+
import { getLogger } from '../utils/logger.js';
|
|
10
|
+
// ── Migration ───────────────────────────────────────────
|
|
11
|
+
export function runAutonomousResearchMigration(db) {
|
|
12
|
+
db.exec(`
|
|
13
|
+
CREATE TABLE IF NOT EXISTS autonomous_research_log (
|
|
14
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
15
|
+
topic TEXT NOT NULL,
|
|
16
|
+
source TEXT NOT NULL,
|
|
17
|
+
mission_id INTEGER,
|
|
18
|
+
action TEXT NOT NULL,
|
|
19
|
+
reason TEXT,
|
|
20
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
21
|
+
);
|
|
22
|
+
CREATE INDEX IF NOT EXISTS idx_auto_research_created ON autonomous_research_log(created_at);
|
|
23
|
+
`);
|
|
24
|
+
}
|
|
25
|
+
// ── Engine ──────────────────────────────────────────────
|
|
26
|
+
export class AutonomousResearchLoop {
|
|
27
|
+
db;
|
|
28
|
+
config;
|
|
29
|
+
log = getLogger();
|
|
30
|
+
ts = null;
|
|
31
|
+
journal = null;
|
|
32
|
+
sources = {};
|
|
33
|
+
timer = null;
|
|
34
|
+
cyclesCompleted = 0;
|
|
35
|
+
lastCycleAt = null;
|
|
36
|
+
lastTopic = null;
|
|
37
|
+
recentTopics = [];
|
|
38
|
+
// Prepared statements
|
|
39
|
+
stmtLogAction;
|
|
40
|
+
stmtCountToday;
|
|
41
|
+
stmtRecentTopics;
|
|
42
|
+
constructor(db, config = {}) {
|
|
43
|
+
this.db = db;
|
|
44
|
+
this.config = {
|
|
45
|
+
maxMissionsPerDay: config.maxMissionsPerDay ?? 5,
|
|
46
|
+
cycleCooldownMs: config.cycleCooldownMs ?? 30 * 60_000, // 30min
|
|
47
|
+
minGapScore: config.minGapScore ?? 0.5,
|
|
48
|
+
minDesirePriority: config.minDesirePriority ?? 5,
|
|
49
|
+
missionDepth: config.missionDepth ?? 'standard',
|
|
50
|
+
enabled: config.enabled ?? false,
|
|
51
|
+
};
|
|
52
|
+
runAutonomousResearchMigration(db);
|
|
53
|
+
this.stmtLogAction = db.prepare('INSERT INTO autonomous_research_log (topic, source, mission_id, action, reason) VALUES (?, ?, ?, ?, ?)');
|
|
54
|
+
this.stmtCountToday = db.prepare(`SELECT COUNT(*) as c FROM autonomous_research_log WHERE action = 'mission_launched' AND created_at > datetime('now', '-24 hours')`);
|
|
55
|
+
this.stmtRecentTopics = db.prepare(`SELECT DISTINCT topic FROM autonomous_research_log WHERE action = 'mission_launched' ORDER BY id DESC LIMIT 10`);
|
|
56
|
+
}
|
|
57
|
+
// ── Setters ──────────────────────────────────────────
|
|
58
|
+
setThoughtStream(stream) { this.ts = stream; }
|
|
59
|
+
setJournal(journal) { this.journal = journal; }
|
|
60
|
+
setSources(sources) { this.sources = sources; }
|
|
61
|
+
/** Update config at runtime. */
|
|
62
|
+
updateConfig(partial) {
|
|
63
|
+
if (partial.maxMissionsPerDay !== undefined)
|
|
64
|
+
this.config.maxMissionsPerDay = partial.maxMissionsPerDay;
|
|
65
|
+
if (partial.cycleCooldownMs !== undefined)
|
|
66
|
+
this.config.cycleCooldownMs = partial.cycleCooldownMs;
|
|
67
|
+
if (partial.minGapScore !== undefined)
|
|
68
|
+
this.config.minGapScore = partial.minGapScore;
|
|
69
|
+
if (partial.minDesirePriority !== undefined)
|
|
70
|
+
this.config.minDesirePriority = partial.minDesirePriority;
|
|
71
|
+
if (partial.missionDepth !== undefined)
|
|
72
|
+
this.config.missionDepth = partial.missionDepth;
|
|
73
|
+
if (partial.enabled !== undefined)
|
|
74
|
+
this.config.enabled = partial.enabled;
|
|
75
|
+
}
|
|
76
|
+
// ── Lifecycle ─────────────────────────────────────────
|
|
77
|
+
/** Start the autonomous research timer. */
|
|
78
|
+
start() {
|
|
79
|
+
if (this.timer)
|
|
80
|
+
return;
|
|
81
|
+
if (!this.config.enabled) {
|
|
82
|
+
this.log.info('[autonomous-research] Not enabled — skipping start');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.timer = setInterval(() => {
|
|
86
|
+
this.cycle().catch(err => this.log.error(`[autonomous-research] Cycle error: ${err.message}`));
|
|
87
|
+
}, this.config.cycleCooldownMs);
|
|
88
|
+
this.log.info(`[autonomous-research] Started (interval: ${(this.config.cycleCooldownMs / 60_000).toFixed(0)}min, max: ${this.config.maxMissionsPerDay}/day)`);
|
|
89
|
+
}
|
|
90
|
+
/** Stop the timer. */
|
|
91
|
+
stop() {
|
|
92
|
+
if (this.timer) {
|
|
93
|
+
clearInterval(this.timer);
|
|
94
|
+
this.timer = null;
|
|
95
|
+
this.log.info('[autonomous-research] Stopped');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// ── Core Cycle ─────────────────────────────────────────
|
|
99
|
+
/** Run one autonomous research cycle. Can be called manually or by timer. */
|
|
100
|
+
async cycle() {
|
|
101
|
+
// Guard: enabled?
|
|
102
|
+
if (!this.config.enabled) {
|
|
103
|
+
return { action: 'skipped_disabled', reason: 'Autonomous research not enabled' };
|
|
104
|
+
}
|
|
105
|
+
// Guard: cooldown?
|
|
106
|
+
if (this.lastCycleAt && Date.now() - this.lastCycleAt < this.config.cycleCooldownMs * 0.9) {
|
|
107
|
+
return { action: 'skipped_cooldown', reason: 'Cooldown not elapsed' };
|
|
108
|
+
}
|
|
109
|
+
// Guard: daily budget?
|
|
110
|
+
const todayCount = this.stmtCountToday.get().c;
|
|
111
|
+
if (todayCount >= this.config.maxMissionsPerDay) {
|
|
112
|
+
return { action: 'skipped_budget', reason: `Daily limit reached (${todayCount}/${this.config.maxMissionsPerDay})` };
|
|
113
|
+
}
|
|
114
|
+
// Guard: token budget?
|
|
115
|
+
if (this.sources.checkBudget) {
|
|
116
|
+
const budget = this.sources.checkBudget('autonomous_research');
|
|
117
|
+
if (!budget.allowed) {
|
|
118
|
+
return { action: 'skipped_budget', reason: budget.reason ?? 'Token budget exhausted' };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Step 1: Select research target
|
|
122
|
+
const target = this.selectTarget();
|
|
123
|
+
if (!target) {
|
|
124
|
+
this.lastCycleAt = Date.now();
|
|
125
|
+
this.cyclesCompleted++;
|
|
126
|
+
return { action: 'skipped_no_target', reason: 'No gaps or desires above threshold' };
|
|
127
|
+
}
|
|
128
|
+
// Step 2: Check we haven't researched this recently
|
|
129
|
+
const recentTopics = this.stmtRecentTopics.all().map(r => r.topic);
|
|
130
|
+
if (recentTopics.some(t => this.topicOverlap(t, target.topic) > 0.7)) {
|
|
131
|
+
this.log.debug(`[autonomous-research] Skipping "${target.topic}" — too similar to recent research`);
|
|
132
|
+
this.lastCycleAt = Date.now();
|
|
133
|
+
return { action: 'skipped_no_target', reason: `Topic "${target.topic}" too similar to recent research` };
|
|
134
|
+
}
|
|
135
|
+
// Step 3: Launch mission
|
|
136
|
+
if (!this.sources.createMission) {
|
|
137
|
+
return { action: 'skipped_no_target', reason: 'MissionEngine not wired' };
|
|
138
|
+
}
|
|
139
|
+
this.ts?.emit('research', 'exploring', `Autonomous research: "${target.topic}" (source: ${target.source})`, 'notable');
|
|
140
|
+
const mission = this.sources.createMission(target.topic, this.config.missionDepth);
|
|
141
|
+
// Step 4: Log
|
|
142
|
+
this.stmtLogAction.run(target.topic, target.source, mission.id ?? null, 'mission_launched', null);
|
|
143
|
+
this.lastCycleAt = Date.now();
|
|
144
|
+
this.lastTopic = target.topic;
|
|
145
|
+
this.recentTopics = [target.topic, ...this.recentTopics.slice(0, 9)];
|
|
146
|
+
this.cyclesCompleted++;
|
|
147
|
+
// Step 5: Observe for hypothesis engine
|
|
148
|
+
if (this.sources.observeHypothesis) {
|
|
149
|
+
this.sources.observeHypothesis({
|
|
150
|
+
source: 'autonomous_research',
|
|
151
|
+
type: 'mission_launched',
|
|
152
|
+
value: 1,
|
|
153
|
+
timestamp: Date.now(),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
// Step 6: Journal entry
|
|
157
|
+
if (this.journal) {
|
|
158
|
+
try {
|
|
159
|
+
this.journal.recordDiscovery(`Autonomous research: ${target.topic}`, `Self-directed research mission launched. Source: ${target.source}. Depth: ${this.config.missionDepth}.`, { mission_id: mission.id, source: target.source }, 'routine');
|
|
160
|
+
}
|
|
161
|
+
catch { /* best effort */ }
|
|
162
|
+
}
|
|
163
|
+
this.log.info(`[autonomous-research] Mission launched: "${target.topic}" (id: ${mission.id}, source: ${target.source})`);
|
|
164
|
+
return { action: 'mission_launched', topic: target.topic, missionId: mission.id };
|
|
165
|
+
}
|
|
166
|
+
// ── Target Selection ──────────────────────────────────
|
|
167
|
+
/** Select the best research target from curiosity gaps and desires. */
|
|
168
|
+
selectTarget() {
|
|
169
|
+
const candidates = [];
|
|
170
|
+
// Source 1: Curiosity gaps
|
|
171
|
+
if (this.sources.getCuriosityGaps) {
|
|
172
|
+
const gaps = this.sources.getCuriosityGaps(5);
|
|
173
|
+
for (const gap of gaps) {
|
|
174
|
+
if (gap.gapScore >= this.config.minGapScore) {
|
|
175
|
+
// Use the first question as research topic, or the gap topic itself
|
|
176
|
+
const topic = gap.questions[0] ?? gap.topic;
|
|
177
|
+
candidates.push({ topic, source: `curiosity_gap:${gap.gapType}`, score: gap.gapScore });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Source 2: Desires
|
|
182
|
+
if (this.sources.getDesires) {
|
|
183
|
+
const desires = this.sources.getDesires();
|
|
184
|
+
for (const desire of desires) {
|
|
185
|
+
if (desire.priority >= this.config.minDesirePriority) {
|
|
186
|
+
// Extract topic from desire suggestion
|
|
187
|
+
const topic = this.extractTopicFromDesire(desire.suggestion);
|
|
188
|
+
if (topic) {
|
|
189
|
+
candidates.push({ topic, source: `desire:${desire.key}`, score: desire.priority / 10 });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (candidates.length === 0)
|
|
195
|
+
return null;
|
|
196
|
+
// Sort by score descending, pick the best
|
|
197
|
+
candidates.sort((a, b) => b.score - a.score);
|
|
198
|
+
return candidates[0];
|
|
199
|
+
}
|
|
200
|
+
/** Extract a researchable topic from a desire suggestion string. */
|
|
201
|
+
extractTopicFromDesire(suggestion) {
|
|
202
|
+
// Try to extract quoted topic
|
|
203
|
+
const match = suggestion.match(/"([^"]+)"/);
|
|
204
|
+
if (match)
|
|
205
|
+
return match[1];
|
|
206
|
+
// Try to extract after "regarding" or "about"
|
|
207
|
+
const aboutMatch = suggestion.match(/(?:regarding|about|gap:?)\s+"?([^"]+)"?/i);
|
|
208
|
+
if (aboutMatch)
|
|
209
|
+
return aboutMatch[1].trim();
|
|
210
|
+
// Fallback: use the suggestion itself if short enough
|
|
211
|
+
if (suggestion.length < 100)
|
|
212
|
+
return suggestion;
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/** Simple topic overlap check (Jaccard on words). */
|
|
216
|
+
topicOverlap(a, b) {
|
|
217
|
+
const wordsA = new Set(a.toLowerCase().split(/\W+/).filter(w => w.length > 2));
|
|
218
|
+
const wordsB = new Set(b.toLowerCase().split(/\W+/).filter(w => w.length > 2));
|
|
219
|
+
if (wordsA.size === 0 || wordsB.size === 0)
|
|
220
|
+
return 0;
|
|
221
|
+
let intersection = 0;
|
|
222
|
+
for (const w of wordsA)
|
|
223
|
+
if (wordsB.has(w))
|
|
224
|
+
intersection++;
|
|
225
|
+
return intersection / Math.max(wordsA.size, wordsB.size);
|
|
226
|
+
}
|
|
227
|
+
// ── Status ─────────────────────────────────────────────
|
|
228
|
+
getStatus() {
|
|
229
|
+
const todayCount = this.stmtCountToday.get().c;
|
|
230
|
+
return {
|
|
231
|
+
enabled: this.config.enabled,
|
|
232
|
+
running: this.timer !== null,
|
|
233
|
+
cyclesCompleted: this.cyclesCompleted,
|
|
234
|
+
missionsLaunchedToday: todayCount,
|
|
235
|
+
maxMissionsPerDay: this.config.maxMissionsPerDay,
|
|
236
|
+
lastCycleAt: this.lastCycleAt,
|
|
237
|
+
nextCycleAt: this.lastCycleAt ? this.lastCycleAt + this.config.cycleCooldownMs : null,
|
|
238
|
+
lastTopic: this.lastTopic,
|
|
239
|
+
recentTopics: this.recentTopics,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
getConfig() {
|
|
243
|
+
return { ...this.config };
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=autonomous-research-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autonomous-research-loop.js","sourceRoot":"","sources":["../../src/research/autonomous-research-loop.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,gEAAgE;AAChE,EAAE;AACF,uDAAuD;AACvD,iEAAiE;AACjE,EAAE;AACF,mEAAmE;AAGnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAmD/C,2DAA2D;AAE3D,MAAM,UAAU,8BAA8B,CAAC,EAAqB;IAClE,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;GAWP,CAAC,CAAC;AACL,CAAC;AAED,2DAA2D;AAE3D,MAAM,OAAO,sBAAsB;IAChB,EAAE,CAAoB;IACtB,MAAM,CAAqC;IAC3C,GAAG,GAAG,SAAS,EAAE,CAAC;IAC3B,EAAE,GAAyB,IAAI,CAAC;IAChC,OAAO,GAA2B,IAAI,CAAC;IACvC,OAAO,GAA8B,EAAE,CAAC;IACxC,KAAK,GAA0C,IAAI,CAAC;IACpD,eAAe,GAAG,CAAC,CAAC;IACpB,WAAW,GAAkB,IAAI,CAAC;IAClC,SAAS,GAAkB,IAAI,CAAC;IAChC,YAAY,GAAa,EAAE,CAAC;IAEpC,sBAAsB;IACL,aAAa,CAAC;IACd,cAAc,CAAC;IACf,gBAAgB,CAAC;IAElC,YAAY,EAAqB,EAAE,SAAmC,EAAE;QACtE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG;YACZ,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,CAAC;YAChD,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE,GAAG,MAAM,EAAE,QAAQ;YAChE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,GAAG;YACtC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,CAAC;YAChD,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,UAAU;YAC/C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,KAAK;SACjC,CAAC;QAEF,8BAA8B,CAAC,EAAE,CAAC,CAAC;QAEnC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAC7B,wGAAwG,CACzG,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAC9B,mIAAmI,CACpI,CAAC;QACF,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC,OAAO,CAChC,gHAAgH,CACjH,CAAC;IACJ,CAAC;IAED,wDAAwD;IAExD,gBAAgB,CAAC,MAAqB,IAAU,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IACnE,UAAU,CAAC,OAAwB,IAAU,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IACtE,UAAU,CAAC,OAAkC,IAAU,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAEhF,gCAAgC;IAChC,YAAY,CAAC,OAA0C;QACrD,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACvG,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QACjG,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACrF,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QACvG,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACxF,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAC3E,CAAC;IAED,yDAAyD;IAEzD,2CAA2C;IAC3C,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sCAAuC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5G,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,iBAAiB,OAAO,CAAC,CAAC;IAChK,CAAC;IAED,sBAAsB;IACtB,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,0DAA0D;IAE1D,6EAA6E;IAC7E,KAAK,CAAC,KAAK;QACT,kBAAkB;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;QACnF,CAAC;QAED,mBAAmB;QACnB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,GAAG,EAAE,CAAC;YAC1F,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;QACxE,CAAC;QAED,uBAAuB;QACvB,MAAM,UAAU,GAAI,IAAI,CAAC,cAAc,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;QAClE,IAAI,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAChD,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,wBAAwB,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,EAAE,CAAC;QACtH,CAAC;QAED,uBAAuB;QACvB,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;YAC/D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,wBAAwB,EAAE,CAAC;YACzF,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,oCAAoC,EAAE,CAAC;QACvF,CAAC;QAED,oDAAoD;QACpD,MAAM,YAAY,GAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC5F,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,MAAM,CAAC,KAAK,oCAAoC,CAAC,CAAC;YACpG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,UAAU,MAAM,CAAC,KAAK,kCAAkC,EAAE,CAAC;QAC3G,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;YAChC,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;QAC5E,CAAC;QAED,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,yBAAyB,MAAM,CAAC,KAAK,cAAc,MAAM,CAAC,MAAM,GAAG,EAAE,SAAS,CAAC,CAAC;QAEvH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEnF,cAAc;QACd,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAClG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,wCAAwC;QACxC,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;gBAC7B,MAAM,EAAE,qBAAqB;gBAC7B,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,CAAC;gBACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;QACL,CAAC;QAED,wBAAwB;QACxB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,CAAC,eAAe,CAC1B,wBAAwB,MAAM,CAAC,KAAK,EAAE,EACtC,oDAAoD,MAAM,CAAC,MAAM,YAAY,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,EACxG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EACjD,SAAS,CACV,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4CAA4C,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAE,aAAa,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAEzH,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;IACpF,CAAC;IAED,yDAAyD;IAEzD,uEAAuE;IAC/D,YAAY;QAClB,MAAM,UAAU,GAA4D,EAAE,CAAC;QAE/E,2BAA2B;QAC3B,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;YAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;oBAC5C,oEAAoE;oBACpE,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;oBAC5C,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1F,CAAC;YACH,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC1C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;oBACrD,uCAAuC;oBACvC,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBAC7D,IAAI,KAAK,EAAE,CAAC;wBACV,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,MAAM,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC1F,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEzC,0CAA0C;QAC1C,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,UAAU,CAAC,CAAC,CAAE,CAAC;IACxB,CAAC;IAED,oEAAoE;IAC5D,sBAAsB,CAAC,UAAkB;QAC/C,8BAA8B;QAC9B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC5C,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC,CAAC,CAAE,CAAC;QAE5B,8CAA8C;QAC9C,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAChF,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;QAE7C,sDAAsD;QACtD,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG;YAAE,OAAO,UAAU,CAAC;QAE/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qDAAqD;IAC7C,YAAY,CAAC,CAAS,EAAE,CAAS;QACvC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/E,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACrD,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,YAAY,EAAE,CAAC;QAC1D,OAAO,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,0DAA0D;IAE1D,SAAS;QACP,MAAM,UAAU,GAAI,IAAI,CAAC,cAAc,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;QAClE,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;YAC5B,OAAO,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI;YAC5B,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,qBAAqB,EAAE,UAAU;YACjC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;YAChD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI;YACrF,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -143,6 +143,7 @@ export declare class ResearchOrchestrator {
|
|
|
143
143
|
private governanceLayer;
|
|
144
144
|
private adaptiveScheduler;
|
|
145
145
|
private cycleOutcomeTracker;
|
|
146
|
+
private conversationMemory;
|
|
146
147
|
private lastAutoMissionTime;
|
|
147
148
|
private lastGoalMissionTime;
|
|
148
149
|
private roadmapBootstrapped;
|
|
@@ -180,6 +181,8 @@ export declare class ResearchOrchestrator {
|
|
|
180
181
|
setAdaptiveScheduler(scheduler: AdaptiveScheduler): void;
|
|
181
182
|
/** Set the CycleOutcomeTracker for long-term cycle metrics. */
|
|
182
183
|
setCycleOutcomeTracker(tracker: import('./cycle-outcome-tracker.js').CycleOutcomeTracker): void;
|
|
184
|
+
/** Set ConversationMemory for auto-remembering cycle outcomes. */
|
|
185
|
+
setConversationMemory(memory: import('../memory/conversation-memory.js').ConversationMemory): void;
|
|
183
186
|
/** Get the AdaptiveScheduler instance. */
|
|
184
187
|
getAdaptiveScheduler(): AdaptiveScheduler | null;
|
|
185
188
|
/** Set the DataMiner instance for DB-driven engine feeding. */
|
|
@@ -91,6 +91,7 @@ export class ResearchOrchestrator {
|
|
|
91
91
|
governanceLayer = null;
|
|
92
92
|
adaptiveScheduler = null;
|
|
93
93
|
cycleOutcomeTracker = null;
|
|
94
|
+
conversationMemory = null;
|
|
94
95
|
lastAutoMissionTime = 0;
|
|
95
96
|
lastGoalMissionTime = 0;
|
|
96
97
|
roadmapBootstrapped = false;
|
|
@@ -156,6 +157,10 @@ export class ResearchOrchestrator {
|
|
|
156
157
|
setCycleOutcomeTracker(tracker) {
|
|
157
158
|
this.cycleOutcomeTracker = tracker;
|
|
158
159
|
}
|
|
160
|
+
/** Set ConversationMemory for auto-remembering cycle outcomes. */
|
|
161
|
+
setConversationMemory(memory) {
|
|
162
|
+
this.conversationMemory = memory;
|
|
163
|
+
}
|
|
159
164
|
/** Get the AdaptiveScheduler instance. */
|
|
160
165
|
getAdaptiveScheduler() {
|
|
161
166
|
return this.adaptiveScheduler;
|
|
@@ -3177,6 +3182,29 @@ export class ResearchOrchestrator {
|
|
|
3177
3182
|
this.log.debug(`[orchestrator] CycleOutcomeTracker error: ${err.message}`);
|
|
3178
3183
|
}
|
|
3179
3184
|
}
|
|
3185
|
+
// Auto-remember notable cycles in ConversationMemory
|
|
3186
|
+
if (this.conversationMemory) {
|
|
3187
|
+
try {
|
|
3188
|
+
const hypSummary2 = this.hypothesisEngine.getSummary();
|
|
3189
|
+
const notable = insights.length > 0 || (hypSummary2.confirmed ?? 0) > 0;
|
|
3190
|
+
if (notable) {
|
|
3191
|
+
const summary = [
|
|
3192
|
+
`Cycle #${this.cycleCount}: ${insights.length} insights`,
|
|
3193
|
+
hypSummary2.confirmed ? `${hypSummary2.confirmed} hypotheses confirmed` : null,
|
|
3194
|
+
hypSummary2.rejected ? `${hypSummary2.rejected} rejected` : null,
|
|
3195
|
+
`${Math.round(duration / 1000)}s`,
|
|
3196
|
+
].filter(Boolean).join(', ');
|
|
3197
|
+
this.conversationMemory.remember(summary, {
|
|
3198
|
+
category: 'fact',
|
|
3199
|
+
key: `cycle_${this.cycleCount}`,
|
|
3200
|
+
importance: (hypSummary2.confirmed ?? 0) > 0 ? 8 : 6,
|
|
3201
|
+
tags: ['cycle', 'autonomous', this.brainName],
|
|
3202
|
+
source: 'inferred',
|
|
3203
|
+
});
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
catch { /* best effort */ }
|
|
3207
|
+
}
|
|
3180
3208
|
// Step-profiling summary: log slow steps if any
|
|
3181
3209
|
if (stepTimings.length > 0) {
|
|
3182
3210
|
this.log.warn(`[orchestrator] Cycle #${this.cycleCount} slow steps: ${stepTimings.map(s => `${s.step}(${s.ms}ms)`).join(', ')}`);
|