agentdb 1.2.0 → 1.3.1
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/README.md +180 -33
- package/dist/cli/agentdb-cli.d.ts +1 -0
- package/dist/cli/agentdb-cli.d.ts.map +1 -1
- package/dist/cli/agentdb-cli.js +108 -134
- package/dist/cli/agentdb-cli.js.map +1 -1
- package/dist/controllers/CausalMemoryGraph.d.ts.map +1 -1
- package/dist/controllers/CausalMemoryGraph.js +3 -3
- package/dist/controllers/CausalMemoryGraph.js.map +1 -1
- package/dist/controllers/CausalRecall.d.ts +25 -0
- package/dist/controllers/CausalRecall.d.ts.map +1 -1
- package/dist/controllers/CausalRecall.js +44 -1
- package/dist/controllers/CausalRecall.js.map +1 -1
- package/dist/controllers/EmbeddingService.d.ts.map +1 -1
- package/dist/controllers/EmbeddingService.js +4 -0
- package/dist/controllers/EmbeddingService.js.map +1 -1
- package/dist/controllers/ExplainableRecall.js +1 -1
- package/dist/controllers/LearningSystem.d.ts +194 -0
- package/dist/controllers/LearningSystem.d.ts.map +1 -0
- package/dist/controllers/LearningSystem.js +929 -0
- package/dist/controllers/LearningSystem.js.map +1 -0
- package/dist/controllers/NightlyLearner.d.ts.map +1 -1
- package/dist/controllers/NightlyLearner.js +9 -1
- package/dist/controllers/NightlyLearner.js.map +1 -1
- package/dist/controllers/ReasoningBank.d.ts +96 -0
- package/dist/controllers/ReasoningBank.d.ts.map +1 -0
- package/dist/controllers/ReasoningBank.js +302 -0
- package/dist/controllers/ReasoningBank.js.map +1 -0
- package/dist/controllers/ReflexionMemory.d.ts.map +1 -1
- package/dist/controllers/ReflexionMemory.js +4 -0
- package/dist/controllers/ReflexionMemory.js.map +1 -1
- package/dist/controllers/SkillLibrary.d.ts +37 -3
- package/dist/controllers/SkillLibrary.d.ts.map +1 -1
- package/dist/controllers/SkillLibrary.js +196 -15
- package/dist/controllers/SkillLibrary.js.map +1 -1
- package/dist/mcp/agentdb-mcp-server.d.ts +8 -0
- package/dist/mcp/agentdb-mcp-server.d.ts.map +1 -0
- package/dist/mcp/agentdb-mcp-server.js +1485 -352
- package/dist/mcp/agentdb-mcp-server.js.map +1 -0
- package/dist/mcp/learning-tools-handlers.d.ts +16 -0
- package/dist/mcp/learning-tools-handlers.d.ts.map +1 -0
- package/dist/mcp/learning-tools-handlers.js +105 -0
- package/dist/mcp/learning-tools-handlers.js.map +1 -0
- package/dist/optimizations/QueryOptimizer.d.ts.map +1 -1
- package/dist/optimizations/QueryOptimizer.js +3 -1
- package/dist/optimizations/QueryOptimizer.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/agentdb-cli.ts +136 -51
- package/src/controllers/CausalMemoryGraph.ts +2 -3
- package/src/controllers/CausalRecall.ts +73 -1
- package/src/controllers/EmbeddingService.ts +6 -1
- package/src/controllers/ExplainableRecall.ts +1 -1
- package/src/controllers/LearningSystem.ts +1286 -0
- package/src/controllers/NightlyLearner.ts +11 -1
- package/src/controllers/ReasoningBank.ts +411 -0
- package/src/controllers/ReflexionMemory.ts +4 -0
- package/src/controllers/SkillLibrary.ts +254 -16
- package/src/mcp/agentdb-mcp-server.ts +1710 -0
- package/src/mcp/learning-tools-handlers.ts +106 -0
- package/src/optimizations/QueryOptimizer.ts +4 -2
- package/dist/benchmarks/comprehensive-benchmark.js +0 -664
- package/dist/benchmarks/frontier-benchmark.js +0 -419
- package/dist/benchmarks/reflexion-benchmark.js +0 -370
- package/dist/cli/agentdb-cli.js.backup +0 -718
- package/dist/schemas/frontier-schema.sql +0 -341
- package/dist/schemas/schema.sql +0 -382
- package/dist/tests/frontier-features.test.js +0 -665
|
@@ -59,8 +59,8 @@ export class SkillLibrary {
|
|
|
59
59
|
const stmt = this.db.prepare(`
|
|
60
60
|
INSERT INTO skills (
|
|
61
61
|
name, description, signature, code, success_rate, uses,
|
|
62
|
-
avg_reward, avg_latency_ms,
|
|
63
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
|
|
62
|
+
avg_reward, avg_latency_ms, metadata
|
|
63
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
64
64
|
`);
|
|
65
65
|
|
|
66
66
|
const result = stmt.run(
|
|
@@ -72,7 +72,6 @@ export class SkillLibrary {
|
|
|
72
72
|
skill.uses,
|
|
73
73
|
skill.avgReward,
|
|
74
74
|
skill.avgLatencyMs,
|
|
75
|
-
skill.createdFromEpisode || null,
|
|
76
75
|
skill.metadata ? JSON.stringify(skill.metadata) : null
|
|
77
76
|
);
|
|
78
77
|
|
|
@@ -226,15 +225,30 @@ export class SkillLibrary {
|
|
|
226
225
|
}
|
|
227
226
|
|
|
228
227
|
/**
|
|
229
|
-
* Consolidate high-reward episodes into skills
|
|
230
|
-
* This is the core learning mechanism
|
|
228
|
+
* Consolidate high-reward episodes into skills with ML pattern extraction
|
|
229
|
+
* This is the core learning mechanism enhanced with pattern analysis
|
|
231
230
|
*/
|
|
232
|
-
consolidateEpisodesIntoSkills(config: {
|
|
231
|
+
async consolidateEpisodesIntoSkills(config: {
|
|
233
232
|
minAttempts?: number;
|
|
234
233
|
minReward?: number;
|
|
235
234
|
timeWindowDays?: number;
|
|
236
|
-
|
|
237
|
-
|
|
235
|
+
extractPatterns?: boolean;
|
|
236
|
+
}): Promise<{
|
|
237
|
+
created: number;
|
|
238
|
+
updated: number;
|
|
239
|
+
patterns: Array<{
|
|
240
|
+
task: string;
|
|
241
|
+
commonPatterns: string[];
|
|
242
|
+
successIndicators: string[];
|
|
243
|
+
avgReward: number;
|
|
244
|
+
}>;
|
|
245
|
+
}> {
|
|
246
|
+
const {
|
|
247
|
+
minAttempts = 3,
|
|
248
|
+
minReward = 0.7,
|
|
249
|
+
timeWindowDays = 7,
|
|
250
|
+
extractPatterns = true
|
|
251
|
+
} = config;
|
|
238
252
|
|
|
239
253
|
const stmt = this.db.prepare(`
|
|
240
254
|
SELECT
|
|
@@ -254,16 +268,47 @@ export class SkillLibrary {
|
|
|
254
268
|
|
|
255
269
|
const candidates = stmt.all(timeWindowDays * 86400, minReward, minAttempts);
|
|
256
270
|
let created = 0;
|
|
271
|
+
let updated = 0;
|
|
272
|
+
const patterns: Array<{
|
|
273
|
+
task: string;
|
|
274
|
+
commonPatterns: string[];
|
|
275
|
+
successIndicators: string[];
|
|
276
|
+
avgReward: number;
|
|
277
|
+
}> = [];
|
|
257
278
|
|
|
258
279
|
for (const candidate of candidates as any[]) {
|
|
280
|
+
const episodeIds = candidate.episode_ids.split(',').map(Number);
|
|
281
|
+
|
|
282
|
+
// Extract patterns from successful episodes if requested
|
|
283
|
+
let extractedPatterns: string[] = [];
|
|
284
|
+
let successIndicators: string[] = [];
|
|
285
|
+
let enhancedDescription = `Auto-generated skill from successful episodes`;
|
|
286
|
+
|
|
287
|
+
if (extractPatterns) {
|
|
288
|
+
const patternData = await this.extractPatternsFromEpisodes(episodeIds);
|
|
289
|
+
extractedPatterns = patternData.commonPatterns;
|
|
290
|
+
successIndicators = patternData.successIndicators;
|
|
291
|
+
|
|
292
|
+
if (extractedPatterns.length > 0) {
|
|
293
|
+
enhancedDescription = `Skill learned from ${episodeIds.length} successful episodes. Common patterns: ${extractedPatterns.slice(0, 3).join(', ')}`;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
patterns.push({
|
|
297
|
+
task: candidate.task,
|
|
298
|
+
commonPatterns: extractedPatterns,
|
|
299
|
+
successIndicators: successIndicators,
|
|
300
|
+
avgReward: candidate.avg_reward
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
259
304
|
// Check if skill already exists
|
|
260
305
|
const existing = this.db.prepare('SELECT id FROM skills WHERE name = ?').get(candidate.task);
|
|
261
306
|
|
|
262
307
|
if (!existing) {
|
|
263
|
-
// Create new skill
|
|
308
|
+
// Create new skill with extracted patterns
|
|
264
309
|
const skill: Skill = {
|
|
265
310
|
name: candidate.task,
|
|
266
|
-
description:
|
|
311
|
+
description: enhancedDescription,
|
|
267
312
|
signature: {
|
|
268
313
|
inputs: { task: 'string' },
|
|
269
314
|
outputs: { result: 'any' }
|
|
@@ -274,15 +319,16 @@ export class SkillLibrary {
|
|
|
274
319
|
avgLatencyMs: candidate.avg_latency || 0,
|
|
275
320
|
createdFromEpisode: candidate.latest_episode_id,
|
|
276
321
|
metadata: {
|
|
277
|
-
sourceEpisodes:
|
|
322
|
+
sourceEpisodes: episodeIds,
|
|
278
323
|
autoGenerated: true,
|
|
279
|
-
consolidatedAt: Date.now()
|
|
324
|
+
consolidatedAt: Date.now(),
|
|
325
|
+
extractedPatterns: extractedPatterns,
|
|
326
|
+
successIndicators: successIndicators,
|
|
327
|
+
patternConfidence: this.calculatePatternConfidence(episodeIds.length, candidate.success_rate)
|
|
280
328
|
}
|
|
281
329
|
};
|
|
282
330
|
|
|
283
|
-
this.createSkill(skill)
|
|
284
|
-
console.error('Error creating skill:', err);
|
|
285
|
-
});
|
|
331
|
+
await this.createSkill(skill);
|
|
286
332
|
created++;
|
|
287
333
|
} else {
|
|
288
334
|
// Update existing skill stats
|
|
@@ -292,10 +338,202 @@ export class SkillLibrary {
|
|
|
292
338
|
candidate.avg_reward,
|
|
293
339
|
candidate.avg_latency || 0
|
|
294
340
|
);
|
|
341
|
+
updated++;
|
|
295
342
|
}
|
|
296
343
|
}
|
|
297
344
|
|
|
298
|
-
return created;
|
|
345
|
+
return { created, updated, patterns };
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Extract common patterns from successful episodes using ML-inspired analysis
|
|
350
|
+
*/
|
|
351
|
+
private async extractPatternsFromEpisodes(episodeIds: number[]): Promise<{
|
|
352
|
+
commonPatterns: string[];
|
|
353
|
+
successIndicators: string[];
|
|
354
|
+
}> {
|
|
355
|
+
// Retrieve episodes with their outputs and critiques
|
|
356
|
+
const episodes = this.db.prepare(`
|
|
357
|
+
SELECT id, task, input, output, critique, reward, success, metadata
|
|
358
|
+
FROM episodes
|
|
359
|
+
WHERE id IN (${episodeIds.map(() => '?').join(',')})
|
|
360
|
+
AND success = 1
|
|
361
|
+
`).all(...episodeIds) as any[];
|
|
362
|
+
|
|
363
|
+
if (episodes.length === 0) {
|
|
364
|
+
return { commonPatterns: [], successIndicators: [] };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const commonPatterns: string[] = [];
|
|
368
|
+
const successIndicators: string[] = [];
|
|
369
|
+
|
|
370
|
+
// Pattern 1: Analyze output text for common keywords and phrases
|
|
371
|
+
const outputTexts = episodes
|
|
372
|
+
.map(ep => ep.output)
|
|
373
|
+
.filter(Boolean);
|
|
374
|
+
|
|
375
|
+
if (outputTexts.length > 0) {
|
|
376
|
+
const keywordFrequency = this.extractKeywordFrequency(outputTexts);
|
|
377
|
+
const topKeywords = this.getTopKeywords(keywordFrequency, 5);
|
|
378
|
+
|
|
379
|
+
if (topKeywords.length > 0) {
|
|
380
|
+
commonPatterns.push(`Common techniques: ${topKeywords.join(', ')}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Pattern 2: Analyze critique patterns for successful strategies
|
|
385
|
+
const critiques = episodes
|
|
386
|
+
.map(ep => ep.critique)
|
|
387
|
+
.filter(Boolean);
|
|
388
|
+
|
|
389
|
+
if (critiques.length > 0) {
|
|
390
|
+
const critiqueKeywords = this.extractKeywordFrequency(critiques);
|
|
391
|
+
const topCritiquePatterns = this.getTopKeywords(critiqueKeywords, 3);
|
|
392
|
+
|
|
393
|
+
if (topCritiquePatterns.length > 0) {
|
|
394
|
+
successIndicators.push(...topCritiquePatterns);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Pattern 3: Analyze reward distribution
|
|
399
|
+
const avgReward = episodes.reduce((sum, ep) => sum + ep.reward, 0) / episodes.length;
|
|
400
|
+
const highRewardCount = episodes.filter(ep => ep.reward > avgReward).length;
|
|
401
|
+
const highRewardRatio = highRewardCount / episodes.length;
|
|
402
|
+
|
|
403
|
+
if (highRewardRatio > 0.6) {
|
|
404
|
+
successIndicators.push(`High consistency (${(highRewardRatio * 100).toFixed(0)}% above average)`);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Pattern 4: Analyze metadata for common parameters
|
|
408
|
+
const metadataPatterns = this.extractMetadataPatterns(episodes);
|
|
409
|
+
if (metadataPatterns.length > 0) {
|
|
410
|
+
commonPatterns.push(...metadataPatterns);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// Pattern 5: Temporal analysis - learning curve
|
|
414
|
+
const learningTrend = this.analyzeLearningTrend(episodes);
|
|
415
|
+
if (learningTrend) {
|
|
416
|
+
successIndicators.push(learningTrend);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return { commonPatterns, successIndicators };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Extract keyword frequency from text array using NLP-inspired techniques
|
|
424
|
+
*/
|
|
425
|
+
private extractKeywordFrequency(texts: string[]): Map<string, number> {
|
|
426
|
+
const frequency = new Map<string, number>();
|
|
427
|
+
|
|
428
|
+
// Common stop words to filter out
|
|
429
|
+
const stopWords = new Set([
|
|
430
|
+
'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
431
|
+
'of', 'with', 'by', 'from', 'as', 'is', 'was', 'are', 'were', 'been',
|
|
432
|
+
'be', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'should',
|
|
433
|
+
'could', 'may', 'might', 'must', 'can', 'this', 'that', 'these', 'those'
|
|
434
|
+
]);
|
|
435
|
+
|
|
436
|
+
for (const text of texts) {
|
|
437
|
+
// Extract words (alphanumeric sequences)
|
|
438
|
+
const words = text.toLowerCase().match(/\b[a-z0-9_-]+\b/g) || [];
|
|
439
|
+
|
|
440
|
+
for (const word of words) {
|
|
441
|
+
if (word.length > 3 && !stopWords.has(word)) {
|
|
442
|
+
frequency.set(word, (frequency.get(word) || 0) + 1);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return frequency;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Get top N keywords by frequency
|
|
452
|
+
*/
|
|
453
|
+
private getTopKeywords(frequency: Map<string, number>, n: number): string[] {
|
|
454
|
+
return Array.from(frequency.entries())
|
|
455
|
+
.sort((a, b) => b[1] - a[1])
|
|
456
|
+
.slice(0, n)
|
|
457
|
+
.filter(([_, count]) => count >= 2) // Only keywords appearing at least twice
|
|
458
|
+
.map(([word, _]) => word);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Extract common patterns from episode metadata
|
|
463
|
+
*/
|
|
464
|
+
private extractMetadataPatterns(episodes: any[]): string[] {
|
|
465
|
+
const patterns: string[] = [];
|
|
466
|
+
const metadataFields = new Map<string, Set<any>>();
|
|
467
|
+
|
|
468
|
+
for (const episode of episodes) {
|
|
469
|
+
if (episode.metadata) {
|
|
470
|
+
try {
|
|
471
|
+
const metadata = typeof episode.metadata === 'string'
|
|
472
|
+
? JSON.parse(episode.metadata)
|
|
473
|
+
: episode.metadata;
|
|
474
|
+
|
|
475
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
476
|
+
if (!metadataFields.has(key)) {
|
|
477
|
+
metadataFields.set(key, new Set());
|
|
478
|
+
}
|
|
479
|
+
metadataFields.get(key)!.add(value);
|
|
480
|
+
}
|
|
481
|
+
} catch (e) {
|
|
482
|
+
// Skip invalid metadata
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Find fields with consistent values
|
|
488
|
+
metadataFields.forEach((values, field) => {
|
|
489
|
+
if (values.size === 1) {
|
|
490
|
+
// All episodes have the same value for this field
|
|
491
|
+
const value = Array.from(values)[0];
|
|
492
|
+
patterns.push(`Consistent ${field}: ${value}`);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
return patterns;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Analyze learning trend across episodes
|
|
501
|
+
*/
|
|
502
|
+
private analyzeLearningTrend(episodes: any[]): string | null {
|
|
503
|
+
if (episodes.length < 3) return null;
|
|
504
|
+
|
|
505
|
+
// Sort by episode ID (temporal order)
|
|
506
|
+
const sorted = [...episodes].sort((a, b) => a.id - b.id);
|
|
507
|
+
|
|
508
|
+
const firstHalfReward = sorted.slice(0, Math.floor(sorted.length / 2))
|
|
509
|
+
.reduce((sum, ep) => sum + ep.reward, 0) / Math.floor(sorted.length / 2);
|
|
510
|
+
|
|
511
|
+
const secondHalfReward = sorted.slice(Math.floor(sorted.length / 2))
|
|
512
|
+
.reduce((sum, ep) => sum + ep.reward, 0) / (sorted.length - Math.floor(sorted.length / 2));
|
|
513
|
+
|
|
514
|
+
const improvement = ((secondHalfReward - firstHalfReward) / firstHalfReward) * 100;
|
|
515
|
+
|
|
516
|
+
if (improvement > 10) {
|
|
517
|
+
return `Strong learning curve (+${improvement.toFixed(0)}% improvement)`;
|
|
518
|
+
} else if (improvement > 5) {
|
|
519
|
+
return `Moderate learning curve (+${improvement.toFixed(0)}% improvement)`;
|
|
520
|
+
} else if (Math.abs(improvement) < 5) {
|
|
521
|
+
return `Stable performance (±${Math.abs(improvement).toFixed(0)}%)`;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Calculate pattern confidence score based on sample size and success rate
|
|
529
|
+
*/
|
|
530
|
+
private calculatePatternConfidence(sampleSize: number, successRate: number): number {
|
|
531
|
+
// Confidence increases with sample size and success rate
|
|
532
|
+
// Using a sigmoid-like function for smooth scaling
|
|
533
|
+
const sampleFactor = Math.min(sampleSize / 10, 1.0); // Saturates at 10 samples
|
|
534
|
+
const successFactor = successRate;
|
|
535
|
+
|
|
536
|
+
return Math.min(sampleFactor * successFactor, 0.99);
|
|
299
537
|
}
|
|
300
538
|
|
|
301
539
|
/**
|