agentic-flow 1.4.6 → 1.4.8

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/CHANGELOG.md CHANGED
@@ -5,6 +5,102 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.4.7] - 2025-10-11
9
+
10
+ ### 🐛 Critical Bug Fix: ReasoningBank CLI Now Accessible
11
+
12
+ This release fixes the ReasoningBank CLI commands not being accessible in v1.4.6.
13
+
14
+ ### Fixed
15
+ - **Critical:** ReasoningBank CLI commands now work after npm install
16
+ - Fixed incomplete dist/ build in published v1.4.6 package
17
+ - All 5 CLI commands now accessible: demo, test, init, benchmark, status
18
+ - Command handler properly integrated into main CLI
19
+ - Complete rebuild ensures all 25 ReasoningBank modules included
20
+
21
+ ### Verified
22
+ - ✅ `npx agentic-flow reasoningbank help` - Shows full help menu
23
+ - ✅ `npx agentic-flow reasoningbank demo` - Interactive demo works
24
+ - ✅ `npx agentic-flow reasoningbank test` - 27 tests passing
25
+ - ✅ `npx agentic-flow reasoningbank init` - Database initialization works
26
+ - ✅ `npx agentic-flow reasoningbank benchmark` - Performance tests work
27
+ - ✅ `npx agentic-flow reasoningbank status` - Memory statistics work
28
+ - ✅ 502 files in package (up from incomplete v1.4.6)
29
+ - ✅ dist/reasoningbank/ directory fully compiled (25 modules)
30
+ - ✅ dist/utils/reasoningbankCommands.js properly linked
31
+
32
+ ### Technical Details
33
+ - **Root Cause:** v1.4.6 was published before TypeScript build completed
34
+ - **Fix:** Clean rebuild with `rm -rf dist/ && npm run build`
35
+ - **Prevention:** `prepublishOnly` hook ensures build before publish
36
+
37
+ ### Package Contents
38
+ **ReasoningBank Core (dist/reasoningbank/):**
39
+ - core/ - retrieve.js, judge.js, distill.js, consolidate.js, matts.js
40
+ - db/ - schema.js, queries.js
41
+ - utils/ - config.js, embeddings.js, mmr.js, pii-scrubber.js
42
+ - hooks/ - pre-task.js, post-task.js
43
+ - Tests - demo-comparison.js, test-*.js, benchmark.js
44
+
45
+ ### Documentation
46
+ - Added `docs/releases/v1.4.7-bugfix.md` - Complete bug fix details
47
+ - Updated `CHANGELOG.md` with fix verification
48
+
49
+ ### Breaking Changes
50
+ None - fully backward compatible with v1.4.6
51
+
52
+ ### Migration from v1.4.6
53
+ Simply upgrade:
54
+ ```bash
55
+ npm install -g agentic-flow@latest
56
+ ```
57
+
58
+ ## [1.4.6] - 2025-10-10
59
+
60
+ ### ✨ Major Feature: ReasoningBank - Memory System that Learns from Experience
61
+
62
+ **⚠️ Known Issue:** CLI commands not accessible in published package. Fixed in v1.4.7.
63
+
64
+ ### Added
65
+ - **ReasoningBank** - Full closed-loop memory system implementation
66
+ - 4-phase learning loop (RETRIEVE → JUDGE → DISTILL → CONSOLIDATE)
67
+ - 4-factor scoring formula (similarity, recency, reliability, diversity)
68
+ - MaTTS (Memory-aware Test-Time Scaling)
69
+ - 27/27 tests passing
70
+ - Performance 2-200x faster than targets
71
+
72
+ - **Database Schema** - 6 new tables for memory persistence
73
+ - reasoning_memory, pattern_embeddings, task_trajectory
74
+ - matts_runs, consolidation_runs, pattern_links
75
+
76
+ - **CLI Commands** (5 new commands - broken in v1.4.6, fixed in v1.4.7)
77
+ - `reasoningbank demo` - Interactive demo comparison
78
+ - `reasoningbank test` - Validation test suite
79
+ - `reasoningbank init` - Database initialization
80
+ - `reasoningbank benchmark` - Performance benchmarks
81
+ - `reasoningbank status` - Memory statistics
82
+
83
+ - **Documentation** (3 comprehensive guides, 1,400+ lines)
84
+ - src/reasoningbank/README.md (528 lines)
85
+ - docs/REASONINGBANK-DEMO.md (420 lines)
86
+ - docs/REASONINGBANK-CLI-INTEGRATION.md (456 lines)
87
+
88
+ - **Security**
89
+ - PII scrubbing with 9 pattern types
90
+ - Multi-tenant support with tenant isolation
91
+ - Full audit trail
92
+
93
+ ### Performance
94
+ - Insert memory: 1.175ms (851 ops/sec)
95
+ - Retrieve (filtered): 0.924ms (1,083 ops/sec)
96
+ - MMR diversity: 0.005ms (208K ops/sec)
97
+ - Scales to 10,000+ memories with linear performance
98
+
99
+ ### Changed
100
+ - Version: 1.4.5 → 1.4.6
101
+ - README: Added ReasoningBank as primary feature
102
+ - Keywords: Added reasoning, memory, and learning tags
103
+
8
104
  ## [1.1.14] - 2025-10-05
9
105
 
10
106
  ### 🎉 Major Fix: OpenRouter Proxy Now Working!
package/dist/cli-proxy.js CHANGED
@@ -30,6 +30,7 @@ import { logger } from "./utils/logger.js";
30
30
  import { parseArgs } from "./utils/cli.js";
31
31
  import { getAgent, listAgents } from "./utils/agentLoader.js";
32
32
  import { claudeAgent } from "./agents/claudeAgent.js";
33
+ import { handleReasoningBankCommand } from "./utils/reasoningbankCommands.js";
33
34
  import { handleConfigCommand } from "./cli/config-wizard.js";
34
35
  import { handleAgentCommand } from "./cli/agent-manager.js";
35
36
  import { ModelOptimizer } from "./utils/modelOptimizer.js";
@@ -53,7 +54,7 @@ class AgenticFlowCLI {
53
54
  process.exit(0);
54
55
  }
55
56
  // If no mode and no agent specified, show help
56
- if (!options.agent && options.mode !== 'list' && !['config', 'agent-manager', 'mcp-manager', 'proxy', 'claude-code', 'mcp'].includes(options.mode)) {
57
+ if (!options.agent && options.mode !== 'list' && !['config', 'agent-manager', 'mcp-manager', 'proxy', 'claude-code', 'mcp', 'reasoningbank'].includes(options.mode)) {
57
58
  this.printHelp();
58
59
  process.exit(0);
59
60
  }
@@ -132,6 +133,12 @@ class AgenticFlowCLI {
132
133
  process.on('SIGTERM', () => proc.kill('SIGTERM'));
133
134
  return;
134
135
  }
136
+ if (options.mode === 'reasoningbank') {
137
+ // Handle ReasoningBank commands
138
+ const subcommand = process.argv[3] || 'help';
139
+ await handleReasoningBankCommand(subcommand);
140
+ process.exit(0);
141
+ }
135
142
  // Apply model optimization if requested
136
143
  if (options.optimize && options.agent && options.task) {
137
144
  const recommendation = ModelOptimizer.optimize({
@@ -0,0 +1,250 @@
1
+ /**
2
+ * SQLite Database Layer for ReasoningBank
3
+ * Handles memory storage, retrieval, and consolidation
4
+ */
5
+ import Database from 'better-sqlite3';
6
+ import { ulid } from 'ulid';
7
+ export class ReasoningBankDB {
8
+ db;
9
+ constructor(dbPath) {
10
+ this.db = new Database(dbPath);
11
+ this.db.pragma('journal_mode = WAL'); // Enable Write-Ahead Logging for concurrency
12
+ this.initSchema();
13
+ }
14
+ initSchema() {
15
+ // Main memory table
16
+ this.db.exec(`
17
+ CREATE TABLE IF NOT EXISTS reasoning_memory (
18
+ id TEXT PRIMARY KEY,
19
+ title TEXT NOT NULL,
20
+ description TEXT NOT NULL,
21
+ content TEXT NOT NULL,
22
+ confidence REAL DEFAULT 0.5,
23
+ usage_count INTEGER DEFAULT 0,
24
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
25
+ pattern_data JSON NOT NULL
26
+ );
27
+
28
+ CREATE INDEX IF NOT EXISTS idx_memory_confidence ON reasoning_memory(confidence);
29
+ CREATE INDEX IF NOT EXISTS idx_memory_created_at ON reasoning_memory(created_at);
30
+ CREATE INDEX IF NOT EXISTS idx_memory_domain ON reasoning_memory(json_extract(pattern_data, '$.domain'));
31
+ `);
32
+ // Pattern embeddings table
33
+ this.db.exec(`
34
+ CREATE TABLE IF NOT EXISTS pattern_embeddings (
35
+ pattern_id TEXT PRIMARY KEY,
36
+ embedding BLOB NOT NULL,
37
+ FOREIGN KEY (pattern_id) REFERENCES reasoning_memory(id) ON DELETE CASCADE
38
+ );
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_embeddings_pattern ON pattern_embeddings(pattern_id);
41
+ `);
42
+ // Task trajectory table
43
+ this.db.exec(`
44
+ CREATE TABLE IF NOT EXISTS task_trajectory (
45
+ id TEXT PRIMARY KEY,
46
+ task_id TEXT NOT NULL,
47
+ trajectory TEXT NOT NULL,
48
+ verdict TEXT NOT NULL CHECK(verdict IN ('Success', 'Failure')),
49
+ confidence REAL NOT NULL,
50
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
51
+ );
52
+
53
+ CREATE INDEX IF NOT EXISTS idx_trajectory_task ON task_trajectory(task_id);
54
+ CREATE INDEX IF NOT EXISTS idx_trajectory_verdict ON task_trajectory(verdict);
55
+ `);
56
+ // MaTTS runs table
57
+ this.db.exec(`
58
+ CREATE TABLE IF NOT EXISTS matts_runs (
59
+ id TEXT PRIMARY KEY,
60
+ task_id TEXT NOT NULL,
61
+ run_index INTEGER NOT NULL,
62
+ result TEXT NOT NULL,
63
+ verdict TEXT NOT NULL CHECK(verdict IN ('Success', 'Failure')),
64
+ confidence REAL NOT NULL,
65
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
66
+ );
67
+
68
+ CREATE INDEX IF NOT EXISTS idx_matts_task ON matts_runs(task_id);
69
+ `);
70
+ }
71
+ // Memory operations
72
+ insertMemory(memory) {
73
+ const id = ulid();
74
+ const stmt = this.db.prepare(`
75
+ INSERT INTO reasoning_memory (id, title, description, content, confidence, usage_count, pattern_data)
76
+ VALUES (?, ?, ?, ?, ?, ?, json(?))
77
+ `);
78
+ stmt.run(id, memory.title, memory.description, memory.content, memory.confidence, memory.usage_count, JSON.stringify(memory.pattern_data));
79
+ return id;
80
+ }
81
+ getMemory(id) {
82
+ const stmt = this.db.prepare(`
83
+ SELECT id, title, description, content, confidence, usage_count,
84
+ datetime(created_at) as created_at, pattern_data
85
+ FROM reasoning_memory
86
+ WHERE id = ?
87
+ `);
88
+ const row = stmt.get(id);
89
+ if (!row)
90
+ return null;
91
+ return {
92
+ ...row,
93
+ pattern_data: JSON.parse(row.pattern_data)
94
+ };
95
+ }
96
+ getAllMemories() {
97
+ const stmt = this.db.prepare(`
98
+ SELECT id, title, description, content, confidence, usage_count,
99
+ datetime(created_at) as created_at, pattern_data
100
+ FROM reasoning_memory
101
+ ORDER BY created_at DESC
102
+ `);
103
+ const rows = stmt.all();
104
+ return rows.map(row => ({
105
+ ...row,
106
+ pattern_data: JSON.parse(row.pattern_data)
107
+ }));
108
+ }
109
+ updateMemoryUsage(id) {
110
+ const stmt = this.db.prepare(`
111
+ UPDATE reasoning_memory
112
+ SET usage_count = usage_count + 1
113
+ WHERE id = ?
114
+ `);
115
+ stmt.run(id);
116
+ }
117
+ updateMemoryConfidence(id, confidence) {
118
+ const stmt = this.db.prepare(`
119
+ UPDATE reasoning_memory
120
+ SET confidence = ?
121
+ WHERE id = ?
122
+ `);
123
+ stmt.run(confidence, id);
124
+ }
125
+ deleteMemory(id) {
126
+ const stmt = this.db.prepare('DELETE FROM reasoning_memory WHERE id = ?');
127
+ stmt.run(id);
128
+ }
129
+ // Embedding operations
130
+ insertEmbedding(patternId, embedding) {
131
+ const buffer = Buffer.from(new Float64Array(embedding).buffer);
132
+ const stmt = this.db.prepare(`
133
+ INSERT OR REPLACE INTO pattern_embeddings (pattern_id, embedding)
134
+ VALUES (?, ?)
135
+ `);
136
+ stmt.run(patternId, buffer);
137
+ }
138
+ getEmbedding(patternId) {
139
+ const stmt = this.db.prepare('SELECT embedding FROM pattern_embeddings WHERE pattern_id = ?');
140
+ const row = stmt.get(patternId);
141
+ if (!row)
142
+ return null;
143
+ const buffer = row.embedding;
144
+ return Array.from(new Float64Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 8));
145
+ }
146
+ getAllEmbeddings() {
147
+ const stmt = this.db.prepare('SELECT pattern_id, embedding FROM pattern_embeddings');
148
+ const rows = stmt.all();
149
+ const embeddings = new Map();
150
+ for (const row of rows) {
151
+ const buffer = row.embedding;
152
+ const embedding = Array.from(new Float64Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 8));
153
+ embeddings.set(row.pattern_id, embedding);
154
+ }
155
+ return embeddings;
156
+ }
157
+ // Trajectory operations
158
+ insertTrajectory(trajectory) {
159
+ const id = ulid();
160
+ const stmt = this.db.prepare(`
161
+ INSERT INTO task_trajectory (id, task_id, trajectory, verdict, confidence)
162
+ VALUES (?, ?, ?, ?, ?)
163
+ `);
164
+ stmt.run(id, trajectory.task_id, trajectory.trajectory, trajectory.verdict, trajectory.confidence);
165
+ return id;
166
+ }
167
+ getTrajectories(taskId) {
168
+ const stmt = this.db.prepare(`
169
+ SELECT id, task_id, trajectory, verdict, confidence, datetime(created_at) as created_at
170
+ FROM task_trajectory
171
+ WHERE task_id = ?
172
+ ORDER BY created_at DESC
173
+ `);
174
+ return stmt.all(taskId);
175
+ }
176
+ // MaTTS operations
177
+ insertMattsRun(run) {
178
+ const id = ulid();
179
+ const stmt = this.db.prepare(`
180
+ INSERT INTO matts_runs (id, task_id, run_index, result, verdict, confidence)
181
+ VALUES (?, ?, ?, ?, ?, ?)
182
+ `);
183
+ stmt.run(id, run.task_id, run.run_index, run.result, run.verdict, run.confidence);
184
+ return id;
185
+ }
186
+ getMattsRuns(taskId) {
187
+ const stmt = this.db.prepare(`
188
+ SELECT id, task_id, run_index, result, verdict, confidence, datetime(created_at) as created_at
189
+ FROM matts_runs
190
+ WHERE task_id = ?
191
+ ORDER BY run_index ASC
192
+ `);
193
+ return stmt.all(taskId);
194
+ }
195
+ // Statistics
196
+ getStats() {
197
+ const memoryStats = this.db.prepare(`
198
+ SELECT COUNT(*) as total, AVG(confidence) as avg_conf, SUM(usage_count) as total_usage
199
+ FROM reasoning_memory
200
+ `).get();
201
+ const trajectoryStats = this.db.prepare(`
202
+ SELECT
203
+ SUM(CASE WHEN verdict = 'Success' THEN 1 ELSE 0 END) as successes,
204
+ COUNT(*) as total
205
+ FROM task_trajectory
206
+ `).get();
207
+ return {
208
+ totalMemories: memoryStats.total || 0,
209
+ avgConfidence: memoryStats.avg_conf || 0,
210
+ totalUsage: memoryStats.total_usage || 0,
211
+ successRate: trajectoryStats.total > 0
212
+ ? trajectoryStats.successes / trajectoryStats.total
213
+ : 0
214
+ };
215
+ }
216
+ // Consolidation helpers
217
+ findDuplicates(threshold = 0.95) {
218
+ // Returns pairs of memory IDs that are likely duplicates
219
+ const memories = this.getAllMemories();
220
+ const embeddings = this.getAllEmbeddings();
221
+ const duplicates = [];
222
+ for (let i = 0; i < memories.length; i++) {
223
+ for (let j = i + 1; j < memories.length; j++) {
224
+ const emb1 = embeddings.get(memories[i].id);
225
+ const emb2 = embeddings.get(memories[j].id);
226
+ if (emb1 && emb2) {
227
+ const similarity = this.cosineSimilarity(emb1, emb2);
228
+ if (similarity >= threshold) {
229
+ duplicates.push([memories[i].id, memories[j].id]);
230
+ }
231
+ }
232
+ }
233
+ }
234
+ return duplicates;
235
+ }
236
+ cosineSimilarity(a, b) {
237
+ let dotProduct = 0;
238
+ let normA = 0;
239
+ let normB = 0;
240
+ for (let i = 0; i < a.length; i++) {
241
+ dotProduct += a[i] * b[i];
242
+ normA += a[i] * a[i];
243
+ normB += b[i] * b[i];
244
+ }
245
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
246
+ }
247
+ close() {
248
+ this.db.close();
249
+ }
250
+ }