@timmeck/brain-core 2.36.28 → 2.36.30

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.
@@ -50,6 +50,7 @@ import type { RAGIndexer } from '../rag/rag-indexer.js';
50
50
  import type { TeachingProtocol } from '../teaching/teaching-protocol.js';
51
51
  import type { CodeHealthMonitor } from '../code-health/health-monitor.js';
52
52
  import type { KnowledgeGraphEngine } from '../knowledge-graph/graph-engine.js';
53
+ import type { RepoAbsorber } from '../codegen/repo-absorber.js';
53
54
  import { AutoResponder } from './auto-responder.js';
54
55
  export interface ResearchOrchestratorConfig {
55
56
  brainName: string;
@@ -114,6 +115,7 @@ export declare class ResearchOrchestrator {
114
115
  private teachingProtocol;
115
116
  private codeHealthMonitor;
116
117
  private knowledgeGraph;
118
+ private repoAbsorber;
117
119
  private lastAutoMissionTime;
118
120
  private onSuggestionCallback;
119
121
  private db;
@@ -209,6 +211,8 @@ export declare class ResearchOrchestrator {
209
211
  setCodeHealthMonitor(monitor: CodeHealthMonitor): void;
210
212
  /** Set the KnowledgeGraphEngine — typed fact storage and inference. */
211
213
  setKnowledgeGraph(graph: KnowledgeGraphEngine): void;
214
+ /** Set the RepoAbsorber — autonomous code learning from discovered repos. */
215
+ setRepoAbsorber(absorber: RepoAbsorber): void;
212
216
  /** Set the LLMService — propagates to all engines that can use LLM. */
213
217
  setLLMService(llm: LLMService): void;
214
218
  /** Get the LLMService instance. */
@@ -66,6 +66,7 @@ export class ResearchOrchestrator {
66
66
  teachingProtocol = null;
67
67
  codeHealthMonitor = null;
68
68
  knowledgeGraph = null;
69
+ repoAbsorber = null;
69
70
  lastAutoMissionTime = 0;
70
71
  onSuggestionCallback = null;
71
72
  db;
@@ -232,6 +233,8 @@ export class ResearchOrchestrator {
232
233
  setCodeHealthMonitor(monitor) { this.codeHealthMonitor = monitor; }
233
234
  /** Set the KnowledgeGraphEngine — typed fact storage and inference. */
234
235
  setKnowledgeGraph(graph) { this.knowledgeGraph = graph; }
236
+ /** Set the RepoAbsorber — autonomous code learning from discovered repos. */
237
+ setRepoAbsorber(absorber) { this.repoAbsorber = absorber; }
235
238
  /** Set the LLMService — propagates to all engines that can use LLM. */
236
239
  setLLMService(llm) {
237
240
  this.llmService = llm;
@@ -1725,24 +1728,46 @@ export class ResearchOrchestrator {
1725
1728
  ts?.emit('fact_extractor', 'analyzing', 'Step 42: Extracting facts from insights...', 'routine');
1726
1729
  let factsAdded = 0;
1727
1730
  // Extract from recent insights
1731
+ // Extract from insights NOT yet in knowledge_facts
1728
1732
  try {
1729
- const recentInsights = this.db.prepare(`SELECT id, description FROM insights WHERE created_at > datetime('now', '-1 day') AND description IS NOT NULL ORDER BY id DESC LIMIT 20`).all();
1730
- for (const ins of recentInsights) {
1733
+ const unprocessed = this.db.prepare(`SELECT i.id, i.description FROM insights i
1734
+ WHERE i.description IS NOT NULL
1735
+ AND NOT EXISTS (SELECT 1 FROM knowledge_facts kf WHERE kf.source_type = 'insight' AND kf.source_id = i.id)
1736
+ ORDER BY i.id DESC LIMIT 30`).all();
1737
+ for (const ins of unprocessed) {
1731
1738
  const facts = this.factExtractor.extractFromInsight(ins.description, `insight:${ins.id}`);
1732
1739
  for (const f of facts) {
1733
- this.knowledgeGraph.addFact(f.subject, f.predicate, f.object, f.context, f.confidence);
1740
+ this.knowledgeGraph.addFact(f.subject, f.predicate, f.object, f.context, f.confidence, 'insight', String(ins.id));
1734
1741
  factsAdded++;
1735
1742
  }
1736
1743
  }
1737
1744
  }
1738
1745
  catch { /* table may not exist */ }
1739
- // Extract from rules
1746
+ // Extract from error-solution pairs NOT yet processed
1740
1747
  try {
1741
- const recentRules = this.db.prepare(`SELECT id, pattern, action FROM rules WHERE created_at > datetime('now', '-1 day') AND pattern IS NOT NULL ORDER BY id DESC LIMIT 10`).all();
1742
- for (const rule of recentRules) {
1748
+ const pairs = this.db.prepare(`SELECT e.id, e.type, e.message, s.description as solution, e.context
1749
+ FROM errors e JOIN solutions s ON s.error_id = e.id
1750
+ WHERE NOT EXISTS (SELECT 1 FROM knowledge_facts kf WHERE kf.source_type = 'error' AND kf.source_id = e.id)
1751
+ LIMIT 20`).all();
1752
+ for (const p of pairs) {
1753
+ const facts = this.factExtractor.extractFromErrorSolution(`${p.type}: ${p.message}`, p.solution, p.context ?? '', String(p.id));
1754
+ for (const f of facts) {
1755
+ this.knowledgeGraph.addFact(f.subject, f.predicate, f.object, f.context, f.confidence, 'error', String(p.id));
1756
+ factsAdded++;
1757
+ }
1758
+ }
1759
+ }
1760
+ catch { /* table may not exist */ }
1761
+ // Extract from rules NOT yet processed
1762
+ try {
1763
+ const rules = this.db.prepare(`SELECT id, pattern, action FROM rules
1764
+ WHERE pattern IS NOT NULL
1765
+ AND NOT EXISTS (SELECT 1 FROM knowledge_facts kf WHERE kf.source_type = 'rule' AND kf.source_id = rules.id)
1766
+ LIMIT 10`).all();
1767
+ for (const rule of rules) {
1743
1768
  const facts = this.factExtractor.extractFromRule(rule.pattern, rule.action, `rule:${rule.id}`);
1744
1769
  for (const f of facts) {
1745
- this.knowledgeGraph.addFact(f.subject, f.predicate, f.object, f.context, f.confidence);
1770
+ this.knowledgeGraph.addFact(f.subject, f.predicate, f.object, f.context, f.confidence, 'rule', String(rule.id));
1746
1771
  factsAdded++;
1747
1772
  }
1748
1773
  }
@@ -1892,6 +1917,26 @@ export class ResearchOrchestrator {
1892
1917
  this.log.warn(`[orchestrator] Step 48 error: ${err.message}`);
1893
1918
  }
1894
1919
  }
1920
+ // Step 49: RepoAbsorber — absorb one discovered repo per cycle (every 10 cycles)
1921
+ if (this.repoAbsorber && this.cycleCount % 10 === 0) {
1922
+ try {
1923
+ ts?.emit('repo_absorber', 'perceiving', 'Step 49: Absorbing next discovered repo...', 'routine');
1924
+ const result = await this.repoAbsorber.absorbNext();
1925
+ if (result) {
1926
+ this.journal.write({
1927
+ title: `Repo Absorbed: ${result.repo}`,
1928
+ type: 'insight', content: `Files: ${result.filesScanned}, Patterns: ${result.patternsFound}, Facts: ${result.factsExtracted}, RAG vectors: ${result.ragVectorsAdded} (${result.durationMs}ms)`,
1929
+ tags: [this.brainName, 'repo-absorber', 'code-learning'],
1930
+ references: [], significance: result.ragVectorsAdded > 10 ? 'notable' : 'routine', data: { ...result },
1931
+ });
1932
+ }
1933
+ if (this.metaCognitionLayer)
1934
+ this.metaCognitionLayer.recordStep('repo_absorber', this.cycleCount, { insights: result ? 1 : 0 });
1935
+ }
1936
+ catch (err) {
1937
+ this.log.warn(`[orchestrator] Step 49 error: ${err.message}`);
1938
+ }
1939
+ }
1895
1940
  const duration = Date.now() - start;
1896
1941
  ts?.emit('orchestrator', 'reflecting', `Feedback Cycle #${this.cycleCount} complete (${duration}ms)`);
1897
1942
  this.log.info(`[orchestrator] ─── Feedback Cycle #${this.cycleCount} complete (${duration}ms) ───`);