@timmeck/brain-core 2.36.67 → 2.36.68

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.
@@ -89,6 +89,7 @@ export class ResearchOrchestrator {
89
89
  runtimeInfluenceTracker = null;
90
90
  loopDetector = null;
91
91
  governanceLayer = null;
92
+ adaptiveScheduler = null;
92
93
  lastAutoMissionTime = 0;
93
94
  lastGoalMissionTime = 0;
94
95
  roadmapBootstrapped = false;
@@ -139,6 +140,14 @@ export class ResearchOrchestrator {
139
140
  setOnSuggestion(callback) {
140
141
  this.onSuggestionCallback = callback;
141
142
  }
143
+ /** Set the AdaptiveScheduler for dynamic cycle intervals. */
144
+ setAdaptiveScheduler(scheduler) {
145
+ this.adaptiveScheduler = scheduler;
146
+ }
147
+ /** Get the AdaptiveScheduler instance. */
148
+ getAdaptiveScheduler() {
149
+ return this.adaptiveScheduler;
150
+ }
142
151
  /** Set the DataMiner instance for DB-driven engine feeding. */
143
152
  setDataMiner(miner) {
144
153
  this.dataMiner = miner;
@@ -326,20 +335,31 @@ export class ResearchOrchestrator {
326
335
  start(intervalMs = 300_000) {
327
336
  if (this.feedbackTimer)
328
337
  return;
329
- this.feedbackTimer = setInterval(() => {
338
+ this.startIntervalMs = intervalMs;
339
+ this.scheduleNextCycle(intervalMs);
340
+ this.log.info(`[orchestrator] Research orchestrator started (feedback every ${intervalMs}ms)`);
341
+ }
342
+ /** Schedule the next feedback cycle (supports adaptive intervals). */
343
+ scheduleNextCycle(intervalMs) {
344
+ if (this.feedbackTimer)
345
+ clearTimeout(this.feedbackTimer);
346
+ this.feedbackTimer = setTimeout(async () => {
330
347
  try {
331
- void this.runFeedbackCycle();
348
+ await this.runFeedbackCycle();
332
349
  }
333
350
  catch (err) {
334
351
  this.log.error('[orchestrator] Feedback cycle error', { error: err.message });
335
352
  }
353
+ // Re-schedule with adaptive or base interval
354
+ const nextInterval = this.adaptiveScheduler?.getNextInterval() ?? this.startIntervalMs;
355
+ this.scheduleNextCycle(nextInterval);
336
356
  }, intervalMs);
337
- this.log.info(`[orchestrator] Research orchestrator started (feedback every ${intervalMs}ms)`);
338
357
  }
358
+ startIntervalMs = 300_000;
339
359
  /** Stop the feedback loop. */
340
360
  stop() {
341
361
  if (this.feedbackTimer) {
342
- clearInterval(this.feedbackTimer);
362
+ clearTimeout(this.feedbackTimer);
343
363
  this.feedbackTimer = null;
344
364
  }
345
365
  this.dreamEngine?.stop();
@@ -1245,6 +1265,11 @@ export class ResearchOrchestrator {
1245
1265
  const kSummary = this.knowledgeDistiller.getSummary();
1246
1266
  this.hypothesisEngine.observe({ source: this.brainName, type: 'internal:distillation_throughput', value: kSummary.principles + kSummary.antiPatterns + kSummary.strategies, timestamp: now, metadata: { principles: kSummary.principles, avgConfidence: kSummary.avgConfidence } });
1247
1267
  }
1268
+ else if (topic.includes('dream') || topic.includes('consolidat')) {
1269
+ const dStatus = this.dreamEngine?.getStatus();
1270
+ const totals = dStatus?.totals;
1271
+ this.hypothesisEngine.observe({ source: this.brainName, type: 'internal:dream_consolidation_count', value: (totals?.memoriesConsolidated ?? 0), timestamp: now });
1272
+ }
1248
1273
  }
1249
1274
  catch { /* internal observation non-critical */ }
1250
1275
  }
@@ -2934,6 +2959,15 @@ export class ResearchOrchestrator {
2934
2959
  }
2935
2960
  catch { /* checkpoint save should never break the cycle */ }
2936
2961
  }
2962
+ // Adaptive Scheduling: record cycle outcome for interval optimization
2963
+ if (this.adaptiveScheduler) {
2964
+ this.adaptiveScheduler.recordOutcome({
2965
+ insightsFound: insights.length,
2966
+ rulesLearned: 0, // rules come from external learning engines
2967
+ anomaliesDetected: anomalies.length,
2968
+ durationMs: duration,
2969
+ });
2970
+ }
2937
2971
  // Step-profiling summary: log slow steps if any
2938
2972
  if (stepTimings.length > 0) {
2939
2973
  this.log.warn(`[orchestrator] Cycle #${this.cycleCount} slow steps: ${stepTimings.map(s => `${s.step}(${s.ms}ms)`).join(', ')}`);