@timmeck/brain 3.36.54 → 3.36.56

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/brain.js CHANGED
@@ -2,7 +2,6 @@ import path from 'node:path';
2
2
  import fs from 'node:fs';
3
3
  import { loadConfig } from './config.js';
4
4
  import { createLogger, getLogger } from './utils/logger.js';
5
- import { getEventBus } from './utils/events.js';
6
5
  import { getCurrentVersion } from './cli/update-check.js';
7
6
  import { createConnection } from '@timmeck/brain-core';
8
7
  import { runMigrations } from './db/migrations/index.js';
@@ -56,8 +55,12 @@ import { McpHttpServer } from './mcp/http-server.js';
56
55
  // Embeddings
57
56
  import { EmbeddingEngine } from './embeddings/engine.js';
58
57
  // Cross-Brain
59
- import { CrossBrainClient, CrossBrainNotifier, CrossBrainSubscriptionManager, CrossBrainCorrelator, EcosystemService, WebhookService, ExportService, BackupService, AutonomousResearchScheduler, ResearchOrchestrator, DataMiner, BrainDataMinerAdapter, ScannerDataMinerAdapter, BootstrapService, DreamEngine, ThoughtStream, PredictionEngine, SignalScanner, CodeMiner, PatternExtractor, ContextBuilder, CodeGenerator, AttentionEngine, TransferEngine, NarrativeEngine, CuriosityEngine, EmergenceEngine, DebateEngine, ParameterRegistry, MetaCognitionLayer, AutoExperimentEngine, SelfTestEngine, TeachEngine, DataScout, runDataScoutMigration, GitHubTrendingAdapter, NpmStatsAdapter, HackerNewsAdapter, SimulationEngine, runSimulationMigration, MemoryPalace, GoalEngine, EvolutionEngine, runEvolutionMigration, ReasoningEngine, EmotionalModel, SelfScanner, SelfModificationEngine, ConceptAbstraction, PeerNetwork, LLMService, OllamaProvider, ResearchMissionEngine, runMissionMigration, BraveSearchAdapter, JinaReaderAdapter, PlaywrightAdapter, FirecrawlAdapter, TechRadarEngine, runTechRadarMigration, NotificationService as MultiChannelNotificationService, runNotificationMigration, DiscordProvider, TelegramProvider, EmailProvider, CommandCenterServer, WatchdogService, createDefaultWatchdogConfig, PluginRegistry, BorgSyncEngine } from '@timmeck/brain-core';
60
- import { RAGEngine, RAGIndexer, KnowledgeGraphEngine, FactExtractor, SemanticCompressor, FeedbackEngine, ToolTracker, ToolPatternAnalyzer, ProactiveEngine, UserModel, CodeHealthMonitor, TeachingProtocol, Curriculum, ConsensusEngine, ActiveLearner, RepoAbsorber, FeatureExtractor, FeatureRecommender, ContradictionResolver, CheckpointManager, TraceCollector, MessageRouter, TelegramBot, DiscordBot, BenchmarkSuite, AgentTrainer, ToolScopeManager, PluginMarketplace, CodeSandbox, GuardrailEngine, CausalPlanner, ResearchRoadmap, runRoadmapMigration, CreativeEngine, runCreativeMigration, ActionBridgeEngine, runActionBridgeMigration, ContentForge, runContentForgeMigration, CodeForge, runCodeForgeMigration, StrategyForge, runStrategyForgeMigration } from '@timmeck/brain-core';
58
+ import { CrossBrainClient, CrossBrainNotifier, CrossBrainSubscriptionManager, CrossBrainCorrelator, EcosystemService, WebhookService, ExportService, BackupService, AutonomousResearchScheduler, ResearchOrchestrator, DataMiner, BrainDataMinerAdapter, ScannerDataMinerAdapter, BootstrapService, DreamEngine, ThoughtStream, PredictionEngine, AttentionEngine, TransferEngine, NarrativeEngine, CuriosityEngine, EmergenceEngine, DebateEngine, ParameterRegistry, MetaCognitionLayer, AutoExperimentEngine, SelfTestEngine, TeachEngine, DataScout, runDataScoutMigration, GitHubTrendingAdapter, NpmStatsAdapter, HackerNewsAdapter, SimulationEngine, runSimulationMigration, MemoryPalace, GoalEngine, EvolutionEngine, runEvolutionMigration, ReasoningEngine, EmotionalModel, SelfScanner, SelfModificationEngine, ConceptAbstraction, PeerNetwork, LLMService, OllamaProvider, ResearchMissionEngine, runMissionMigration, BraveSearchAdapter, JinaReaderAdapter, PlaywrightAdapter, FirecrawlAdapter, WatchdogService, createDefaultWatchdogConfig, PluginRegistry, BorgSyncEngine } from '@timmeck/brain-core';
59
+ // Init modules (extracted from God-Class)
60
+ import { setupEventListeners, setupCrossBrainSubscriptions } from './init/events-init.js';
61
+ import { logCrash as logCrashHelper, runRetentionCleanup as runRetentionHelper, cleanup as cleanupEngines, setupCrashRecovery } from './init/lifecycle.js';
62
+ import { createCommandCenter } from './init/dashboard-init.js';
63
+ import { createIntelligenceEngines } from './init/engine-factory.js';
61
64
  export class BrainCore {
62
65
  db = null;
63
66
  ipcServer = null;
@@ -804,295 +807,19 @@ export class BrainCore {
804
807
  services.missionEngine = missionEngine;
805
808
  this.orchestrator.setMissionEngine(missionEngine);
806
809
  logger.info('ResearchMissionEngine activated — "brain missions create <topic>" ready');
807
- // ── Intelligence Upgrade (Sessions 55-65) ────────────────
808
- // 55. RAG Pipeline — vector search across all knowledge
809
- const ragEngine = new RAGEngine(this.db, { brainName: 'brain' });
810
- if (this.embeddingEngine)
811
- ragEngine.setEmbeddingEngine(this.embeddingEngine);
812
- ragEngine.setThoughtStream(thoughtStream);
813
- if (llmService.isAvailable())
814
- ragEngine.setLLMService(llmService);
815
- services.ragEngine = ragEngine;
816
- const ragIndexer = new RAGIndexer(this.db);
817
- ragIndexer.setRAGEngine(ragEngine);
818
- services.ragIndexer = ragIndexer;
819
- // Background: initial RAG indexing after 30s startup delay
820
- setTimeout(() => {
821
- ragIndexer.indexAll().then(count => {
822
- if (count > 0)
823
- logger.info(`[RAG] Initial indexing: ${count} vectors`);
824
- }).catch(err => logger.debug(`[RAG] Initial indexing skipped: ${err.message}`));
825
- }, 30_000);
826
- // 56. Knowledge Graph 2.0 — typed fact relations
827
- const knowledgeGraph = new KnowledgeGraphEngine(this.db, { brainName: 'brain' });
828
- knowledgeGraph.setThoughtStream(thoughtStream);
829
- services.knowledgeGraph = knowledgeGraph;
830
- const factExtractor = new FactExtractor(this.db, { brainName: 'brain' });
831
- if (llmService.isAvailable())
832
- factExtractor.setLLMService(llmService);
833
- services.factExtractor = factExtractor;
834
- // 57. Semantic Compression — deduplicate knowledge
835
- const semanticCompressor = new SemanticCompressor(this.db, { brainName: 'brain' });
836
- semanticCompressor.setRAGEngine(ragEngine);
837
- if (llmService.isAvailable())
838
- semanticCompressor.setLLMService(llmService);
839
- semanticCompressor.setThoughtStream(thoughtStream);
840
- services.semanticCompressor = semanticCompressor;
841
- // 58. Feedback Learning — RLHF reward signals
842
- const feedbackEngine = new FeedbackEngine(this.db, { brainName: 'brain' });
843
- feedbackEngine.setThoughtStream(thoughtStream);
844
- services.feedbackEngine = feedbackEngine;
845
- // 59. Tool-Use Learning — track tool outcomes
846
- const toolTracker = new ToolTracker(this.db, { brainName: 'brain' });
847
- const toolPatternAnalyzer = new ToolPatternAnalyzer(this.db);
848
- services.toolTracker = toolTracker;
849
- services.toolPatternAnalyzer = toolPatternAnalyzer;
850
- // 60. Proactive Suggestions — trigger-based improvement proposals
851
- const proactiveEngine = new ProactiveEngine(this.db, { brainName: 'brain' });
852
- proactiveEngine.setThoughtStream(thoughtStream);
853
- services.proactiveEngine = proactiveEngine;
854
- // 61. User Modeling — adaptive responses
855
- const userModel = new UserModel(this.db, { brainName: 'brain' });
856
- services.userModel = userModel;
857
- // 62. Code Health Monitor — codebase quality tracking
858
- const codeHealthMonitor = new CodeHealthMonitor(this.db, { brainName: 'brain' });
859
- codeHealthMonitor.setThoughtStream(thoughtStream);
860
- services.codeHealthMonitor = codeHealthMonitor;
861
- // 63. Inter-Brain Teaching — knowledge transfer protocol
862
- const teachingProtocol = new TeachingProtocol(this.db, { brainName: 'brain' });
863
- services.teachingProtocol = teachingProtocol;
864
- const curriculum = new Curriculum(this.db);
865
- services.curriculum = curriculum;
866
- // 64. Consensus Decisions — multi-brain voting
867
- const consensusEngine = new ConsensusEngine(this.db, { brainName: 'brain' });
868
- services.consensusEngine = consensusEngine;
869
- // 65. Active Learning — gap identification & closing strategies
870
- const activeLearner = new ActiveLearner(this.db, { brainName: 'brain' });
871
- activeLearner.setThoughtStream(thoughtStream);
872
- services.activeLearner = activeLearner;
873
- // 66. RepoAbsorber — autonomous code learning from discovered repos
874
- const repoAbsorber = new RepoAbsorber(this.db);
875
- repoAbsorber.setThoughtStream(thoughtStream);
876
- repoAbsorber.setRAGEngine(ragEngine);
877
- repoAbsorber.setKnowledgeGraph(knowledgeGraph);
878
- services.repoAbsorber = repoAbsorber;
879
- // 67. FeatureExtractor — extract useful functions/patterns from absorbed repos
880
- const featureExtractor = new FeatureExtractor(this.db);
881
- featureExtractor.setRAGEngine(ragEngine);
882
- featureExtractor.setKnowledgeGraph(knowledgeGraph);
883
- if (services.llmService)
884
- featureExtractor.setLLMService(services.llmService);
885
- services.featureExtractor = featureExtractor;
886
- repoAbsorber.setFeatureExtractor(featureExtractor);
887
- // 68. FeatureRecommender — wishlist, connections, periodic need scanning
888
- const featureRecommender = new FeatureRecommender(this.db);
889
- featureRecommender.setFeatureExtractor(featureExtractor);
890
- featureRecommender.setRAGEngine(ragEngine);
891
- featureRecommender.setKnowledgeGraph(knowledgeGraph);
892
- featureRecommender.setThoughtStream(thoughtStream);
893
- services.featureRecommender = featureRecommender;
894
- // 69. ContradictionResolver — resolve knowledge graph contradictions
895
- const contradictionResolver = new ContradictionResolver(this.db);
896
- contradictionResolver.setKnowledgeGraph(knowledgeGraph);
897
- services.contradictionResolver = contradictionResolver;
898
- // 70. CheckpointManager — workflow state persistence for crash recovery & time-travel
899
- const checkpointManager = new CheckpointManager(this.db);
900
- services.checkpointManager = checkpointManager;
901
- // 71. TraceCollector — observability & tracing for all workflows
902
- const traceCollector = new TraceCollector(this.db);
903
- services.traceCollector = traceCollector;
904
- // 72. Messaging Bots — bidirectional Telegram/Discord (optional, if tokens configured)
905
- const messageRouter = new MessageRouter({ brainName: 'brain' });
906
- services.messageRouter = messageRouter;
907
- this.telegramBot = new TelegramBot();
908
- this.telegramBot.setRouter(messageRouter);
909
- services.telegramBot = this.telegramBot;
910
- this.discordBot = new DiscordBot();
911
- this.discordBot.setRouter(messageRouter);
912
- services.discordBot = this.discordBot;
913
- // 73. Agent Training — BenchmarkSuite + AgentTrainer (eval harness with curriculum learning)
914
- const benchmarkSuite = new BenchmarkSuite(this.db);
915
- const agentTrainer = new AgentTrainer(this.db);
916
- agentTrainer.setBenchmarkSuite(benchmarkSuite);
917
- services.benchmarkSuite = benchmarkSuite;
918
- services.agentTrainer = agentTrainer;
919
- // 74. Tool Scoping — dynamic tool availability per workflow phase (LangGraph-inspired)
920
- const toolScopeManager = new ToolScopeManager(this.db);
921
- toolScopeManager.registerDefaults();
922
- services.toolScopeManager = toolScopeManager;
923
- // 75. Plugin Marketplace — browse, install, rate plugins (OpenClaw-inspired)
924
- const pluginMarketplace = new PluginMarketplace(this.db, { brainVersion: getCurrentVersion() });
925
- services.pluginMarketplace = pluginMarketplace;
926
- // 76. Code Sandbox — isolated code execution with Docker/local fallback (AutoGen-inspired)
927
- const codeSandbox = new CodeSandbox(this.db);
928
- services.codeSandbox = codeSandbox;
929
- // 89. GuardrailEngine — self-protection: parameter bounds, circuit breaker, health checks
930
- const guardrailEngine = new GuardrailEngine(this.db, { brainName: 'brain' });
931
- guardrailEngine.setParameterRegistry(parameterRegistry);
932
- if (goalEngine)
933
- guardrailEngine.setGoalEngine(goalEngine);
934
- guardrailEngine.setThoughtStream(thoughtStream);
935
- this.guardrailEngine = guardrailEngine;
936
- services.guardrailEngine = guardrailEngine;
937
- // 86. CausalPlanner — root-cause diagnosis + intervention planning
938
- const causalPlanner = new CausalPlanner(researchScheduler.causalGraph);
939
- causalPlanner.setGoalEngine(goalEngine);
940
- this.causalPlanner = causalPlanner;
941
- services.causalPlanner = causalPlanner;
942
- // 87. ResearchRoadmap — goal dependencies + multi-step research plans
943
- runRoadmapMigration(this.db);
944
- const researchRoadmap = new ResearchRoadmap(this.db, goalEngine);
945
- researchRoadmap.setThoughtStream(thoughtStream);
946
- this.researchRoadmap = researchRoadmap;
947
- services.researchRoadmap = researchRoadmap;
948
- // 88. CreativeEngine — cross-domain idea generation
949
- runCreativeMigration(this.db);
950
- const creativeEngine = new CreativeEngine(this.db, { brainName: 'brain' });
951
- creativeEngine.setKnowledgeDistiller(this.orchestrator.knowledgeDistiller);
952
- creativeEngine.setHypothesisEngine(researchScheduler.hypothesisEngine);
953
- if (llmService)
954
- creativeEngine.setLLMService(llmService);
955
- creativeEngine.setThoughtStream(thoughtStream);
956
- this.creativeEngine = creativeEngine;
957
- services.creativeEngine = creativeEngine;
958
- // 91. ActionBridgeEngine — risk-assessed auto-execution of proposed actions
959
- runActionBridgeMigration(this.db);
960
- const actionBridge = new ActionBridgeEngine(this.db, { brainName: 'brain' });
961
- services.actionBridge = actionBridge;
962
- // 92. ContentForge — autonomous content generation + publishing
963
- runContentForgeMigration(this.db);
964
- const contentForge = new ContentForge(this.db, { brainName: 'brain' });
965
- if (llmService)
966
- contentForge.setLLMService(llmService);
967
- contentForge.setActionBridge(actionBridge);
968
- services.contentForge = contentForge;
969
- // 93. CodeForge — pattern extraction + auto-apply code changes
970
- runCodeForgeMigration(this.db);
971
- const codeForge = new CodeForge(this.db, { brainName: 'brain' });
972
- codeForge.setActionBridge(actionBridge);
973
- if (services.guardrailEngine)
974
- codeForge.setGuardrailEngine(services.guardrailEngine);
975
- if (services.selfModificationEngine)
976
- codeForge.setSelfModificationEngine(services.selfModificationEngine);
977
- if (services.codeHealthMonitor)
978
- codeForge.setCodeHealthMonitor(services.codeHealthMonitor);
979
- services.codeForge = codeForge;
980
- // 94. StrategyForge — autonomous strategy creation + execution
981
- runStrategyForgeMigration(this.db);
982
- const strategyForge = new StrategyForge(this.db, { brainName: 'brain' });
983
- strategyForge.setActionBridge(actionBridge);
984
- strategyForge.setKnowledgeDistiller(this.orchestrator.knowledgeDistiller);
985
- services.strategyForge = strategyForge;
986
- // ── Wire intelligence engines into autonomous ResearchOrchestrator ──
987
- this.orchestrator.setFactExtractor(factExtractor);
988
- this.orchestrator.setKnowledgeGraph(knowledgeGraph);
989
- this.orchestrator.setSemanticCompressor(semanticCompressor);
990
- this.orchestrator.setProactiveEngine(proactiveEngine);
991
- this.orchestrator.setActiveLearner(activeLearner);
992
- this.orchestrator.setRAGIndexer(ragIndexer);
993
- this.orchestrator.setTeachingProtocol(teachingProtocol);
994
- this.orchestrator.setCodeHealthMonitor(codeHealthMonitor);
995
- this.orchestrator.setRepoAbsorber(repoAbsorber);
996
- this.orchestrator.setFeatureRecommender(featureRecommender);
997
- this.orchestrator.setFeatureExtractor(featureExtractor);
998
- this.orchestrator.setContradictionResolver(contradictionResolver);
999
- this.orchestrator.setCheckpointManager(checkpointManager);
1000
- this.orchestrator.setFeedbackEngine(feedbackEngine);
1001
- this.orchestrator.setUserModel(userModel);
1002
- this.orchestrator.setConsensusEngine(consensusEngine);
1003
- this.orchestrator.setTraceCollector(traceCollector);
1004
- this.orchestrator.setGuardrailEngine(guardrailEngine);
1005
- this.orchestrator.setCausalPlanner(causalPlanner);
1006
- this.orchestrator.setResearchRoadmap(researchRoadmap);
1007
- this.orchestrator.setCreativeEngine(creativeEngine);
1008
- this.orchestrator.setActionBridge(actionBridge);
1009
- this.orchestrator.setContentForge(contentForge);
1010
- this.orchestrator.setCodeForge(codeForge);
1011
- this.orchestrator.setStrategyForge(strategyForge);
1012
- logger.info('Intelligence upgrade active (RAG, KG, Compression, Feedback, Tool-Learning, Proactive, UserModel, CodeHealth, Teaching, Consensus, ActiveLearning, RepoAbsorber, Guardrails, CausalPlanner, Roadmap, Creative — all wired into orchestrator)');
1013
- logger.info('Research orchestrator started (48+ steps, feedback loops active, DataMiner bootstrapped, Dream Mode active, Prediction Engine active)');
1014
- // 11k. Signal Scanner — GitHub/HN/Crypto signal tracking
1015
- if (config.scanner.enabled) {
1016
- const signalScanner = new SignalScanner(this.db, config.scanner);
1017
- this.orchestrator.setSignalScanner(signalScanner);
1018
- signalScanner.start();
1019
- services.signalScanner = signalScanner;
1020
- logger.info(`Signal scanner started (interval: ${config.scanner.scanIntervalMs}ms, token: ${config.scanner.githubToken ? 'yes' : 'NO — set GITHUB_TOKEN'})`);
1021
- }
1022
- // 11k2. TechRadar Engine — daily tech trend scanning + relevance analysis
1023
- try {
1024
- runTechRadarMigration(this.db);
1025
- const techRadar = new TechRadarEngine(this.db, {
1026
- githubToken: config.scanner.githubToken,
1027
- });
1028
- if (llmService)
1029
- techRadar.setLLMService(llmService);
1030
- techRadar.start();
1031
- services.techRadar = techRadar;
1032
- logger.info('TechRadar engine started');
1033
- }
1034
- catch (err) {
1035
- logger.warn(`TechRadar setup failed (non-critical): ${err.message}`);
1036
- }
1037
- // 11k3. NotificationService — multi-channel notifications
1038
- try {
1039
- runNotificationMigration(this.db);
1040
- const notificationService = new MultiChannelNotificationService(this.db);
1041
- // Auto-register available providers
1042
- const discordProvider = new DiscordProvider();
1043
- const telegramProvider = new TelegramProvider();
1044
- const emailProvider = new EmailProvider();
1045
- discordProvider.isAvailable().then(ok => {
1046
- if (ok) {
1047
- notificationService.registerProvider(discordProvider);
1048
- logger.info('Discord notification provider registered');
1049
- }
1050
- }).catch(() => { });
1051
- telegramProvider.isAvailable().then(ok => {
1052
- if (ok) {
1053
- notificationService.registerProvider(telegramProvider);
1054
- logger.info('Telegram notification provider registered');
1055
- }
1056
- }).catch(() => { });
1057
- emailProvider.isAvailable().then(ok => {
1058
- if (ok) {
1059
- notificationService.registerProvider(emailProvider);
1060
- logger.info('Email notification provider registered');
1061
- }
1062
- }).catch(() => { });
1063
- services.multiChannelNotifications = notificationService;
1064
- logger.info('NotificationService initialized');
1065
- }
1066
- catch (err) {
1067
- logger.warn(`NotificationService setup failed (non-critical): ${err.message}`);
1068
- }
1069
- // 11l. CodeMiner — mine repo contents from GitHub (needs GITHUB_TOKEN)
1070
- let patternExtractor;
1071
- if (config.scanner.githubToken) {
1072
- const codeMiner = new CodeMiner(this.db, { githubToken: config.scanner.githubToken });
1073
- patternExtractor = new PatternExtractor(this.db);
1074
- this.orchestrator.setCodeMiner(codeMiner);
1075
- services.codeMiner = codeMiner;
1076
- services.patternExtractor = patternExtractor;
1077
- void codeMiner.bootstrap();
1078
- logger.info('CodeMiner activated (GITHUB_TOKEN set)');
1079
- }
1080
- // 11m. CodeGenerator — autonomous code generation (needs ANTHROPIC_API_KEY)
1081
- if (process.env.ANTHROPIC_API_KEY) {
1082
- const codeGenerator = new CodeGenerator(this.db, { brainName: 'brain', apiKey: process.env.ANTHROPIC_API_KEY });
1083
- const contextBuilder = new ContextBuilder(this.orchestrator.knowledgeDistiller, this.orchestrator.journal, patternExtractor ?? null, services.signalScanner ?? null);
1084
- codeGenerator.setContextBuilder(contextBuilder);
1085
- codeGenerator.setThoughtStream(thoughtStream);
1086
- this.orchestrator.setCodeGenerator(codeGenerator);
1087
- services.codeGenerator = codeGenerator;
1088
- logger.info('CodeGenerator activated (ANTHROPIC_API_KEY set)');
1089
- // Wire ContextBuilder with SelfScanner into SelfModificationEngine
1090
- if (services.selfModificationEngine && services.selfScanner) {
1091
- const selfmodCtx = new ContextBuilder(this.orchestrator.knowledgeDistiller, this.orchestrator.journal, patternExtractor ?? null, services.signalScanner ?? null);
1092
- selfmodCtx.setSelfScanner(services.selfScanner);
1093
- services.selfModificationEngine.setContextBuilder(selfmodCtx);
1094
- }
1095
- }
810
+ // ── Intelligence Upgrade + Forges + Scanners (extracted to engine-factory.ts) ──
811
+ const intelligenceResult = createIntelligenceEngines({
812
+ db: this.db, config, services, embeddingEngine: this.embeddingEngine,
813
+ orchestrator: this.orchestrator, researchScheduler, thoughtStream,
814
+ llmService, notifier: this.notifier, goalEngine,
815
+ });
816
+ this.guardrailEngine = intelligenceResult.guardrailEngine;
817
+ this.causalPlanner = intelligenceResult.causalPlanner;
818
+ this.researchRoadmap = intelligenceResult.researchRoadmap;
819
+ this.creativeEngine = intelligenceResult.creativeEngine;
820
+ this.telegramBot = intelligenceResult.telegramBot;
821
+ this.discordBot = intelligenceResult.discordBot;
822
+ const chatEngine = services.chatEngine;
1096
823
  // 11c. Watchdog — monitoring only (detect peers via PID, run health checks)
1097
824
  const watchdogConfig = createDefaultWatchdogConfig();
1098
825
  const watchdog = new WatchdogService(watchdogConfig);
@@ -1132,101 +859,10 @@ export class BrainCore {
1132
859
  this.borgSync = new BorgSyncEngine('brain', this.crossBrain, borgProvider);
1133
860
  services.borgSync = this.borgSync;
1134
861
  // 11f. Command Center Dashboard
1135
- this.commandCenter = new CommandCenterServer({
1136
- port: 7790,
1137
- selfName: 'brain',
1138
- crossBrain: this.crossBrain,
1139
- ecosystemService: this.ecosystemService,
1140
- correlator: this.correlator,
1141
- watchdog,
1142
- pluginRegistry: this.pluginRegistry,
1143
- borgSync: this.borgSync,
1144
- thoughtStream,
1145
- getLLMStats: () => services.llmService?.getStats() ?? null,
1146
- getLLMHistory: (hours) => services.llmService?.getUsageHistory(hours) ?? [],
1147
- getErrors: () => {
1148
- const errors = services.error?.query({ limit: 20 }) ?? [];
1149
- const summary = services.analytics?.getSummary() ?? null;
1150
- return { errors, summary };
1151
- },
1152
- getSelfModStatus: () => services.selfModificationEngine?.getStatus() ?? null,
1153
- getSelfModHistory: (limit = 10) => services.selfModificationEngine?.getHistory(limit) ?? [],
1154
- selfmodApprove: (id) => services.selfModificationEngine?.approveModification(id),
1155
- selfmodReject: (id, notes) => services.selfModificationEngine?.rejectModification(id, notes),
1156
- getMissions: () => services.missionEngine?.getStatus() ?? null,
1157
- getMissionList: (status, limit = 20) => services.missionEngine?.listMissions(status, limit) ?? [],
1158
- getKnowledgeStats: () => {
1159
- const timeSeries = services.analytics?.getTimeSeries(undefined, 30) ?? [];
1160
- const summary = services.analytics?.getSummary();
1161
- const kgFacts = services.knowledgeGraph?.getStatus()?.totalFacts ?? 0;
1162
- const selfModStatus = services.selfModificationEngine?.getStatus();
1163
- return {
1164
- totals: {
1165
- principles: kgFacts + (summary?.rules?.active ?? 0),
1166
- hypotheses: summary?.insights?.active ?? 0,
1167
- experiments: (selfModStatus?.totalModifications ?? 0) + (summary?.antipatterns?.total ?? 0),
1168
- solutions: (summary?.solutions?.total ?? 0) + (selfModStatus?.byStatus?.['applied'] ?? 0),
1169
- },
1170
- timeSeries,
1171
- };
1172
- },
1173
- getRepoAbsorberStatus: () => services.repoAbsorber?.getStatus() ?? null,
1174
- getRepoAbsorberHistory: (limit = 10) => services.repoAbsorber?.getHistory(limit) ?? [],
1175
- getIntelligenceStats: () => ({
1176
- rag: services.ragEngine?.getStatus() ?? null,
1177
- ragIndexer: services.ragIndexer?.getStatus() ?? null,
1178
- kg: services.knowledgeGraph?.getStatus() ?? null,
1179
- contradictionResolver: services.contradictionResolver?.getStatus() ?? null,
1180
- feedback: services.feedbackEngine?.getStats() ?? null,
1181
- toolStats: services.toolTracker?.getToolStats() ?? [],
1182
- proactive: services.proactiveEngine?.getStatus() ?? null,
1183
- userModel: services.userModel?.getStatus() ?? null,
1184
- userProfile: services.userModel?.getProfile() ?? null,
1185
- goals: services.goalEngine ? (() => {
1186
- const status = services.goalEngine.getStatus();
1187
- const activeGoals = services.goalEngine.listGoals('active');
1188
- const progressList = activeGoals.map(g => ({
1189
- ...g,
1190
- progress: services.goalEngine.getProgress(g.id),
1191
- }));
1192
- return { ...status, progressList };
1193
- })() : null,
1194
- recommender: services.featureRecommender ? {
1195
- ...services.featureRecommender.getStatus(),
1196
- wishlist: services.featureRecommender.getWishlist()
1197
- .filter(w => w.status !== 'satisfied' && w.status !== 'dismissed'),
1198
- connections: services.featureRecommender.getConnections(),
1199
- } : null,
1200
- checkpoints: services.checkpointManager?.getStatus() ?? null,
1201
- traces: services.traceCollector?.getStatus() ?? null,
1202
- benchmark: services.benchmarkSuite?.getStatus() ?? null,
1203
- trainer: services.agentTrainer?.getStatus() ?? null,
1204
- toolScoping: services.toolScopeManager?.getStatus() ?? null,
1205
- marketplace: services.pluginMarketplace?.getStatus() ?? null,
1206
- sandbox: services.codeSandbox?.getStatus() ?? null,
1207
- }),
1208
- getEmotionalStatus: () => {
1209
- const mood = services.emotionalModel?.getMood?.();
1210
- return mood ?? { mood: 'reflective', score: 0.5, valence: 0, arousal: 0, dimensions: {} };
1211
- },
1212
- getGuardrailHealth: () => services.guardrailEngine?.checkHealth() ?? null,
1213
- getRoadmaps: () => services.researchRoadmap?.listRoadmaps() ?? [],
1214
- getCreativeInsights: () => services.creativeEngine?.getInsights(20) ?? [],
1215
- getDebateStatus: () => this.debateEngine?.getStatus() ?? null,
1216
- getDebateList: (limit = 10) => this.debateEngine?.listDebates(limit) ?? [],
1217
- getChallengeHistory: (limit = 20) => this.debateEngine?.getChallengeHistory(limit) ?? [],
1218
- getChallengeVulnerable: (limit = 5) => this.debateEngine?.getMostVulnerable(limit) ?? [],
1219
- triggerAction: async (action) => {
1220
- switch (action) {
1221
- case 'learning-cycle':
1222
- services.learning?.runCycle();
1223
- return { triggered: true };
1224
- case 'health-check':
1225
- return services.analytics?.getSummary() ?? {};
1226
- default:
1227
- return { triggered: false, message: `Unknown action: ${action}` };
1228
- }
1229
- },
862
+ this.commandCenter = createCommandCenter({
863
+ services, crossBrain: this.crossBrain, ecosystemService: this.ecosystemService,
864
+ correlator: this.correlator, watchdog, pluginRegistry: this.pluginRegistry,
865
+ borgSync: this.borgSync, thoughtStream, debateEngine: this.debateEngine,
1230
866
  });
1231
867
  this.commandCenter.start();
1232
868
  services.commandCenter = this.commandCenter;
@@ -1235,6 +871,11 @@ export class BrainCore {
1235
871
  const router = new IpcRouter(services);
1236
872
  this.ipcServer = new IpcServer(router, config.ipc.pipeName, 'brain', 'brain');
1237
873
  this.ipcServer.start();
874
+ // Wire ChatEngine to IPC router for NLU → IPC routing
875
+ chatEngine.setIpcHandler(async (method, params) => {
876
+ return router.handle(method, params);
877
+ });
878
+ chatEngine.setAvailableRoutes(router.listMethods());
1238
879
  // Wire local handler so cross-brain self-queries resolve locally
1239
880
  this.crossBrain.setLocalHandler((method, params) => router.handle(method, params));
1240
881
  // Wire subscription manager into IPC router
@@ -1334,15 +975,15 @@ export class BrainCore {
1334
975
  services.terminal.cleanup();
1335
976
  }, 60_000);
1336
977
  // 12b. DB retention cleanup + VACUUM (once at start, then every 24h)
1337
- this.runRetentionCleanup(this.db, config);
978
+ runRetentionHelper(this.db, config);
1338
979
  this.retentionTimer = setInterval(() => {
1339
980
  if (this.db && this.config)
1340
- this.runRetentionCleanup(this.db, this.config);
981
+ runRetentionHelper(this.db, this.config);
1341
982
  }, 24 * 60 * 60 * 1000);
1342
983
  // 13. Event listeners (synapse wiring)
1343
- this.setupEventListeners(services, synapseManager);
984
+ setupEventListeners(services, synapseManager, this.notifier, this.correlator, this.orchestrator);
1344
985
  // 13b. Cross-Brain Event Subscriptions
1345
- this.setupCrossBrainSubscriptions();
986
+ setupCrossBrainSubscriptions(this.subscriptionManager, this.correlator, this.orchestrator);
1346
987
  // 13c. Project Watch — rescan known projects on startup (delayed 5min)
1347
988
  setTimeout(() => {
1348
989
  try {
@@ -1379,111 +1020,26 @@ export class BrainCore {
1379
1020
  process.on('SIGINT', () => this.stop());
1380
1021
  process.on('SIGTERM', () => this.stop());
1381
1022
  // 16. Crash recovery — auto-restart on uncaught errors (with loop protection)
1382
- process.on('uncaughtException', (err) => {
1383
- // EPIPE = writing to closed stdout/stderr (daemon mode) — ignore silently
1384
- if (err.code === 'EPIPE')
1385
- return;
1386
- try {
1387
- logger.error('Uncaught exception', { error: err.message, stack: err.stack });
1388
- }
1389
- catch { /* logger may be broken */ }
1390
- this.logCrash('uncaughtException', err);
1391
- // Don't restart on port conflicts — it will just loop
1392
- if (err.code === 'EADDRINUSE') {
1393
- try {
1394
- logger.error('Port conflict during restart — stopping to prevent crash loop');
1395
- }
1396
- catch { /* ignore */ }
1397
- return;
1398
- }
1399
- this.restart();
1400
- });
1401
- process.on('unhandledRejection', (reason) => {
1402
- try {
1403
- logger.error('Unhandled rejection', { reason: String(reason) });
1404
- }
1405
- catch { /* logger may be broken */ }
1406
- this.logCrash('unhandledRejection', reason instanceof Error ? reason : new Error(String(reason)));
1407
- this.restart();
1408
- });
1023
+ setupCrashRecovery(config, () => this.restart());
1409
1024
  logger.info(`Brain daemon started (PID: ${process.pid})`);
1410
1025
  }
1411
1026
  logCrash(type, err) {
1412
- if (!this.config)
1413
- return;
1414
- const crashLog = path.join(path.dirname(this.config.dbPath), 'crashes.log');
1415
- const entry = `[${new Date().toISOString()}] ${type}: ${err.message}\n${err.stack ?? ''}\n\n`;
1416
- try {
1417
- // Rotate crash log if > 5MB (max 1 rotation = 10MB total)
1418
- try {
1419
- const stat = fs.statSync(crashLog);
1420
- if (stat.size > 5 * 1024 * 1024) {
1421
- const rotated = crashLog.replace('.log', '.1.log');
1422
- try {
1423
- fs.unlinkSync(rotated);
1424
- }
1425
- catch { /* no previous rotation */ }
1426
- fs.renameSync(crashLog, rotated);
1427
- }
1428
- }
1429
- catch { /* file doesn't exist yet */ }
1430
- fs.appendFileSync(crashLog, entry);
1431
- }
1432
- catch { /* best effort */ }
1433
- }
1434
- runRetentionCleanup(db, config) {
1435
- const logger = getLogger();
1436
- try {
1437
- const now = Date.now();
1438
- const errorCutoff = new Date(now - config.retention.errorDays * 86_400_000).toISOString();
1439
- const insightCutoff = new Date(now - config.retention.insightDays * 2 * 86_400_000).toISOString();
1440
- // Delete resolved errors older than retention period
1441
- const errResult = db.prepare("DELETE FROM errors WHERE status = 'resolved' AND created_at < ?").run(errorCutoff);
1442
- // Delete inactive insights older than 2× insightDays
1443
- const insResult = db.prepare("DELETE FROM insights WHERE status = 'inactive' AND created_at < ?").run(insightCutoff);
1444
- if (Number(errResult.changes) > 0 || Number(insResult.changes) > 0) {
1445
- logger.info(`[retention] Cleaned up ${errResult.changes} old errors, ${insResult.changes} old insights`);
1446
- }
1447
- // Optimize DB
1448
- db.pragma('optimize');
1449
- logger.debug('[retention] DB optimized');
1450
- }
1451
- catch (err) {
1452
- logger.warn(`[retention] Cleanup failed (non-critical): ${err.message}`);
1453
- }
1027
+ logCrashHelper(this.config, type, err);
1454
1028
  }
1455
1029
  cleanup() {
1456
- if (this.cleanupTimer) {
1457
- clearInterval(this.cleanupTimer);
1458
- this.cleanupTimer = null;
1459
- }
1460
- if (this.retentionTimer) {
1461
- clearInterval(this.retentionTimer);
1462
- this.retentionTimer = null;
1463
- }
1464
- this.borgSync?.stop();
1465
- // Stop messaging bots
1466
- this.telegramBot?.stop().catch(() => { });
1467
- this.discordBot?.stop().catch(() => { });
1468
- this.peerNetwork?.stopDiscovery();
1469
- // Unload all plugins gracefully
1470
- if (this.pluginRegistry?.size) {
1471
- for (const p of this.pluginRegistry.list()) {
1472
- this.pluginRegistry.unloadPlugin(p.name).catch(() => { });
1473
- }
1474
- }
1475
- this.subscriptionManager?.disconnectAll();
1476
- this.attentionEngine?.stop();
1477
- this.commandCenter?.stop();
1478
- this.orchestrator?.stop();
1479
- this.researchScheduler?.stop();
1480
- this.researchEngine?.stop();
1481
- this.embeddingEngine?.stop();
1482
- this.learningEngine?.stop();
1483
- this.mcpHttpServer?.stop();
1484
- this.apiServer?.stop();
1485
- this.ipcServer?.stop();
1486
- this.db?.close();
1030
+ cleanupEngines({
1031
+ cleanupTimer: this.cleanupTimer, retentionTimer: this.retentionTimer,
1032
+ borgSync: this.borgSync, telegramBot: this.telegramBot, discordBot: this.discordBot,
1033
+ peerNetwork: this.peerNetwork, pluginRegistry: this.pluginRegistry,
1034
+ subscriptionManager: this.subscriptionManager, attentionEngine: this.attentionEngine,
1035
+ commandCenter: this.commandCenter, orchestrator: this.orchestrator,
1036
+ researchScheduler: this.researchScheduler, researchEngine: this.researchEngine,
1037
+ embeddingEngine: this.embeddingEngine, learningEngine: this.learningEngine,
1038
+ mcpHttpServer: this.mcpHttpServer, apiServer: this.apiServer,
1039
+ ipcServer: this.ipcServer, db: this.db,
1040
+ });
1041
+ this.cleanupTimer = null;
1042
+ this.retentionTimer = null;
1487
1043
  this.db = null;
1488
1044
  this.ipcServer = null;
1489
1045
  this.apiServer = null;
@@ -1560,120 +1116,5 @@ export class BrainCore {
1560
1116
  logger.on('finish', () => { clearTimeout(exitTimeout); process.exit(0); });
1561
1117
  logger.end();
1562
1118
  }
1563
- setupCrossBrainSubscriptions() {
1564
- if (!this.subscriptionManager || !this.correlator)
1565
- return;
1566
- const logger = getLogger();
1567
- const correlator = this.correlator;
1568
- // Subscribe to trading-brain: trade:completed events for error-trade correlation
1569
- this.subscriptionManager.subscribe('trading-brain', ['trade:completed'], (event, data) => {
1570
- logger.info(`[cross-brain] Received ${event} from trading-brain`, { data });
1571
- correlator.recordEvent('trading-brain', event, data);
1572
- this.orchestrator?.onCrossBrainEvent('trading-brain', event, data);
1573
- });
1574
- // Subscribe to trading-brain: trade:outcome for win/loss correlation with errors
1575
- this.subscriptionManager.subscribe('trading-brain', ['trade:outcome'], (event, data) => {
1576
- correlator.recordEvent('trading-brain', event, data);
1577
- this.orchestrator?.onCrossBrainEvent('trading-brain', event, data);
1578
- const d = data;
1579
- if (d && d.win === false) {
1580
- // Check if correlator detected error-trade-loss pattern
1581
- const lossCorrelations = correlator.getCorrelations(0.3)
1582
- .filter(c => c.type === 'error-trade-loss');
1583
- if (lossCorrelations.length > 0) {
1584
- logger.warn(`[cross-brain] Trade loss correlated with recent errors (strength: ${lossCorrelations[0].strength.toFixed(2)})`);
1585
- }
1586
- }
1587
- });
1588
- // Subscribe to marketing-brain: post:published events for project activity tracking
1589
- this.subscriptionManager.subscribe('marketing-brain', ['post:published'], (event, data) => {
1590
- logger.info(`[cross-brain] Received ${event} from marketing-brain`, { data });
1591
- correlator.recordEvent('marketing-brain', event, data);
1592
- this.orchestrator?.onCrossBrainEvent('marketing-brain', event, data);
1593
- });
1594
- // Subscribe to marketing-brain: campaign:created for ecosystem awareness
1595
- this.subscriptionManager.subscribe('marketing-brain', ['campaign:created'], (event, data) => {
1596
- correlator.recordEvent('marketing-brain', event, data);
1597
- this.orchestrator?.onCrossBrainEvent('marketing-brain', event, data);
1598
- });
1599
- }
1600
- setupEventListeners(services, synapseManager) {
1601
- const bus = getEventBus();
1602
- const notifier = this.notifier;
1603
- const webhook = services.webhook;
1604
- const causal = services.causal;
1605
- const hypothesis = services.hypothesis;
1606
- const orch = this.orchestrator;
1607
- // Error → Project synapse + notify peers + feed correlator + webhooks + causal + hypothesis + orchestrator + prediction
1608
- bus.on('error:reported', ({ errorId, projectId }) => {
1609
- synapseManager.strengthen({ type: 'error', id: errorId }, { type: 'project', id: projectId }, 'co_occurs');
1610
- notifier?.notify('error:reported', { errorId, projectId });
1611
- this.correlator?.recordEvent('brain', 'error:reported', { errorId, projectId });
1612
- webhook?.fire('error:reported', { errorId, projectId });
1613
- causal?.recordEvent('brain', 'error:reported', { errorId, projectId });
1614
- hypothesis?.observe({ source: 'brain', type: 'error:reported', value: 1, timestamp: Date.now() });
1615
- orch?.onEvent('error:reported', { errorId, projectId });
1616
- });
1617
- // Solution applied → strengthen or weaken
1618
- bus.on('solution:applied', ({ errorId, solutionId, success }) => {
1619
- if (success) {
1620
- synapseManager.strengthen({ type: 'solution', id: solutionId }, { type: 'error', id: errorId }, 'solves');
1621
- }
1622
- else {
1623
- const synapse = synapseManager.find({ type: 'solution', id: solutionId }, { type: 'error', id: errorId }, 'solves');
1624
- if (synapse)
1625
- synapseManager.weaken(synapse.id, 0.7);
1626
- }
1627
- });
1628
- // Module registered → link to project
1629
- bus.on('module:registered', ({ moduleId, projectId }) => {
1630
- synapseManager.strengthen({ type: 'code_module', id: moduleId }, { type: 'project', id: projectId }, 'co_occurs');
1631
- });
1632
- // Rule learned → log + causal + hypothesis
1633
- bus.on('rule:learned', ({ ruleId, pattern }) => {
1634
- getLogger().info(`New rule #${ruleId} learned: ${pattern}`);
1635
- causal?.recordEvent('brain', 'rule:learned', { ruleId, pattern });
1636
- hypothesis?.observe({ source: 'brain', type: 'rule:learned', value: 1, timestamp: Date.now() });
1637
- orch?.onEvent('rule:learned', { ruleId });
1638
- });
1639
- // Insight created → log + notify marketing (content opportunity) + feed correlator + webhooks + causal + hypothesis
1640
- bus.on('insight:created', ({ insightId, type }) => {
1641
- getLogger().info(`New insight #${insightId} (${type})`);
1642
- notifier?.notifyPeer('marketing-brain', 'insight:created', { insightId, type });
1643
- this.correlator?.recordEvent('brain', 'insight:created', { insightId, type });
1644
- webhook?.fire('insight:created', { insightId, type });
1645
- causal?.recordEvent('brain', 'insight:created', { insightId, type });
1646
- hypothesis?.observe({ source: 'brain', type: 'insight:created', value: 1, timestamp: Date.now() });
1647
- orch?.onEvent('insight:created', { insightId, type });
1648
- });
1649
- // Solution applied → orchestrator
1650
- bus.on('solution:applied', ({ errorId, solutionId, success }) => {
1651
- orch?.onEvent('solution:applied', { errorId, solutionId, success: success ? 1 : 0 });
1652
- });
1653
- // Memory → Project synapse
1654
- bus.on('memory:created', ({ memoryId, projectId }) => {
1655
- if (projectId) {
1656
- synapseManager.strengthen({ type: 'memory', id: memoryId }, { type: 'project', id: projectId }, 'co_occurs');
1657
- }
1658
- });
1659
- // Session → Project synapse
1660
- bus.on('session:ended', ({ sessionId }) => {
1661
- getLogger().info(`Session #${sessionId} ended`);
1662
- });
1663
- // Decision → Project synapse
1664
- bus.on('decision:recorded', ({ decisionId, projectId }) => {
1665
- if (projectId) {
1666
- synapseManager.strengthen({ type: 'decision', id: decisionId }, { type: 'project', id: projectId }, 'co_occurs');
1667
- }
1668
- });
1669
- // Task created → log
1670
- bus.on('task:created', ({ taskId }) => {
1671
- getLogger().info(`Task #${taskId} created`);
1672
- });
1673
- // Task completed → log
1674
- bus.on('task:completed', ({ taskId }) => {
1675
- getLogger().info(`Task #${taskId} completed`);
1676
- });
1677
- }
1678
1119
  }
1679
1120
  //# sourceMappingURL=brain.js.map