agentic-flow 1.7.3 → 1.7.4
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/.claude/agents/test-neural.md +0 -5
- package/.claude/answer.md +1 -0
- package/.claude/settings.json +19 -20
- package/CHANGELOG.md +0 -117
- package/README.md +17 -81
- package/dist/agentdb/benchmarks/comprehensive-benchmark.js +664 -0
- package/dist/agentdb/benchmarks/frontier-benchmark.js +419 -0
- package/dist/agentdb/benchmarks/reflexion-benchmark.js +370 -0
- package/dist/agentdb/cli/agentdb-cli.js +717 -0
- package/dist/agentdb/controllers/CausalMemoryGraph.js +322 -0
- package/dist/agentdb/controllers/CausalRecall.js +281 -0
- package/dist/agentdb/controllers/EmbeddingService.js +118 -0
- package/dist/agentdb/controllers/ExplainableRecall.js +387 -0
- package/dist/agentdb/controllers/NightlyLearner.js +382 -0
- package/dist/agentdb/controllers/ReflexionMemory.js +239 -0
- package/dist/agentdb/controllers/SkillLibrary.js +276 -0
- package/dist/agentdb/controllers/frontier-index.js +9 -0
- package/dist/agentdb/controllers/index.js +8 -0
- package/dist/agentdb/index.js +32 -0
- package/dist/agentdb/optimizations/BatchOperations.js +198 -0
- package/dist/agentdb/optimizations/QueryOptimizer.js +225 -0
- package/dist/agentdb/optimizations/index.js +7 -0
- package/dist/agentdb/tests/frontier-features.test.js +665 -0
- package/dist/cli-proxy.js +2 -33
- package/dist/mcp/standalone-stdio.js +200 -4
- package/dist/memory/SharedMemoryPool.js +211 -0
- package/dist/memory/index.js +6 -0
- package/dist/reasoningbank/AdvancedMemory.js +239 -0
- package/dist/reasoningbank/HybridBackend.js +305 -0
- package/dist/reasoningbank/index-new.js +87 -0
- package/dist/reasoningbank/index.js +23 -44
- package/dist/utils/cli.js +0 -22
- package/docs/AGENTDB_TESTING.md +411 -0
- package/docs/v1.7.1-QUICK-START.md +399 -0
- package/package.json +4 -4
- package/scripts/run-validation.sh +165 -0
- package/scripts/test-agentdb.sh +153 -0
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +0 -166
- package/.claude/skills/agentdb-vector-search/SKILL.md +0 -126
- package/.claude/skills/agentic-flow/agentdb-memory-patterns/SKILL.md +0 -166
- package/.claude/skills/agentic-flow/agentdb-vector-search/SKILL.md +0 -126
- package/.claude/skills/agentic-flow/reasoningbank-intelligence/SKILL.md +0 -201
- package/.claude/skills/agentic-flow/swarm-orchestration/SKILL.md +0 -179
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +0 -201
- package/.claude/skills/skill-builder/README.md +0 -308
- package/.claude/skills/skill-builder/SKILL.md +0 -910
- package/.claude/skills/skill-builder/docs/SPECIFICATION.md +0 -358
- package/.claude/skills/skill-builder/resources/schemas/skill-frontmatter.schema.json +0 -41
- package/.claude/skills/skill-builder/resources/templates/full-skill.template +0 -118
- package/.claude/skills/skill-builder/resources/templates/minimal-skill.template +0 -38
- package/.claude/skills/skill-builder/scripts/generate-skill.sh +0 -334
- package/.claude/skills/skill-builder/scripts/validate-skill.sh +0 -198
- package/.claude/skills/swarm-orchestration/SKILL.md +0 -179
- package/docs/AGENTDB_INTEGRATION.md +0 -379
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AgentDB CLI - Command-line interface for frontier memory features
|
|
4
|
+
*
|
|
5
|
+
* Provides commands for:
|
|
6
|
+
* - Causal memory graph operations
|
|
7
|
+
* - Explainable recall with certificates
|
|
8
|
+
* - Nightly learner automation
|
|
9
|
+
* - Database management
|
|
10
|
+
*/
|
|
11
|
+
import Database from 'better-sqlite3';
|
|
12
|
+
import { CausalMemoryGraph } from '../controllers/CausalMemoryGraph.js';
|
|
13
|
+
import { CausalRecall } from '../controllers/CausalRecall.js';
|
|
14
|
+
import { ExplainableRecall } from '../controllers/ExplainableRecall.js';
|
|
15
|
+
import { NightlyLearner } from '../controllers/NightlyLearner.js';
|
|
16
|
+
import { ReflexionMemory } from '../controllers/ReflexionMemory.js';
|
|
17
|
+
import { SkillLibrary } from '../controllers/SkillLibrary.js';
|
|
18
|
+
import { EmbeddingService } from '../controllers/EmbeddingService.js';
|
|
19
|
+
import * as fs from 'fs';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
// Color codes for terminal output
|
|
22
|
+
const colors = {
|
|
23
|
+
reset: '\x1b[0m',
|
|
24
|
+
bright: '\x1b[1m',
|
|
25
|
+
green: '\x1b[32m',
|
|
26
|
+
yellow: '\x1b[33m',
|
|
27
|
+
blue: '\x1b[34m',
|
|
28
|
+
red: '\x1b[31m',
|
|
29
|
+
cyan: '\x1b[36m'
|
|
30
|
+
};
|
|
31
|
+
const log = {
|
|
32
|
+
success: (msg) => console.log(`${colors.green}✅ ${msg}${colors.reset}`),
|
|
33
|
+
error: (msg) => console.error(`${colors.red}❌ ${msg}${colors.reset}`),
|
|
34
|
+
info: (msg) => console.log(`${colors.blue}ℹ ${msg}${colors.reset}`),
|
|
35
|
+
warning: (msg) => console.log(`${colors.yellow}⚠ ${msg}${colors.reset}`),
|
|
36
|
+
header: (msg) => console.log(`${colors.bright}${colors.cyan}${msg}${colors.reset}`)
|
|
37
|
+
};
|
|
38
|
+
class AgentDBCLI {
|
|
39
|
+
db;
|
|
40
|
+
causalGraph;
|
|
41
|
+
causalRecall;
|
|
42
|
+
explainableRecall;
|
|
43
|
+
nightlyLearner;
|
|
44
|
+
reflexion;
|
|
45
|
+
skills;
|
|
46
|
+
embedder;
|
|
47
|
+
async initialize(dbPath = './agentdb.db') {
|
|
48
|
+
// Initialize database
|
|
49
|
+
this.db = new Database(dbPath);
|
|
50
|
+
// Configure for performance
|
|
51
|
+
this.db.pragma('journal_mode = WAL');
|
|
52
|
+
this.db.pragma('synchronous = NORMAL');
|
|
53
|
+
this.db.pragma('cache_size = -64000');
|
|
54
|
+
// Load schema if needed
|
|
55
|
+
const schemaPath = path.join(__dirname, '../schemas/frontier-schema.sql');
|
|
56
|
+
if (fs.existsSync(schemaPath)) {
|
|
57
|
+
const schema = fs.readFileSync(schemaPath, 'utf-8');
|
|
58
|
+
this.db.exec(schema);
|
|
59
|
+
}
|
|
60
|
+
// Initialize embedding service
|
|
61
|
+
this.embedder = new EmbeddingService({
|
|
62
|
+
model: 'all-MiniLM-L6-v2',
|
|
63
|
+
dimension: 384,
|
|
64
|
+
provider: 'transformers'
|
|
65
|
+
});
|
|
66
|
+
await this.embedder.initialize();
|
|
67
|
+
// Initialize controllers
|
|
68
|
+
this.causalGraph = new CausalMemoryGraph(this.db);
|
|
69
|
+
this.explainableRecall = new ExplainableRecall(this.db);
|
|
70
|
+
this.causalRecall = new CausalRecall(this.db, this.embedder, this.causalGraph, this.explainableRecall);
|
|
71
|
+
this.nightlyLearner = new NightlyLearner(this.db, this.embedder, this.causalGraph);
|
|
72
|
+
this.reflexion = new ReflexionMemory(this.db, this.embedder);
|
|
73
|
+
this.skills = new SkillLibrary(this.db, this.embedder);
|
|
74
|
+
}
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Causal Commands
|
|
77
|
+
// ============================================================================
|
|
78
|
+
async causalAddEdge(params) {
|
|
79
|
+
if (!this.causalGraph)
|
|
80
|
+
throw new Error('Not initialized');
|
|
81
|
+
log.header('\n📊 Adding Causal Edge');
|
|
82
|
+
log.info(`Cause: ${params.cause}`);
|
|
83
|
+
log.info(`Effect: ${params.effect}`);
|
|
84
|
+
log.info(`Uplift: ${params.uplift}`);
|
|
85
|
+
const edgeId = this.causalGraph.addEdge({
|
|
86
|
+
cause: params.cause,
|
|
87
|
+
effect: params.effect,
|
|
88
|
+
uplift: params.uplift,
|
|
89
|
+
confidence: params.confidence || 0.95,
|
|
90
|
+
sampleSize: params.sampleSize || 0,
|
|
91
|
+
evidenceIds: []
|
|
92
|
+
});
|
|
93
|
+
log.success(`Added causal edge #${edgeId}`);
|
|
94
|
+
}
|
|
95
|
+
async causalExperimentCreate(params) {
|
|
96
|
+
if (!this.causalGraph)
|
|
97
|
+
throw new Error('Not initialized');
|
|
98
|
+
log.header('\n🧪 Creating A/B Experiment');
|
|
99
|
+
log.info(`Name: ${params.name}`);
|
|
100
|
+
log.info(`Cause: ${params.cause}`);
|
|
101
|
+
log.info(`Effect: ${params.effect}`);
|
|
102
|
+
const expId = this.causalGraph.createExperiment({
|
|
103
|
+
name: params.name,
|
|
104
|
+
cause: params.cause,
|
|
105
|
+
effect: params.effect
|
|
106
|
+
});
|
|
107
|
+
log.success(`Created experiment #${expId}`);
|
|
108
|
+
log.info('Use `agentdb causal experiment add-observation` to record data');
|
|
109
|
+
}
|
|
110
|
+
async causalExperimentAddObservation(params) {
|
|
111
|
+
if (!this.causalGraph)
|
|
112
|
+
throw new Error('Not initialized');
|
|
113
|
+
this.causalGraph.recordObservation({
|
|
114
|
+
experimentId: params.experimentId,
|
|
115
|
+
isTreatment: params.isTreatment,
|
|
116
|
+
outcome: params.outcome,
|
|
117
|
+
context: params.context || '{}'
|
|
118
|
+
});
|
|
119
|
+
log.success(`Recorded ${params.isTreatment ? 'treatment' : 'control'} observation: ${params.outcome}`);
|
|
120
|
+
}
|
|
121
|
+
async causalExperimentCalculate(experimentId) {
|
|
122
|
+
if (!this.causalGraph)
|
|
123
|
+
throw new Error('Not initialized');
|
|
124
|
+
log.header('\n📈 Calculating Uplift');
|
|
125
|
+
const result = this.causalGraph.calculateUplift(experimentId);
|
|
126
|
+
log.info(`Treatment Mean: ${result.treatmentMean.toFixed(3)}`);
|
|
127
|
+
log.info(`Control Mean: ${result.controlMean.toFixed(3)}`);
|
|
128
|
+
log.success(`Uplift: ${result.uplift.toFixed(3)}`);
|
|
129
|
+
log.info(`95% CI: [${result.confidenceLower.toFixed(3)}, ${result.confidenceUpper.toFixed(3)}]`);
|
|
130
|
+
log.info(`p-value: ${result.pValue.toFixed(4)}`);
|
|
131
|
+
log.info(`Sample Sizes: ${result.treatmentN} treatment, ${result.controlN} control`);
|
|
132
|
+
if (result.pValue < 0.05) {
|
|
133
|
+
log.success('Result is statistically significant (p < 0.05)');
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
log.warning('Result is not statistically significant');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async causalQuery(params) {
|
|
140
|
+
if (!this.causalGraph)
|
|
141
|
+
throw new Error('Not initialized');
|
|
142
|
+
log.header('\n🔍 Querying Causal Edges');
|
|
143
|
+
const edges = this.causalGraph.getCausalEffects({
|
|
144
|
+
cause: params.cause,
|
|
145
|
+
effect: params.effect,
|
|
146
|
+
minConfidence: params.minConfidence || 0.7,
|
|
147
|
+
minUplift: params.minUplift || 0.1
|
|
148
|
+
});
|
|
149
|
+
if (edges.length === 0) {
|
|
150
|
+
log.warning('No causal edges found');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
console.log('\n' + '═'.repeat(80));
|
|
154
|
+
edges.slice(0, params.limit || 10).forEach((edge, i) => {
|
|
155
|
+
console.log(`${colors.bright}#${i + 1}: ${edge.cause} → ${edge.effect}${colors.reset}`);
|
|
156
|
+
console.log(` Uplift: ${colors.green}${edge.uplift.toFixed(3)}${colors.reset}`);
|
|
157
|
+
console.log(` Confidence: ${edge.confidence.toFixed(2)} (n=${edge.sampleSize})`);
|
|
158
|
+
console.log('─'.repeat(80));
|
|
159
|
+
});
|
|
160
|
+
log.success(`Found ${edges.length} causal edges`);
|
|
161
|
+
}
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// Recall Commands
|
|
164
|
+
// ============================================================================
|
|
165
|
+
async recallWithCertificate(params) {
|
|
166
|
+
if (!this.causalRecall)
|
|
167
|
+
throw new Error('Not initialized');
|
|
168
|
+
log.header('\n🔍 Causal Recall with Certificate');
|
|
169
|
+
log.info(`Query: "${params.query}"`);
|
|
170
|
+
log.info(`k: ${params.k || 12}`);
|
|
171
|
+
const startTime = Date.now();
|
|
172
|
+
const result = await this.causalRecall.recall({
|
|
173
|
+
qid: 'cli-' + Date.now(),
|
|
174
|
+
query: params.query,
|
|
175
|
+
k: params.k || 12,
|
|
176
|
+
weights: {
|
|
177
|
+
alpha: params.alpha || 0.7,
|
|
178
|
+
beta: params.beta || 0.2,
|
|
179
|
+
gamma: params.gamma || 0.1
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const duration = Date.now() - startTime;
|
|
183
|
+
console.log('\n' + '═'.repeat(80));
|
|
184
|
+
console.log(`${colors.bright}Results (${result.results.length})${colors.reset}`);
|
|
185
|
+
console.log('═'.repeat(80));
|
|
186
|
+
result.results.slice(0, 5).forEach((r, i) => {
|
|
187
|
+
console.log(`\n${colors.bright}#${i + 1}: Episode ${r.episode.id}${colors.reset}`);
|
|
188
|
+
console.log(` Task: ${r.episode.task}`);
|
|
189
|
+
console.log(` Similarity: ${colors.cyan}${r.similarity.toFixed(3)}${colors.reset}`);
|
|
190
|
+
console.log(` Uplift: ${colors.green}${r.uplift?.toFixed(3) || 'N/A'}${colors.reset}`);
|
|
191
|
+
console.log(` Utility: ${colors.yellow}${r.utility.toFixed(3)}${colors.reset}`);
|
|
192
|
+
console.log(` Reward: ${r.episode.reward.toFixed(2)}`);
|
|
193
|
+
});
|
|
194
|
+
console.log('\n' + '═'.repeat(80));
|
|
195
|
+
log.info(`Certificate ID: ${result.certificate.id}`);
|
|
196
|
+
log.info(`Query: ${result.certificate.queryText}`);
|
|
197
|
+
log.info(`Completeness: ${result.certificate.completenessScore.toFixed(2)}`);
|
|
198
|
+
log.success(`Completed in ${duration}ms`);
|
|
199
|
+
}
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Learner Commands
|
|
202
|
+
// ============================================================================
|
|
203
|
+
async learnerRun(params) {
|
|
204
|
+
if (!this.nightlyLearner)
|
|
205
|
+
throw new Error('Not initialized');
|
|
206
|
+
log.header('\n🌙 Running Nightly Learner');
|
|
207
|
+
log.info(`Min Attempts: ${params.minAttempts || 3}`);
|
|
208
|
+
log.info(`Min Success Rate: ${params.minSuccessRate || 0.6}`);
|
|
209
|
+
log.info(`Min Confidence: ${params.minConfidence || 0.7}`);
|
|
210
|
+
const startTime = Date.now();
|
|
211
|
+
const discovered = await this.nightlyLearner.discover({
|
|
212
|
+
minAttempts: params.minAttempts || 3,
|
|
213
|
+
minSuccessRate: params.minSuccessRate || 0.6,
|
|
214
|
+
minConfidence: params.minConfidence || 0.7,
|
|
215
|
+
dryRun: params.dryRun || false
|
|
216
|
+
});
|
|
217
|
+
const duration = Date.now() - startTime;
|
|
218
|
+
log.success(`Discovered ${discovered.length} causal edges in ${(duration / 1000).toFixed(1)}s`);
|
|
219
|
+
if (discovered.length > 0) {
|
|
220
|
+
console.log('\n' + '═'.repeat(80));
|
|
221
|
+
discovered.slice(0, 10).forEach((edge, i) => {
|
|
222
|
+
console.log(`${colors.bright}#${i + 1}: ${edge.cause} → ${edge.effect}${colors.reset}`);
|
|
223
|
+
console.log(` Uplift: ${colors.green}${edge.uplift.toFixed(3)}${colors.reset} (CI: ${edge.confidence.toFixed(2)})`);
|
|
224
|
+
console.log(` Sample size: ${edge.sampleSize}`);
|
|
225
|
+
console.log('─'.repeat(80));
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async learnerPrune(params) {
|
|
230
|
+
if (!this.nightlyLearner)
|
|
231
|
+
throw new Error('Not initialized');
|
|
232
|
+
log.header('\n🧹 Pruning Low-Quality Edges');
|
|
233
|
+
const pruned = await this.nightlyLearner.pruneEdges(params);
|
|
234
|
+
log.success(`Pruned ${pruned} edges`);
|
|
235
|
+
}
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Reflexion Commands
|
|
238
|
+
// ============================================================================
|
|
239
|
+
async reflexionStoreEpisode(params) {
|
|
240
|
+
if (!this.reflexion)
|
|
241
|
+
throw new Error('Not initialized');
|
|
242
|
+
log.header('\n💭 Storing Episode');
|
|
243
|
+
log.info(`Task: ${params.task}`);
|
|
244
|
+
log.info(`Success: ${params.success ? 'Yes' : 'No'}`);
|
|
245
|
+
log.info(`Reward: ${params.reward.toFixed(2)}`);
|
|
246
|
+
const episodeId = await this.reflexion.storeEpisode(params);
|
|
247
|
+
log.success(`Stored episode #${episodeId}`);
|
|
248
|
+
if (params.critique) {
|
|
249
|
+
log.info(`Critique: "${params.critique}"`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
async reflexionRetrieve(params) {
|
|
253
|
+
if (!this.reflexion)
|
|
254
|
+
throw new Error('Not initialized');
|
|
255
|
+
log.header('\n🔍 Retrieving Past Episodes');
|
|
256
|
+
log.info(`Task: "${params.task}"`);
|
|
257
|
+
log.info(`k: ${params.k || 5}`);
|
|
258
|
+
if (params.onlyFailures)
|
|
259
|
+
log.info('Filter: Failures only');
|
|
260
|
+
if (params.onlySuccesses)
|
|
261
|
+
log.info('Filter: Successes only');
|
|
262
|
+
const episodes = await this.reflexion.retrieveRelevant({
|
|
263
|
+
task: params.task,
|
|
264
|
+
k: params.k || 5,
|
|
265
|
+
onlyFailures: params.onlyFailures,
|
|
266
|
+
onlySuccesses: params.onlySuccesses,
|
|
267
|
+
minReward: params.minReward
|
|
268
|
+
});
|
|
269
|
+
if (episodes.length === 0) {
|
|
270
|
+
log.warning('No episodes found');
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
console.log('\n' + '═'.repeat(80));
|
|
274
|
+
episodes.forEach((ep, i) => {
|
|
275
|
+
console.log(`${colors.bright}#${i + 1}: Episode ${ep.id}${colors.reset}`);
|
|
276
|
+
console.log(` Task: ${ep.task}`);
|
|
277
|
+
console.log(` Reward: ${colors.green}${ep.reward.toFixed(2)}${colors.reset}`);
|
|
278
|
+
console.log(` Success: ${ep.success ? colors.green + 'Yes' : colors.red + 'No'}${colors.reset}`);
|
|
279
|
+
console.log(` Similarity: ${colors.cyan}${ep.similarity?.toFixed(3) || 'N/A'}${colors.reset}`);
|
|
280
|
+
if (ep.critique) {
|
|
281
|
+
console.log(` Critique: "${ep.critique}"`);
|
|
282
|
+
}
|
|
283
|
+
console.log('─'.repeat(80));
|
|
284
|
+
});
|
|
285
|
+
log.success(`Retrieved ${episodes.length} relevant episodes`);
|
|
286
|
+
}
|
|
287
|
+
async reflexionGetCritiqueSummary(params) {
|
|
288
|
+
if (!this.reflexion)
|
|
289
|
+
throw new Error('Not initialized');
|
|
290
|
+
log.header('\n📋 Critique Summary');
|
|
291
|
+
log.info(`Task: "${params.task}"`);
|
|
292
|
+
const summary = await this.reflexion.getCritiqueSummary({
|
|
293
|
+
task: params.task,
|
|
294
|
+
k: params.k || 5
|
|
295
|
+
});
|
|
296
|
+
console.log('\n' + '═'.repeat(80));
|
|
297
|
+
console.log(colors.bright + 'Past Lessons:' + colors.reset);
|
|
298
|
+
console.log(summary);
|
|
299
|
+
console.log('═'.repeat(80));
|
|
300
|
+
}
|
|
301
|
+
async reflexionPrune(params) {
|
|
302
|
+
if (!this.reflexion)
|
|
303
|
+
throw new Error('Not initialized');
|
|
304
|
+
log.header('\n🧹 Pruning Episodes');
|
|
305
|
+
const pruned = await this.reflexion.pruneEpisodes({
|
|
306
|
+
minReward: params.minReward || 0.3,
|
|
307
|
+
maxAgeDays: params.maxAgeDays || 30,
|
|
308
|
+
keepMinPerTask: params.keepMinPerTask || 5
|
|
309
|
+
});
|
|
310
|
+
log.success(`Pruned ${pruned} low-quality episodes`);
|
|
311
|
+
}
|
|
312
|
+
// ============================================================================
|
|
313
|
+
// Skill Library Commands
|
|
314
|
+
// ============================================================================
|
|
315
|
+
async skillCreate(params) {
|
|
316
|
+
if (!this.skills)
|
|
317
|
+
throw new Error('Not initialized');
|
|
318
|
+
log.header('\n🎯 Creating Skill');
|
|
319
|
+
log.info(`Name: ${params.name}`);
|
|
320
|
+
log.info(`Description: ${params.description}`);
|
|
321
|
+
const skillId = await this.skills.createSkill({
|
|
322
|
+
name: params.name,
|
|
323
|
+
description: params.description,
|
|
324
|
+
signature: { inputs: {}, outputs: {} },
|
|
325
|
+
code: params.code,
|
|
326
|
+
successRate: params.successRate || 0.0,
|
|
327
|
+
uses: 0,
|
|
328
|
+
avgReward: 0.0,
|
|
329
|
+
avgLatencyMs: 0.0,
|
|
330
|
+
createdFromEpisode: params.episodeId
|
|
331
|
+
});
|
|
332
|
+
log.success(`Created skill #${skillId}`);
|
|
333
|
+
}
|
|
334
|
+
async skillSearch(params) {
|
|
335
|
+
if (!this.skills)
|
|
336
|
+
throw new Error('Not initialized');
|
|
337
|
+
log.header('\n🔍 Searching Skills');
|
|
338
|
+
log.info(`Task: "${params.task}"`);
|
|
339
|
+
log.info(`Min Success Rate: ${params.minSuccessRate || 0.0}`);
|
|
340
|
+
const skills = await this.skills.searchSkills({
|
|
341
|
+
task: params.task,
|
|
342
|
+
k: params.k || 10,
|
|
343
|
+
minSuccessRate: params.minSuccessRate || 0.0
|
|
344
|
+
});
|
|
345
|
+
if (skills.length === 0) {
|
|
346
|
+
log.warning('No skills found');
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
console.log('\n' + '═'.repeat(80));
|
|
350
|
+
skills.forEach((skill, i) => {
|
|
351
|
+
console.log(`${colors.bright}#${i + 1}: ${skill.name}${colors.reset}`);
|
|
352
|
+
console.log(` Description: ${skill.description}`);
|
|
353
|
+
console.log(` Success Rate: ${colors.green}${(skill.successRate * 100).toFixed(1)}%${colors.reset}`);
|
|
354
|
+
console.log(` Uses: ${skill.uses}`);
|
|
355
|
+
console.log(` Avg Reward: ${skill.avgReward.toFixed(2)}`);
|
|
356
|
+
console.log(` Avg Latency: ${skill.avgLatencyMs.toFixed(0)}ms`);
|
|
357
|
+
console.log('─'.repeat(80));
|
|
358
|
+
});
|
|
359
|
+
log.success(`Found ${skills.length} matching skills`);
|
|
360
|
+
}
|
|
361
|
+
async skillConsolidate(params) {
|
|
362
|
+
if (!this.skills)
|
|
363
|
+
throw new Error('Not initialized');
|
|
364
|
+
log.header('\n🔄 Consolidating Episodes into Skills');
|
|
365
|
+
log.info(`Min Attempts: ${params.minAttempts || 3}`);
|
|
366
|
+
log.info(`Min Reward: ${params.minReward || 0.7}`);
|
|
367
|
+
log.info(`Time Window: ${params.timeWindowDays || 7} days`);
|
|
368
|
+
const created = this.skills.consolidateEpisodesIntoSkills({
|
|
369
|
+
minAttempts: params.minAttempts || 3,
|
|
370
|
+
minReward: params.minReward || 0.7,
|
|
371
|
+
timeWindowDays: params.timeWindowDays || 7
|
|
372
|
+
});
|
|
373
|
+
log.success(`Created ${created} new skills from successful episodes`);
|
|
374
|
+
}
|
|
375
|
+
async skillPrune(params) {
|
|
376
|
+
if (!this.skills)
|
|
377
|
+
throw new Error('Not initialized');
|
|
378
|
+
log.header('\n🧹 Pruning Skills');
|
|
379
|
+
const pruned = this.skills.pruneSkills({
|
|
380
|
+
minUses: params.minUses || 3,
|
|
381
|
+
minSuccessRate: params.minSuccessRate || 0.4,
|
|
382
|
+
maxAgeDays: params.maxAgeDays || 60
|
|
383
|
+
});
|
|
384
|
+
log.success(`Pruned ${pruned} underperforming skills`);
|
|
385
|
+
}
|
|
386
|
+
// ============================================================================
|
|
387
|
+
// Database Commands
|
|
388
|
+
// ============================================================================
|
|
389
|
+
async dbStats() {
|
|
390
|
+
if (!this.db)
|
|
391
|
+
throw new Error('Not initialized');
|
|
392
|
+
log.header('\n📊 Database Statistics');
|
|
393
|
+
const tables = ['causal_edges', 'causal_experiments', 'causal_observations',
|
|
394
|
+
'certificates', 'provenance_lineage', 'episodes'];
|
|
395
|
+
console.log('\n' + '═'.repeat(80));
|
|
396
|
+
tables.forEach(table => {
|
|
397
|
+
try {
|
|
398
|
+
const count = this.db.prepare(`SELECT COUNT(*) as count FROM ${table}`).get();
|
|
399
|
+
console.log(`${colors.bright}${table}:${colors.reset} ${colors.cyan}${count.count}${colors.reset} records`);
|
|
400
|
+
}
|
|
401
|
+
catch (e) {
|
|
402
|
+
console.log(`${colors.bright}${table}:${colors.reset} ${colors.yellow}N/A${colors.reset}`);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
console.log('═'.repeat(80));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// ============================================================================
|
|
409
|
+
// CLI Entry Point
|
|
410
|
+
// ============================================================================
|
|
411
|
+
async function main() {
|
|
412
|
+
const args = process.argv.slice(2);
|
|
413
|
+
if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
414
|
+
printHelp();
|
|
415
|
+
process.exit(0);
|
|
416
|
+
}
|
|
417
|
+
const cli = new AgentDBCLI();
|
|
418
|
+
const dbPath = process.env.AGENTDB_PATH || './agentdb.db';
|
|
419
|
+
try {
|
|
420
|
+
await cli.initialize(dbPath);
|
|
421
|
+
const command = args[0];
|
|
422
|
+
const subcommand = args[1];
|
|
423
|
+
if (command === 'causal') {
|
|
424
|
+
await handleCausalCommands(cli, subcommand, args.slice(2));
|
|
425
|
+
}
|
|
426
|
+
else if (command === 'recall') {
|
|
427
|
+
await handleRecallCommands(cli, subcommand, args.slice(2));
|
|
428
|
+
}
|
|
429
|
+
else if (command === 'learner') {
|
|
430
|
+
await handleLearnerCommands(cli, subcommand, args.slice(2));
|
|
431
|
+
}
|
|
432
|
+
else if (command === 'reflexion') {
|
|
433
|
+
await handleReflexionCommands(cli, subcommand, args.slice(2));
|
|
434
|
+
}
|
|
435
|
+
else if (command === 'skill') {
|
|
436
|
+
await handleSkillCommands(cli, subcommand, args.slice(2));
|
|
437
|
+
}
|
|
438
|
+
else if (command === 'db') {
|
|
439
|
+
await handleDbCommands(cli, subcommand, args.slice(2));
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
log.error(`Unknown command: ${command}`);
|
|
443
|
+
printHelp();
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
log.error(error.message);
|
|
449
|
+
process.exit(1);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// Command handlers
|
|
453
|
+
async function handleCausalCommands(cli, subcommand, args) {
|
|
454
|
+
if (subcommand === 'add-edge') {
|
|
455
|
+
await cli.causalAddEdge({
|
|
456
|
+
cause: args[0],
|
|
457
|
+
effect: args[1],
|
|
458
|
+
uplift: parseFloat(args[2]),
|
|
459
|
+
confidence: args[3] ? parseFloat(args[3]) : undefined,
|
|
460
|
+
sampleSize: args[4] ? parseInt(args[4]) : undefined
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
else if (subcommand === 'experiment' && args[0] === 'create') {
|
|
464
|
+
await cli.causalExperimentCreate({
|
|
465
|
+
name: args[1],
|
|
466
|
+
cause: args[2],
|
|
467
|
+
effect: args[3]
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
else if (subcommand === 'experiment' && args[0] === 'add-observation') {
|
|
471
|
+
await cli.causalExperimentAddObservation({
|
|
472
|
+
experimentId: parseInt(args[1]),
|
|
473
|
+
isTreatment: args[2] === 'true',
|
|
474
|
+
outcome: parseFloat(args[3]),
|
|
475
|
+
context: args[4]
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
else if (subcommand === 'experiment' && args[0] === 'calculate') {
|
|
479
|
+
await cli.causalExperimentCalculate(parseInt(args[1]));
|
|
480
|
+
}
|
|
481
|
+
else if (subcommand === 'query') {
|
|
482
|
+
await cli.causalQuery({
|
|
483
|
+
cause: args[0],
|
|
484
|
+
effect: args[1],
|
|
485
|
+
minConfidence: args[2] ? parseFloat(args[2]) : undefined,
|
|
486
|
+
minUplift: args[3] ? parseFloat(args[3]) : undefined,
|
|
487
|
+
limit: args[4] ? parseInt(args[4]) : undefined
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
log.error(`Unknown causal subcommand: ${subcommand}`);
|
|
492
|
+
printHelp();
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
async function handleRecallCommands(cli, subcommand, args) {
|
|
496
|
+
if (subcommand === 'with-certificate') {
|
|
497
|
+
await cli.recallWithCertificate({
|
|
498
|
+
query: args[0],
|
|
499
|
+
k: args[1] ? parseInt(args[1]) : undefined,
|
|
500
|
+
alpha: args[2] ? parseFloat(args[2]) : undefined,
|
|
501
|
+
beta: args[3] ? parseFloat(args[3]) : undefined,
|
|
502
|
+
gamma: args[4] ? parseFloat(args[4]) : undefined
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
log.error(`Unknown recall subcommand: ${subcommand}`);
|
|
507
|
+
printHelp();
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
async function handleLearnerCommands(cli, subcommand, args) {
|
|
511
|
+
if (subcommand === 'run') {
|
|
512
|
+
await cli.learnerRun({
|
|
513
|
+
minAttempts: args[0] ? parseInt(args[0]) : undefined,
|
|
514
|
+
minSuccessRate: args[1] ? parseFloat(args[1]) : undefined,
|
|
515
|
+
minConfidence: args[2] ? parseFloat(args[2]) : undefined,
|
|
516
|
+
dryRun: args[3] === 'true'
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
else if (subcommand === 'prune') {
|
|
520
|
+
await cli.learnerPrune({
|
|
521
|
+
minConfidence: args[0] ? parseFloat(args[0]) : undefined,
|
|
522
|
+
minUplift: args[1] ? parseFloat(args[1]) : undefined,
|
|
523
|
+
maxAgeDays: args[2] ? parseInt(args[2]) : undefined
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
log.error(`Unknown learner subcommand: ${subcommand}`);
|
|
528
|
+
printHelp();
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
async function handleReflexionCommands(cli, subcommand, args) {
|
|
532
|
+
if (subcommand === 'store') {
|
|
533
|
+
await cli.reflexionStoreEpisode({
|
|
534
|
+
sessionId: args[0],
|
|
535
|
+
task: args[1],
|
|
536
|
+
reward: parseFloat(args[2]),
|
|
537
|
+
success: args[3] === 'true',
|
|
538
|
+
critique: args[4],
|
|
539
|
+
input: args[5],
|
|
540
|
+
output: args[6],
|
|
541
|
+
latencyMs: args[7] ? parseInt(args[7]) : undefined,
|
|
542
|
+
tokensUsed: args[8] ? parseInt(args[8]) : undefined
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
else if (subcommand === 'retrieve') {
|
|
546
|
+
await cli.reflexionRetrieve({
|
|
547
|
+
task: args[0],
|
|
548
|
+
k: args[1] ? parseInt(args[1]) : undefined,
|
|
549
|
+
minReward: args[2] ? parseFloat(args[2]) : undefined,
|
|
550
|
+
onlyFailures: args[3] === 'true' ? true : undefined,
|
|
551
|
+
onlySuccesses: args[4] === 'true' ? true : undefined
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
else if (subcommand === 'critique-summary') {
|
|
555
|
+
await cli.reflexionGetCritiqueSummary({
|
|
556
|
+
task: args[0],
|
|
557
|
+
onlyFailures: args[1] === 'true'
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
else if (subcommand === 'prune') {
|
|
561
|
+
await cli.reflexionPrune({
|
|
562
|
+
maxAgeDays: args[0] ? parseInt(args[0]) : undefined,
|
|
563
|
+
minReward: args[1] ? parseFloat(args[1]) : undefined
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
log.error(`Unknown reflexion subcommand: ${subcommand}`);
|
|
568
|
+
printHelp();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
async function handleSkillCommands(cli, subcommand, args) {
|
|
572
|
+
if (subcommand === 'create') {
|
|
573
|
+
await cli.skillCreate({
|
|
574
|
+
name: args[0],
|
|
575
|
+
description: args[1],
|
|
576
|
+
code: args[2]
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
else if (subcommand === 'search') {
|
|
580
|
+
await cli.skillSearch({
|
|
581
|
+
task: args[0],
|
|
582
|
+
k: args[1] ? parseInt(args[1]) : undefined
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
else if (subcommand === 'consolidate') {
|
|
586
|
+
await cli.skillConsolidate({
|
|
587
|
+
minAttempts: args[0] ? parseInt(args[0]) : undefined,
|
|
588
|
+
minReward: args[1] ? parseFloat(args[1]) : undefined,
|
|
589
|
+
timeWindowDays: args[2] ? parseInt(args[2]) : undefined
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
else if (subcommand === 'prune') {
|
|
593
|
+
await cli.skillPrune({
|
|
594
|
+
minUses: args[0] ? parseInt(args[0]) : undefined,
|
|
595
|
+
minSuccessRate: args[1] ? parseFloat(args[1]) : undefined,
|
|
596
|
+
maxAgeDays: args[2] ? parseInt(args[2]) : undefined
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
log.error(`Unknown skill subcommand: ${subcommand}`);
|
|
601
|
+
printHelp();
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
async function handleDbCommands(cli, subcommand, args) {
|
|
605
|
+
if (subcommand === 'stats') {
|
|
606
|
+
await cli.dbStats();
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
log.error(`Unknown db subcommand: ${subcommand}`);
|
|
610
|
+
printHelp();
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
function printHelp() {
|
|
614
|
+
console.log(`
|
|
615
|
+
${colors.bright}${colors.cyan}█▀█ █▀▀ █▀▀ █▄░█ ▀█▀ █▀▄ █▄▄
|
|
616
|
+
█▀█ █▄█ ██▄ █░▀█ ░█░ █▄▀ █▄█${colors.reset}
|
|
617
|
+
|
|
618
|
+
${colors.bright}${colors.cyan}AgentDB CLI - Frontier Memory Features${colors.reset}
|
|
619
|
+
|
|
620
|
+
${colors.bright}USAGE:${colors.reset}
|
|
621
|
+
agentdb <command> <subcommand> [options]
|
|
622
|
+
|
|
623
|
+
${colors.bright}CAUSAL COMMANDS:${colors.reset}
|
|
624
|
+
agentdb causal add-edge <cause> <effect> <uplift> [confidence] [sample-size]
|
|
625
|
+
Add a causal edge manually
|
|
626
|
+
|
|
627
|
+
agentdb causal experiment create <name> <cause> <effect>
|
|
628
|
+
Create a new A/B experiment
|
|
629
|
+
|
|
630
|
+
agentdb causal experiment add-observation <experiment-id> <is-treatment> <outcome> [context]
|
|
631
|
+
Record an observation (is-treatment: true/false)
|
|
632
|
+
|
|
633
|
+
agentdb causal experiment calculate <experiment-id>
|
|
634
|
+
Calculate uplift and statistical significance
|
|
635
|
+
|
|
636
|
+
agentdb causal query [cause] [effect] [min-confidence] [min-uplift] [limit]
|
|
637
|
+
Query causal edges with filters
|
|
638
|
+
|
|
639
|
+
${colors.bright}RECALL COMMANDS:${colors.reset}
|
|
640
|
+
agentdb recall with-certificate <query> [k] [alpha] [beta] [gamma]
|
|
641
|
+
Retrieve episodes with causal utility and provenance certificate
|
|
642
|
+
Defaults: k=12, alpha=0.7, beta=0.2, gamma=0.1
|
|
643
|
+
|
|
644
|
+
${colors.bright}LEARNER COMMANDS:${colors.reset}
|
|
645
|
+
agentdb learner run [min-attempts] [min-success-rate] [min-confidence] [dry-run]
|
|
646
|
+
Discover causal edges from episode patterns
|
|
647
|
+
Defaults: min-attempts=3, min-success-rate=0.6, min-confidence=0.7
|
|
648
|
+
|
|
649
|
+
agentdb learner prune [min-confidence] [min-uplift] [max-age-days]
|
|
650
|
+
Remove low-quality or old causal edges
|
|
651
|
+
Defaults: min-confidence=0.5, min-uplift=0.05, max-age-days=90
|
|
652
|
+
|
|
653
|
+
${colors.bright}REFLEXION COMMANDS:${colors.reset}
|
|
654
|
+
agentdb reflexion store <session-id> <task> <reward> <success> [critique] [input] [output] [latency-ms] [tokens]
|
|
655
|
+
Store episode with self-critique
|
|
656
|
+
|
|
657
|
+
agentdb reflexion retrieve <task> [k] [min-reward] [only-failures] [only-successes]
|
|
658
|
+
Retrieve relevant past episodes
|
|
659
|
+
|
|
660
|
+
agentdb reflexion critique-summary <task> [only-failures]
|
|
661
|
+
Get aggregated critique lessons
|
|
662
|
+
|
|
663
|
+
agentdb reflexion prune [max-age-days] [max-reward]
|
|
664
|
+
Clean up old or low-value episodes
|
|
665
|
+
|
|
666
|
+
${colors.bright}SKILL COMMANDS:${colors.reset}
|
|
667
|
+
agentdb skill create <name> <description> [code]
|
|
668
|
+
Create a reusable skill
|
|
669
|
+
|
|
670
|
+
agentdb skill search <query> [k]
|
|
671
|
+
Find applicable skills by similarity
|
|
672
|
+
|
|
673
|
+
agentdb skill consolidate [min-attempts] [min-reward] [time-window-days]
|
|
674
|
+
Auto-create skills from successful episodes (defaults: 3, 0.7, 7)
|
|
675
|
+
|
|
676
|
+
agentdb skill prune [min-uses] [min-success-rate] [max-age-days]
|
|
677
|
+
Remove underperforming skills (defaults: 3, 0.4, 60)
|
|
678
|
+
|
|
679
|
+
${colors.bright}DATABASE COMMANDS:${colors.reset}
|
|
680
|
+
agentdb db stats
|
|
681
|
+
Show database statistics
|
|
682
|
+
|
|
683
|
+
${colors.bright}ENVIRONMENT:${colors.reset}
|
|
684
|
+
AGENTDB_PATH Database file path (default: ./agentdb.db)
|
|
685
|
+
|
|
686
|
+
${colors.bright}EXAMPLES:${colors.reset}
|
|
687
|
+
# Reflexion: Store and retrieve episodes
|
|
688
|
+
agentdb reflexion store "session-1" "implement_auth" 0.95 true "Used OAuth2"
|
|
689
|
+
agentdb reflexion retrieve "authentication" 10 0.8
|
|
690
|
+
agentdb reflexion critique-summary "bug_fix" true
|
|
691
|
+
|
|
692
|
+
# Skills: Create and search
|
|
693
|
+
agentdb skill create "jwt_auth" "Generate JWT tokens" "code here..."
|
|
694
|
+
agentdb skill search "authentication" 5
|
|
695
|
+
agentdb skill consolidate 3 0.7 7
|
|
696
|
+
|
|
697
|
+
# Causal: Add edges and run experiments
|
|
698
|
+
agentdb causal add-edge "add_tests" "code_quality" 0.25 0.95 100
|
|
699
|
+
agentdb causal experiment create "test-coverage-quality" "test_coverage" "bug_rate"
|
|
700
|
+
agentdb causal experiment add-observation 1 true 0.15
|
|
701
|
+
agentdb causal experiment calculate 1
|
|
702
|
+
|
|
703
|
+
# Retrieve with causal utility
|
|
704
|
+
agentdb recall with-certificate "implement authentication" 10
|
|
705
|
+
|
|
706
|
+
# Discover patterns automatically
|
|
707
|
+
agentdb learner run 3 0.6 0.7
|
|
708
|
+
|
|
709
|
+
# Get database stats
|
|
710
|
+
agentdb db stats
|
|
711
|
+
`);
|
|
712
|
+
}
|
|
713
|
+
// ESM entry point check
|
|
714
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
715
|
+
main().catch(console.error);
|
|
716
|
+
}
|
|
717
|
+
export { AgentDBCLI };
|