@timmeck/brain-core 2.5.0 → 2.7.0

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.
Files changed (38) hide show
  1. package/dist/dashboard/research-server.d.ts +11 -0
  2. package/dist/dashboard/research-server.js +47 -0
  3. package/dist/dashboard/research-server.js.map +1 -0
  4. package/dist/index.d.ts +22 -0
  5. package/dist/index.js +21 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/research/adaptive-strategy.d.ts +56 -0
  8. package/dist/research/adaptive-strategy.js +236 -0
  9. package/dist/research/adaptive-strategy.js.map +1 -0
  10. package/dist/research/agenda-engine.d.ts +46 -0
  11. package/dist/research/agenda-engine.js +264 -0
  12. package/dist/research/agenda-engine.js.map +1 -0
  13. package/dist/research/anomaly-detective.d.ts +62 -0
  14. package/dist/research/anomaly-detective.js +318 -0
  15. package/dist/research/anomaly-detective.js.map +1 -0
  16. package/dist/research/counterfactual-engine.d.ts +63 -0
  17. package/dist/research/counterfactual-engine.js +263 -0
  18. package/dist/research/counterfactual-engine.js.map +1 -0
  19. package/dist/research/cross-domain-engine.d.ts +52 -0
  20. package/dist/research/cross-domain-engine.js +283 -0
  21. package/dist/research/cross-domain-engine.js.map +1 -0
  22. package/dist/research/experiment-engine.d.ts +77 -0
  23. package/dist/research/experiment-engine.js +328 -0
  24. package/dist/research/experiment-engine.js.map +1 -0
  25. package/dist/research/journal.d.ts +62 -0
  26. package/dist/research/journal.js +262 -0
  27. package/dist/research/journal.js.map +1 -0
  28. package/dist/research/knowledge-distiller.d.ts +95 -0
  29. package/dist/research/knowledge-distiller.js +426 -0
  30. package/dist/research/knowledge-distiller.js.map +1 -0
  31. package/dist/research/research-orchestrator.d.ts +68 -0
  32. package/dist/research/research-orchestrator.js +228 -0
  33. package/dist/research/research-orchestrator.js.map +1 -0
  34. package/dist/research/self-observer.d.ts +55 -0
  35. package/dist/research/self-observer.js +268 -0
  36. package/dist/research/self-observer.js.map +1 -0
  37. package/package.json +1 -1
  38. package/research-dashboard.html +735 -0
@@ -0,0 +1,228 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ import { SelfObserver } from './self-observer.js';
3
+ import { AdaptiveStrategyEngine } from './adaptive-strategy.js';
4
+ import { ExperimentEngine } from './experiment-engine.js';
5
+ import { CrossDomainEngine } from './cross-domain-engine.js';
6
+ import { CounterfactualEngine } from './counterfactual-engine.js';
7
+ import { KnowledgeDistiller } from './knowledge-distiller.js';
8
+ import { ResearchAgendaEngine } from './agenda-engine.js';
9
+ import { AnomalyDetective } from './anomaly-detective.js';
10
+ import { ResearchJournal } from './journal.js';
11
+ // ── Orchestrator ────────────────────────────────────────
12
+ export class ResearchOrchestrator {
13
+ selfObserver;
14
+ adaptiveStrategy;
15
+ experimentEngine;
16
+ crossDomain;
17
+ counterfactual;
18
+ knowledgeDistiller;
19
+ researchAgenda;
20
+ anomalyDetective;
21
+ journal;
22
+ brainName;
23
+ feedbackTimer = null;
24
+ cycleCount = 0;
25
+ distillEvery;
26
+ agendaEvery;
27
+ reflectEvery;
28
+ log = getLogger();
29
+ constructor(db, config, causalGraph) {
30
+ this.brainName = config.brainName;
31
+ this.distillEvery = config.distillEvery ?? 5;
32
+ this.agendaEvery = config.agendaEvery ?? 3;
33
+ this.reflectEvery = config.reflectEvery ?? 10;
34
+ this.selfObserver = new SelfObserver(db, { brainName: config.brainName });
35
+ this.adaptiveStrategy = new AdaptiveStrategyEngine(db, { brainName: config.brainName });
36
+ this.experimentEngine = new ExperimentEngine(db, { brainName: config.brainName });
37
+ this.crossDomain = new CrossDomainEngine(db);
38
+ this.counterfactual = new CounterfactualEngine(db, causalGraph ?? null);
39
+ this.knowledgeDistiller = new KnowledgeDistiller(db, { brainName: config.brainName });
40
+ this.researchAgenda = new ResearchAgendaEngine(db, { brainName: config.brainName });
41
+ this.anomalyDetective = new AnomalyDetective(db, { brainName: config.brainName });
42
+ this.journal = new ResearchJournal(db, { brainName: config.brainName });
43
+ }
44
+ /** Start the autonomous feedback loop timer. */
45
+ start(intervalMs = 300_000) {
46
+ if (this.feedbackTimer)
47
+ return;
48
+ this.feedbackTimer = setInterval(() => {
49
+ try {
50
+ this.runFeedbackCycle();
51
+ }
52
+ catch (err) {
53
+ this.log.error('[orchestrator] Feedback cycle error', { error: err.message });
54
+ }
55
+ }, intervalMs);
56
+ this.log.info(`[orchestrator] Research orchestrator started (feedback every ${intervalMs}ms)`);
57
+ }
58
+ /** Stop the feedback loop. */
59
+ stop() {
60
+ if (this.feedbackTimer) {
61
+ clearInterval(this.feedbackTimer);
62
+ this.feedbackTimer = null;
63
+ }
64
+ }
65
+ /**
66
+ * Feed a domain event from the brain's EventBus.
67
+ * Routes to: SelfObserver, AnomalyDetective, CrossDomain.
68
+ */
69
+ onEvent(eventType, data = {}) {
70
+ this.selfObserver.record({
71
+ category: categorize(eventType),
72
+ event_type: eventType,
73
+ metrics: data,
74
+ });
75
+ this.anomalyDetective.recordMetric(eventType, 1);
76
+ this.crossDomain.recordEvent(this.brainName, eventType, data);
77
+ }
78
+ /**
79
+ * Feed a cross-brain event from CrossBrainSubscription.
80
+ * Routes to: CrossDomainEngine, AnomalyDetective.
81
+ */
82
+ onCrossBrainEvent(sourceBrain, eventType, data = {}) {
83
+ this.crossDomain.recordEvent(sourceBrain, eventType, data);
84
+ this.anomalyDetective.recordMetric(`cross:${sourceBrain}:${eventType}`, 1);
85
+ }
86
+ /**
87
+ * Hook into AutonomousResearchScheduler cycle completion.
88
+ * Records discoveries in journal and feeds metrics to anomaly detection.
89
+ */
90
+ onResearchCycleComplete(report) {
91
+ // Record cycle metrics for anomaly detection
92
+ this.anomalyDetective.recordMetric('research_discoveries', report.discoveriesProduced);
93
+ this.anomalyDetective.recordMetric('research_hypotheses_tested', report.hypothesesTested);
94
+ this.anomalyDetective.recordMetric('research_confirmed', report.hypothesesConfirmed);
95
+ this.anomalyDetective.recordMetric('research_duration_ms', report.duration);
96
+ // Self-observe the research cycle
97
+ this.selfObserver.record({
98
+ category: 'latency',
99
+ event_type: 'research:cycle_complete',
100
+ metrics: {
101
+ cycle: report.cycle,
102
+ discoveries: report.discoveriesProduced,
103
+ duration_ms: report.duration,
104
+ confirmed: report.hypothesesConfirmed,
105
+ rejected: report.hypothesesRejected,
106
+ },
107
+ });
108
+ // Journal the cycle
109
+ if (report.discoveriesProduced > 0 || report.hypothesesConfirmed > 0) {
110
+ this.journal.recordDiscovery(`Research Cycle #${report.cycle}`, `Cycle completed: ${report.discoveriesProduced} discoveries, ${report.hypothesesConfirmed} hypotheses confirmed, ${report.hypothesesRejected} rejected, ${report.causalEdgesFound} causal edges. Duration: ${report.duration}ms.`, { report }, report.hypothesesConfirmed > 0 ? 'notable' : 'routine');
111
+ }
112
+ }
113
+ /**
114
+ * Run one autonomous feedback cycle.
115
+ * This is where the engines talk to each other.
116
+ */
117
+ runFeedbackCycle() {
118
+ this.cycleCount++;
119
+ const start = Date.now();
120
+ this.log.info(`[orchestrator] ─── Feedback Cycle #${this.cycleCount} ───`);
121
+ // 1. Self-observer analyzes accumulated observations → insights
122
+ const insights = this.selfObserver.analyze();
123
+ if (insights.length > 0) {
124
+ this.log.info(`[orchestrator] Self-observer: ${insights.length} insights`);
125
+ for (const insight of insights) {
126
+ this.journal.recordDiscovery(insight.title, insight.description, { ...insight.evidence, type: insight.type, confidence: insight.confidence }, insight.confidence > 0.8 ? 'notable' : 'routine');
127
+ }
128
+ }
129
+ // 2. Anomaly detection
130
+ const anomalies = this.anomalyDetective.detect();
131
+ if (anomalies.length > 0) {
132
+ this.log.info(`[orchestrator] Anomalies detected: ${anomalies.length}`);
133
+ for (const a of anomalies) {
134
+ this.journal.write({
135
+ type: 'anomaly',
136
+ title: a.title,
137
+ content: a.description,
138
+ tags: [this.brainName, 'anomaly', a.type, a.severity],
139
+ references: [],
140
+ significance: a.severity === 'critical' ? 'breakthrough' : a.severity === 'high' ? 'notable' : 'routine',
141
+ data: { metric: a.metric, expected: a.expected_value, actual: a.actual_value, deviation: a.deviation },
142
+ });
143
+ }
144
+ }
145
+ // 3. Cross-domain correlation analysis
146
+ const correlations = this.crossDomain.analyze();
147
+ const significant = correlations.filter(c => Math.abs(c.correlation) > 0.5 && c.p_value < 0.05);
148
+ if (significant.length > 0) {
149
+ this.log.info(`[orchestrator] Cross-domain: ${significant.length} significant correlations`);
150
+ for (const corr of significant) {
151
+ this.journal.recordDiscovery(`Cross-domain: ${corr.source_brain}:${corr.source_event} → ${corr.target_brain}:${corr.target_event}`, corr.narrative, { correlation: corr.correlation, pValue: corr.p_value, lag: corr.lag_seconds }, 'notable');
152
+ }
153
+ }
154
+ // 4. Adaptive strategy: check for regressions and revert
155
+ const reverted = this.adaptiveStrategy.checkAndRevert(this.cycleCount);
156
+ for (const r of reverted) {
157
+ this.journal.write({
158
+ type: 'adaptation',
159
+ title: `Reverted: ${r.strategy}/${r.parameter}`,
160
+ content: `Strategy adaptation reverted: ${r.parameter} from ${r.new_value} back to ${r.old_value}. Reason: ${r.reason}`,
161
+ tags: [this.brainName, 'revert', r.strategy],
162
+ references: [],
163
+ significance: 'notable',
164
+ data: { adaptation: r },
165
+ });
166
+ }
167
+ // 5. Check running experiments
168
+ const experiments = this.experimentEngine.list();
169
+ for (const exp of experiments) {
170
+ if (exp.status === 'analyzing' && exp.id) {
171
+ const result = this.experimentEngine.analyze(exp.id);
172
+ if (result?.conclusion) {
173
+ const sig = result.conclusion.significant;
174
+ this.journal.recordExperiment(exp.name, sig ? (result.conclusion.direction === 'positive' ? 'confirmed' : 'rejected') : 'inconclusive', { conclusion: result.conclusion, hypothesis: exp.hypothesis }, sig);
175
+ this.log.info(`[orchestrator] Experiment "${exp.name}": ${sig ? result.conclusion.direction : 'inconclusive'} (p=${result.conclusion.p_value.toFixed(4)}, d=${result.conclusion.effect_size.toFixed(2)})`);
176
+ }
177
+ }
178
+ }
179
+ // 6. Knowledge distillation (periodic)
180
+ if (this.cycleCount % this.distillEvery === 0) {
181
+ const { principles, antiPatterns, strategies } = this.knowledgeDistiller.distill();
182
+ if (principles.length + antiPatterns.length + strategies.length > 0) {
183
+ this.log.info(`[orchestrator] Knowledge distilled: ${principles.length} principles, ${antiPatterns.length} anti-patterns, ${strategies.length} strategies`);
184
+ }
185
+ }
186
+ // 7. Research agenda generation (periodic)
187
+ if (this.cycleCount % this.agendaEvery === 0) {
188
+ const agenda = this.researchAgenda.generate();
189
+ if (agenda.length > 0) {
190
+ this.log.info(`[orchestrator] Research agenda: ${agenda.length} items generated`);
191
+ }
192
+ }
193
+ // 8. Journal reflection (periodic)
194
+ if (this.cycleCount % this.reflectEvery === 0) {
195
+ this.journal.reflect();
196
+ }
197
+ const duration = Date.now() - start;
198
+ this.log.info(`[orchestrator] ─── Feedback Cycle #${this.cycleCount} complete (${duration}ms) ───`);
199
+ }
200
+ /** Get a comprehensive research summary for dashboards/API. */
201
+ getSummary() {
202
+ return {
203
+ brainName: this.brainName,
204
+ feedbackCycles: this.cycleCount,
205
+ selfInsights: this.selfObserver.getInsights(undefined, 10),
206
+ anomalies: this.anomalyDetective.getAnomalies(undefined, 10),
207
+ experiments: this.experimentEngine.list(undefined, 10),
208
+ agenda: this.researchAgenda.getAgenda(10),
209
+ journal: this.journal.getSummary(),
210
+ knowledge: this.knowledgeDistiller.getSummary(),
211
+ correlations: this.crossDomain.getCorrelations(10),
212
+ strategy: this.adaptiveStrategy.getStatus(),
213
+ };
214
+ }
215
+ }
216
+ // ── Helpers ─────────────────────────────────────────────
217
+ function categorize(eventType) {
218
+ if (eventType.includes('cross_brain') || eventType.includes('cross:'))
219
+ return 'cross_brain';
220
+ if (eventType.includes('latency') || eventType.includes('duration'))
221
+ return 'latency';
222
+ if (eventType.includes('resolution') || eventType.includes('solved'))
223
+ return 'resolution_rate';
224
+ if (eventType.includes('query') || eventType.includes('search') || eventType.includes('recall'))
225
+ return 'query_quality';
226
+ return 'tool_usage';
227
+ }
228
+ //# sourceMappingURL=research-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-orchestrator.js","sourceRoot":"","sources":["../../src/research/research-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type Database from 'better-sqlite3';
2
+ export type ObservationCategory = 'tool_usage' | 'query_quality' | 'resolution_rate' | 'latency' | 'cross_brain';
3
+ export type InsightType = 'usage_pattern' | 'quality_issue' | 'optimization_opportunity' | 'anomaly';
4
+ export interface SelfObservation {
5
+ id?: number;
6
+ timestamp: number;
7
+ category: ObservationCategory;
8
+ event_type: string;
9
+ metrics: Record<string, unknown>;
10
+ context?: Record<string, unknown>;
11
+ }
12
+ export interface SelfInsight {
13
+ id?: number;
14
+ timestamp: number;
15
+ type: InsightType;
16
+ title: string;
17
+ description: string;
18
+ evidence: Record<string, unknown>;
19
+ confidence: number;
20
+ actionable: boolean;
21
+ }
22
+ export interface ImprovementSuggestion {
23
+ area: string;
24
+ problem: string;
25
+ suggestion: string;
26
+ evidence: Record<string, unknown>;
27
+ priority: number;
28
+ estimated_impact: string;
29
+ }
30
+ export interface SelfObserverConfig {
31
+ brainName: string;
32
+ /** Minimum observations before generating insights. Default: 10 */
33
+ minObservationsForInsight?: number;
34
+ /** How many recent observations to analyze. Default: 500 */
35
+ analysisWindow?: number;
36
+ }
37
+ export declare function runSelfObserverMigration(db: Database.Database): void;
38
+ export declare class SelfObserver {
39
+ private db;
40
+ private config;
41
+ private log;
42
+ constructor(db: Database.Database, config: SelfObserverConfig);
43
+ /** Record a self-observation about tool usage, query quality, etc. */
44
+ record(obs: Omit<SelfObservation, 'id' | 'timestamp'>): void;
45
+ /** Get observation statistics grouped by category and event type. */
46
+ getStats(): Record<string, unknown>;
47
+ /** Analyze observations and generate insights. */
48
+ analyze(): SelfInsight[];
49
+ /** Get all insights, optionally filtered by type. */
50
+ getInsights(type?: InsightType, limit?: number): SelfInsight[];
51
+ /** Generate an improvement plan based on insights. */
52
+ getImprovementPlan(): ImprovementSuggestion[];
53
+ private createInsight;
54
+ private persistInsight;
55
+ }
@@ -0,0 +1,268 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ───────────────────────────────────────────
3
+ export function runSelfObserverMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS self_observations (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ timestamp INTEGER NOT NULL,
8
+ category TEXT NOT NULL,
9
+ event_type TEXT NOT NULL,
10
+ metrics TEXT NOT NULL,
11
+ context TEXT,
12
+ created_at TEXT DEFAULT (datetime('now'))
13
+ );
14
+ CREATE INDEX IF NOT EXISTS idx_self_obs_category ON self_observations(category);
15
+ CREATE INDEX IF NOT EXISTS idx_self_obs_event ON self_observations(event_type);
16
+ CREATE INDEX IF NOT EXISTS idx_self_obs_ts ON self_observations(timestamp);
17
+
18
+ CREATE TABLE IF NOT EXISTS self_insights (
19
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
20
+ timestamp INTEGER NOT NULL,
21
+ type TEXT NOT NULL,
22
+ title TEXT NOT NULL,
23
+ description TEXT NOT NULL,
24
+ evidence TEXT NOT NULL,
25
+ confidence REAL NOT NULL,
26
+ actionable INTEGER DEFAULT 0,
27
+ created_at TEXT DEFAULT (datetime('now'))
28
+ );
29
+ CREATE INDEX IF NOT EXISTS idx_self_insights_type ON self_insights(type);
30
+ `);
31
+ }
32
+ // ── Engine ──────────────────────────────────────────────
33
+ export class SelfObserver {
34
+ db;
35
+ config;
36
+ log = getLogger();
37
+ constructor(db, config) {
38
+ this.db = db;
39
+ this.config = {
40
+ brainName: config.brainName,
41
+ minObservationsForInsight: config.minObservationsForInsight ?? 10,
42
+ analysisWindow: config.analysisWindow ?? 500,
43
+ };
44
+ runSelfObserverMigration(db);
45
+ }
46
+ /** Record a self-observation about tool usage, query quality, etc. */
47
+ record(obs) {
48
+ const timestamp = Date.now();
49
+ this.db.prepare(`
50
+ INSERT INTO self_observations (timestamp, category, event_type, metrics, context)
51
+ VALUES (?, ?, ?, ?, ?)
52
+ `).run(timestamp, obs.category, obs.event_type, JSON.stringify(obs.metrics), obs.context ? JSON.stringify(obs.context) : null);
53
+ }
54
+ /** Get observation statistics grouped by category and event type. */
55
+ getStats() {
56
+ const byCategory = this.db.prepare(`
57
+ SELECT category, COUNT(*) as count,
58
+ AVG(json_extract(metrics, '$.duration_ms')) as avg_duration,
59
+ AVG(json_extract(metrics, '$.result_count')) as avg_results,
60
+ AVG(json_extract(metrics, '$.success')) as success_rate
61
+ FROM self_observations
62
+ GROUP BY category
63
+ ORDER BY count DESC
64
+ `).all();
65
+ const byEventType = this.db.prepare(`
66
+ SELECT event_type, COUNT(*) as count,
67
+ AVG(json_extract(metrics, '$.duration_ms')) as avg_duration,
68
+ AVG(json_extract(metrics, '$.result_count')) as avg_results
69
+ FROM self_observations
70
+ GROUP BY event_type
71
+ ORDER BY count DESC
72
+ LIMIT 20
73
+ `).all();
74
+ const total = this.db.prepare(`SELECT COUNT(*) as count FROM self_observations`).get();
75
+ return {
76
+ totalObservations: total.count,
77
+ byCategory,
78
+ topEventTypes: byEventType,
79
+ };
80
+ }
81
+ /** Analyze observations and generate insights. */
82
+ analyze() {
83
+ const total = this.db.prepare(`SELECT COUNT(*) as c FROM self_observations`).get().c;
84
+ if (total < this.config.minObservationsForInsight)
85
+ return [];
86
+ const insights = [];
87
+ // 1. Usage pattern insights — which tools are used most/least
88
+ const usagePatterns = this.db.prepare(`
89
+ SELECT event_type, COUNT(*) as count
90
+ FROM self_observations
91
+ WHERE category = 'tool_usage'
92
+ GROUP BY event_type
93
+ ORDER BY count DESC
94
+ `).all();
95
+ if (usagePatterns.length >= 2) {
96
+ const top = usagePatterns[0];
97
+ const bottom = usagePatterns[usagePatterns.length - 1];
98
+ if (top.count > bottom.count * 5) {
99
+ insights.push(this.createInsight('usage_pattern', `${top.event_type} is used ${Math.round(top.count / bottom.count)}x more than ${bottom.event_type}`, `Users strongly prefer ${top.event_type} (${top.count} calls) over ${bottom.event_type} (${bottom.count} calls). Consider optimizing the popular tool or investigating why the other is underused.`, { top, bottom, ratio: top.count / bottom.count }, Math.min(0.9, 0.5 + (top.count / (top.count + bottom.count))), true));
100
+ }
101
+ }
102
+ // 2. Quality insights — tools that return empty results
103
+ const qualityIssues = this.db.prepare(`
104
+ SELECT event_type,
105
+ COUNT(*) as total,
106
+ SUM(CASE WHEN json_extract(metrics, '$.result_count') = 0 THEN 1 ELSE 0 END) as empty_count
107
+ FROM self_observations
108
+ WHERE category = 'query_quality' AND json_extract(metrics, '$.result_count') IS NOT NULL
109
+ GROUP BY event_type
110
+ HAVING total >= 5
111
+ `).all();
112
+ for (const q of qualityIssues) {
113
+ const emptyRate = q.empty_count / q.total;
114
+ if (emptyRate > 0.5) {
115
+ insights.push(this.createInsight('quality_issue', `${(emptyRate * 100).toFixed(0)}% of ${q.event_type} calls return empty results`, `${q.event_type} returns no results in ${q.empty_count}/${q.total} calls (${(emptyRate * 100).toFixed(0)}%). The underlying algorithm may need improvement.`, { event_type: q.event_type, total: q.total, empty_count: q.empty_count, empty_rate: emptyRate }, Math.min(0.95, 0.5 + emptyRate * 0.4), true));
116
+ }
117
+ }
118
+ // 3. Latency insights — slow operations
119
+ const latencyIssues = this.db.prepare(`
120
+ SELECT event_type,
121
+ COUNT(*) as total,
122
+ AVG(json_extract(metrics, '$.duration_ms')) as avg_ms,
123
+ MAX(json_extract(metrics, '$.duration_ms')) as max_ms
124
+ FROM self_observations
125
+ WHERE category = 'latency' AND json_extract(metrics, '$.duration_ms') IS NOT NULL
126
+ GROUP BY event_type
127
+ HAVING total >= 3
128
+ ORDER BY avg_ms DESC
129
+ LIMIT 5
130
+ `).all();
131
+ const overallAvg = this.db.prepare(`
132
+ SELECT AVG(json_extract(metrics, '$.duration_ms')) as avg
133
+ FROM self_observations
134
+ WHERE category = 'latency' AND json_extract(metrics, '$.duration_ms') IS NOT NULL
135
+ `).get();
136
+ if (overallAvg?.avg && latencyIssues.length > 0) {
137
+ for (const l of latencyIssues) {
138
+ if (l.avg_ms > overallAvg.avg * 3) {
139
+ insights.push(this.createInsight('optimization_opportunity', `${l.event_type} is ${(l.avg_ms / overallAvg.avg).toFixed(1)}x slower than average`, `${l.event_type} averages ${l.avg_ms.toFixed(0)}ms (overall avg: ${overallAvg.avg.toFixed(0)}ms). Peak: ${l.max_ms.toFixed(0)}ms. Consider optimizing.`, { event_type: l.event_type, avg_ms: l.avg_ms, max_ms: l.max_ms, overall_avg: overallAvg.avg }, 0.8, true));
140
+ }
141
+ }
142
+ }
143
+ // 4. Resolution rate insights
144
+ const resolutionData = this.db.prepare(`
145
+ SELECT json_extract(metrics, '$.tag') as tag,
146
+ COUNT(*) as total,
147
+ SUM(CASE WHEN json_extract(metrics, '$.resolved') = 1 THEN 1 ELSE 0 END) as resolved
148
+ FROM self_observations
149
+ WHERE category = 'resolution_rate' AND json_extract(metrics, '$.tag') IS NOT NULL
150
+ GROUP BY tag
151
+ HAVING total >= 3
152
+ `).all();
153
+ for (const r of resolutionData) {
154
+ const rate = r.resolved / r.total;
155
+ if (rate < 0.3) {
156
+ insights.push(this.createInsight('quality_issue', `Low resolution rate for "${r.tag}" errors: ${(rate * 100).toFixed(0)}%`, `Errors tagged "${r.tag}" are resolved only ${(rate * 100).toFixed(0)}% of the time (${r.resolved}/${r.total}). Knowledge in this area is weak.`, { tag: r.tag, total: r.total, resolved: r.resolved, rate }, Math.min(0.9, 0.6 + (1 - rate) * 0.3), true));
157
+ }
158
+ }
159
+ // Persist insights
160
+ for (const insight of insights) {
161
+ this.persistInsight(insight);
162
+ }
163
+ return insights;
164
+ }
165
+ /** Get all insights, optionally filtered by type. */
166
+ getInsights(type, limit = 20) {
167
+ let sql = `SELECT * FROM self_insights`;
168
+ const params = [];
169
+ if (type) {
170
+ sql += ` WHERE type = ?`;
171
+ params.push(type);
172
+ }
173
+ sql += ` ORDER BY timestamp DESC LIMIT ?`;
174
+ params.push(limit);
175
+ return this.db.prepare(sql).all(...params).map(row => ({
176
+ id: row.id,
177
+ timestamp: row.timestamp,
178
+ type: row.type,
179
+ title: row.title,
180
+ description: row.description,
181
+ evidence: JSON.parse(row.evidence),
182
+ confidence: row.confidence,
183
+ actionable: row.actionable === 1,
184
+ }));
185
+ }
186
+ /** Generate an improvement plan based on insights. */
187
+ getImprovementPlan() {
188
+ const insights = this.getInsights(undefined, 50);
189
+ const suggestions = [];
190
+ for (const insight of insights) {
191
+ if (!insight.actionable)
192
+ continue;
193
+ let suggestion;
194
+ switch (insight.type) {
195
+ case 'quality_issue':
196
+ suggestion = {
197
+ area: 'Quality',
198
+ problem: insight.title,
199
+ suggestion: `Improve the algorithm or data behind this operation. ${insight.description}`,
200
+ evidence: insight.evidence,
201
+ priority: insight.confidence * 0.9,
202
+ estimated_impact: 'medium',
203
+ };
204
+ break;
205
+ case 'optimization_opportunity':
206
+ suggestion = {
207
+ area: 'Performance',
208
+ problem: insight.title,
209
+ suggestion: `Optimize this operation to reduce latency. ${insight.description}`,
210
+ evidence: insight.evidence,
211
+ priority: insight.confidence * 0.7,
212
+ estimated_impact: 'low',
213
+ };
214
+ break;
215
+ case 'usage_pattern':
216
+ suggestion = {
217
+ area: 'UX',
218
+ problem: insight.title,
219
+ suggestion: `Investigate why certain tools are underused. ${insight.description}`,
220
+ evidence: insight.evidence,
221
+ priority: insight.confidence * 0.5,
222
+ estimated_impact: 'medium',
223
+ };
224
+ break;
225
+ case 'anomaly':
226
+ suggestion = {
227
+ area: 'Reliability',
228
+ problem: insight.title,
229
+ suggestion: `Investigate this anomaly. ${insight.description}`,
230
+ evidence: insight.evidence,
231
+ priority: insight.confidence * 0.8,
232
+ estimated_impact: 'high',
233
+ };
234
+ break;
235
+ default:
236
+ continue;
237
+ }
238
+ suggestions.push(suggestion);
239
+ }
240
+ return suggestions.sort((a, b) => b.priority - a.priority);
241
+ }
242
+ createInsight(type, title, description, evidence, confidence, actionable) {
243
+ return {
244
+ timestamp: Date.now(),
245
+ type,
246
+ title,
247
+ description,
248
+ evidence,
249
+ confidence,
250
+ actionable,
251
+ };
252
+ }
253
+ persistInsight(insight) {
254
+ // Avoid duplicates: check if similar insight exists recently (last 24h)
255
+ const existing = this.db.prepare(`
256
+ SELECT id FROM self_insights
257
+ WHERE title = ? AND timestamp > ?
258
+ LIMIT 1
259
+ `).get(insight.title, Date.now() - 86_400_000);
260
+ if (existing)
261
+ return;
262
+ this.db.prepare(`
263
+ INSERT INTO self_insights (timestamp, type, title, description, evidence, confidence, actionable)
264
+ VALUES (?, ?, ?, ?, ?, ?, ?)
265
+ `).run(insight.timestamp, insight.type, insight.title, insight.description, JSON.stringify(insight.evidence), insight.confidence, insight.actionable ? 1 : 0);
266
+ }
267
+ }
268
+ //# sourceMappingURL=self-observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-observer.js","sourceRoot":"","sources":["../../src/research/self-observer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmeck/brain-core",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Shared core infrastructure for the Brain ecosystem — IPC, MCP, CLI, DB connection, and utilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",