@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.
Files changed (119) hide show
  1. package/command-center.html +259 -153
  2. package/dist/active-learning/__tests__/active-learning.test.d.ts +1 -0
  3. package/dist/active-learning/__tests__/active-learning.test.js +132 -0
  4. package/dist/active-learning/__tests__/active-learning.test.js.map +1 -0
  5. package/dist/active-learning/active-learner.d.ts +79 -0
  6. package/dist/active-learning/active-learner.js +224 -0
  7. package/dist/active-learning/active-learner.js.map +1 -0
  8. package/dist/active-learning/index.d.ts +2 -0
  9. package/dist/active-learning/index.js +2 -0
  10. package/dist/active-learning/index.js.map +1 -0
  11. package/dist/code-health/__tests__/code-health.test.d.ts +1 -0
  12. package/dist/code-health/__tests__/code-health.test.js +123 -0
  13. package/dist/code-health/__tests__/code-health.test.js.map +1 -0
  14. package/dist/code-health/health-monitor.d.ts +55 -0
  15. package/dist/code-health/health-monitor.js +180 -0
  16. package/dist/code-health/health-monitor.js.map +1 -0
  17. package/dist/code-health/index.d.ts +2 -0
  18. package/dist/code-health/index.js +2 -0
  19. package/dist/code-health/index.js.map +1 -0
  20. package/dist/consensus/__tests__/consensus.test.d.ts +1 -0
  21. package/dist/consensus/__tests__/consensus.test.js +159 -0
  22. package/dist/consensus/__tests__/consensus.test.js.map +1 -0
  23. package/dist/consensus/consensus-engine.d.ts +81 -0
  24. package/dist/consensus/consensus-engine.js +237 -0
  25. package/dist/consensus/consensus-engine.js.map +1 -0
  26. package/dist/consensus/index.d.ts +2 -0
  27. package/dist/consensus/index.js +2 -0
  28. package/dist/consensus/index.js.map +1 -0
  29. package/dist/feedback/__tests__/feedback-engine.test.d.ts +1 -0
  30. package/dist/feedback/__tests__/feedback-engine.test.js +156 -0
  31. package/dist/feedback/__tests__/feedback-engine.test.js.map +1 -0
  32. package/dist/feedback/feedback-engine.d.ts +61 -0
  33. package/dist/feedback/feedback-engine.js +203 -0
  34. package/dist/feedback/feedback-engine.js.map +1 -0
  35. package/dist/feedback/index.d.ts +2 -0
  36. package/dist/feedback/index.js +2 -0
  37. package/dist/feedback/index.js.map +1 -0
  38. package/dist/index.d.ts +32 -0
  39. package/dist/index.js +27 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/knowledge-graph/__tests__/knowledge-graph.test.d.ts +1 -0
  42. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js +215 -0
  43. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js.map +1 -0
  44. package/dist/knowledge-graph/fact-extractor.d.ts +23 -0
  45. package/dist/knowledge-graph/fact-extractor.js +70 -0
  46. package/dist/knowledge-graph/fact-extractor.js.map +1 -0
  47. package/dist/knowledge-graph/graph-engine.d.ts +78 -0
  48. package/dist/knowledge-graph/graph-engine.js +276 -0
  49. package/dist/knowledge-graph/graph-engine.js.map +1 -0
  50. package/dist/knowledge-graph/index.d.ts +4 -0
  51. package/dist/knowledge-graph/index.js +3 -0
  52. package/dist/knowledge-graph/index.js.map +1 -0
  53. package/dist/proactive/__tests__/proactive-engine.test.d.ts +1 -0
  54. package/dist/proactive/__tests__/proactive-engine.test.js +183 -0
  55. package/dist/proactive/__tests__/proactive-engine.test.js.map +1 -0
  56. package/dist/proactive/index.d.ts +2 -0
  57. package/dist/proactive/index.js +2 -0
  58. package/dist/proactive/index.js.map +1 -0
  59. package/dist/proactive/proactive-engine.d.ts +86 -0
  60. package/dist/proactive/proactive-engine.js +252 -0
  61. package/dist/proactive/proactive-engine.js.map +1 -0
  62. package/dist/rag/__tests__/rag-engine.test.d.ts +1 -0
  63. package/dist/rag/__tests__/rag-engine.test.js +235 -0
  64. package/dist/rag/__tests__/rag-engine.test.js.map +1 -0
  65. package/dist/rag/index.d.ts +4 -0
  66. package/dist/rag/index.js +3 -0
  67. package/dist/rag/index.js.map +1 -0
  68. package/dist/rag/rag-engine.d.ts +98 -0
  69. package/dist/rag/rag-engine.js +310 -0
  70. package/dist/rag/rag-engine.js.map +1 -0
  71. package/dist/rag/rag-indexer.d.ts +52 -0
  72. package/dist/rag/rag-indexer.js +144 -0
  73. package/dist/rag/rag-indexer.js.map +1 -0
  74. package/dist/research/__tests__/autonomy-features.test.d.ts +1 -0
  75. package/dist/research/__tests__/autonomy-features.test.js +155 -0
  76. package/dist/research/__tests__/autonomy-features.test.js.map +1 -0
  77. package/dist/research/__tests__/semantic-compressor.test.d.ts +1 -0
  78. package/dist/research/__tests__/semantic-compressor.test.js +153 -0
  79. package/dist/research/__tests__/semantic-compressor.test.js.map +1 -0
  80. package/dist/research/semantic-compressor.d.ts +55 -0
  81. package/dist/research/semantic-compressor.js +227 -0
  82. package/dist/research/semantic-compressor.js.map +1 -0
  83. package/dist/teaching/__tests__/teaching.test.d.ts +1 -0
  84. package/dist/teaching/__tests__/teaching.test.js +151 -0
  85. package/dist/teaching/__tests__/teaching.test.js.map +1 -0
  86. package/dist/teaching/curriculum.d.ts +32 -0
  87. package/dist/teaching/curriculum.js +89 -0
  88. package/dist/teaching/curriculum.js.map +1 -0
  89. package/dist/teaching/index.d.ts +4 -0
  90. package/dist/teaching/index.js +3 -0
  91. package/dist/teaching/index.js.map +1 -0
  92. package/dist/teaching/teaching-protocol.d.ts +74 -0
  93. package/dist/teaching/teaching-protocol.js +164 -0
  94. package/dist/teaching/teaching-protocol.js.map +1 -0
  95. package/dist/tool-learning/__tests__/tool-learning.test.d.ts +1 -0
  96. package/dist/tool-learning/__tests__/tool-learning.test.js +187 -0
  97. package/dist/tool-learning/__tests__/tool-learning.test.js.map +1 -0
  98. package/dist/tool-learning/index.d.ts +4 -0
  99. package/dist/tool-learning/index.js +3 -0
  100. package/dist/tool-learning/index.js.map +1 -0
  101. package/dist/tool-learning/tool-patterns.d.ts +47 -0
  102. package/dist/tool-learning/tool-patterns.js +125 -0
  103. package/dist/tool-learning/tool-patterns.js.map +1 -0
  104. package/dist/tool-learning/tool-tracker.d.ts +58 -0
  105. package/dist/tool-learning/tool-tracker.js +135 -0
  106. package/dist/tool-learning/tool-tracker.js.map +1 -0
  107. package/dist/user-model/__tests__/user-model.test.d.ts +1 -0
  108. package/dist/user-model/__tests__/user-model.test.js +142 -0
  109. package/dist/user-model/__tests__/user-model.test.js.map +1 -0
  110. package/dist/user-model/adaptive-context.d.ts +18 -0
  111. package/dist/user-model/adaptive-context.js +46 -0
  112. package/dist/user-model/adaptive-context.js.map +1 -0
  113. package/dist/user-model/index.d.ts +4 -0
  114. package/dist/user-model/index.js +3 -0
  115. package/dist/user-model/index.js.map +1 -0
  116. package/dist/user-model/user-model.d.ts +53 -0
  117. package/dist/user-model/user-model.js +204 -0
  118. package/dist/user-model/user-model.js.map +1 -0
  119. package/package.json +1 -1
@@ -0,0 +1,237 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ // ── Migration ───────────────────────────────────────────
3
+ export function runConsensusMigration(db) {
4
+ db.exec(`
5
+ CREATE TABLE IF NOT EXISTS consensus_proposals (
6
+ id INTEGER PRIMARY KEY,
7
+ type TEXT NOT NULL,
8
+ description TEXT NOT NULL,
9
+ options TEXT NOT NULL,
10
+ context TEXT,
11
+ status TEXT DEFAULT 'open' CHECK(status IN ('open','resolved','timeout')),
12
+ result TEXT,
13
+ created_at TEXT DEFAULT (datetime('now')),
14
+ resolved_at TEXT
15
+ );
16
+ CREATE INDEX IF NOT EXISTS idx_consensus_status ON consensus_proposals(status);
17
+
18
+ CREATE TABLE IF NOT EXISTS consensus_votes (
19
+ id INTEGER PRIMARY KEY,
20
+ proposal_id INTEGER NOT NULL REFERENCES consensus_proposals(id),
21
+ voter TEXT NOT NULL,
22
+ chosen_option TEXT NOT NULL,
23
+ confidence REAL DEFAULT 0.5,
24
+ reasoning TEXT,
25
+ created_at TEXT DEFAULT (datetime('now')),
26
+ UNIQUE(proposal_id, voter)
27
+ );
28
+ CREATE INDEX IF NOT EXISTS idx_consensus_votes_proposal ON consensus_votes(proposal_id);
29
+ `);
30
+ }
31
+ // ── Engine ──────────────────────────────────────────────
32
+ export class ConsensusEngine {
33
+ db;
34
+ config;
35
+ log = getLogger();
36
+ ts = null;
37
+ // Prepared statements
38
+ stmtInsertProposal;
39
+ stmtGetProposal;
40
+ stmtUpdateProposalStatus;
41
+ stmtUpsertVote;
42
+ stmtGetVotes;
43
+ stmtListProposals;
44
+ stmtListByStatus;
45
+ stmtTotalProposals;
46
+ stmtOpenCount;
47
+ stmtResolvedCount;
48
+ stmtAvgVotesPerProposal;
49
+ constructor(db, config) {
50
+ this.db = db;
51
+ this.config = {
52
+ brainName: config.brainName,
53
+ timeoutMs: config.timeoutMs ?? 60000,
54
+ requiredMajority: config.requiredMajority ?? 0.5,
55
+ vetoThreshold: config.vetoThreshold ?? 0.67,
56
+ };
57
+ runConsensusMigration(db);
58
+ this.stmtInsertProposal = db.prepare('INSERT INTO consensus_proposals (type, description, options, context) VALUES (?, ?, ?, ?)');
59
+ this.stmtGetProposal = db.prepare('SELECT * FROM consensus_proposals WHERE id = ?');
60
+ this.stmtUpdateProposalStatus = db.prepare('UPDATE consensus_proposals SET status = ?, result = ?, resolved_at = datetime(\'now\') WHERE id = ?');
61
+ this.stmtUpsertVote = db.prepare(`INSERT INTO consensus_votes (proposal_id, voter, chosen_option, confidence, reasoning)
62
+ VALUES (?, ?, ?, ?, ?)
63
+ ON CONFLICT(proposal_id, voter) DO UPDATE SET
64
+ chosen_option = excluded.chosen_option,
65
+ confidence = excluded.confidence,
66
+ reasoning = excluded.reasoning`);
67
+ this.stmtGetVotes = db.prepare('SELECT * FROM consensus_votes WHERE proposal_id = ? ORDER BY id ASC');
68
+ this.stmtListProposals = db.prepare('SELECT * FROM consensus_proposals ORDER BY id DESC LIMIT ?');
69
+ this.stmtListByStatus = db.prepare('SELECT * FROM consensus_proposals WHERE status = ? ORDER BY id DESC LIMIT ?');
70
+ this.stmtTotalProposals = db.prepare('SELECT COUNT(*) as cnt FROM consensus_proposals');
71
+ this.stmtOpenCount = db.prepare("SELECT COUNT(*) as cnt FROM consensus_proposals WHERE status = 'open'");
72
+ this.stmtResolvedCount = db.prepare("SELECT COUNT(*) as cnt FROM consensus_proposals WHERE status = 'resolved'");
73
+ this.stmtAvgVotesPerProposal = db.prepare(`SELECT AVG(vote_count) as avg FROM (
74
+ SELECT proposal_id, COUNT(*) as vote_count FROM consensus_votes GROUP BY proposal_id
75
+ )`);
76
+ this.log.debug(`[ConsensusEngine] Initialized for ${this.config.brainName}`);
77
+ }
78
+ // ── Setters ──────────────────────────────────────────
79
+ setThoughtStream(stream) {
80
+ this.ts = stream;
81
+ }
82
+ // ── Core: Propose ────────────────────────────────────
83
+ propose(decision) {
84
+ const info = this.stmtInsertProposal.run(decision.type, decision.description, JSON.stringify(decision.options), decision.context ?? null);
85
+ const id = Number(info.lastInsertRowid);
86
+ this.ts?.emit('consensus', 'reflecting', `New proposal: ${decision.description.substring(0, 60)} (${decision.options.length} options)`, 'notable');
87
+ this.log.debug(`[ConsensusEngine] Proposal #${id}: ${decision.type}`);
88
+ return { id, type: decision.type, status: 'open' };
89
+ }
90
+ // ── Core: Vote ───────────────────────────────────────
91
+ vote(proposalId, option, confidence, reasoning) {
92
+ this.stmtUpsertVote.run(proposalId, this.config.brainName, option, confidence, reasoning ?? null);
93
+ this.ts?.emit('consensus', 'reflecting', `Voted on proposal #${proposalId}: ${option} (confidence=${confidence.toFixed(2)})`, 'routine');
94
+ this.log.debug(`[ConsensusEngine] Vote on #${proposalId}: ${option} (${confidence.toFixed(2)})`);
95
+ return {
96
+ proposalId,
97
+ voter: this.config.brainName,
98
+ chosenOption: option,
99
+ confidence,
100
+ reasoning,
101
+ };
102
+ }
103
+ // ── Core: Resolve ────────────────────────────────────
104
+ resolve(proposalId) {
105
+ const proposal = this.getProposal(proposalId);
106
+ if (!proposal) {
107
+ return { winner: null, votes: [], vetoed: false };
108
+ }
109
+ const votes = proposal.votes;
110
+ if (votes.length === 0) {
111
+ return { winner: null, votes: [], vetoed: false };
112
+ }
113
+ // Determine majority requirement
114
+ const isSelfmod = proposal.type === 'selfmod_approval';
115
+ const requiredMajority = isSelfmod ? 2 / 3 : this.config.requiredMajority;
116
+ // Count votes per option
117
+ const voteCounts = new Map();
118
+ for (const v of votes) {
119
+ const entry = voteCounts.get(v.chosenOption) ?? { count: 0, totalConfidence: 0, voters: [] };
120
+ entry.count++;
121
+ entry.totalConfidence += v.confidence;
122
+ entry.voters.push(v.voter);
123
+ voteCounts.set(v.chosenOption, entry);
124
+ }
125
+ // Check for veto: single dissenter with high confidence
126
+ let vetoed = false;
127
+ if (votes.length > 1) {
128
+ for (const v of votes) {
129
+ const entry = voteCounts.get(v.chosenOption);
130
+ // This voter is the only one for their option and has high confidence
131
+ if (entry.count === 1 && v.confidence > this.config.vetoThreshold) {
132
+ // Check if all other votes agree on a different option
133
+ const otherVotes = votes.filter(ov => ov.voter !== v.voter);
134
+ const otherOptions = new Set(otherVotes.map(ov => ov.chosenOption));
135
+ if (otherOptions.size === 1) {
136
+ vetoed = true;
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ // Find winner
143
+ let winner = null;
144
+ let maxCount = 0;
145
+ for (const [option, entry] of voteCounts) {
146
+ if (entry.count > maxCount) {
147
+ maxCount = entry.count;
148
+ winner = option;
149
+ }
150
+ }
151
+ // Check if majority reached
152
+ if (winner && maxCount / votes.length < requiredMajority) {
153
+ winner = null; // Not enough votes for majority
154
+ }
155
+ // Update proposal status
156
+ const status = vetoed ? 'resolved' : (winner ? 'resolved' : 'open');
157
+ if (status === 'resolved') {
158
+ const resultText = vetoed ? `VETOED (proposed: ${winner})` : winner;
159
+ this.stmtUpdateProposalStatus.run('resolved', resultText, proposalId);
160
+ }
161
+ this.ts?.emit('consensus', 'discovering', `Proposal #${proposalId} ${vetoed ? 'VETOED' : (winner ? `resolved: ${winner}` : 'no majority')}`, vetoed ? 'breakthrough' : 'notable');
162
+ return { winner: vetoed ? null : winner, votes, vetoed };
163
+ }
164
+ // ── Core: Get Proposal ───────────────────────────────
165
+ getProposal(id) {
166
+ const row = this.stmtGetProposal.get(id);
167
+ if (!row)
168
+ return null;
169
+ const votes = this.loadVotes(id);
170
+ return this.toProposal(row, votes);
171
+ }
172
+ // ── Core: History ────────────────────────────────────
173
+ getHistory(status, limit = 20) {
174
+ const rows = status
175
+ ? this.stmtListByStatus.all(status, limit)
176
+ : this.stmtListProposals.all(limit);
177
+ return rows.map(r => {
178
+ const votes = this.loadVotes(r.id);
179
+ return this.toProposal(r, votes);
180
+ });
181
+ }
182
+ // ── Core: Status ─────────────────────────────────────
183
+ getStatus() {
184
+ const totalProposals = this.stmtTotalProposals.get().cnt;
185
+ const openCount = this.stmtOpenCount.get().cnt;
186
+ const resolvedCount = this.stmtResolvedCount.get().cnt;
187
+ const avgRow = this.stmtAvgVotesPerProposal.get();
188
+ const avgParticipation = avgRow.avg ?? 0;
189
+ return { totalProposals, openCount, resolvedCount, avgParticipation };
190
+ }
191
+ // ── Core: Timeout ────────────────────────────────────
192
+ timeoutProposal(proposalId) {
193
+ const proposal = this.getProposal(proposalId);
194
+ if (!proposal || proposal.status !== 'open')
195
+ return false;
196
+ this.stmtUpdateProposalStatus.run('timeout', null, proposalId);
197
+ this.ts?.emit('consensus', 'reflecting', `Proposal #${proposalId} timed out`, 'routine');
198
+ return true;
199
+ }
200
+ // ── Private: Vote Loading ────────────────────────────
201
+ loadVotes(proposalId) {
202
+ const rows = this.stmtGetVotes.all(proposalId);
203
+ return rows.map(r => this.toVote(r));
204
+ }
205
+ // ── Private: Row Mapping ─────────────────────────────
206
+ toProposal(row, votes) {
207
+ let options = [];
208
+ try {
209
+ options = JSON.parse(row.options || '[]');
210
+ }
211
+ catch { /* ignore */ }
212
+ return {
213
+ id: row.id,
214
+ type: row.type,
215
+ description: row.description,
216
+ options,
217
+ context: row.context ?? undefined,
218
+ status: row.status,
219
+ result: row.result ?? undefined,
220
+ votes,
221
+ createdAt: row.created_at,
222
+ resolvedAt: row.resolved_at ?? undefined,
223
+ };
224
+ }
225
+ toVote(row) {
226
+ return {
227
+ id: row.id,
228
+ proposalId: row.proposal_id,
229
+ voter: row.voter,
230
+ chosenOption: row.chosen_option,
231
+ confidence: row.confidence,
232
+ reasoning: row.reasoning ?? undefined,
233
+ createdAt: row.created_at,
234
+ };
235
+ }
236
+ }
237
+ //# sourceMappingURL=consensus-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus-engine.js","sourceRoot":"","sources":["../../src/consensus/consensus-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { ConsensusEngine, runConsensusMigration } from './consensus-engine.js';
2
+ export type { ConsensusConfig, ProposalStatus, Proposal, ProposalInput, Vote, ResolutionResult, ResolutionResult as ConsensusResult, ConsensusStatus, } from './consensus-engine.js';
@@ -0,0 +1,2 @@
1
+ export { ConsensusEngine, runConsensusMigration } from './consensus-engine.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consensus/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,156 @@
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 { FeedbackEngine, runFeedbackMigration } from '../feedback-engine.js';
9
+ // ── Helpers ──────────────────────────────────────────────────
10
+ function createTestDb() {
11
+ return new Database(':memory:');
12
+ }
13
+ // ── Tests ───────────────────────────────────────────────────
14
+ describe('FeedbackEngine', () => {
15
+ let db;
16
+ let engine;
17
+ beforeEach(() => {
18
+ db = createTestDb();
19
+ engine = new FeedbackEngine(db, { brainName: 'test' });
20
+ });
21
+ afterEach(() => {
22
+ try {
23
+ db.close();
24
+ }
25
+ catch { /* ignore */ }
26
+ });
27
+ it('creates feedback tables on migration', () => {
28
+ const signalTable = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='feedback_signals'").all();
29
+ const correctionTable = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='feedback_corrections'").all();
30
+ expect(signalTable).toHaveLength(1);
31
+ expect(correctionTable).toHaveLength(1);
32
+ });
33
+ it('migration is idempotent', () => {
34
+ runFeedbackMigration(db);
35
+ runFeedbackMigration(db);
36
+ const signalTable = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='feedback_signals'").all();
37
+ expect(signalTable).toHaveLength(1);
38
+ });
39
+ it('records positive feedback', () => {
40
+ const record = engine.recordFeedback('insight', 1, 'positive', 'Great insight');
41
+ expect(record.signal).toBe('positive');
42
+ expect(record.reward_score).toBe(1.0);
43
+ expect(record.target_type).toBe('insight');
44
+ expect(record.target_id).toBe(1);
45
+ expect(record.detail).toBe('Great insight');
46
+ });
47
+ it('records negative feedback', () => {
48
+ const record = engine.recordFeedback('prediction', 2, 'negative', 'Incorrect prediction');
49
+ expect(record.signal).toBe('negative');
50
+ expect(record.reward_score).toBe(-1.0);
51
+ });
52
+ it('records correction feedback', () => {
53
+ const record = engine.recordFeedback('rule', 3, 'correction');
54
+ expect(record.signal).toBe('correction');
55
+ expect(record.reward_score).toBe(-0.5);
56
+ expect(record.detail).toBeNull();
57
+ });
58
+ it('calculates reward score from multiple signals', () => {
59
+ engine.recordFeedback('insight', 1, 'positive');
60
+ engine.recordFeedback('insight', 1, 'positive');
61
+ engine.recordFeedback('insight', 1, 'negative');
62
+ const score = engine.getRewardScore('insight', 1);
63
+ // (1 + 1 + -1) / 3 = 0.333...
64
+ expect(score).toBeCloseTo(1 / 3, 2);
65
+ });
66
+ it('clamps reward score to [-1, 1]', () => {
67
+ // All positive -> should be exactly 1.0
68
+ engine.recordFeedback('insight', 1, 'positive');
69
+ engine.recordFeedback('insight', 1, 'positive');
70
+ engine.recordFeedback('insight', 1, 'positive');
71
+ const positiveScore = engine.getRewardScore('insight', 1);
72
+ expect(positiveScore).toBe(1.0);
73
+ // All negative -> should be exactly -1.0
74
+ engine.recordFeedback('prediction', 2, 'negative');
75
+ engine.recordFeedback('prediction', 2, 'negative');
76
+ const negativeScore = engine.getRewardScore('prediction', 2);
77
+ expect(negativeScore).toBe(-1.0);
78
+ });
79
+ it('returns 0 for target with no feedback', () => {
80
+ const score = engine.getRewardScore('nonexistent', 999);
81
+ expect(score).toBe(0);
82
+ });
83
+ it('learns from correction', () => {
84
+ const correction = engine.learnFromCorrection('X causes Y', 'X correlates with Y', 'fact', 10);
85
+ expect(correction.original).toBe('X causes Y');
86
+ expect(correction.correction).toBe('X correlates with Y');
87
+ expect(correction.target_type).toBe('fact');
88
+ expect(correction.target_id).toBe(10);
89
+ expect(correction.applied).toBe(0);
90
+ // Should also have created a correction feedback signal
91
+ const history = engine.getFeedbackHistory('fact', 10);
92
+ expect(history).toHaveLength(1);
93
+ expect(history[0].signal).toBe('correction');
94
+ });
95
+ it('returns correct stats', () => {
96
+ engine.recordFeedback('insight', 1, 'positive');
97
+ engine.recordFeedback('insight', 2, 'positive');
98
+ engine.recordFeedback('prediction', 1, 'negative');
99
+ engine.recordFeedback('rule', 1, 'correction');
100
+ const stats = engine.getStats();
101
+ expect(stats.totalFeedback).toBe(4);
102
+ expect(stats.positiveCount).toBe(2);
103
+ expect(stats.negativeCount).toBe(1);
104
+ expect(stats.correctionCount).toBe(1);
105
+ // avg: (1 + 1 + -1 + -0.5) / 4 = 0.125
106
+ expect(stats.avgRewardScore).toBeCloseTo(0.125, 2);
107
+ });
108
+ it('returns feedback history for a target', () => {
109
+ engine.recordFeedback('insight', 1, 'positive', 'good');
110
+ engine.recordFeedback('insight', 1, 'negative', 'bad');
111
+ engine.recordFeedback('insight', 1, 'positive', 'better');
112
+ engine.recordFeedback('insight', 2, 'positive', 'other target');
113
+ const history = engine.getFeedbackHistory('insight', 1);
114
+ expect(history).toHaveLength(3);
115
+ // Should not include target_id=2
116
+ expect(history.every(h => h.target_id === 1)).toBe(true);
117
+ });
118
+ it('limits feedback history results', () => {
119
+ for (let i = 0; i < 10; i++) {
120
+ engine.recordFeedback('insight', 1, 'positive', `feedback ${i}`);
121
+ }
122
+ const history = engine.getFeedbackHistory('insight', 1, 5);
123
+ expect(history).toHaveLength(5);
124
+ });
125
+ it('handles multiple signals for same target in reward calculation', () => {
126
+ // 3 positive, 2 negative, 1 correction
127
+ engine.recordFeedback('insight', 1, 'positive');
128
+ engine.recordFeedback('insight', 1, 'positive');
129
+ engine.recordFeedback('insight', 1, 'positive');
130
+ engine.recordFeedback('insight', 1, 'negative');
131
+ engine.recordFeedback('insight', 1, 'negative');
132
+ engine.recordFeedback('insight', 1, 'correction');
133
+ const score = engine.getRewardScore('insight', 1);
134
+ // (3*1 + 2*-1 + 1*-0.5) / 6 = 0.5 / 6 = 0.0833...
135
+ expect(score).toBeCloseTo(0.5 / 6, 2);
136
+ });
137
+ it('calls synapse manager strengthen/weaken in applyRewards', () => {
138
+ const mockSynapseManager = {
139
+ strengthen: vi.fn(),
140
+ weaken: vi.fn(),
141
+ find: vi.fn().mockReturnValue({ id: 1, weight: 0.5 }),
142
+ };
143
+ engine.recordFeedback('insight', 1, 'positive');
144
+ engine.recordFeedback('prediction', 2, 'negative');
145
+ engine.applyRewards(mockSynapseManager);
146
+ expect(mockSynapseManager.strengthen).toHaveBeenCalled();
147
+ expect(mockSynapseManager.find).toHaveBeenCalled();
148
+ expect(mockSynapseManager.weaken).toHaveBeenCalled();
149
+ });
150
+ it('skips applyRewards without synapse manager', () => {
151
+ engine.recordFeedback('insight', 1, 'positive');
152
+ // Should not throw
153
+ expect(() => engine.applyRewards()).not.toThrow();
154
+ });
155
+ });
156
+ //# sourceMappingURL=feedback-engine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-engine.test.js","sourceRoot":"","sources":["../../../src/feedback/__tests__/feedback-engine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { ThoughtStream } from '../consciousness/thought-stream.js';
3
+ import type { BaseSynapseManager } from '../synapses/synapse-manager.js';
4
+ export interface FeedbackEngineConfig {
5
+ brainName: string;
6
+ /** Reward adjustment per positive signal. Default: 0.1 */
7
+ positiveRewardDelta?: number;
8
+ /** Reward adjustment per negative signal. Default: 0.1 */
9
+ negativeRewardDelta?: number;
10
+ }
11
+ export type FeedbackSignal = 'positive' | 'negative' | 'correction';
12
+ export interface FeedbackRecord {
13
+ id?: number;
14
+ target_type: string;
15
+ target_id: number;
16
+ signal: FeedbackSignal;
17
+ detail: string | null;
18
+ reward_score: number;
19
+ created_at: string;
20
+ }
21
+ export interface FeedbackCorrection {
22
+ id?: number;
23
+ target_type: string;
24
+ target_id: number;
25
+ original: string;
26
+ correction: string;
27
+ applied: number;
28
+ created_at: string;
29
+ }
30
+ export interface FeedbackStats {
31
+ totalFeedback: number;
32
+ positiveCount: number;
33
+ negativeCount: number;
34
+ correctionCount: number;
35
+ avgRewardScore: number;
36
+ }
37
+ export declare function runFeedbackMigration(db: Database.Database): void;
38
+ export declare class FeedbackEngine {
39
+ private readonly db;
40
+ private readonly config;
41
+ private readonly log;
42
+ private ts;
43
+ private readonly stmtInsertFeedback;
44
+ private readonly stmtGetFeedback;
45
+ private readonly stmtGetFeedbackHistory;
46
+ private readonly stmtCountBySignal;
47
+ private readonly stmtTotalFeedback;
48
+ private readonly stmtAvgReward;
49
+ private readonly stmtInsertCorrection;
50
+ private readonly stmtGetCorrections;
51
+ private readonly stmtDistinctTargets;
52
+ private readonly stmtGetRewardComponents;
53
+ constructor(db: Database.Database, config: FeedbackEngineConfig);
54
+ setThoughtStream(ts: ThoughtStream): void;
55
+ recordFeedback(type: string, targetId: number, signal: FeedbackSignal, detail?: string): FeedbackRecord;
56
+ getRewardScore(type: string, targetId: number): number;
57
+ applyRewards(synapseManager?: BaseSynapseManager): void;
58
+ learnFromCorrection(original: string, correction: string, targetType: string, targetId: number): FeedbackCorrection;
59
+ getStats(): FeedbackStats;
60
+ getFeedbackHistory(type: string, targetId: number, limit?: number): FeedbackRecord[];
61
+ }