@timmeck/brain 3.36.55 → 3.36.57
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.d.ts +0 -3
- package/dist/brain.js +42 -627
- package/dist/brain.js.map +1 -1
- package/dist/cli/commands/desires.d.ts +2 -0
- package/dist/cli/commands/desires.js +44 -0
- package/dist/cli/commands/desires.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/init/dashboard-init.d.ts +24 -0
- package/dist/init/dashboard-init.js +112 -0
- package/dist/init/dashboard-init.js.map +1 -0
- package/dist/init/engine-factory.d.ts +33 -0
- package/dist/init/engine-factory.js +351 -0
- package/dist/init/engine-factory.js.map +1 -0
- package/dist/init/events-init.d.ts +5 -0
- package/dist/init/events-init.js +104 -0
- package/dist/init/events-init.js.map +1 -0
- package/dist/init/lifecycle.d.ts +65 -0
- package/dist/init/lifecycle.js +117 -0
- package/dist/init/lifecycle.js.map +1 -0
- package/dist/ipc/router.js +18 -0
- package/dist/ipc/router.js.map +1 -1
- package/dist/mcp/intelligence-tools.js +5 -0
- package/dist/mcp/intelligence-tools.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lifecycle helpers — extracted from BrainCore.logCrash, runRetentionCleanup, cleanup, restart, stop.
|
|
3
|
+
* Pure extraction, no logic changes.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { getLogger } from '../utils/logger.js';
|
|
8
|
+
// ── Standalone helpers (no BrainCore refs needed) ──────────
|
|
9
|
+
export function logCrash(config, type, err) {
|
|
10
|
+
if (!config)
|
|
11
|
+
return;
|
|
12
|
+
const crashLog = path.join(path.dirname(config.dbPath), 'crashes.log');
|
|
13
|
+
const entry = `[${new Date().toISOString()}] ${type}: ${err.message}\n${err.stack ?? ''}\n\n`;
|
|
14
|
+
try {
|
|
15
|
+
// Rotate crash log if > 5MB (max 1 rotation = 10MB total)
|
|
16
|
+
try {
|
|
17
|
+
const stat = fs.statSync(crashLog);
|
|
18
|
+
if (stat.size > 5 * 1024 * 1024) {
|
|
19
|
+
const rotated = crashLog.replace('.log', '.1.log');
|
|
20
|
+
try {
|
|
21
|
+
fs.unlinkSync(rotated);
|
|
22
|
+
}
|
|
23
|
+
catch { /* no previous rotation */ }
|
|
24
|
+
fs.renameSync(crashLog, rotated);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch { /* file doesn't exist yet */ }
|
|
28
|
+
fs.appendFileSync(crashLog, entry);
|
|
29
|
+
}
|
|
30
|
+
catch { /* best effort */ }
|
|
31
|
+
}
|
|
32
|
+
export function runRetentionCleanup(db, config) {
|
|
33
|
+
const logger = getLogger();
|
|
34
|
+
try {
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
const errorCutoff = new Date(now - config.retention.errorDays * 86_400_000).toISOString();
|
|
37
|
+
const insightCutoff = new Date(now - config.retention.insightDays * 2 * 86_400_000).toISOString();
|
|
38
|
+
// Delete resolved errors older than retention period
|
|
39
|
+
const errResult = db.prepare("DELETE FROM errors WHERE status = 'resolved' AND created_at < ?").run(errorCutoff);
|
|
40
|
+
// Delete inactive insights older than 2× insightDays
|
|
41
|
+
const insResult = db.prepare("DELETE FROM insights WHERE status = 'inactive' AND created_at < ?").run(insightCutoff);
|
|
42
|
+
if (Number(errResult.changes) > 0 || Number(insResult.changes) > 0) {
|
|
43
|
+
logger.info(`[retention] Cleaned up ${errResult.changes} old errors, ${insResult.changes} old insights`);
|
|
44
|
+
}
|
|
45
|
+
// Optimize DB
|
|
46
|
+
db.pragma('optimize');
|
|
47
|
+
logger.debug('[retention] DB optimized');
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
logger.warn(`[retention] Cleanup failed (non-critical): ${err.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function cleanup(refs) {
|
|
54
|
+
if (refs.cleanupTimer) {
|
|
55
|
+
clearInterval(refs.cleanupTimer);
|
|
56
|
+
refs.cleanupTimer = null;
|
|
57
|
+
}
|
|
58
|
+
if (refs.retentionTimer) {
|
|
59
|
+
clearInterval(refs.retentionTimer);
|
|
60
|
+
refs.retentionTimer = null;
|
|
61
|
+
}
|
|
62
|
+
refs.borgSync?.stop();
|
|
63
|
+
// Stop messaging bots
|
|
64
|
+
refs.telegramBot?.stop().catch(() => { });
|
|
65
|
+
refs.discordBot?.stop().catch(() => { });
|
|
66
|
+
refs.peerNetwork?.stopDiscovery();
|
|
67
|
+
// Unload all plugins gracefully
|
|
68
|
+
if (refs.pluginRegistry?.size) {
|
|
69
|
+
for (const p of refs.pluginRegistry.list()) {
|
|
70
|
+
refs.pluginRegistry.unloadPlugin(p.name).catch(() => { });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
refs.subscriptionManager?.disconnectAll();
|
|
74
|
+
refs.attentionEngine?.stop();
|
|
75
|
+
refs.commandCenter?.stop();
|
|
76
|
+
refs.orchestrator?.stop();
|
|
77
|
+
refs.researchScheduler?.stop();
|
|
78
|
+
refs.researchEngine?.stop();
|
|
79
|
+
refs.embeddingEngine?.stop();
|
|
80
|
+
refs.learningEngine?.stop();
|
|
81
|
+
refs.mcpHttpServer?.stop();
|
|
82
|
+
refs.apiServer?.stop();
|
|
83
|
+
refs.ipcServer?.stop();
|
|
84
|
+
refs.db?.close();
|
|
85
|
+
}
|
|
86
|
+
// ── Crash recovery: process-level error handlers ──────────
|
|
87
|
+
export function setupCrashRecovery(config, onRestart) {
|
|
88
|
+
const logger = getLogger();
|
|
89
|
+
process.on('uncaughtException', (err) => {
|
|
90
|
+
// EPIPE = writing to closed stdout/stderr (daemon mode) — ignore silently
|
|
91
|
+
if (err.code === 'EPIPE')
|
|
92
|
+
return;
|
|
93
|
+
try {
|
|
94
|
+
logger.error('Uncaught exception', { error: err.message, stack: err.stack });
|
|
95
|
+
}
|
|
96
|
+
catch { /* logger may be broken */ }
|
|
97
|
+
logCrash(config, 'uncaughtException', err);
|
|
98
|
+
// Don't restart on port conflicts — it will just loop
|
|
99
|
+
if (err.code === 'EADDRINUSE') {
|
|
100
|
+
try {
|
|
101
|
+
logger.error('Port conflict during restart — stopping to prevent crash loop');
|
|
102
|
+
}
|
|
103
|
+
catch { /* ignore */ }
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
onRestart();
|
|
107
|
+
});
|
|
108
|
+
process.on('unhandledRejection', (reason) => {
|
|
109
|
+
try {
|
|
110
|
+
logger.error('Unhandled rejection', { reason: String(reason) });
|
|
111
|
+
}
|
|
112
|
+
catch { /* logger may be broken */ }
|
|
113
|
+
logCrash(config, 'unhandledRejection', reason instanceof Error ? reason : new Error(String(reason)));
|
|
114
|
+
onRestart();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/init/lifecycle.ts"],"names":[],"mappings":"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"}
|
package/dist/ipc/router.js
CHANGED
|
@@ -33,6 +33,11 @@ export class IpcRouter {
|
|
|
33
33
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
34
|
const { source, event, data } = params;
|
|
35
35
|
logger.info(`Cross-brain event from ${source}: ${event}`);
|
|
36
|
+
// Route teaching lessons to TeachingProtocol
|
|
37
|
+
if (event === 'teaching.learn' && this.services.teachingProtocol) {
|
|
38
|
+
this.services.teachingProtocol.learn(data);
|
|
39
|
+
logger.info(`[cross-brain] Learned lesson from ${source}`);
|
|
40
|
+
}
|
|
36
41
|
manager.handleIncomingEvent(source, event, data);
|
|
37
42
|
return { received: true, source, event };
|
|
38
43
|
});
|
|
@@ -506,6 +511,8 @@ export class IpcRouter {
|
|
|
506
511
|
throw new Error('Prediction engine not available'); return { resolved: s.predictionEngine.resolveExpired() }; }],
|
|
507
512
|
['predict.record', (params) => { if (!s.predictionEngine)
|
|
508
513
|
throw new Error('Prediction engine not available'); s.predictionEngine.recordMetric(p(params).metric, p(params).value, p(params)?.domain); return { recorded: true }; }],
|
|
514
|
+
['predict.calibration', () => { if (!s.predictionEngine)
|
|
515
|
+
throw new Error('Prediction engine not available'); return s.predictionEngine.getCalibration(); }],
|
|
509
516
|
// ─── Consciousness ──────────────────────────────────────
|
|
510
517
|
['consciousness.status', () => { if (!s.thoughtStream)
|
|
511
518
|
throw new Error('ThoughtStream not available'); return { ...s.thoughtStream.getStats(), engines: s.thoughtStream.getEngineActivity(), clients: s.consciousnessServer?.getClientCount() ?? 0 }; }],
|
|
@@ -1444,6 +1451,17 @@ export class IpcRouter {
|
|
|
1444
1451
|
throw new Error(`Agent not found: ${pp.name}`); return agent.execute(pp.input); }],
|
|
1445
1452
|
['subagent.presets', () => { if (!s.subAgentFactory)
|
|
1446
1453
|
throw new Error('SubAgentFactory not available'); return s.subAgentFactory.getPresets(); }],
|
|
1454
|
+
// ─── Self-Improvement Desires ─────────────────────────────
|
|
1455
|
+
['desires.suggestions', () => { if (!s.orchestrator)
|
|
1456
|
+
throw new Error('Orchestrator not available'); return s.orchestrator.generateSelfImprovementSuggestions(); }],
|
|
1457
|
+
['desires.structured', () => { if (!s.orchestrator)
|
|
1458
|
+
throw new Error('Orchestrator not available'); return s.orchestrator.getDesires(); }],
|
|
1459
|
+
['desires.status', () => {
|
|
1460
|
+
if (!s.orchestrator)
|
|
1461
|
+
throw new Error('Orchestrator not available');
|
|
1462
|
+
const desires = s.orchestrator.getDesires();
|
|
1463
|
+
return { count: desires.length, topPriority: desires[0]?.priority ?? 0, top: desires[0]?.suggestion ?? 'none' };
|
|
1464
|
+
}],
|
|
1447
1465
|
// Status (cross-brain)
|
|
1448
1466
|
['status', () => ({
|
|
1449
1467
|
name: 'brain',
|