@timmeck/brain 3.36.55 → 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, CrossBrainSignalRouter, runSignalRouterMigration, ChatEngine, runChatMigration, SubAgentFactory, runSubAgentMigration } 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,309 +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
- // CrossBrainSignalRouter — bidirectional signal routing
987
- runSignalRouterMigration(this.db);
988
- const signalRouter = new CrossBrainSignalRouter(this.db, 'brain');
989
- if (this.notifier)
990
- signalRouter.setNotifier(this.notifier);
991
- services.signalRouter = signalRouter;
992
- // 100. ChatEngine — NLU-routed chat interface
993
- runChatMigration(this.db);
994
- const chatEngine = new ChatEngine(this.db, { brainName: 'brain' });
995
- services.chatEngine = chatEngine;
996
- // 101. SubAgentFactory — spawn specialized sub-agents
997
- runSubAgentMigration(this.db);
998
- const subAgentFactory = new SubAgentFactory(this.db);
999
- services.subAgentFactory = subAgentFactory;
1000
- // ── Wire intelligence engines into autonomous ResearchOrchestrator ──
1001
- this.orchestrator.setFactExtractor(factExtractor);
1002
- this.orchestrator.setKnowledgeGraph(knowledgeGraph);
1003
- this.orchestrator.setSemanticCompressor(semanticCompressor);
1004
- this.orchestrator.setProactiveEngine(proactiveEngine);
1005
- this.orchestrator.setActiveLearner(activeLearner);
1006
- this.orchestrator.setRAGIndexer(ragIndexer);
1007
- this.orchestrator.setTeachingProtocol(teachingProtocol);
1008
- this.orchestrator.setCodeHealthMonitor(codeHealthMonitor);
1009
- this.orchestrator.setRepoAbsorber(repoAbsorber);
1010
- this.orchestrator.setFeatureRecommender(featureRecommender);
1011
- this.orchestrator.setFeatureExtractor(featureExtractor);
1012
- this.orchestrator.setContradictionResolver(contradictionResolver);
1013
- this.orchestrator.setCheckpointManager(checkpointManager);
1014
- this.orchestrator.setFeedbackEngine(feedbackEngine);
1015
- this.orchestrator.setUserModel(userModel);
1016
- this.orchestrator.setConsensusEngine(consensusEngine);
1017
- this.orchestrator.setTraceCollector(traceCollector);
1018
- this.orchestrator.setGuardrailEngine(guardrailEngine);
1019
- this.orchestrator.setCausalPlanner(causalPlanner);
1020
- this.orchestrator.setResearchRoadmap(researchRoadmap);
1021
- this.orchestrator.setCreativeEngine(creativeEngine);
1022
- this.orchestrator.setActionBridge(actionBridge);
1023
- this.orchestrator.setContentForge(contentForge);
1024
- this.orchestrator.setCodeForge(codeForge);
1025
- this.orchestrator.setStrategyForge(strategyForge);
1026
- 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)');
1027
- logger.info('Research orchestrator started (48+ steps, feedback loops active, DataMiner bootstrapped, Dream Mode active, Prediction Engine active)');
1028
- // 11k. Signal Scanner — GitHub/HN/Crypto signal tracking
1029
- if (config.scanner.enabled) {
1030
- const signalScanner = new SignalScanner(this.db, config.scanner);
1031
- this.orchestrator.setSignalScanner(signalScanner);
1032
- signalScanner.start();
1033
- services.signalScanner = signalScanner;
1034
- logger.info(`Signal scanner started (interval: ${config.scanner.scanIntervalMs}ms, token: ${config.scanner.githubToken ? 'yes' : 'NO — set GITHUB_TOKEN'})`);
1035
- }
1036
- // 11k2. TechRadar Engine — daily tech trend scanning + relevance analysis
1037
- try {
1038
- runTechRadarMigration(this.db);
1039
- const techRadar = new TechRadarEngine(this.db, {
1040
- githubToken: config.scanner.githubToken,
1041
- });
1042
- if (llmService)
1043
- techRadar.setLLMService(llmService);
1044
- techRadar.start();
1045
- services.techRadar = techRadar;
1046
- logger.info('TechRadar engine started');
1047
- }
1048
- catch (err) {
1049
- logger.warn(`TechRadar setup failed (non-critical): ${err.message}`);
1050
- }
1051
- // 11k3. NotificationService — multi-channel notifications
1052
- try {
1053
- runNotificationMigration(this.db);
1054
- const notificationService = new MultiChannelNotificationService(this.db);
1055
- // Auto-register available providers
1056
- const discordProvider = new DiscordProvider();
1057
- const telegramProvider = new TelegramProvider();
1058
- const emailProvider = new EmailProvider();
1059
- discordProvider.isAvailable().then(ok => {
1060
- if (ok) {
1061
- notificationService.registerProvider(discordProvider);
1062
- logger.info('Discord notification provider registered');
1063
- }
1064
- }).catch(() => { });
1065
- telegramProvider.isAvailable().then(ok => {
1066
- if (ok) {
1067
- notificationService.registerProvider(telegramProvider);
1068
- logger.info('Telegram notification provider registered');
1069
- }
1070
- }).catch(() => { });
1071
- emailProvider.isAvailable().then(ok => {
1072
- if (ok) {
1073
- notificationService.registerProvider(emailProvider);
1074
- logger.info('Email notification provider registered');
1075
- }
1076
- }).catch(() => { });
1077
- services.multiChannelNotifications = notificationService;
1078
- logger.info('NotificationService initialized');
1079
- }
1080
- catch (err) {
1081
- logger.warn(`NotificationService setup failed (non-critical): ${err.message}`);
1082
- }
1083
- // 11l. CodeMiner — mine repo contents from GitHub (needs GITHUB_TOKEN)
1084
- let patternExtractor;
1085
- if (config.scanner.githubToken) {
1086
- const codeMiner = new CodeMiner(this.db, { githubToken: config.scanner.githubToken });
1087
- patternExtractor = new PatternExtractor(this.db);
1088
- this.orchestrator.setCodeMiner(codeMiner);
1089
- services.codeMiner = codeMiner;
1090
- services.patternExtractor = patternExtractor;
1091
- void codeMiner.bootstrap();
1092
- logger.info('CodeMiner activated (GITHUB_TOKEN set)');
1093
- }
1094
- // 11m. CodeGenerator — autonomous code generation (needs ANTHROPIC_API_KEY)
1095
- if (process.env.ANTHROPIC_API_KEY) {
1096
- const codeGenerator = new CodeGenerator(this.db, { brainName: 'brain', apiKey: process.env.ANTHROPIC_API_KEY });
1097
- const contextBuilder = new ContextBuilder(this.orchestrator.knowledgeDistiller, this.orchestrator.journal, patternExtractor ?? null, services.signalScanner ?? null);
1098
- codeGenerator.setContextBuilder(contextBuilder);
1099
- codeGenerator.setThoughtStream(thoughtStream);
1100
- this.orchestrator.setCodeGenerator(codeGenerator);
1101
- services.codeGenerator = codeGenerator;
1102
- logger.info('CodeGenerator activated (ANTHROPIC_API_KEY set)');
1103
- // Wire ContextBuilder with SelfScanner into SelfModificationEngine
1104
- if (services.selfModificationEngine && services.selfScanner) {
1105
- const selfmodCtx = new ContextBuilder(this.orchestrator.knowledgeDistiller, this.orchestrator.journal, patternExtractor ?? null, services.signalScanner ?? null);
1106
- selfmodCtx.setSelfScanner(services.selfScanner);
1107
- services.selfModificationEngine.setContextBuilder(selfmodCtx);
1108
- }
1109
- }
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;
1110
823
  // 11c. Watchdog — monitoring only (detect peers via PID, run health checks)
1111
824
  const watchdogConfig = createDefaultWatchdogConfig();
1112
825
  const watchdog = new WatchdogService(watchdogConfig);
@@ -1146,108 +859,10 @@ export class BrainCore {
1146
859
  this.borgSync = new BorgSyncEngine('brain', this.crossBrain, borgProvider);
1147
860
  services.borgSync = this.borgSync;
1148
861
  // 11f. Command Center Dashboard
1149
- this.commandCenter = new CommandCenterServer({
1150
- port: 7790,
1151
- selfName: 'brain',
1152
- crossBrain: this.crossBrain,
1153
- ecosystemService: this.ecosystemService,
1154
- correlator: this.correlator,
1155
- watchdog,
1156
- pluginRegistry: this.pluginRegistry,
1157
- borgSync: this.borgSync,
1158
- thoughtStream,
1159
- getLLMStats: () => services.llmService?.getStats() ?? null,
1160
- getLLMHistory: (hours) => services.llmService?.getUsageHistory(hours) ?? [],
1161
- getErrors: () => {
1162
- const errors = services.error?.query({ limit: 20 }) ?? [];
1163
- const summary = services.analytics?.getSummary() ?? null;
1164
- return { errors, summary };
1165
- },
1166
- getSelfModStatus: () => services.selfModificationEngine?.getStatus() ?? null,
1167
- getSelfModHistory: (limit = 10) => services.selfModificationEngine?.getHistory(limit) ?? [],
1168
- selfmodApprove: (id) => services.selfModificationEngine?.approveModification(id),
1169
- selfmodReject: (id, notes) => services.selfModificationEngine?.rejectModification(id, notes),
1170
- getMissions: () => services.missionEngine?.getStatus() ?? null,
1171
- getMissionList: (status, limit = 20) => services.missionEngine?.listMissions(status, limit) ?? [],
1172
- getKnowledgeStats: () => {
1173
- const timeSeries = services.analytics?.getTimeSeries(undefined, 30) ?? [];
1174
- const summary = services.analytics?.getSummary();
1175
- const kgFacts = services.knowledgeGraph?.getStatus()?.totalFacts ?? 0;
1176
- const selfModStatus = services.selfModificationEngine?.getStatus();
1177
- return {
1178
- totals: {
1179
- principles: kgFacts + (summary?.rules?.active ?? 0),
1180
- hypotheses: summary?.insights?.active ?? 0,
1181
- experiments: (selfModStatus?.totalModifications ?? 0) + (summary?.antipatterns?.total ?? 0),
1182
- solutions: (summary?.solutions?.total ?? 0) + (selfModStatus?.byStatus?.['applied'] ?? 0),
1183
- },
1184
- timeSeries,
1185
- };
1186
- },
1187
- getRepoAbsorberStatus: () => services.repoAbsorber?.getStatus() ?? null,
1188
- getRepoAbsorberHistory: (limit = 10) => services.repoAbsorber?.getHistory(limit) ?? [],
1189
- getIntelligenceStats: () => ({
1190
- rag: services.ragEngine?.getStatus() ?? null,
1191
- ragIndexer: services.ragIndexer?.getStatus() ?? null,
1192
- kg: services.knowledgeGraph?.getStatus() ?? null,
1193
- contradictionResolver: services.contradictionResolver?.getStatus() ?? null,
1194
- feedback: services.feedbackEngine?.getStats() ?? null,
1195
- toolStats: services.toolTracker?.getToolStats() ?? [],
1196
- proactive: services.proactiveEngine?.getStatus() ?? null,
1197
- userModel: services.userModel?.getStatus() ?? null,
1198
- userProfile: services.userModel?.getProfile() ?? null,
1199
- goals: services.goalEngine ? (() => {
1200
- const status = services.goalEngine.getStatus();
1201
- const activeGoals = services.goalEngine.listGoals('active');
1202
- const progressList = activeGoals.map(g => ({
1203
- ...g,
1204
- progress: services.goalEngine.getProgress(g.id),
1205
- }));
1206
- return { ...status, progressList };
1207
- })() : null,
1208
- recommender: services.featureRecommender ? {
1209
- ...services.featureRecommender.getStatus(),
1210
- wishlist: services.featureRecommender.getWishlist()
1211
- .filter(w => w.status !== 'satisfied' && w.status !== 'dismissed'),
1212
- connections: services.featureRecommender.getConnections(),
1213
- } : null,
1214
- checkpoints: services.checkpointManager?.getStatus() ?? null,
1215
- traces: services.traceCollector?.getStatus() ?? null,
1216
- benchmark: services.benchmarkSuite?.getStatus() ?? null,
1217
- trainer: services.agentTrainer?.getStatus() ?? null,
1218
- toolScoping: services.toolScopeManager?.getStatus() ?? null,
1219
- marketplace: services.pluginMarketplace?.getStatus() ?? null,
1220
- sandbox: services.codeSandbox?.getStatus() ?? null,
1221
- }),
1222
- getEmotionalStatus: () => {
1223
- const mood = services.emotionalModel?.getMood?.();
1224
- return mood ?? { mood: 'reflective', score: 0.5, valence: 0, arousal: 0, dimensions: {} };
1225
- },
1226
- getGuardrailHealth: () => services.guardrailEngine?.checkHealth() ?? null,
1227
- getRoadmaps: () => services.researchRoadmap?.listRoadmaps() ?? [],
1228
- getCreativeInsights: () => services.creativeEngine?.getInsights(20) ?? [],
1229
- getActionBridgeStatus: () => services.actionBridge?.getStatus() ?? null,
1230
- getContentForgeStatus: () => services.contentForge?.getStatus() ?? null,
1231
- getStrategyForgeStatus: () => services.strategyForge?.getStatus() ?? null,
1232
- getSignalRouterStatus: () => services.signalRouter?.getStatus() ?? null,
1233
- chatMessage: async (sessionId, content) => services.chatEngine?.processMessage(sessionId, content) ?? null,
1234
- chatHistory: (sessionId) => services.chatEngine?.getHistory(sessionId) ?? [],
1235
- chatStatus: () => services.chatEngine?.getStatus() ?? null,
1236
- getDebateStatus: () => this.debateEngine?.getStatus() ?? null,
1237
- getDebateList: (limit = 10) => this.debateEngine?.listDebates(limit) ?? [],
1238
- getChallengeHistory: (limit = 20) => this.debateEngine?.getChallengeHistory(limit) ?? [],
1239
- getChallengeVulnerable: (limit = 5) => this.debateEngine?.getMostVulnerable(limit) ?? [],
1240
- triggerAction: async (action) => {
1241
- switch (action) {
1242
- case 'learning-cycle':
1243
- services.learning?.runCycle();
1244
- return { triggered: true };
1245
- case 'health-check':
1246
- return services.analytics?.getSummary() ?? {};
1247
- default:
1248
- return { triggered: false, message: `Unknown action: ${action}` };
1249
- }
1250
- },
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,
1251
866
  });
1252
867
  this.commandCenter.start();
1253
868
  services.commandCenter = this.commandCenter;
@@ -1360,15 +975,15 @@ export class BrainCore {
1360
975
  services.terminal.cleanup();
1361
976
  }, 60_000);
1362
977
  // 12b. DB retention cleanup + VACUUM (once at start, then every 24h)
1363
- this.runRetentionCleanup(this.db, config);
978
+ runRetentionHelper(this.db, config);
1364
979
  this.retentionTimer = setInterval(() => {
1365
980
  if (this.db && this.config)
1366
- this.runRetentionCleanup(this.db, this.config);
981
+ runRetentionHelper(this.db, this.config);
1367
982
  }, 24 * 60 * 60 * 1000);
1368
983
  // 13. Event listeners (synapse wiring)
1369
- this.setupEventListeners(services, synapseManager);
984
+ setupEventListeners(services, synapseManager, this.notifier, this.correlator, this.orchestrator);
1370
985
  // 13b. Cross-Brain Event Subscriptions
1371
- this.setupCrossBrainSubscriptions();
986
+ setupCrossBrainSubscriptions(this.subscriptionManager, this.correlator, this.orchestrator);
1372
987
  // 13c. Project Watch — rescan known projects on startup (delayed 5min)
1373
988
  setTimeout(() => {
1374
989
  try {
@@ -1405,111 +1020,26 @@ export class BrainCore {
1405
1020
  process.on('SIGINT', () => this.stop());
1406
1021
  process.on('SIGTERM', () => this.stop());
1407
1022
  // 16. Crash recovery — auto-restart on uncaught errors (with loop protection)
1408
- process.on('uncaughtException', (err) => {
1409
- // EPIPE = writing to closed stdout/stderr (daemon mode) — ignore silently
1410
- if (err.code === 'EPIPE')
1411
- return;
1412
- try {
1413
- logger.error('Uncaught exception', { error: err.message, stack: err.stack });
1414
- }
1415
- catch { /* logger may be broken */ }
1416
- this.logCrash('uncaughtException', err);
1417
- // Don't restart on port conflicts — it will just loop
1418
- if (err.code === 'EADDRINUSE') {
1419
- try {
1420
- logger.error('Port conflict during restart — stopping to prevent crash loop');
1421
- }
1422
- catch { /* ignore */ }
1423
- return;
1424
- }
1425
- this.restart();
1426
- });
1427
- process.on('unhandledRejection', (reason) => {
1428
- try {
1429
- logger.error('Unhandled rejection', { reason: String(reason) });
1430
- }
1431
- catch { /* logger may be broken */ }
1432
- this.logCrash('unhandledRejection', reason instanceof Error ? reason : new Error(String(reason)));
1433
- this.restart();
1434
- });
1023
+ setupCrashRecovery(config, () => this.restart());
1435
1024
  logger.info(`Brain daemon started (PID: ${process.pid})`);
1436
1025
  }
1437
1026
  logCrash(type, err) {
1438
- if (!this.config)
1439
- return;
1440
- const crashLog = path.join(path.dirname(this.config.dbPath), 'crashes.log');
1441
- const entry = `[${new Date().toISOString()}] ${type}: ${err.message}\n${err.stack ?? ''}\n\n`;
1442
- try {
1443
- // Rotate crash log if > 5MB (max 1 rotation = 10MB total)
1444
- try {
1445
- const stat = fs.statSync(crashLog);
1446
- if (stat.size > 5 * 1024 * 1024) {
1447
- const rotated = crashLog.replace('.log', '.1.log');
1448
- try {
1449
- fs.unlinkSync(rotated);
1450
- }
1451
- catch { /* no previous rotation */ }
1452
- fs.renameSync(crashLog, rotated);
1453
- }
1454
- }
1455
- catch { /* file doesn't exist yet */ }
1456
- fs.appendFileSync(crashLog, entry);
1457
- }
1458
- catch { /* best effort */ }
1459
- }
1460
- runRetentionCleanup(db, config) {
1461
- const logger = getLogger();
1462
- try {
1463
- const now = Date.now();
1464
- const errorCutoff = new Date(now - config.retention.errorDays * 86_400_000).toISOString();
1465
- const insightCutoff = new Date(now - config.retention.insightDays * 2 * 86_400_000).toISOString();
1466
- // Delete resolved errors older than retention period
1467
- const errResult = db.prepare("DELETE FROM errors WHERE status = 'resolved' AND created_at < ?").run(errorCutoff);
1468
- // Delete inactive insights older than 2× insightDays
1469
- const insResult = db.prepare("DELETE FROM insights WHERE status = 'inactive' AND created_at < ?").run(insightCutoff);
1470
- if (Number(errResult.changes) > 0 || Number(insResult.changes) > 0) {
1471
- logger.info(`[retention] Cleaned up ${errResult.changes} old errors, ${insResult.changes} old insights`);
1472
- }
1473
- // Optimize DB
1474
- db.pragma('optimize');
1475
- logger.debug('[retention] DB optimized');
1476
- }
1477
- catch (err) {
1478
- logger.warn(`[retention] Cleanup failed (non-critical): ${err.message}`);
1479
- }
1027
+ logCrashHelper(this.config, type, err);
1480
1028
  }
1481
1029
  cleanup() {
1482
- if (this.cleanupTimer) {
1483
- clearInterval(this.cleanupTimer);
1484
- this.cleanupTimer = null;
1485
- }
1486
- if (this.retentionTimer) {
1487
- clearInterval(this.retentionTimer);
1488
- this.retentionTimer = null;
1489
- }
1490
- this.borgSync?.stop();
1491
- // Stop messaging bots
1492
- this.telegramBot?.stop().catch(() => { });
1493
- this.discordBot?.stop().catch(() => { });
1494
- this.peerNetwork?.stopDiscovery();
1495
- // Unload all plugins gracefully
1496
- if (this.pluginRegistry?.size) {
1497
- for (const p of this.pluginRegistry.list()) {
1498
- this.pluginRegistry.unloadPlugin(p.name).catch(() => { });
1499
- }
1500
- }
1501
- this.subscriptionManager?.disconnectAll();
1502
- this.attentionEngine?.stop();
1503
- this.commandCenter?.stop();
1504
- this.orchestrator?.stop();
1505
- this.researchScheduler?.stop();
1506
- this.researchEngine?.stop();
1507
- this.embeddingEngine?.stop();
1508
- this.learningEngine?.stop();
1509
- this.mcpHttpServer?.stop();
1510
- this.apiServer?.stop();
1511
- this.ipcServer?.stop();
1512
- 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;
1513
1043
  this.db = null;
1514
1044
  this.ipcServer = null;
1515
1045
  this.apiServer = null;
@@ -1586,120 +1116,5 @@ export class BrainCore {
1586
1116
  logger.on('finish', () => { clearTimeout(exitTimeout); process.exit(0); });
1587
1117
  logger.end();
1588
1118
  }
1589
- setupCrossBrainSubscriptions() {
1590
- if (!this.subscriptionManager || !this.correlator)
1591
- return;
1592
- const logger = getLogger();
1593
- const correlator = this.correlator;
1594
- // Subscribe to trading-brain: trade:completed events for error-trade correlation
1595
- this.subscriptionManager.subscribe('trading-brain', ['trade:completed'], (event, data) => {
1596
- logger.info(`[cross-brain] Received ${event} from trading-brain`, { data });
1597
- correlator.recordEvent('trading-brain', event, data);
1598
- this.orchestrator?.onCrossBrainEvent('trading-brain', event, data);
1599
- });
1600
- // Subscribe to trading-brain: trade:outcome for win/loss correlation with errors
1601
- this.subscriptionManager.subscribe('trading-brain', ['trade:outcome'], (event, data) => {
1602
- correlator.recordEvent('trading-brain', event, data);
1603
- this.orchestrator?.onCrossBrainEvent('trading-brain', event, data);
1604
- const d = data;
1605
- if (d && d.win === false) {
1606
- // Check if correlator detected error-trade-loss pattern
1607
- const lossCorrelations = correlator.getCorrelations(0.3)
1608
- .filter(c => c.type === 'error-trade-loss');
1609
- if (lossCorrelations.length > 0) {
1610
- logger.warn(`[cross-brain] Trade loss correlated with recent errors (strength: ${lossCorrelations[0].strength.toFixed(2)})`);
1611
- }
1612
- }
1613
- });
1614
- // Subscribe to marketing-brain: post:published events for project activity tracking
1615
- this.subscriptionManager.subscribe('marketing-brain', ['post:published'], (event, data) => {
1616
- logger.info(`[cross-brain] Received ${event} from marketing-brain`, { data });
1617
- correlator.recordEvent('marketing-brain', event, data);
1618
- this.orchestrator?.onCrossBrainEvent('marketing-brain', event, data);
1619
- });
1620
- // Subscribe to marketing-brain: campaign:created for ecosystem awareness
1621
- this.subscriptionManager.subscribe('marketing-brain', ['campaign:created'], (event, data) => {
1622
- correlator.recordEvent('marketing-brain', event, data);
1623
- this.orchestrator?.onCrossBrainEvent('marketing-brain', event, data);
1624
- });
1625
- }
1626
- setupEventListeners(services, synapseManager) {
1627
- const bus = getEventBus();
1628
- const notifier = this.notifier;
1629
- const webhook = services.webhook;
1630
- const causal = services.causal;
1631
- const hypothesis = services.hypothesis;
1632
- const orch = this.orchestrator;
1633
- // Error → Project synapse + notify peers + feed correlator + webhooks + causal + hypothesis + orchestrator + prediction
1634
- bus.on('error:reported', ({ errorId, projectId }) => {
1635
- synapseManager.strengthen({ type: 'error', id: errorId }, { type: 'project', id: projectId }, 'co_occurs');
1636
- notifier?.notify('error:reported', { errorId, projectId });
1637
- this.correlator?.recordEvent('brain', 'error:reported', { errorId, projectId });
1638
- webhook?.fire('error:reported', { errorId, projectId });
1639
- causal?.recordEvent('brain', 'error:reported', { errorId, projectId });
1640
- hypothesis?.observe({ source: 'brain', type: 'error:reported', value: 1, timestamp: Date.now() });
1641
- orch?.onEvent('error:reported', { errorId, projectId });
1642
- });
1643
- // Solution applied → strengthen or weaken
1644
- bus.on('solution:applied', ({ errorId, solutionId, success }) => {
1645
- if (success) {
1646
- synapseManager.strengthen({ type: 'solution', id: solutionId }, { type: 'error', id: errorId }, 'solves');
1647
- }
1648
- else {
1649
- const synapse = synapseManager.find({ type: 'solution', id: solutionId }, { type: 'error', id: errorId }, 'solves');
1650
- if (synapse)
1651
- synapseManager.weaken(synapse.id, 0.7);
1652
- }
1653
- });
1654
- // Module registered → link to project
1655
- bus.on('module:registered', ({ moduleId, projectId }) => {
1656
- synapseManager.strengthen({ type: 'code_module', id: moduleId }, { type: 'project', id: projectId }, 'co_occurs');
1657
- });
1658
- // Rule learned → log + causal + hypothesis
1659
- bus.on('rule:learned', ({ ruleId, pattern }) => {
1660
- getLogger().info(`New rule #${ruleId} learned: ${pattern}`);
1661
- causal?.recordEvent('brain', 'rule:learned', { ruleId, pattern });
1662
- hypothesis?.observe({ source: 'brain', type: 'rule:learned', value: 1, timestamp: Date.now() });
1663
- orch?.onEvent('rule:learned', { ruleId });
1664
- });
1665
- // Insight created → log + notify marketing (content opportunity) + feed correlator + webhooks + causal + hypothesis
1666
- bus.on('insight:created', ({ insightId, type }) => {
1667
- getLogger().info(`New insight #${insightId} (${type})`);
1668
- notifier?.notifyPeer('marketing-brain', 'insight:created', { insightId, type });
1669
- this.correlator?.recordEvent('brain', 'insight:created', { insightId, type });
1670
- webhook?.fire('insight:created', { insightId, type });
1671
- causal?.recordEvent('brain', 'insight:created', { insightId, type });
1672
- hypothesis?.observe({ source: 'brain', type: 'insight:created', value: 1, timestamp: Date.now() });
1673
- orch?.onEvent('insight:created', { insightId, type });
1674
- });
1675
- // Solution applied → orchestrator
1676
- bus.on('solution:applied', ({ errorId, solutionId, success }) => {
1677
- orch?.onEvent('solution:applied', { errorId, solutionId, success: success ? 1 : 0 });
1678
- });
1679
- // Memory → Project synapse
1680
- bus.on('memory:created', ({ memoryId, projectId }) => {
1681
- if (projectId) {
1682
- synapseManager.strengthen({ type: 'memory', id: memoryId }, { type: 'project', id: projectId }, 'co_occurs');
1683
- }
1684
- });
1685
- // Session → Project synapse
1686
- bus.on('session:ended', ({ sessionId }) => {
1687
- getLogger().info(`Session #${sessionId} ended`);
1688
- });
1689
- // Decision → Project synapse
1690
- bus.on('decision:recorded', ({ decisionId, projectId }) => {
1691
- if (projectId) {
1692
- synapseManager.strengthen({ type: 'decision', id: decisionId }, { type: 'project', id: projectId }, 'co_occurs');
1693
- }
1694
- });
1695
- // Task created → log
1696
- bus.on('task:created', ({ taskId }) => {
1697
- getLogger().info(`Task #${taskId} created`);
1698
- });
1699
- // Task completed → log
1700
- bus.on('task:completed', ({ taskId }) => {
1701
- getLogger().info(`Task #${taskId} completed`);
1702
- });
1703
- }
1704
1119
  }
1705
1120
  //# sourceMappingURL=brain.js.map