@timmeck/brain-core 2.36.23 → 2.36.25
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/command-center.html +259 -153
- package/dist/active-learning/__tests__/active-learning.test.d.ts +1 -0
- package/dist/active-learning/__tests__/active-learning.test.js +132 -0
- package/dist/active-learning/__tests__/active-learning.test.js.map +1 -0
- package/dist/active-learning/active-learner.d.ts +79 -0
- package/dist/active-learning/active-learner.js +224 -0
- package/dist/active-learning/active-learner.js.map +1 -0
- package/dist/active-learning/index.d.ts +2 -0
- package/dist/active-learning/index.js +2 -0
- package/dist/active-learning/index.js.map +1 -0
- package/dist/code-health/__tests__/code-health.test.d.ts +1 -0
- package/dist/code-health/__tests__/code-health.test.js +123 -0
- package/dist/code-health/__tests__/code-health.test.js.map +1 -0
- package/dist/code-health/health-monitor.d.ts +55 -0
- package/dist/code-health/health-monitor.js +180 -0
- package/dist/code-health/health-monitor.js.map +1 -0
- package/dist/code-health/index.d.ts +2 -0
- package/dist/code-health/index.js +2 -0
- package/dist/code-health/index.js.map +1 -0
- package/dist/consensus/__tests__/consensus.test.d.ts +1 -0
- package/dist/consensus/__tests__/consensus.test.js +159 -0
- package/dist/consensus/__tests__/consensus.test.js.map +1 -0
- package/dist/consensus/consensus-engine.d.ts +81 -0
- package/dist/consensus/consensus-engine.js +237 -0
- package/dist/consensus/consensus-engine.js.map +1 -0
- package/dist/consensus/index.d.ts +2 -0
- package/dist/consensus/index.js +2 -0
- package/dist/consensus/index.js.map +1 -0
- package/dist/feedback/__tests__/feedback-engine.test.d.ts +1 -0
- package/dist/feedback/__tests__/feedback-engine.test.js +156 -0
- package/dist/feedback/__tests__/feedback-engine.test.js.map +1 -0
- package/dist/feedback/feedback-engine.d.ts +61 -0
- package/dist/feedback/feedback-engine.js +203 -0
- package/dist/feedback/feedback-engine.js.map +1 -0
- package/dist/feedback/index.d.ts +2 -0
- package/dist/feedback/index.js +2 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -1
- package/dist/knowledge-graph/__tests__/knowledge-graph.test.d.ts +1 -0
- package/dist/knowledge-graph/__tests__/knowledge-graph.test.js +215 -0
- package/dist/knowledge-graph/__tests__/knowledge-graph.test.js.map +1 -0
- package/dist/knowledge-graph/fact-extractor.d.ts +23 -0
- package/dist/knowledge-graph/fact-extractor.js +70 -0
- package/dist/knowledge-graph/fact-extractor.js.map +1 -0
- package/dist/knowledge-graph/graph-engine.d.ts +78 -0
- package/dist/knowledge-graph/graph-engine.js +276 -0
- package/dist/knowledge-graph/graph-engine.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +4 -0
- package/dist/knowledge-graph/index.js +3 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/proactive/__tests__/proactive-engine.test.d.ts +1 -0
- package/dist/proactive/__tests__/proactive-engine.test.js +183 -0
- package/dist/proactive/__tests__/proactive-engine.test.js.map +1 -0
- package/dist/proactive/index.d.ts +2 -0
- package/dist/proactive/index.js +2 -0
- package/dist/proactive/index.js.map +1 -0
- package/dist/proactive/proactive-engine.d.ts +86 -0
- package/dist/proactive/proactive-engine.js +252 -0
- package/dist/proactive/proactive-engine.js.map +1 -0
- package/dist/rag/__tests__/rag-engine.test.d.ts +1 -0
- package/dist/rag/__tests__/rag-engine.test.js +235 -0
- package/dist/rag/__tests__/rag-engine.test.js.map +1 -0
- package/dist/rag/index.d.ts +4 -0
- package/dist/rag/index.js +3 -0
- package/dist/rag/index.js.map +1 -0
- package/dist/rag/rag-engine.d.ts +98 -0
- package/dist/rag/rag-engine.js +310 -0
- package/dist/rag/rag-engine.js.map +1 -0
- package/dist/rag/rag-indexer.d.ts +52 -0
- package/dist/rag/rag-indexer.js +144 -0
- package/dist/rag/rag-indexer.js.map +1 -0
- package/dist/research/__tests__/autonomy-features.test.d.ts +1 -0
- package/dist/research/__tests__/autonomy-features.test.js +155 -0
- package/dist/research/__tests__/autonomy-features.test.js.map +1 -0
- package/dist/research/__tests__/semantic-compressor.test.d.ts +1 -0
- package/dist/research/__tests__/semantic-compressor.test.js +153 -0
- package/dist/research/__tests__/semantic-compressor.test.js.map +1 -0
- package/dist/research/semantic-compressor.d.ts +55 -0
- package/dist/research/semantic-compressor.js +227 -0
- package/dist/research/semantic-compressor.js.map +1 -0
- package/dist/teaching/__tests__/teaching.test.d.ts +1 -0
- package/dist/teaching/__tests__/teaching.test.js +151 -0
- package/dist/teaching/__tests__/teaching.test.js.map +1 -0
- package/dist/teaching/curriculum.d.ts +32 -0
- package/dist/teaching/curriculum.js +89 -0
- package/dist/teaching/curriculum.js.map +1 -0
- package/dist/teaching/index.d.ts +4 -0
- package/dist/teaching/index.js +3 -0
- package/dist/teaching/index.js.map +1 -0
- package/dist/teaching/teaching-protocol.d.ts +74 -0
- package/dist/teaching/teaching-protocol.js +164 -0
- package/dist/teaching/teaching-protocol.js.map +1 -0
- package/dist/tool-learning/__tests__/tool-learning.test.d.ts +1 -0
- package/dist/tool-learning/__tests__/tool-learning.test.js +187 -0
- package/dist/tool-learning/__tests__/tool-learning.test.js.map +1 -0
- package/dist/tool-learning/index.d.ts +4 -0
- package/dist/tool-learning/index.js +3 -0
- package/dist/tool-learning/index.js.map +1 -0
- package/dist/tool-learning/tool-patterns.d.ts +47 -0
- package/dist/tool-learning/tool-patterns.js +125 -0
- package/dist/tool-learning/tool-patterns.js.map +1 -0
- package/dist/tool-learning/tool-tracker.d.ts +58 -0
- package/dist/tool-learning/tool-tracker.js +135 -0
- package/dist/tool-learning/tool-tracker.js.map +1 -0
- package/dist/user-model/__tests__/user-model.test.d.ts +1 -0
- package/dist/user-model/__tests__/user-model.test.js +142 -0
- package/dist/user-model/__tests__/user-model.test.js.map +1 -0
- package/dist/user-model/adaptive-context.d.ts +18 -0
- package/dist/user-model/adaptive-context.js +46 -0
- package/dist/user-model/adaptive-context.js.map +1 -0
- package/dist/user-model/index.d.ts +4 -0
- package/dist/user-model/index.js +3 -0
- package/dist/user-model/index.js.map +1 -0
- package/dist/user-model/user-model.d.ts +53 -0
- package/dist/user-model/user-model.js +204 -0
- package/dist/user-model/user-model.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import Database from 'better-sqlite3';
|
|
3
|
+
vi.mock('../../utils/logger.js', () => ({
|
|
4
|
+
getLogger: () => ({
|
|
5
|
+
info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(),
|
|
6
|
+
}),
|
|
7
|
+
}));
|
|
8
|
+
import { ToolTracker, runToolTrackerMigration } from '../tool-tracker.js';
|
|
9
|
+
import { ToolPatternAnalyzer } from '../tool-patterns.js';
|
|
10
|
+
function createDb() {
|
|
11
|
+
return new Database(':memory:');
|
|
12
|
+
}
|
|
13
|
+
describe('ToolTracker', () => {
|
|
14
|
+
let db;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
db = createDb();
|
|
17
|
+
});
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
db.close();
|
|
20
|
+
});
|
|
21
|
+
it('records usage and retrieves it', () => {
|
|
22
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
23
|
+
tracker.recordUsage('mcp.search', 'searching docs', 150, 'success');
|
|
24
|
+
const stats = tracker.getToolStats('mcp.search');
|
|
25
|
+
expect(stats).toEqual(expect.objectContaining({
|
|
26
|
+
tool: 'mcp.search',
|
|
27
|
+
totalUses: 1,
|
|
28
|
+
successRate: 1,
|
|
29
|
+
}));
|
|
30
|
+
});
|
|
31
|
+
it('returns stats for a single tool', () => {
|
|
32
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
33
|
+
tracker.recordUsage('mcp.search', 'ctx', 100, 'success');
|
|
34
|
+
tracker.recordUsage('mcp.search', 'ctx', 200, 'failure');
|
|
35
|
+
const stats = tracker.getToolStats('mcp.search');
|
|
36
|
+
expect(stats).toEqual(expect.objectContaining({
|
|
37
|
+
tool: 'mcp.search',
|
|
38
|
+
totalUses: 2,
|
|
39
|
+
successRate: 0.5,
|
|
40
|
+
avgDuration: 150,
|
|
41
|
+
}));
|
|
42
|
+
});
|
|
43
|
+
it('returns stats for all tools', () => {
|
|
44
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
45
|
+
tracker.recordUsage('tool-a', 'ctx', 100, 'success');
|
|
46
|
+
tracker.recordUsage('tool-b', 'ctx', 200, 'success');
|
|
47
|
+
tracker.recordUsage('tool-a', 'ctx', 300, 'success');
|
|
48
|
+
const stats = tracker.getToolStats();
|
|
49
|
+
expect(Array.isArray(stats)).toBe(true);
|
|
50
|
+
expect(stats.length).toBe(2);
|
|
51
|
+
// tool-a should be first (more uses)
|
|
52
|
+
expect(stats[0].tool).toBe('tool-a');
|
|
53
|
+
});
|
|
54
|
+
it('recommends tools sorted by success rate * frequency', () => {
|
|
55
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
56
|
+
// tool-a: 3 successes in 'debug' context
|
|
57
|
+
tracker.recordUsage('tool-a', 'debug error', 100, 'success');
|
|
58
|
+
tracker.recordUsage('tool-a', 'debug crash', 100, 'success');
|
|
59
|
+
tracker.recordUsage('tool-a', 'debug log', 100, 'success');
|
|
60
|
+
// tool-b: 1 success in 'debug' context
|
|
61
|
+
tracker.recordUsage('tool-b', 'debug issue', 200, 'success');
|
|
62
|
+
// tool-c: no 'debug' context
|
|
63
|
+
tracker.recordUsage('tool-c', 'build project', 50, 'success');
|
|
64
|
+
const recs = tracker.recommend('debug');
|
|
65
|
+
expect(recs.length).toBeGreaterThanOrEqual(2);
|
|
66
|
+
expect(recs[0].tool).toBe('tool-a');
|
|
67
|
+
// tool-c should not appear (no debug context)
|
|
68
|
+
expect(recs.find(r => r.tool === 'tool-c')).toBeUndefined();
|
|
69
|
+
});
|
|
70
|
+
it('records usage with different outcomes', () => {
|
|
71
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
72
|
+
tracker.recordUsage('tool-x', 'ctx', 100, 'success');
|
|
73
|
+
tracker.recordUsage('tool-x', 'ctx', 100, 'failure');
|
|
74
|
+
tracker.recordUsage('tool-x', 'ctx', 100, 'partial');
|
|
75
|
+
const stats = tracker.getToolStats('tool-x');
|
|
76
|
+
expect(stats).toEqual(expect.objectContaining({
|
|
77
|
+
totalUses: 3,
|
|
78
|
+
}));
|
|
79
|
+
// 1 success out of 3 = 0.333...
|
|
80
|
+
expect(stats.successRate).toBeCloseTo(1 / 3, 5);
|
|
81
|
+
});
|
|
82
|
+
it('returns empty stats for unknown tool', () => {
|
|
83
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
84
|
+
const stats = tracker.getToolStats('nonexistent');
|
|
85
|
+
expect(stats).toEqual(expect.objectContaining({
|
|
86
|
+
tool: 'nonexistent',
|
|
87
|
+
totalUses: 0,
|
|
88
|
+
successRate: 0,
|
|
89
|
+
}));
|
|
90
|
+
});
|
|
91
|
+
it('getStatus returns correct counts', () => {
|
|
92
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
93
|
+
tracker.recordUsage('tool-a', null, null, 'success');
|
|
94
|
+
tracker.recordUsage('tool-b', null, null, 'failure');
|
|
95
|
+
tracker.recordUsage('tool-a', null, null, 'success');
|
|
96
|
+
const status = tracker.getStatus();
|
|
97
|
+
expect(status.totalTracked).toBe(3);
|
|
98
|
+
expect(status.uniqueTools).toBe(2);
|
|
99
|
+
// 2 successes out of 3
|
|
100
|
+
expect(status.avgSuccessRate).toBeCloseTo(2 / 3, 5);
|
|
101
|
+
});
|
|
102
|
+
it('migration is idempotent', () => {
|
|
103
|
+
const tracker1 = new ToolTracker(db, { brainName: 'test' });
|
|
104
|
+
tracker1.recordUsage('tool-a', 'ctx', 100, 'success');
|
|
105
|
+
// Run migration again — should not throw or lose data
|
|
106
|
+
runToolTrackerMigration(db);
|
|
107
|
+
const tracker2 = new ToolTracker(db, { brainName: 'test' });
|
|
108
|
+
const stats = tracker2.getToolStats('tool-a');
|
|
109
|
+
expect(stats).toEqual(expect.objectContaining({ totalUses: 1 }));
|
|
110
|
+
});
|
|
111
|
+
it('getStatus returns zeros when empty', () => {
|
|
112
|
+
const tracker = new ToolTracker(db, { brainName: 'test' });
|
|
113
|
+
const status = tracker.getStatus();
|
|
114
|
+
expect(status.totalTracked).toBe(0);
|
|
115
|
+
expect(status.uniqueTools).toBe(0);
|
|
116
|
+
expect(status.avgSuccessRate).toBe(0);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('ToolPatternAnalyzer', () => {
|
|
120
|
+
let db;
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
db = createDb();
|
|
123
|
+
// ToolTracker migration creates the table
|
|
124
|
+
runToolTrackerMigration(db);
|
|
125
|
+
});
|
|
126
|
+
afterEach(() => {
|
|
127
|
+
db.close();
|
|
128
|
+
});
|
|
129
|
+
function insertUsage(tool, createdAt) {
|
|
130
|
+
db.prepare(`
|
|
131
|
+
INSERT INTO tool_usage (tool_name, context, outcome, created_at)
|
|
132
|
+
VALUES (?, 'test', 'success', ?)
|
|
133
|
+
`).run(tool, createdAt);
|
|
134
|
+
}
|
|
135
|
+
it('builds transitions correctly', () => {
|
|
136
|
+
insertUsage('search', '2026-03-06 10:00:00');
|
|
137
|
+
insertUsage('read', '2026-03-06 10:01:00');
|
|
138
|
+
insertUsage('edit', '2026-03-06 10:02:00');
|
|
139
|
+
insertUsage('search', '2026-03-06 10:03:00');
|
|
140
|
+
insertUsage('read', '2026-03-06 10:04:00');
|
|
141
|
+
const analyzer = new ToolPatternAnalyzer(db);
|
|
142
|
+
const transitions = analyzer.getTransitions();
|
|
143
|
+
expect(transitions.get('search')?.get('read')).toBe(2);
|
|
144
|
+
expect(transitions.get('read')?.get('edit')).toBe(1);
|
|
145
|
+
expect(transitions.get('edit')?.get('search')).toBe(1);
|
|
146
|
+
});
|
|
147
|
+
it('predicts next tool based on transitions', () => {
|
|
148
|
+
insertUsage('search', '2026-03-06 10:00:00');
|
|
149
|
+
insertUsage('read', '2026-03-06 10:01:00');
|
|
150
|
+
insertUsage('search', '2026-03-06 10:02:00');
|
|
151
|
+
insertUsage('read', '2026-03-06 10:03:00');
|
|
152
|
+
insertUsage('search', '2026-03-06 10:04:00');
|
|
153
|
+
insertUsage('edit', '2026-03-06 10:05:00');
|
|
154
|
+
const analyzer = new ToolPatternAnalyzer(db);
|
|
155
|
+
const predictions = analyzer.predictNext('search');
|
|
156
|
+
expect(predictions.length).toBeGreaterThanOrEqual(1);
|
|
157
|
+
// 'read' follows 'search' 2 out of 3 times
|
|
158
|
+
expect(predictions[0].tool).toBe('read');
|
|
159
|
+
expect(predictions[0].probability).toBeCloseTo(2 / 3, 5);
|
|
160
|
+
});
|
|
161
|
+
it('finds frequent pairs within 5-minute windows', () => {
|
|
162
|
+
// All within 5 minutes of each other
|
|
163
|
+
insertUsage('search', '2026-03-06 10:00:00');
|
|
164
|
+
insertUsage('read', '2026-03-06 10:01:00');
|
|
165
|
+
insertUsage('search', '2026-03-06 10:02:00');
|
|
166
|
+
insertUsage('read', '2026-03-06 10:03:00');
|
|
167
|
+
const analyzer = new ToolPatternAnalyzer(db);
|
|
168
|
+
const pairs = analyzer.getFrequentPairs();
|
|
169
|
+
expect(pairs.length).toBeGreaterThanOrEqual(1);
|
|
170
|
+
const searchRead = pairs.find(p => (p.toolA === 'read' && p.toolB === 'search') ||
|
|
171
|
+
(p.toolA === 'search' && p.toolB === 'read'));
|
|
172
|
+
expect(searchRead).toBeDefined();
|
|
173
|
+
expect(searchRead.count).toBeGreaterThanOrEqual(2);
|
|
174
|
+
});
|
|
175
|
+
it('returns empty predictions for unknown tool', () => {
|
|
176
|
+
const analyzer = new ToolPatternAnalyzer(db);
|
|
177
|
+
const predictions = analyzer.predictNext('nonexistent');
|
|
178
|
+
expect(predictions).toEqual([]);
|
|
179
|
+
});
|
|
180
|
+
it('returns empty sequences when not enough data', () => {
|
|
181
|
+
insertUsage('search', '2026-03-06 10:00:00');
|
|
182
|
+
const analyzer = new ToolPatternAnalyzer(db);
|
|
183
|
+
const sequences = analyzer.getSequences(3);
|
|
184
|
+
expect(sequences).toEqual([]);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=tool-learning.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-learning.test.js","sourceRoot":"","sources":["../../../src/tool-learning/__tests__/tool-learning.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ToolTracker, runToolTrackerMigration } from './tool-tracker.js';
|
|
2
|
+
export { ToolPatternAnalyzer } from './tool-patterns.js';
|
|
3
|
+
export type { ToolOutcome, ToolUsageRecord, ToolStats, ToolRecommendation, ToolTrackerStatus, ToolTrackerConfig, } from './tool-tracker.js';
|
|
4
|
+
export type { ToolSequence, ToolPrediction, ToolPair, ToolTransition, } from './tool-patterns.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tool-learning/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface ToolSequence {
|
|
3
|
+
sequence: string[];
|
|
4
|
+
count: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolPrediction {
|
|
7
|
+
tool: string;
|
|
8
|
+
probability: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ToolPair {
|
|
11
|
+
toolA: string;
|
|
12
|
+
toolB: string;
|
|
13
|
+
count: number;
|
|
14
|
+
}
|
|
15
|
+
/** A single from→to transition with its count. */
|
|
16
|
+
export interface ToolTransition {
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
count: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class ToolPatternAnalyzer {
|
|
22
|
+
private db;
|
|
23
|
+
private log;
|
|
24
|
+
private stmtAllUsage;
|
|
25
|
+
private stmtWindowUsage;
|
|
26
|
+
constructor(db: Database.Database);
|
|
27
|
+
/**
|
|
28
|
+
* Find common tool sequences (N-grams) of the given window size.
|
|
29
|
+
* Returns sequences sorted by frequency descending.
|
|
30
|
+
*/
|
|
31
|
+
getSequences(windowSize?: number): ToolSequence[];
|
|
32
|
+
/**
|
|
33
|
+
* Build a Markov transition matrix: which tool follows which.
|
|
34
|
+
* Returns Map<toolA, Map<toolB, count>>.
|
|
35
|
+
*/
|
|
36
|
+
getTransitions(): Map<string, Map<string, number>>;
|
|
37
|
+
/**
|
|
38
|
+
* Predict the top 3 most likely next tools given the current tool,
|
|
39
|
+
* based on transition probabilities from the Markov chain.
|
|
40
|
+
*/
|
|
41
|
+
predictNext(currentTool: string): ToolPrediction[];
|
|
42
|
+
/**
|
|
43
|
+
* Find tool pairs that frequently occur together within 5-minute windows.
|
|
44
|
+
* Returns pairs sorted by co-occurrence count descending.
|
|
45
|
+
*/
|
|
46
|
+
getFrequentPairs(): ToolPair[];
|
|
47
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// ── Tool Pattern Analyzer — Sequence & Transition Analysis ───
|
|
2
|
+
//
|
|
3
|
+
// Analyzes tool usage sequences to find patterns, build Markov
|
|
4
|
+
// transition matrices, and predict likely next tools.
|
|
5
|
+
import { getLogger } from '../utils/logger.js';
|
|
6
|
+
// ── Engine ──────────────────────────────────────────────
|
|
7
|
+
export class ToolPatternAnalyzer {
|
|
8
|
+
db;
|
|
9
|
+
log = getLogger();
|
|
10
|
+
// Prepared statements
|
|
11
|
+
stmtAllUsage;
|
|
12
|
+
stmtWindowUsage;
|
|
13
|
+
constructor(db) {
|
|
14
|
+
this.db = db;
|
|
15
|
+
// These statements query the tool_usage table created by ToolTracker
|
|
16
|
+
this.stmtAllUsage = db.prepare(`
|
|
17
|
+
SELECT tool_name, created_at FROM tool_usage ORDER BY created_at ASC
|
|
18
|
+
`);
|
|
19
|
+
this.stmtWindowUsage = db.prepare(`
|
|
20
|
+
SELECT tool_name, created_at FROM tool_usage ORDER BY created_at ASC
|
|
21
|
+
`);
|
|
22
|
+
this.log.info('[tool-patterns] Analyzer initialized');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Find common tool sequences (N-grams) of the given window size.
|
|
26
|
+
* Returns sequences sorted by frequency descending.
|
|
27
|
+
*/
|
|
28
|
+
getSequences(windowSize = 3) {
|
|
29
|
+
const rows = this.stmtAllUsage.all();
|
|
30
|
+
if (rows.length < windowSize)
|
|
31
|
+
return [];
|
|
32
|
+
const seqMap = new Map();
|
|
33
|
+
for (let i = 0; i <= rows.length - windowSize; i++) {
|
|
34
|
+
const seq = rows.slice(i, i + windowSize).map(r => r.tool_name);
|
|
35
|
+
const key = seq.join(' → ');
|
|
36
|
+
seqMap.set(key, (seqMap.get(key) ?? 0) + 1);
|
|
37
|
+
}
|
|
38
|
+
const sequences = [];
|
|
39
|
+
for (const [key, count] of seqMap.entries()) {
|
|
40
|
+
if (count >= 2) {
|
|
41
|
+
sequences.push({ sequence: key.split(' → '), count });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
sequences.sort((a, b) => b.count - a.count);
|
|
45
|
+
return sequences;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build a Markov transition matrix: which tool follows which.
|
|
49
|
+
* Returns Map<toolA, Map<toolB, count>>.
|
|
50
|
+
*/
|
|
51
|
+
getTransitions() {
|
|
52
|
+
const rows = this.stmtAllUsage.all();
|
|
53
|
+
const transitions = new Map();
|
|
54
|
+
for (let i = 0; i < rows.length - 1; i++) {
|
|
55
|
+
const from = rows[i].tool_name;
|
|
56
|
+
const to = rows[i + 1].tool_name;
|
|
57
|
+
if (!transitions.has(from)) {
|
|
58
|
+
transitions.set(from, new Map());
|
|
59
|
+
}
|
|
60
|
+
const inner = transitions.get(from);
|
|
61
|
+
inner.set(to, (inner.get(to) ?? 0) + 1);
|
|
62
|
+
}
|
|
63
|
+
return transitions;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Predict the top 3 most likely next tools given the current tool,
|
|
67
|
+
* based on transition probabilities from the Markov chain.
|
|
68
|
+
*/
|
|
69
|
+
predictNext(currentTool) {
|
|
70
|
+
const transitions = this.getTransitions();
|
|
71
|
+
const fromMap = transitions.get(currentTool);
|
|
72
|
+
if (!fromMap || fromMap.size === 0)
|
|
73
|
+
return [];
|
|
74
|
+
// Calculate total transitions from this tool
|
|
75
|
+
let total = 0;
|
|
76
|
+
for (const count of fromMap.values()) {
|
|
77
|
+
total += count;
|
|
78
|
+
}
|
|
79
|
+
const predictions = [];
|
|
80
|
+
for (const [tool, count] of fromMap.entries()) {
|
|
81
|
+
predictions.push({
|
|
82
|
+
tool,
|
|
83
|
+
probability: count / total,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
predictions.sort((a, b) => b.probability - a.probability);
|
|
87
|
+
return predictions.slice(0, 3);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Find tool pairs that frequently occur together within 5-minute windows.
|
|
91
|
+
* Returns pairs sorted by co-occurrence count descending.
|
|
92
|
+
*/
|
|
93
|
+
getFrequentPairs() {
|
|
94
|
+
const rows = this.stmtWindowUsage.all();
|
|
95
|
+
if (rows.length < 2)
|
|
96
|
+
return [];
|
|
97
|
+
const pairMap = new Map();
|
|
98
|
+
const WINDOW_MS = 5 * 60 * 1000; // 5 minutes
|
|
99
|
+
for (let i = 0; i < rows.length; i++) {
|
|
100
|
+
const timeI = new Date(rows[i].created_at).getTime();
|
|
101
|
+
for (let j = i + 1; j < rows.length; j++) {
|
|
102
|
+
const timeJ = new Date(rows[j].created_at).getTime();
|
|
103
|
+
if (timeJ - timeI > WINDOW_MS)
|
|
104
|
+
break;
|
|
105
|
+
const toolA = rows[i].tool_name;
|
|
106
|
+
const toolB = rows[j].tool_name;
|
|
107
|
+
if (toolA === toolB)
|
|
108
|
+
continue;
|
|
109
|
+
// Normalize pair key (alphabetical order) so A-B and B-A count together
|
|
110
|
+
const key = toolA < toolB ? `${toolA}|${toolB}` : `${toolB}|${toolA}`;
|
|
111
|
+
pairMap.set(key, (pairMap.get(key) ?? 0) + 1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const pairs = [];
|
|
115
|
+
for (const [key, count] of pairMap.entries()) {
|
|
116
|
+
if (count >= 2) {
|
|
117
|
+
const [toolA, toolB] = key.split('|');
|
|
118
|
+
pairs.push({ toolA, toolB, count });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
pairs.sort((a, b) => b.count - a.count);
|
|
122
|
+
return pairs;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=tool-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-patterns.js","sourceRoot":"","sources":["../../src/tool-learning/tool-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { ThoughtStream } from '../consciousness/thought-stream.js';
|
|
3
|
+
export type ToolOutcome = 'success' | 'failure' | 'partial';
|
|
4
|
+
export interface ToolUsageRecord {
|
|
5
|
+
id?: number;
|
|
6
|
+
tool_name: string;
|
|
7
|
+
context: string | null;
|
|
8
|
+
duration_ms: number | null;
|
|
9
|
+
outcome: ToolOutcome;
|
|
10
|
+
metadata: Record<string, unknown> | null;
|
|
11
|
+
created_at: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ToolStats {
|
|
14
|
+
tool: string;
|
|
15
|
+
totalUses: number;
|
|
16
|
+
successRate: number;
|
|
17
|
+
avgDuration: number;
|
|
18
|
+
lastUsed: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ToolRecommendation {
|
|
21
|
+
tool: string;
|
|
22
|
+
score: number;
|
|
23
|
+
successRate: number;
|
|
24
|
+
frequency: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ToolTrackerStatus {
|
|
27
|
+
totalTracked: number;
|
|
28
|
+
uniqueTools: number;
|
|
29
|
+
avgSuccessRate: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ToolTrackerConfig {
|
|
32
|
+
brainName: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function runToolTrackerMigration(db: Database.Database): void;
|
|
35
|
+
export declare class ToolTracker {
|
|
36
|
+
private db;
|
|
37
|
+
private config;
|
|
38
|
+
private ts;
|
|
39
|
+
private log;
|
|
40
|
+
private stmtInsert;
|
|
41
|
+
private stmtStatsSingle;
|
|
42
|
+
private stmtStatsAll;
|
|
43
|
+
private stmtRecommend;
|
|
44
|
+
private stmtTotalTracked;
|
|
45
|
+
private stmtUniqueTools;
|
|
46
|
+
private stmtAvgSuccessRate;
|
|
47
|
+
constructor(db: Database.Database, config: ToolTrackerConfig);
|
|
48
|
+
/** Set the ThoughtStream for consciousness integration. */
|
|
49
|
+
setThoughtStream(stream: ThoughtStream): void;
|
|
50
|
+
/** Record a tool usage event. */
|
|
51
|
+
recordUsage(tool: string, context: string | null, duration: number | null, outcome?: ToolOutcome, metadata?: Record<string, unknown>): void;
|
|
52
|
+
/** Get statistics for a specific tool, or all tools if none specified. */
|
|
53
|
+
getToolStats(tool?: string): ToolStats | ToolStats[];
|
|
54
|
+
/** Recommend top-5 tools for a given context based on success rate * frequency. */
|
|
55
|
+
recommend(context: string): ToolRecommendation[];
|
|
56
|
+
/** Get tracker status summary. */
|
|
57
|
+
getStatus(): ToolTrackerStatus;
|
|
58
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// ── Tool Tracker — Usage Recording & Recommendation ──────────
|
|
2
|
+
//
|
|
3
|
+
// Tracks tool usage with context, duration, and outcome.
|
|
4
|
+
// Provides statistics and context-based recommendations.
|
|
5
|
+
import { getLogger } from '../utils/logger.js';
|
|
6
|
+
// ── Migration ───────────────────────────────────────────
|
|
7
|
+
export function runToolTrackerMigration(db) {
|
|
8
|
+
db.exec(`
|
|
9
|
+
CREATE TABLE IF NOT EXISTS tool_usage (
|
|
10
|
+
id INTEGER PRIMARY KEY,
|
|
11
|
+
tool_name TEXT NOT NULL,
|
|
12
|
+
context TEXT,
|
|
13
|
+
duration_ms INTEGER,
|
|
14
|
+
outcome TEXT DEFAULT 'success' CHECK(outcome IN ('success','failure','partial')),
|
|
15
|
+
metadata TEXT,
|
|
16
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
17
|
+
);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_tool_name ON tool_usage(tool_name);
|
|
19
|
+
`);
|
|
20
|
+
}
|
|
21
|
+
// ── Engine ──────────────────────────────────────────────
|
|
22
|
+
export class ToolTracker {
|
|
23
|
+
db;
|
|
24
|
+
config;
|
|
25
|
+
ts = null;
|
|
26
|
+
log = getLogger();
|
|
27
|
+
// Prepared statements
|
|
28
|
+
stmtInsert;
|
|
29
|
+
stmtStatsSingle;
|
|
30
|
+
stmtStatsAll;
|
|
31
|
+
stmtRecommend;
|
|
32
|
+
stmtTotalTracked;
|
|
33
|
+
stmtUniqueTools;
|
|
34
|
+
stmtAvgSuccessRate;
|
|
35
|
+
constructor(db, config) {
|
|
36
|
+
this.db = db;
|
|
37
|
+
this.config = config;
|
|
38
|
+
runToolTrackerMigration(db);
|
|
39
|
+
// Prepare all statements
|
|
40
|
+
this.stmtInsert = db.prepare(`
|
|
41
|
+
INSERT INTO tool_usage (tool_name, context, duration_ms, outcome, metadata)
|
|
42
|
+
VALUES (?, ?, ?, ?, ?)
|
|
43
|
+
`);
|
|
44
|
+
this.stmtStatsSingle = db.prepare(`
|
|
45
|
+
SELECT
|
|
46
|
+
tool_name AS tool,
|
|
47
|
+
COUNT(*) AS totalUses,
|
|
48
|
+
CAST(SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) AS successRate,
|
|
49
|
+
COALESCE(AVG(duration_ms), 0) AS avgDuration,
|
|
50
|
+
MAX(created_at) AS lastUsed
|
|
51
|
+
FROM tool_usage
|
|
52
|
+
WHERE tool_name = ?
|
|
53
|
+
GROUP BY tool_name
|
|
54
|
+
`);
|
|
55
|
+
this.stmtStatsAll = db.prepare(`
|
|
56
|
+
SELECT
|
|
57
|
+
tool_name AS tool,
|
|
58
|
+
COUNT(*) AS totalUses,
|
|
59
|
+
CAST(SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) AS successRate,
|
|
60
|
+
COALESCE(AVG(duration_ms), 0) AS avgDuration,
|
|
61
|
+
MAX(created_at) AS lastUsed
|
|
62
|
+
FROM tool_usage
|
|
63
|
+
GROUP BY tool_name
|
|
64
|
+
ORDER BY totalUses DESC
|
|
65
|
+
`);
|
|
66
|
+
this.stmtRecommend = db.prepare(`
|
|
67
|
+
SELECT
|
|
68
|
+
tool_name AS tool,
|
|
69
|
+
COUNT(*) AS frequency,
|
|
70
|
+
CAST(SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*) AS successRate
|
|
71
|
+
FROM tool_usage
|
|
72
|
+
WHERE context LIKE ?
|
|
73
|
+
GROUP BY tool_name
|
|
74
|
+
ORDER BY (CAST(SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) AS REAL) / COUNT(*)) * COUNT(*) DESC
|
|
75
|
+
LIMIT 5
|
|
76
|
+
`);
|
|
77
|
+
this.stmtTotalTracked = db.prepare(`
|
|
78
|
+
SELECT COUNT(*) AS total FROM tool_usage
|
|
79
|
+
`);
|
|
80
|
+
this.stmtUniqueTools = db.prepare(`
|
|
81
|
+
SELECT COUNT(DISTINCT tool_name) AS unique_tools FROM tool_usage
|
|
82
|
+
`);
|
|
83
|
+
this.stmtAvgSuccessRate = db.prepare(`
|
|
84
|
+
SELECT COALESCE(
|
|
85
|
+
CAST(SUM(CASE WHEN outcome = 'success' THEN 1 ELSE 0 END) AS REAL) / NULLIF(COUNT(*), 0),
|
|
86
|
+
0
|
|
87
|
+
) AS avgRate
|
|
88
|
+
FROM tool_usage
|
|
89
|
+
`);
|
|
90
|
+
this.log.info(`[tool-tracker] Initialized for ${config.brainName}`);
|
|
91
|
+
}
|
|
92
|
+
/** Set the ThoughtStream for consciousness integration. */
|
|
93
|
+
setThoughtStream(stream) {
|
|
94
|
+
this.ts = stream;
|
|
95
|
+
}
|
|
96
|
+
/** Record a tool usage event. */
|
|
97
|
+
recordUsage(tool, context, duration, outcome = 'success', metadata) {
|
|
98
|
+
this.stmtInsert.run(tool, context, duration, outcome, metadata ? JSON.stringify(metadata) : null);
|
|
99
|
+
this.ts?.emit('tool-tracker', 'analyzing', `Recorded ${tool} usage: ${outcome}${duration ? ` (${duration}ms)` : ''}`, 'routine');
|
|
100
|
+
}
|
|
101
|
+
/** Get statistics for a specific tool, or all tools if none specified. */
|
|
102
|
+
getToolStats(tool) {
|
|
103
|
+
if (tool) {
|
|
104
|
+
const row = this.stmtStatsSingle.get(tool);
|
|
105
|
+
if (!row) {
|
|
106
|
+
return { tool, totalUses: 0, successRate: 0, avgDuration: 0, lastUsed: '' };
|
|
107
|
+
}
|
|
108
|
+
return row;
|
|
109
|
+
}
|
|
110
|
+
return this.stmtStatsAll.all();
|
|
111
|
+
}
|
|
112
|
+
/** Recommend top-5 tools for a given context based on success rate * frequency. */
|
|
113
|
+
recommend(context) {
|
|
114
|
+
const pattern = `%${context}%`;
|
|
115
|
+
const rows = this.stmtRecommend.all(pattern);
|
|
116
|
+
return rows.map(r => ({
|
|
117
|
+
tool: r.tool,
|
|
118
|
+
score: r.successRate * r.frequency,
|
|
119
|
+
successRate: r.successRate,
|
|
120
|
+
frequency: r.frequency,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
/** Get tracker status summary. */
|
|
124
|
+
getStatus() {
|
|
125
|
+
const total = this.stmtTotalTracked.get().total;
|
|
126
|
+
const unique = this.stmtUniqueTools.get().unique_tools;
|
|
127
|
+
const avgRate = this.stmtAvgSuccessRate.get().avgRate;
|
|
128
|
+
return {
|
|
129
|
+
totalTracked: total,
|
|
130
|
+
uniqueTools: unique,
|
|
131
|
+
avgSuccessRate: avgRate,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=tool-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-tracker.js","sourceRoot":"","sources":["../../src/tool-learning/tool-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|