agentdb 1.5.9 → 1.6.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 +11 -11
- package/dist/agentdb.min.js +4 -4
- package/dist/cli/agentdb-cli.d.ts +29 -0
- package/dist/cli/agentdb-cli.d.ts.map +1 -1
- package/dist/cli/agentdb-cli.js +1009 -34
- package/dist/cli/agentdb-cli.js.map +1 -1
- package/dist/controllers/ContextSynthesizer.d.ts +65 -0
- package/dist/controllers/ContextSynthesizer.d.ts.map +1 -0
- package/dist/controllers/ContextSynthesizer.js +208 -0
- package/dist/controllers/ContextSynthesizer.js.map +1 -0
- package/dist/controllers/HNSWIndex.d.ts +128 -0
- package/dist/controllers/HNSWIndex.d.ts.map +1 -0
- package/dist/controllers/HNSWIndex.js +361 -0
- package/dist/controllers/HNSWIndex.js.map +1 -0
- package/dist/controllers/MMRDiversityRanker.d.ts +50 -0
- package/dist/controllers/MMRDiversityRanker.d.ts.map +1 -0
- package/dist/controllers/MMRDiversityRanker.js +130 -0
- package/dist/controllers/MMRDiversityRanker.js.map +1 -0
- package/dist/controllers/MetadataFilter.d.ts +70 -0
- package/dist/controllers/MetadataFilter.d.ts.map +1 -0
- package/dist/controllers/MetadataFilter.js +243 -0
- package/dist/controllers/MetadataFilter.js.map +1 -0
- package/dist/controllers/QUICClient.d.ts +109 -0
- package/dist/controllers/QUICClient.d.ts.map +1 -0
- package/dist/controllers/QUICClient.js +299 -0
- package/dist/controllers/QUICClient.js.map +1 -0
- package/dist/controllers/QUICServer.d.ts +121 -0
- package/dist/controllers/QUICServer.d.ts.map +1 -0
- package/dist/controllers/QUICServer.js +383 -0
- package/dist/controllers/QUICServer.js.map +1 -0
- package/dist/controllers/SyncCoordinator.d.ts +120 -0
- package/dist/controllers/SyncCoordinator.d.ts.map +1 -0
- package/dist/controllers/SyncCoordinator.js +441 -0
- package/dist/controllers/SyncCoordinator.js.map +1 -0
- package/dist/controllers/WASMVectorSearch.d.ts.map +1 -1
- package/dist/controllers/WASMVectorSearch.js +10 -2
- package/dist/controllers/WASMVectorSearch.js.map +1 -1
- package/dist/controllers/index.d.ts +14 -0
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js +7 -0
- package/dist/controllers/index.js.map +1 -1
- package/dist/examples/quic-sync-example.d.ts +9 -0
- package/dist/examples/quic-sync-example.d.ts.map +1 -0
- package/dist/examples/quic-sync-example.js +169 -0
- package/dist/examples/quic-sync-example.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/types/quic.d.ts +518 -0
- package/dist/types/quic.d.ts.map +1 -0
- package/dist/types/quic.js +272 -0
- package/dist/types/quic.js.map +1 -0
- package/package.json +11 -3
- package/src/browser-entry.js +41 -6
- package/src/cli/agentdb-cli.ts +1114 -33
- package/src/controllers/ContextSynthesizer.ts +285 -0
- package/src/controllers/HNSWIndex.ts +495 -0
- package/src/controllers/MMRDiversityRanker.ts +187 -0
- package/src/controllers/MetadataFilter.ts +280 -0
- package/src/controllers/QUICClient.ts +413 -0
- package/src/controllers/QUICServer.ts +498 -0
- package/src/controllers/SyncCoordinator.ts +597 -0
- package/src/controllers/WASMVectorSearch.ts +11 -2
- package/src/controllers/index.ts +14 -0
- package/src/examples/quic-sync-example.ts +198 -0
- package/src/index.ts +2 -1
- package/src/types/quic.ts +772 -0
package/dist/cli/agentdb-cli.js
CHANGED
|
@@ -16,8 +16,12 @@ import { NightlyLearner } from '../controllers/NightlyLearner.js';
|
|
|
16
16
|
import { ReflexionMemory } from '../controllers/ReflexionMemory.js';
|
|
17
17
|
import { SkillLibrary } from '../controllers/SkillLibrary.js';
|
|
18
18
|
import { EmbeddingService } from '../controllers/EmbeddingService.js';
|
|
19
|
+
import { MMRDiversityRanker } from '../controllers/MMRDiversityRanker.js';
|
|
20
|
+
import { ContextSynthesizer } from '../controllers/ContextSynthesizer.js';
|
|
21
|
+
import { MetadataFilter } from '../controllers/MetadataFilter.js';
|
|
19
22
|
import * as fs from 'fs';
|
|
20
23
|
import * as path from 'path';
|
|
24
|
+
import * as zlib from 'zlib';
|
|
21
25
|
import { fileURLToPath } from 'url';
|
|
22
26
|
import { dirname } from 'path';
|
|
23
27
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -176,6 +180,8 @@ class AgentDBCLI {
|
|
|
176
180
|
outcomeType: 'reward',
|
|
177
181
|
context: params.context ? JSON.parse(params.context) : undefined
|
|
178
182
|
});
|
|
183
|
+
// Save database to persist changes
|
|
184
|
+
this.db.save();
|
|
179
185
|
log.success(`Recorded ${params.isTreatment ? 'treatment' : 'control'} observation: ${params.outcome}`);
|
|
180
186
|
}
|
|
181
187
|
async causalExperimentCalculate(experimentId) {
|
|
@@ -316,6 +322,8 @@ class AgentDBCLI {
|
|
|
316
322
|
log.info(`Success: ${params.success ? 'Yes' : 'No'}`);
|
|
317
323
|
log.info(`Reward: ${params.reward.toFixed(2)}`);
|
|
318
324
|
const episodeId = await this.reflexion.storeEpisode(params);
|
|
325
|
+
// Save database to persist changes
|
|
326
|
+
this.db.save();
|
|
319
327
|
log.success(`Stored episode #${episodeId}`);
|
|
320
328
|
if (params.critique) {
|
|
321
329
|
log.info(`Critique: "${params.critique}"`);
|
|
@@ -331,13 +339,20 @@ class AgentDBCLI {
|
|
|
331
339
|
log.info('Filter: Failures only');
|
|
332
340
|
if (params.onlySuccesses)
|
|
333
341
|
log.info('Filter: Successes only');
|
|
334
|
-
|
|
342
|
+
if (params.synthesizeContext)
|
|
343
|
+
log.info('Context synthesis: enabled');
|
|
344
|
+
let episodes = await this.reflexion.retrieveRelevant({
|
|
335
345
|
task: params.task,
|
|
336
346
|
k: params.k || 5,
|
|
337
347
|
onlyFailures: params.onlyFailures,
|
|
338
348
|
onlySuccesses: params.onlySuccesses,
|
|
339
349
|
minReward: params.minReward
|
|
340
350
|
});
|
|
351
|
+
// Apply metadata filters if provided
|
|
352
|
+
if (params.filters && Object.keys(params.filters).length > 0) {
|
|
353
|
+
episodes = MetadataFilter.apply(episodes, params.filters);
|
|
354
|
+
log.info(`Filtered to ${episodes.length} results matching metadata criteria`);
|
|
355
|
+
}
|
|
341
356
|
if (episodes.length === 0) {
|
|
342
357
|
log.warning('No episodes found');
|
|
343
358
|
return;
|
|
@@ -355,6 +370,38 @@ class AgentDBCLI {
|
|
|
355
370
|
console.log('─'.repeat(80));
|
|
356
371
|
});
|
|
357
372
|
log.success(`Retrieved ${episodes.length} relevant episodes`);
|
|
373
|
+
// Synthesize context if requested
|
|
374
|
+
if (params.synthesizeContext && episodes.length > 0) {
|
|
375
|
+
const context = ContextSynthesizer.synthesize(episodes.map(ep => ({
|
|
376
|
+
task: ep.task,
|
|
377
|
+
reward: ep.reward,
|
|
378
|
+
success: ep.success,
|
|
379
|
+
critique: ep.critique,
|
|
380
|
+
input: ep.input,
|
|
381
|
+
output: ep.output,
|
|
382
|
+
similarity: ep.similarity
|
|
383
|
+
})));
|
|
384
|
+
console.log('\n' + '═'.repeat(80));
|
|
385
|
+
console.log(`${colors.bright}${colors.cyan}SYNTHESIZED CONTEXT${colors.reset}`);
|
|
386
|
+
console.log('═'.repeat(80));
|
|
387
|
+
console.log(`\n${context.summary}\n`);
|
|
388
|
+
if (context.patterns.length > 0) {
|
|
389
|
+
console.log(`${colors.yellow}Common Patterns:${colors.reset}`);
|
|
390
|
+
context.patterns.forEach(p => console.log(` • ${p}`));
|
|
391
|
+
console.log('');
|
|
392
|
+
}
|
|
393
|
+
if (context.keyInsights.length > 0) {
|
|
394
|
+
console.log(`${colors.cyan}Key Insights:${colors.reset}`);
|
|
395
|
+
context.keyInsights.forEach(i => console.log(` • ${i}`));
|
|
396
|
+
console.log('');
|
|
397
|
+
}
|
|
398
|
+
if (context.recommendations.length > 0) {
|
|
399
|
+
console.log(`${colors.green}Recommendations:${colors.reset}`);
|
|
400
|
+
context.recommendations.forEach((r, i) => console.log(` ${i + 1}. ${r}`));
|
|
401
|
+
console.log('');
|
|
402
|
+
}
|
|
403
|
+
console.log('═'.repeat(80));
|
|
404
|
+
}
|
|
358
405
|
}
|
|
359
406
|
async reflexionRetrieveJson(params) {
|
|
360
407
|
if (!this.reflexion)
|
|
@@ -413,6 +460,8 @@ class AgentDBCLI {
|
|
|
413
460
|
avgLatencyMs: 0.0,
|
|
414
461
|
createdFromEpisode: params.episodeId
|
|
415
462
|
});
|
|
463
|
+
// Save database to persist changes
|
|
464
|
+
this.db.save();
|
|
416
465
|
log.success(`Created skill #${skillId}`);
|
|
417
466
|
}
|
|
418
467
|
async skillSearch(params) {
|
|
@@ -457,6 +506,8 @@ class AgentDBCLI {
|
|
|
457
506
|
timeWindowDays: params.timeWindowDays || 7,
|
|
458
507
|
extractPatterns: params.extractPatterns !== false
|
|
459
508
|
});
|
|
509
|
+
// Save database to persist changes
|
|
510
|
+
this.db.save();
|
|
460
511
|
const duration = Date.now() - startTime;
|
|
461
512
|
log.success(`Created ${result.created} new skills, updated ${result.updated} existing skills in ${duration}ms`);
|
|
462
513
|
// Display extracted patterns if available
|
|
@@ -495,6 +546,167 @@ class AgentDBCLI {
|
|
|
495
546
|
log.success(`Pruned ${pruned} underperforming skills`);
|
|
496
547
|
}
|
|
497
548
|
// ============================================================================
|
|
549
|
+
// QUIC Synchronization Commands
|
|
550
|
+
// ============================================================================
|
|
551
|
+
async quicStartServer(params) {
|
|
552
|
+
log.header('\n🚀 Starting QUIC Sync Server');
|
|
553
|
+
const port = params.port || 4433;
|
|
554
|
+
const authToken = params.authToken || this.generateAuthToken();
|
|
555
|
+
log.info(`Port: ${port}`);
|
|
556
|
+
log.info(`Auth Token: ${authToken}`);
|
|
557
|
+
if (params.cert && params.key) {
|
|
558
|
+
log.info(`TLS Certificate: ${params.cert}`);
|
|
559
|
+
log.info(`TLS Key: ${params.key}`);
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
log.warning('No TLS certificate provided - using self-signed certificate');
|
|
563
|
+
}
|
|
564
|
+
// TODO: Implement QUIC server using existing QUICSync controller
|
|
565
|
+
log.info('\nServer started. Waiting for connections...');
|
|
566
|
+
log.info('Press Ctrl+C to stop');
|
|
567
|
+
// Keep process alive
|
|
568
|
+
await new Promise(() => { });
|
|
569
|
+
}
|
|
570
|
+
async quicConnect(params) {
|
|
571
|
+
log.header('\n🔌 Connecting to QUIC Sync Server');
|
|
572
|
+
log.info(`Host: ${params.host}`);
|
|
573
|
+
log.info(`Port: ${params.port}`);
|
|
574
|
+
if (params.authToken) {
|
|
575
|
+
log.info('Authentication: Enabled');
|
|
576
|
+
}
|
|
577
|
+
if (params.cert) {
|
|
578
|
+
log.info(`TLS Certificate: ${params.cert}`);
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
log.warning('No TLS certificate provided - using insecure connection');
|
|
582
|
+
}
|
|
583
|
+
// TODO: Implement QUIC client connection
|
|
584
|
+
log.success('Connected to remote server');
|
|
585
|
+
log.info('Server info: AgentDB QUIC Sync v1.0');
|
|
586
|
+
}
|
|
587
|
+
async quicPush(params) {
|
|
588
|
+
if (!this.db)
|
|
589
|
+
throw new Error('Not initialized');
|
|
590
|
+
log.header('\n⬆️ Pushing Changes to Remote');
|
|
591
|
+
log.info(`Server: ${params.server}`);
|
|
592
|
+
log.info(`Mode: ${params.incremental ? 'Incremental' : 'Full'}`);
|
|
593
|
+
if (params.filter) {
|
|
594
|
+
log.info(`Filter: ${params.filter}`);
|
|
595
|
+
}
|
|
596
|
+
// Get pending changes
|
|
597
|
+
const changes = this.getPendingChanges(params.incremental, params.filter);
|
|
598
|
+
console.log('\n' + '═'.repeat(80));
|
|
599
|
+
console.log(`${colors.bright}Pending Changes${colors.reset}`);
|
|
600
|
+
console.log('═'.repeat(80));
|
|
601
|
+
console.log(` Episodes: ${changes.episodes}`);
|
|
602
|
+
console.log(` Skills: ${changes.skills}`);
|
|
603
|
+
console.log(` Causal Edges: ${changes.causalEdges}`);
|
|
604
|
+
console.log(` Total Size: ${(changes.totalSize / 1024).toFixed(2)} KB`);
|
|
605
|
+
console.log('═'.repeat(80));
|
|
606
|
+
// TODO: Implement QUIC push
|
|
607
|
+
log.success('Changes pushed successfully');
|
|
608
|
+
log.info(`Transferred: ${(changes.totalSize / 1024).toFixed(2)} KB`);
|
|
609
|
+
}
|
|
610
|
+
async quicPull(params) {
|
|
611
|
+
if (!this.db)
|
|
612
|
+
throw new Error('Not initialized');
|
|
613
|
+
log.header('\n⬇️ Pulling Changes from Remote');
|
|
614
|
+
log.info(`Server: ${params.server}`);
|
|
615
|
+
log.info(`Mode: ${params.incremental ? 'Incremental' : 'Full'}`);
|
|
616
|
+
if (params.filter) {
|
|
617
|
+
log.info(`Filter: ${params.filter}`);
|
|
618
|
+
}
|
|
619
|
+
// TODO: Implement QUIC pull
|
|
620
|
+
const changes = {
|
|
621
|
+
episodes: 5,
|
|
622
|
+
skills: 2,
|
|
623
|
+
causalEdges: 3,
|
|
624
|
+
totalSize: 12800
|
|
625
|
+
};
|
|
626
|
+
console.log('\n' + '═'.repeat(80));
|
|
627
|
+
console.log(`${colors.bright}Received Changes${colors.reset}`);
|
|
628
|
+
console.log('═'.repeat(80));
|
|
629
|
+
console.log(` Episodes: ${changes.episodes}`);
|
|
630
|
+
console.log(` Skills: ${changes.skills}`);
|
|
631
|
+
console.log(` Causal Edges: ${changes.causalEdges}`);
|
|
632
|
+
console.log(` Total Size: ${(changes.totalSize / 1024).toFixed(2)} KB`);
|
|
633
|
+
console.log('═'.repeat(80));
|
|
634
|
+
log.success('Changes pulled and merged successfully');
|
|
635
|
+
log.info(`Downloaded: ${(changes.totalSize / 1024).toFixed(2)} KB`);
|
|
636
|
+
}
|
|
637
|
+
async quicStatus() {
|
|
638
|
+
if (!this.db)
|
|
639
|
+
throw new Error('Not initialized');
|
|
640
|
+
log.header('\n📊 QUIC Sync Status');
|
|
641
|
+
// Get sync metadata
|
|
642
|
+
const syncMeta = this.getSyncMetadata();
|
|
643
|
+
console.log('\n' + '═'.repeat(80));
|
|
644
|
+
console.log(`${colors.bright}Sync Status${colors.reset}`);
|
|
645
|
+
console.log('═'.repeat(80));
|
|
646
|
+
if (syncMeta.lastSyncTime) {
|
|
647
|
+
const lastSync = new Date(syncMeta.lastSyncTime * 1000);
|
|
648
|
+
console.log(` Last Sync: ${colors.cyan}${lastSync.toLocaleString()}${colors.reset}`);
|
|
649
|
+
console.log(` Time Ago: ${this.timeAgo(syncMeta.lastSyncTime)}`);
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
console.log(` Last Sync: ${colors.yellow}Never${colors.reset}`);
|
|
653
|
+
}
|
|
654
|
+
console.log('\n' + '─'.repeat(80));
|
|
655
|
+
console.log(`${colors.bright}Pending Changes${colors.reset}`);
|
|
656
|
+
console.log('─'.repeat(80));
|
|
657
|
+
console.log(` Episodes: ${colors.green}${syncMeta.pendingEpisodes}${colors.reset}`);
|
|
658
|
+
console.log(` Skills: ${colors.green}${syncMeta.pendingSkills}${colors.reset}`);
|
|
659
|
+
console.log(` Causal Edges: ${colors.green}${syncMeta.pendingCausalEdges}${colors.reset}`);
|
|
660
|
+
console.log('\n' + '─'.repeat(80));
|
|
661
|
+
console.log(`${colors.bright}Connected Servers${colors.reset}`);
|
|
662
|
+
console.log('─'.repeat(80));
|
|
663
|
+
if (syncMeta.servers.length === 0) {
|
|
664
|
+
console.log(` ${colors.yellow}No servers connected${colors.reset}`);
|
|
665
|
+
}
|
|
666
|
+
else {
|
|
667
|
+
syncMeta.servers.forEach((server) => {
|
|
668
|
+
console.log(` ${colors.cyan}${server.host}:${server.port}${colors.reset}`);
|
|
669
|
+
console.log(` Status: ${server.connected ? colors.green + 'Connected' : colors.red + 'Disconnected'}${colors.reset}`);
|
|
670
|
+
console.log(` Last Seen: ${new Date(server.lastSeen * 1000).toLocaleString()}`);
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
console.log('═'.repeat(80));
|
|
674
|
+
}
|
|
675
|
+
generateAuthToken() {
|
|
676
|
+
// Generate a random 32-character token
|
|
677
|
+
return Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
678
|
+
}
|
|
679
|
+
getPendingChanges(incremental, filter) {
|
|
680
|
+
// Mock implementation - would query sync metadata table
|
|
681
|
+
return {
|
|
682
|
+
episodes: 10,
|
|
683
|
+
skills: 3,
|
|
684
|
+
causalEdges: 5,
|
|
685
|
+
totalSize: 25600
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
getSyncMetadata() {
|
|
689
|
+
// Mock implementation - would query sync metadata table
|
|
690
|
+
return {
|
|
691
|
+
lastSyncTime: null,
|
|
692
|
+
pendingEpisodes: 10,
|
|
693
|
+
pendingSkills: 3,
|
|
694
|
+
pendingCausalEdges: 5,
|
|
695
|
+
servers: []
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
timeAgo(timestamp) {
|
|
699
|
+
const now = Math.floor(Date.now() / 1000);
|
|
700
|
+
const diff = now - timestamp;
|
|
701
|
+
if (diff < 60)
|
|
702
|
+
return `${diff} seconds ago`;
|
|
703
|
+
if (diff < 3600)
|
|
704
|
+
return `${Math.floor(diff / 60)} minutes ago`;
|
|
705
|
+
if (diff < 86400)
|
|
706
|
+
return `${Math.floor(diff / 3600)} hours ago`;
|
|
707
|
+
return `${Math.floor(diff / 86400)} days ago`;
|
|
708
|
+
}
|
|
709
|
+
// ============================================================================
|
|
498
710
|
// Database Commands
|
|
499
711
|
// ============================================================================
|
|
500
712
|
async dbStats() {
|
|
@@ -549,6 +761,23 @@ async function main() {
|
|
|
549
761
|
await handleInitCommand(args.slice(1));
|
|
550
762
|
return;
|
|
551
763
|
}
|
|
764
|
+
// Handle vector search commands (no CLI initialization needed)
|
|
765
|
+
if (command === 'vector-search') {
|
|
766
|
+
await handleVectorSearchCommand(args.slice(1));
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
if (command === 'export') {
|
|
770
|
+
await handleExportCommand(args.slice(1));
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
if (command === 'import') {
|
|
774
|
+
await handleImportCommand(args.slice(1));
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
if (command === 'stats') {
|
|
778
|
+
await handleStatsCommand(args.slice(1));
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
552
781
|
const cli = new AgentDBCLI();
|
|
553
782
|
const dbPath = process.env.AGENTDB_PATH || './agentdb.db';
|
|
554
783
|
try {
|
|
@@ -572,6 +801,9 @@ async function main() {
|
|
|
572
801
|
else if (command === 'db') {
|
|
573
802
|
await handleDbCommands(cli, subcommand, args.slice(2));
|
|
574
803
|
}
|
|
804
|
+
else if (command === 'sync') {
|
|
805
|
+
await handleSyncCommands(cli, subcommand, args.slice(2));
|
|
806
|
+
}
|
|
575
807
|
else if (command === 'query') {
|
|
576
808
|
await handleQueryCommand(cli, args.slice(1));
|
|
577
809
|
}
|
|
@@ -598,37 +830,77 @@ async function main() {
|
|
|
598
830
|
// Command handlers
|
|
599
831
|
// Init command handler
|
|
600
832
|
async function handleInitCommand(args) {
|
|
601
|
-
|
|
833
|
+
// Parse arguments
|
|
834
|
+
let dbPath = './agentdb.db';
|
|
835
|
+
let dimension = 1536; // Default OpenAI ada-002
|
|
836
|
+
let preset = null;
|
|
837
|
+
let inMemory = false;
|
|
838
|
+
for (let i = 0; i < args.length; i++) {
|
|
839
|
+
const arg = args[i];
|
|
840
|
+
if (arg === '--dimension' && i + 1 < args.length) {
|
|
841
|
+
dimension = parseInt(args[++i]);
|
|
842
|
+
}
|
|
843
|
+
else if (arg === '--preset' && i + 1 < args.length) {
|
|
844
|
+
preset = args[++i];
|
|
845
|
+
}
|
|
846
|
+
else if (arg === '--in-memory') {
|
|
847
|
+
inMemory = true;
|
|
848
|
+
dbPath = ':memory:';
|
|
849
|
+
}
|
|
850
|
+
else if (!arg.startsWith('--')) {
|
|
851
|
+
dbPath = arg;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
// Apply preset configurations
|
|
855
|
+
if (preset) {
|
|
856
|
+
if (preset === 'small') {
|
|
857
|
+
log.info('Using SMALL preset (<10K vectors)');
|
|
858
|
+
}
|
|
859
|
+
else if (preset === 'medium') {
|
|
860
|
+
log.info('Using MEDIUM preset (10K-100K vectors)');
|
|
861
|
+
}
|
|
862
|
+
else if (preset === 'large') {
|
|
863
|
+
log.info('Using LARGE preset (>100K vectors)');
|
|
864
|
+
}
|
|
865
|
+
}
|
|
602
866
|
log.info(`Initializing AgentDB at: ${dbPath}`);
|
|
867
|
+
log.info(`Embedding dimension: ${dimension}`);
|
|
868
|
+
if (inMemory) {
|
|
869
|
+
log.info('Using in-memory database (data will not persist)');
|
|
870
|
+
}
|
|
603
871
|
// Check if database already exists
|
|
604
|
-
if (fs.existsSync(dbPath)) {
|
|
872
|
+
if (!inMemory && fs.existsSync(dbPath)) {
|
|
605
873
|
log.warning(`Database already exists at ${dbPath}`);
|
|
606
874
|
log.info('Use a different path or remove the existing file to reinitialize');
|
|
607
875
|
return;
|
|
608
876
|
}
|
|
609
877
|
// Create parent directories if needed
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
878
|
+
if (!inMemory) {
|
|
879
|
+
const parentDir = path.dirname(dbPath);
|
|
880
|
+
if (parentDir !== '.' && !fs.existsSync(parentDir)) {
|
|
881
|
+
log.info(`Creating directory: ${parentDir}`);
|
|
882
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
883
|
+
}
|
|
614
884
|
}
|
|
615
885
|
// Create new database with schemas
|
|
616
886
|
const cli = new AgentDBCLI();
|
|
617
887
|
await cli.initialize(dbPath);
|
|
618
|
-
// CRITICAL: Save the database to disk
|
|
888
|
+
// CRITICAL: Save the database to disk (unless in-memory)
|
|
619
889
|
// sql.js keeps everything in memory until explicitly saved
|
|
620
|
-
if (
|
|
621
|
-
cli.db.save
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
890
|
+
if (!inMemory) {
|
|
891
|
+
if (cli.db && typeof cli.db.save === 'function') {
|
|
892
|
+
cli.db.save();
|
|
893
|
+
}
|
|
894
|
+
else if (cli.db && typeof cli.db.close === 'function') {
|
|
895
|
+
// close() calls save() internally
|
|
896
|
+
cli.db.close();
|
|
897
|
+
}
|
|
898
|
+
// Verify database file was created
|
|
899
|
+
if (!fs.existsSync(dbPath)) {
|
|
900
|
+
log.error(`Failed to create database file at ${dbPath}`);
|
|
901
|
+
log.error('The database may be in memory only');
|
|
902
|
+
process.exit(1);
|
|
903
|
+
}
|
|
632
904
|
}
|
|
633
905
|
// Verify database has tables
|
|
634
906
|
try {
|
|
@@ -792,12 +1064,64 @@ async function handleReflexionCommands(cli, subcommand, args) {
|
|
|
792
1064
|
});
|
|
793
1065
|
}
|
|
794
1066
|
else if (subcommand === 'retrieve') {
|
|
1067
|
+
// Parse retrieve command with new flags
|
|
1068
|
+
let task = args[0];
|
|
1069
|
+
let k = undefined;
|
|
1070
|
+
let minReward = undefined;
|
|
1071
|
+
let onlyFailures = undefined;
|
|
1072
|
+
let onlySuccesses = undefined;
|
|
1073
|
+
let synthesizeContext = false;
|
|
1074
|
+
let filters = {};
|
|
1075
|
+
for (let i = 1; i < args.length; i++) {
|
|
1076
|
+
const arg = args[i];
|
|
1077
|
+
if (arg === '--k' && i + 1 < args.length) {
|
|
1078
|
+
k = parseInt(args[++i]);
|
|
1079
|
+
}
|
|
1080
|
+
else if (arg === '--min-reward' && i + 1 < args.length) {
|
|
1081
|
+
minReward = parseFloat(args[++i]);
|
|
1082
|
+
}
|
|
1083
|
+
else if (arg === '--only-failures') {
|
|
1084
|
+
onlyFailures = true;
|
|
1085
|
+
}
|
|
1086
|
+
else if (arg === '--only-successes') {
|
|
1087
|
+
onlySuccesses = true;
|
|
1088
|
+
}
|
|
1089
|
+
else if (arg === '--synthesize-context') {
|
|
1090
|
+
synthesizeContext = true;
|
|
1091
|
+
}
|
|
1092
|
+
else if (arg === '--filters' && i + 1 < args.length) {
|
|
1093
|
+
try {
|
|
1094
|
+
filters = JSON.parse(args[++i]);
|
|
1095
|
+
}
|
|
1096
|
+
catch (error) {
|
|
1097
|
+
log.error(`Invalid JSON in --filters parameter: ${error.message}`);
|
|
1098
|
+
process.exit(1);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
else if (!arg.startsWith('--') && k === undefined) {
|
|
1102
|
+
// Legacy positional argument parsing
|
|
1103
|
+
k = parseInt(arg);
|
|
1104
|
+
if (i + 1 < args.length && !args[i + 1].startsWith('--')) {
|
|
1105
|
+
minReward = parseFloat(args[++i]);
|
|
1106
|
+
}
|
|
1107
|
+
if (i + 1 < args.length && args[i + 1] === 'true') {
|
|
1108
|
+
onlyFailures = true;
|
|
1109
|
+
i++;
|
|
1110
|
+
}
|
|
1111
|
+
if (i + 1 < args.length && args[i + 1] === 'true') {
|
|
1112
|
+
onlySuccesses = true;
|
|
1113
|
+
i++;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
795
1117
|
await cli.reflexionRetrieve({
|
|
796
|
-
task
|
|
797
|
-
k
|
|
798
|
-
minReward
|
|
799
|
-
onlyFailures
|
|
800
|
-
onlySuccesses
|
|
1118
|
+
task,
|
|
1119
|
+
k,
|
|
1120
|
+
minReward,
|
|
1121
|
+
onlyFailures,
|
|
1122
|
+
onlySuccesses,
|
|
1123
|
+
synthesizeContext,
|
|
1124
|
+
filters: Object.keys(filters).length > 0 ? filters : undefined
|
|
801
1125
|
});
|
|
802
1126
|
}
|
|
803
1127
|
else if (subcommand === 'critique-summary') {
|
|
@@ -860,7 +1184,112 @@ async function handleDbCommands(cli, subcommand, args) {
|
|
|
860
1184
|
printHelp();
|
|
861
1185
|
}
|
|
862
1186
|
}
|
|
863
|
-
|
|
1187
|
+
async function handleSyncCommands(cli, subcommand, args) {
|
|
1188
|
+
if (subcommand === 'start-server') {
|
|
1189
|
+
// Parse options
|
|
1190
|
+
let port;
|
|
1191
|
+
let cert;
|
|
1192
|
+
let key;
|
|
1193
|
+
let authToken;
|
|
1194
|
+
for (let i = 0; i < args.length; i++) {
|
|
1195
|
+
if (args[i] === '--port' && i + 1 < args.length) {
|
|
1196
|
+
port = parseInt(args[++i]);
|
|
1197
|
+
}
|
|
1198
|
+
else if (args[i] === '--cert' && i + 1 < args.length) {
|
|
1199
|
+
cert = args[++i];
|
|
1200
|
+
}
|
|
1201
|
+
else if (args[i] === '--key' && i + 1 < args.length) {
|
|
1202
|
+
key = args[++i];
|
|
1203
|
+
}
|
|
1204
|
+
else if (args[i] === '--auth-token' && i + 1 < args.length) {
|
|
1205
|
+
authToken = args[++i];
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
await cli.quicStartServer({ port, cert, key, authToken });
|
|
1209
|
+
}
|
|
1210
|
+
else if (subcommand === 'connect') {
|
|
1211
|
+
// Parse host and port
|
|
1212
|
+
const host = args[0];
|
|
1213
|
+
const port = parseInt(args[1]);
|
|
1214
|
+
if (!host || !port) {
|
|
1215
|
+
log.error('Missing required arguments: host and port');
|
|
1216
|
+
log.info('Usage: agentdb sync connect <host> <port> [--auth-token <token>] [--cert <path>]');
|
|
1217
|
+
process.exit(1);
|
|
1218
|
+
}
|
|
1219
|
+
let authToken;
|
|
1220
|
+
let cert;
|
|
1221
|
+
for (let i = 2; i < args.length; i++) {
|
|
1222
|
+
if (args[i] === '--auth-token' && i + 1 < args.length) {
|
|
1223
|
+
authToken = args[++i];
|
|
1224
|
+
}
|
|
1225
|
+
else if (args[i] === '--cert' && i + 1 < args.length) {
|
|
1226
|
+
cert = args[++i];
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
await cli.quicConnect({ host, port, authToken, cert });
|
|
1230
|
+
}
|
|
1231
|
+
else if (subcommand === 'push') {
|
|
1232
|
+
// Parse options
|
|
1233
|
+
let server;
|
|
1234
|
+
let incremental = false;
|
|
1235
|
+
let filter;
|
|
1236
|
+
for (let i = 0; i < args.length; i++) {
|
|
1237
|
+
if (args[i] === '--server' && i + 1 < args.length) {
|
|
1238
|
+
server = args[++i];
|
|
1239
|
+
}
|
|
1240
|
+
else if (args[i] === '--incremental') {
|
|
1241
|
+
incremental = true;
|
|
1242
|
+
}
|
|
1243
|
+
else if (args[i] === '--filter' && i + 1 < args.length) {
|
|
1244
|
+
filter = args[++i];
|
|
1245
|
+
}
|
|
1246
|
+
else if (!args[i].startsWith('--') && !server) {
|
|
1247
|
+
server = args[i];
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (!server) {
|
|
1251
|
+
log.error('Missing required --server parameter');
|
|
1252
|
+
log.info('Usage: agentdb sync push --server <host:port> [--incremental] [--filter <pattern>]');
|
|
1253
|
+
process.exit(1);
|
|
1254
|
+
}
|
|
1255
|
+
await cli.quicPush({ server, incremental, filter });
|
|
1256
|
+
}
|
|
1257
|
+
else if (subcommand === 'pull') {
|
|
1258
|
+
// Parse options
|
|
1259
|
+
let server;
|
|
1260
|
+
let incremental = false;
|
|
1261
|
+
let filter;
|
|
1262
|
+
for (let i = 0; i < args.length; i++) {
|
|
1263
|
+
if (args[i] === '--server' && i + 1 < args.length) {
|
|
1264
|
+
server = args[++i];
|
|
1265
|
+
}
|
|
1266
|
+
else if (args[i] === '--incremental') {
|
|
1267
|
+
incremental = true;
|
|
1268
|
+
}
|
|
1269
|
+
else if (args[i] === '--filter' && i + 1 < args.length) {
|
|
1270
|
+
filter = args[++i];
|
|
1271
|
+
}
|
|
1272
|
+
else if (!args[i].startsWith('--') && !server) {
|
|
1273
|
+
server = args[i];
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
if (!server) {
|
|
1277
|
+
log.error('Missing required --server parameter');
|
|
1278
|
+
log.info('Usage: agentdb sync pull --server <host:port> [--incremental] [--filter <pattern>]');
|
|
1279
|
+
process.exit(1);
|
|
1280
|
+
}
|
|
1281
|
+
await cli.quicPull({ server, incremental, filter });
|
|
1282
|
+
}
|
|
1283
|
+
else if (subcommand === 'status') {
|
|
1284
|
+
await cli.quicStatus();
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
log.error(`Unknown sync subcommand: ${subcommand}`);
|
|
1288
|
+
log.info('Available subcommands: start-server, connect, push, pull, status');
|
|
1289
|
+
printHelp();
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
// Query command - semantic search across reflexion episodes with context synthesis
|
|
864
1293
|
async function handleQueryCommand(cli, args) {
|
|
865
1294
|
// Parse command-line arguments
|
|
866
1295
|
let domain = '';
|
|
@@ -868,6 +1297,8 @@ async function handleQueryCommand(cli, args) {
|
|
|
868
1297
|
let k = 5;
|
|
869
1298
|
let minConfidence = 0.0;
|
|
870
1299
|
let format = 'json';
|
|
1300
|
+
let synthesizeContext = false;
|
|
1301
|
+
let filters = {};
|
|
871
1302
|
for (let i = 0; i < args.length; i++) {
|
|
872
1303
|
if (args[i] === '--domain' && i + 1 < args.length) {
|
|
873
1304
|
domain = args[++i];
|
|
@@ -884,23 +1315,89 @@ async function handleQueryCommand(cli, args) {
|
|
|
884
1315
|
else if (args[i] === '--format' && i + 1 < args.length) {
|
|
885
1316
|
format = args[++i];
|
|
886
1317
|
}
|
|
1318
|
+
else if (args[i] === '--synthesize-context') {
|
|
1319
|
+
synthesizeContext = true;
|
|
1320
|
+
}
|
|
1321
|
+
else if (args[i] === '--filters' && i + 1 < args.length) {
|
|
1322
|
+
try {
|
|
1323
|
+
filters = JSON.parse(args[++i]);
|
|
1324
|
+
}
|
|
1325
|
+
catch (error) {
|
|
1326
|
+
log.error(`Invalid JSON in --filters parameter: ${error.message}`);
|
|
1327
|
+
process.exit(1);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
887
1330
|
}
|
|
888
1331
|
if (!query) {
|
|
889
1332
|
log.error('Missing required --query parameter');
|
|
890
1333
|
process.exit(1);
|
|
891
1334
|
}
|
|
1335
|
+
// Validate filters if provided
|
|
1336
|
+
if (Object.keys(filters).length > 0) {
|
|
1337
|
+
const validation = MetadataFilter.validate(filters);
|
|
1338
|
+
if (!validation.valid) {
|
|
1339
|
+
log.error('Invalid filters:');
|
|
1340
|
+
validation.errors.forEach(err => log.error(` - ${err}`));
|
|
1341
|
+
process.exit(1);
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
892
1344
|
// Use reflexionRetrieveJson method for JSON output
|
|
893
|
-
|
|
1345
|
+
let results = await cli.reflexionRetrieveJson({
|
|
894
1346
|
task: query,
|
|
895
1347
|
k,
|
|
896
1348
|
minReward: minConfidence,
|
|
897
1349
|
onlySuccesses: domain === 'successful-edits'
|
|
898
1350
|
});
|
|
899
|
-
|
|
900
|
-
|
|
1351
|
+
// Apply metadata filters if provided
|
|
1352
|
+
if (Object.keys(filters).length > 0) {
|
|
1353
|
+
results = MetadataFilter.apply(results, filters);
|
|
1354
|
+
log.info(`Filtered to ${results.length} results matching metadata criteria`);
|
|
1355
|
+
}
|
|
1356
|
+
// Synthesize context if requested
|
|
1357
|
+
if (synthesizeContext && results.length > 0) {
|
|
1358
|
+
const context = ContextSynthesizer.synthesize(results.map((r) => ({
|
|
1359
|
+
task: r.task,
|
|
1360
|
+
reward: r.reward,
|
|
1361
|
+
success: r.success,
|
|
1362
|
+
critique: r.critique,
|
|
1363
|
+
input: r.input,
|
|
1364
|
+
output: r.output,
|
|
1365
|
+
similarity: r.similarity
|
|
1366
|
+
})));
|
|
1367
|
+
if (format === 'json') {
|
|
1368
|
+
console.log(JSON.stringify({ results, synthesizedContext: context }, null, 2));
|
|
1369
|
+
}
|
|
1370
|
+
else {
|
|
1371
|
+
console.log('\n' + '═'.repeat(80));
|
|
1372
|
+
console.log('SYNTHESIZED CONTEXT');
|
|
1373
|
+
console.log('═'.repeat(80));
|
|
1374
|
+
console.log(`\n${context.summary}\n`);
|
|
1375
|
+
if (context.patterns.length > 0) {
|
|
1376
|
+
console.log('Common Patterns:');
|
|
1377
|
+
context.patterns.forEach(p => console.log(` • ${p}`));
|
|
1378
|
+
console.log('');
|
|
1379
|
+
}
|
|
1380
|
+
if (context.keyInsights.length > 0) {
|
|
1381
|
+
console.log('Key Insights:');
|
|
1382
|
+
context.keyInsights.forEach(i => console.log(` • ${i}`));
|
|
1383
|
+
console.log('');
|
|
1384
|
+
}
|
|
1385
|
+
if (context.recommendations.length > 0) {
|
|
1386
|
+
console.log('Recommendations:');
|
|
1387
|
+
context.recommendations.forEach((r, i) => console.log(` ${i + 1}. ${r}`));
|
|
1388
|
+
console.log('');
|
|
1389
|
+
}
|
|
1390
|
+
console.log('═'.repeat(80));
|
|
1391
|
+
console.log(`\nMatched ${results.length} memories\n`);
|
|
1392
|
+
}
|
|
901
1393
|
}
|
|
902
1394
|
else {
|
|
903
|
-
|
|
1395
|
+
if (format === 'json') {
|
|
1396
|
+
console.log(JSON.stringify(results, null, 2));
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
console.log(results);
|
|
1400
|
+
}
|
|
904
1401
|
}
|
|
905
1402
|
}
|
|
906
1403
|
// Store-pattern command - store learned patterns
|
|
@@ -1028,6 +1525,366 @@ async function handleOptimizeMemoryCommand(cli, args) {
|
|
|
1028
1525
|
});
|
|
1029
1526
|
console.log(JSON.stringify({ success: true, message: 'Memory optimization completed' }, null, 2));
|
|
1030
1527
|
}
|
|
1528
|
+
// Vector-search command - direct vector similarity search with MMR diversity ranking
|
|
1529
|
+
async function handleVectorSearchCommand(args) {
|
|
1530
|
+
// Parse arguments
|
|
1531
|
+
let dbPath = './agentdb.db';
|
|
1532
|
+
let vector = [];
|
|
1533
|
+
let k = 10;
|
|
1534
|
+
let threshold = 0.0;
|
|
1535
|
+
let metric = 'cosine';
|
|
1536
|
+
let format = 'json';
|
|
1537
|
+
let verbose = false;
|
|
1538
|
+
let useMmr = false;
|
|
1539
|
+
let mmrLambda = 0.5;
|
|
1540
|
+
for (let i = 0; i < args.length; i++) {
|
|
1541
|
+
const arg = args[i];
|
|
1542
|
+
if (arg === '-k' && i + 1 < args.length) {
|
|
1543
|
+
k = parseInt(args[++i]);
|
|
1544
|
+
}
|
|
1545
|
+
else if (arg === '-t' && i + 1 < args.length) {
|
|
1546
|
+
threshold = parseFloat(args[++i]);
|
|
1547
|
+
}
|
|
1548
|
+
else if (arg === '-m' && i + 1 < args.length) {
|
|
1549
|
+
metric = args[++i];
|
|
1550
|
+
}
|
|
1551
|
+
else if (arg === '-f' && i + 1 < args.length) {
|
|
1552
|
+
format = args[++i];
|
|
1553
|
+
}
|
|
1554
|
+
else if (arg === '-v' || arg === '--verbose') {
|
|
1555
|
+
verbose = true;
|
|
1556
|
+
}
|
|
1557
|
+
else if (arg === '--mmr') {
|
|
1558
|
+
useMmr = true;
|
|
1559
|
+
if (i + 1 < args.length && !args[i + 1].startsWith('-')) {
|
|
1560
|
+
mmrLambda = parseFloat(args[++i]);
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
else if (!dbPath.endsWith('.db') && !arg.startsWith('[')) {
|
|
1564
|
+
dbPath = arg;
|
|
1565
|
+
}
|
|
1566
|
+
else if (arg.startsWith('[') || (!isNaN(parseFloat(arg)))) {
|
|
1567
|
+
// Parse vector - either JSON array or space-separated numbers
|
|
1568
|
+
try {
|
|
1569
|
+
if (arg.startsWith('[')) {
|
|
1570
|
+
vector = JSON.parse(arg);
|
|
1571
|
+
}
|
|
1572
|
+
else {
|
|
1573
|
+
// Collect space-separated numbers
|
|
1574
|
+
while (i < args.length && !isNaN(parseFloat(args[i]))) {
|
|
1575
|
+
vector.push(parseFloat(args[i++]));
|
|
1576
|
+
}
|
|
1577
|
+
i--; // Back up one since loop will increment
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
catch (e) {
|
|
1581
|
+
log.error('Invalid vector format. Use JSON array: "[0.1,0.2,0.3]" or space-separated: "0.1 0.2 0.3"');
|
|
1582
|
+
process.exit(1);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
if (vector.length === 0) {
|
|
1587
|
+
log.error('Missing required vector parameter');
|
|
1588
|
+
log.info('Usage: agentdb vector-search <db-path> <vector> [-k 10] [-t 0.75] [-m cosine] [-f json] [-v] [--mmr [lambda]]');
|
|
1589
|
+
process.exit(1);
|
|
1590
|
+
}
|
|
1591
|
+
if (useMmr) {
|
|
1592
|
+
log.info(`Using MMR diversity ranking (λ=${mmrLambda})`);
|
|
1593
|
+
}
|
|
1594
|
+
// Initialize database
|
|
1595
|
+
const cli = new AgentDBCLI();
|
|
1596
|
+
await cli.initialize(dbPath);
|
|
1597
|
+
// Perform vector search using reflexion's retrieveRelevant (which uses embeddings)
|
|
1598
|
+
// We'll need to search episode_embeddings table directly
|
|
1599
|
+
const query = `
|
|
1600
|
+
SELECT
|
|
1601
|
+
e.id,
|
|
1602
|
+
e.session_id,
|
|
1603
|
+
e.task,
|
|
1604
|
+
e.reward,
|
|
1605
|
+
e.success,
|
|
1606
|
+
ee.embedding
|
|
1607
|
+
FROM episodes e
|
|
1608
|
+
JOIN episode_embeddings ee ON e.id = ee.episode_id
|
|
1609
|
+
LIMIT ?
|
|
1610
|
+
`;
|
|
1611
|
+
const results = cli.db.prepare(query).all(k * 10); // Get more for filtering
|
|
1612
|
+
// Calculate similarities
|
|
1613
|
+
let scored = results.map((row) => {
|
|
1614
|
+
const embedding = new Float32Array(row.embedding);
|
|
1615
|
+
const similarity = calculateSimilarity(vector, Array.from(embedding), metric);
|
|
1616
|
+
return {
|
|
1617
|
+
id: row.id,
|
|
1618
|
+
session_id: row.session_id,
|
|
1619
|
+
task: row.task,
|
|
1620
|
+
reward: row.reward,
|
|
1621
|
+
success: row.success,
|
|
1622
|
+
similarity,
|
|
1623
|
+
embedding: Array.from(embedding)
|
|
1624
|
+
};
|
|
1625
|
+
}).filter(r => r.similarity >= threshold)
|
|
1626
|
+
.sort((a, b) => b.similarity - a.similarity);
|
|
1627
|
+
// Apply MMR diversity ranking if requested
|
|
1628
|
+
if (useMmr && scored.length > k) {
|
|
1629
|
+
scored = MMRDiversityRanker.selectDiverse(scored, vector, {
|
|
1630
|
+
lambda: mmrLambda,
|
|
1631
|
+
k,
|
|
1632
|
+
metric: metric
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
else {
|
|
1636
|
+
scored = scored.slice(0, k);
|
|
1637
|
+
}
|
|
1638
|
+
// Remove embedding from output
|
|
1639
|
+
const output = scored.map(({ embedding, ...rest }) => rest);
|
|
1640
|
+
if (format === 'json') {
|
|
1641
|
+
console.log(JSON.stringify(output, null, 2));
|
|
1642
|
+
}
|
|
1643
|
+
else {
|
|
1644
|
+
console.log(`Found ${output.length} results:`);
|
|
1645
|
+
output.forEach((r, i) => {
|
|
1646
|
+
console.log(`${i + 1}. [${r.id}] ${r.task} (similarity: ${r.similarity.toFixed(4)})`);
|
|
1647
|
+
if (verbose) {
|
|
1648
|
+
console.log(` Session: ${r.session_id}, Reward: ${r.reward}, Success: ${r.success}`);
|
|
1649
|
+
}
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
// Helper function to calculate similarity
|
|
1654
|
+
function calculateSimilarity(v1, v2, metric) {
|
|
1655
|
+
if (v1.length !== v2.length) {
|
|
1656
|
+
throw new Error(`Vector dimension mismatch: ${v1.length} vs ${v2.length}`);
|
|
1657
|
+
}
|
|
1658
|
+
if (metric === 'cosine') {
|
|
1659
|
+
let dot = 0, mag1 = 0, mag2 = 0;
|
|
1660
|
+
for (let i = 0; i < v1.length; i++) {
|
|
1661
|
+
dot += v1[i] * v2[i];
|
|
1662
|
+
mag1 += v1[i] * v1[i];
|
|
1663
|
+
mag2 += v2[i] * v2[i];
|
|
1664
|
+
}
|
|
1665
|
+
return dot / (Math.sqrt(mag1) * Math.sqrt(mag2));
|
|
1666
|
+
}
|
|
1667
|
+
else if (metric === 'euclidean') {
|
|
1668
|
+
let sum = 0;
|
|
1669
|
+
for (let i = 0; i < v1.length; i++) {
|
|
1670
|
+
const diff = v1[i] - v2[i];
|
|
1671
|
+
sum += diff * diff;
|
|
1672
|
+
}
|
|
1673
|
+
return 1 / (1 + Math.sqrt(sum)); // Normalize to 0-1 range
|
|
1674
|
+
}
|
|
1675
|
+
else if (metric === 'dot') {
|
|
1676
|
+
let dot = 0;
|
|
1677
|
+
for (let i = 0; i < v1.length; i++) {
|
|
1678
|
+
dot += v1[i] * v2[i];
|
|
1679
|
+
}
|
|
1680
|
+
return dot;
|
|
1681
|
+
}
|
|
1682
|
+
return 0;
|
|
1683
|
+
}
|
|
1684
|
+
// Export command - export vectors to JSON with optional compression
|
|
1685
|
+
async function handleExportCommand(args) {
|
|
1686
|
+
let dbPath = './agentdb.db';
|
|
1687
|
+
let outputPath = './agentdb-export.json';
|
|
1688
|
+
let compress = false;
|
|
1689
|
+
// Parse arguments
|
|
1690
|
+
for (let i = 0; i < args.length; i++) {
|
|
1691
|
+
const arg = args[i];
|
|
1692
|
+
if (arg === '--compress') {
|
|
1693
|
+
compress = true;
|
|
1694
|
+
}
|
|
1695
|
+
else if (arg === '--output' && i + 1 < args.length) {
|
|
1696
|
+
outputPath = args[++i];
|
|
1697
|
+
}
|
|
1698
|
+
else if (!arg.startsWith('--')) {
|
|
1699
|
+
if (dbPath === './agentdb.db') {
|
|
1700
|
+
dbPath = arg;
|
|
1701
|
+
}
|
|
1702
|
+
else if (outputPath === './agentdb-export.json') {
|
|
1703
|
+
outputPath = arg;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
// Add .gz extension if compressing and not already present
|
|
1708
|
+
if (compress && !outputPath.endsWith('.gz')) {
|
|
1709
|
+
outputPath += '.gz';
|
|
1710
|
+
}
|
|
1711
|
+
log.info(`Exporting vectors from: ${dbPath}`);
|
|
1712
|
+
if (compress) {
|
|
1713
|
+
log.info('Compression: enabled');
|
|
1714
|
+
}
|
|
1715
|
+
const cli = new AgentDBCLI();
|
|
1716
|
+
await cli.initialize(dbPath);
|
|
1717
|
+
// Export all episodes with embeddings
|
|
1718
|
+
const query = `
|
|
1719
|
+
SELECT
|
|
1720
|
+
e.*,
|
|
1721
|
+
ee.embedding
|
|
1722
|
+
FROM episodes e
|
|
1723
|
+
LEFT JOIN episode_embeddings ee ON e.id = ee.episode_id
|
|
1724
|
+
`;
|
|
1725
|
+
const results = cli.db.prepare(query).all();
|
|
1726
|
+
const jsonData = JSON.stringify(results, null, 2);
|
|
1727
|
+
try {
|
|
1728
|
+
if (compress) {
|
|
1729
|
+
// Compress with gzip
|
|
1730
|
+
const compressed = zlib.gzipSync(jsonData);
|
|
1731
|
+
fs.writeFileSync(outputPath, compressed);
|
|
1732
|
+
const originalSize = Buffer.byteLength(jsonData);
|
|
1733
|
+
const compressedSize = compressed.length;
|
|
1734
|
+
const ratio = ((1 - compressedSize / originalSize) * 100).toFixed(1);
|
|
1735
|
+
log.success(`Exported ${results.length} episodes to ${outputPath}`);
|
|
1736
|
+
log.info(`Original size: ${(originalSize / 1024).toFixed(2)} KB`);
|
|
1737
|
+
log.info(`Compressed size: ${(compressedSize / 1024).toFixed(2)} KB (${ratio}% reduction)`);
|
|
1738
|
+
}
|
|
1739
|
+
else {
|
|
1740
|
+
fs.writeFileSync(outputPath, jsonData);
|
|
1741
|
+
log.success(`Exported ${results.length} episodes to ${outputPath}`);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
catch (error) {
|
|
1745
|
+
log.error(`Failed to export: ${error.message}`);
|
|
1746
|
+
process.exit(1);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
// Import command - import vectors from JSON with optional decompression
|
|
1750
|
+
async function handleImportCommand(args) {
|
|
1751
|
+
let inputPath = '';
|
|
1752
|
+
let dbPath = './agentdb.db';
|
|
1753
|
+
let decompress = false;
|
|
1754
|
+
// Parse arguments
|
|
1755
|
+
for (let i = 0; i < args.length; i++) {
|
|
1756
|
+
const arg = args[i];
|
|
1757
|
+
if (arg === '--decompress') {
|
|
1758
|
+
decompress = true;
|
|
1759
|
+
}
|
|
1760
|
+
else if (arg === '--db' && i + 1 < args.length) {
|
|
1761
|
+
dbPath = args[++i];
|
|
1762
|
+
}
|
|
1763
|
+
else if (!arg.startsWith('--')) {
|
|
1764
|
+
if (!inputPath) {
|
|
1765
|
+
inputPath = arg;
|
|
1766
|
+
}
|
|
1767
|
+
else if (dbPath === './agentdb.db') {
|
|
1768
|
+
dbPath = arg;
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
// Auto-detect compression from .gz extension
|
|
1773
|
+
if (inputPath.endsWith('.gz')) {
|
|
1774
|
+
decompress = true;
|
|
1775
|
+
}
|
|
1776
|
+
if (!inputPath) {
|
|
1777
|
+
log.error('Missing required input file');
|
|
1778
|
+
log.info('Usage: agentdb import <input-file.json> [db-path] [--decompress]');
|
|
1779
|
+
process.exit(1);
|
|
1780
|
+
}
|
|
1781
|
+
log.info(`Importing vectors from: ${inputPath}`);
|
|
1782
|
+
if (decompress) {
|
|
1783
|
+
log.info('Decompression: enabled');
|
|
1784
|
+
}
|
|
1785
|
+
let data;
|
|
1786
|
+
try {
|
|
1787
|
+
if (decompress) {
|
|
1788
|
+
// Decompress with gunzip
|
|
1789
|
+
const compressed = fs.readFileSync(inputPath);
|
|
1790
|
+
const decompressed = zlib.gunzipSync(compressed);
|
|
1791
|
+
data = JSON.parse(decompressed.toString('utf-8'));
|
|
1792
|
+
log.info(`Decompressed ${(compressed.length / 1024).toFixed(2)} KB to ${(decompressed.length / 1024).toFixed(2)} KB`);
|
|
1793
|
+
}
|
|
1794
|
+
else {
|
|
1795
|
+
data = JSON.parse(fs.readFileSync(inputPath, 'utf-8'));
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
catch (error) {
|
|
1799
|
+
log.error(`Failed to read/parse input file: ${error.message}`);
|
|
1800
|
+
process.exit(1);
|
|
1801
|
+
}
|
|
1802
|
+
const cli = new AgentDBCLI();
|
|
1803
|
+
await cli.initialize(dbPath);
|
|
1804
|
+
let imported = 0;
|
|
1805
|
+
for (const item of data) {
|
|
1806
|
+
try {
|
|
1807
|
+
// Import episode
|
|
1808
|
+
const episodeQuery = `
|
|
1809
|
+
INSERT INTO episodes (session_id, task, input, output, critique, reward, success, latency_ms, tokens_used, tags, metadata)
|
|
1810
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1811
|
+
`;
|
|
1812
|
+
const result = cli.db.prepare(episodeQuery).run(item.session_id, item.task, item.input, item.output, item.critique, item.reward, item.success, item.latency_ms, item.tokens_used, item.tags, item.metadata);
|
|
1813
|
+
// Import embedding if exists
|
|
1814
|
+
if (item.embedding) {
|
|
1815
|
+
const embeddingQuery = `INSERT INTO episode_embeddings (episode_id, embedding) VALUES (?, ?)`;
|
|
1816
|
+
cli.db.prepare(embeddingQuery).run(result.lastInsertRowid, item.embedding);
|
|
1817
|
+
}
|
|
1818
|
+
imported++;
|
|
1819
|
+
}
|
|
1820
|
+
catch (error) {
|
|
1821
|
+
log.warning(`Failed to import item ${imported + 1}: ${error.message}`);
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
// Save database
|
|
1825
|
+
if (cli.db && typeof cli.db.save === 'function') {
|
|
1826
|
+
cli.db.save();
|
|
1827
|
+
}
|
|
1828
|
+
log.success(`Imported ${imported} episodes`);
|
|
1829
|
+
}
|
|
1830
|
+
// Stats command - show database statistics
|
|
1831
|
+
async function handleStatsCommand(args) {
|
|
1832
|
+
const dbPath = args[0] || './agentdb.db';
|
|
1833
|
+
log.info(`Getting statistics for: ${dbPath}`);
|
|
1834
|
+
const cli = new AgentDBCLI();
|
|
1835
|
+
await cli.initialize(dbPath);
|
|
1836
|
+
// Get counts (with fallback for missing tables)
|
|
1837
|
+
const episodeCount = cli.db.prepare('SELECT COUNT(*) as count FROM episodes').get()?.count || 0;
|
|
1838
|
+
const embeddingCount = cli.db.prepare('SELECT COUNT(*) as count FROM episode_embeddings').get()?.count || 0;
|
|
1839
|
+
let skillCount = 0;
|
|
1840
|
+
try {
|
|
1841
|
+
skillCount = cli.db.prepare('SELECT COUNT(*) as count FROM skill_library').get()?.count || 0;
|
|
1842
|
+
}
|
|
1843
|
+
catch (e) {
|
|
1844
|
+
// skill_library table may not exist in older databases
|
|
1845
|
+
}
|
|
1846
|
+
let causalEdges = 0;
|
|
1847
|
+
try {
|
|
1848
|
+
causalEdges = cli.db.prepare('SELECT COUNT(*) as count FROM causal_edges').get()?.count || 0;
|
|
1849
|
+
}
|
|
1850
|
+
catch (e) {
|
|
1851
|
+
// causal_edges table may not exist in older databases
|
|
1852
|
+
}
|
|
1853
|
+
// Get database file size
|
|
1854
|
+
let dbSize = 0;
|
|
1855
|
+
if (dbPath !== ':memory:' && fs.existsSync(dbPath)) {
|
|
1856
|
+
dbSize = fs.statSync(dbPath).size;
|
|
1857
|
+
}
|
|
1858
|
+
// Get average confidence
|
|
1859
|
+
const avgConfidence = cli.db.prepare('SELECT AVG(reward) as avg FROM episodes').get().avg || 0;
|
|
1860
|
+
// Get domains
|
|
1861
|
+
const domains = cli.db.prepare(`
|
|
1862
|
+
SELECT task, COUNT(*) as count
|
|
1863
|
+
FROM episodes
|
|
1864
|
+
GROUP BY task
|
|
1865
|
+
ORDER BY count DESC
|
|
1866
|
+
LIMIT 5
|
|
1867
|
+
`).all();
|
|
1868
|
+
console.log(`
|
|
1869
|
+
📊 AgentDB Statistics
|
|
1870
|
+
|
|
1871
|
+
Database: ${dbPath}
|
|
1872
|
+
Size: ${(dbSize / 1024).toFixed(2)} KB
|
|
1873
|
+
|
|
1874
|
+
📈 Counts:
|
|
1875
|
+
Episodes: ${episodeCount}
|
|
1876
|
+
Embeddings: ${embeddingCount}
|
|
1877
|
+
Skills: ${skillCount}
|
|
1878
|
+
Causal Edges: ${causalEdges}
|
|
1879
|
+
|
|
1880
|
+
📊 Metrics:
|
|
1881
|
+
Average Reward: ${avgConfidence.toFixed(3)}
|
|
1882
|
+
Embedding Coverage: ${episodeCount > 0 ? ((embeddingCount / episodeCount) * 100).toFixed(1) : 0}%
|
|
1883
|
+
|
|
1884
|
+
🏷️ Top Domains:
|
|
1885
|
+
${domains.map(d => ` • ${d.task}: ${d.count}`).join('\n')}
|
|
1886
|
+
`);
|
|
1887
|
+
}
|
|
1031
1888
|
function printHelp() {
|
|
1032
1889
|
console.log(`
|
|
1033
1890
|
${colors.bright}${colors.cyan}█▀█ █▀▀ █▀▀ █▄░█ ▀█▀ █▀▄ █▄▄
|
|
@@ -1039,13 +1896,96 @@ ${colors.bright}USAGE:${colors.reset}
|
|
|
1039
1896
|
agentdb <command> <subcommand> [options]
|
|
1040
1897
|
|
|
1041
1898
|
${colors.bright}SETUP COMMANDS:${colors.reset}
|
|
1042
|
-
agentdb init [db-path]
|
|
1899
|
+
agentdb init [db-path] [--dimension 1536] [--preset small|medium|large] [--in-memory]
|
|
1043
1900
|
Initialize a new AgentDB database (default: ./agentdb.db)
|
|
1901
|
+
Options:
|
|
1902
|
+
--dimension <n> Vector dimension (default: 1536 for OpenAI, 768 for sentence-transformers)
|
|
1903
|
+
--preset <size> small (<10K), medium (10K-100K), large (>100K vectors)
|
|
1904
|
+
--in-memory Use temporary in-memory database (:memory:)
|
|
1905
|
+
|
|
1906
|
+
${colors.bright}VECTOR SEARCH COMMANDS:${colors.reset}
|
|
1907
|
+
agentdb vector-search <db-path> <vector> [-k 10] [-t 0.75] [-m cosine] [-f json] [-v] [--mmr [lambda]]
|
|
1908
|
+
Direct vector similarity search without text embeddings
|
|
1909
|
+
Arguments:
|
|
1910
|
+
<db-path> Database file path (or :memory:)
|
|
1911
|
+
<vector> Vector as JSON array [0.1,0.2,...] or space-separated numbers
|
|
1912
|
+
Options:
|
|
1913
|
+
-k <n> Number of results (default: 10)
|
|
1914
|
+
-t <threshold> Minimum similarity threshold (default: 0.0)
|
|
1915
|
+
-m <metric> Similarity metric: cosine|euclidean|dot (default: cosine)
|
|
1916
|
+
-f <format> Output format: json|table (default: json)
|
|
1917
|
+
-v Verbose mode with similarity scores
|
|
1918
|
+
--mmr [lambda] Enable MMR diversity ranking (lambda: 0-1, default: 0.5)
|
|
1919
|
+
0 = max diversity, 1 = max relevance
|
|
1920
|
+
Example: agentdb vector-search ./vectors.db "[0.1,0.2,0.3]" -k 10 -m cosine
|
|
1921
|
+
Example: agentdb vector-search ./vectors.db "[0.1,0.2,0.3]" --mmr 0.7
|
|
1922
|
+
|
|
1923
|
+
agentdb export <db-path> [output-file] [--compress]
|
|
1924
|
+
Export all vectors and episodes to JSON file
|
|
1925
|
+
Options:
|
|
1926
|
+
--compress Compress output with gzip (adds .gz extension)
|
|
1927
|
+
--output <file> Output file path
|
|
1928
|
+
Example: agentdb export ./agentdb.db ./backup.json
|
|
1929
|
+
Example: agentdb export ./agentdb.db --compress --output backup.json.gz
|
|
1930
|
+
|
|
1931
|
+
agentdb import <input-file> [db-path] [--decompress]
|
|
1932
|
+
Import vectors and episodes from JSON file
|
|
1933
|
+
Options:
|
|
1934
|
+
--decompress Decompress gzip input (auto-detected for .gz files)
|
|
1935
|
+
--db <path> Database file path
|
|
1936
|
+
Example: agentdb import ./backup.json ./new-db.db
|
|
1937
|
+
Example: agentdb import ./backup.json.gz --decompress
|
|
1938
|
+
|
|
1939
|
+
agentdb stats [db-path]
|
|
1940
|
+
Show detailed database statistics and metrics
|
|
1941
|
+
Example: agentdb stats ./agentdb.db
|
|
1044
1942
|
|
|
1045
1943
|
${colors.bright}MCP COMMANDS:${colors.reset}
|
|
1046
1944
|
agentdb mcp start
|
|
1047
1945
|
Start the MCP server for Claude Desktop integration
|
|
1048
1946
|
|
|
1947
|
+
${colors.bright}QUIC SYNC COMMANDS:${colors.reset}
|
|
1948
|
+
agentdb sync start-server [--port 4433] [--cert <path>] [--key <path>] [--auth-token <token>]
|
|
1949
|
+
Start a QUIC synchronization server for multi-agent coordination
|
|
1950
|
+
Options:
|
|
1951
|
+
--port <n> Server port (default: 4433)
|
|
1952
|
+
--cert <path> TLS certificate file path
|
|
1953
|
+
--key <path> TLS key file path
|
|
1954
|
+
--auth-token <token> Authentication token (auto-generated if not provided)
|
|
1955
|
+
Example: agentdb sync start-server --port 4433 --cert ./cert.pem --key ./key.pem
|
|
1956
|
+
|
|
1957
|
+
agentdb sync connect <host> <port> [--auth-token <token>] [--cert <path>]
|
|
1958
|
+
Connect to a remote QUIC sync server
|
|
1959
|
+
Arguments:
|
|
1960
|
+
<host> Remote server hostname or IP
|
|
1961
|
+
<port> Remote server port
|
|
1962
|
+
Options:
|
|
1963
|
+
--auth-token <token> Authentication token
|
|
1964
|
+
--cert <path> TLS certificate for verification
|
|
1965
|
+
Example: agentdb sync connect 192.168.1.100 4433 --auth-token abc123
|
|
1966
|
+
|
|
1967
|
+
agentdb sync push --server <host:port> [--incremental] [--filter <pattern>]
|
|
1968
|
+
Push local changes to remote server
|
|
1969
|
+
Options:
|
|
1970
|
+
--server <host:port> Remote server address (e.g., 192.168.1.100:4433)
|
|
1971
|
+
--incremental Only push changes since last sync
|
|
1972
|
+
--filter <pattern> Filter changes by pattern (e.g., "episodes", "skills")
|
|
1973
|
+
Example: agentdb sync push --server 192.168.1.100:4433 --incremental
|
|
1974
|
+
Example: agentdb sync push --server localhost:4433 --filter "episodes"
|
|
1975
|
+
|
|
1976
|
+
agentdb sync pull --server <host:port> [--incremental] [--filter <pattern>]
|
|
1977
|
+
Pull remote changes from server
|
|
1978
|
+
Options:
|
|
1979
|
+
--server <host:port> Remote server address (e.g., 192.168.1.100:4433)
|
|
1980
|
+
--incremental Only pull changes since last sync
|
|
1981
|
+
--filter <pattern> Filter changes by pattern (e.g., "skills", "causal_edges")
|
|
1982
|
+
Example: agentdb sync pull --server 192.168.1.100:4433 --incremental
|
|
1983
|
+
Example: agentdb sync pull --server localhost:4433 --filter "skills"
|
|
1984
|
+
|
|
1985
|
+
agentdb sync status
|
|
1986
|
+
Show synchronization status, pending changes, and connected servers
|
|
1987
|
+
Example: agentdb sync status
|
|
1988
|
+
|
|
1049
1989
|
${colors.bright}CAUSAL COMMANDS:${colors.reset}
|
|
1050
1990
|
agentdb causal add-edge <cause> <effect> <uplift> [confidence] [sample-size]
|
|
1051
1991
|
Add a causal edge manually
|
|
@@ -1080,8 +2020,17 @@ ${colors.bright}REFLEXION COMMANDS:${colors.reset}
|
|
|
1080
2020
|
agentdb reflexion store <session-id> <task> <reward> <success> [critique] [input] [output] [latency-ms] [tokens]
|
|
1081
2021
|
Store episode with self-critique
|
|
1082
2022
|
|
|
1083
|
-
agentdb reflexion retrieve <task> [k] [min-reward] [only-failures] [only-successes]
|
|
2023
|
+
agentdb reflexion retrieve <task> [--k <n>] [--min-reward <r>] [--only-failures] [--only-successes] [--synthesize-context] [--filters <json>]
|
|
1084
2024
|
Retrieve relevant past episodes
|
|
2025
|
+
Options:
|
|
2026
|
+
--k <n> Number of results (default: 5)
|
|
2027
|
+
--min-reward <r> Minimum reward threshold
|
|
2028
|
+
--only-failures Return only failed episodes
|
|
2029
|
+
--only-successes Return only successful episodes
|
|
2030
|
+
--synthesize-context Generate coherent summary with patterns and insights
|
|
2031
|
+
--filters <json> MongoDB-style metadata filters (e.g., '{"metadata.year":{"$gte":2024}}')
|
|
2032
|
+
Example: agentdb reflexion retrieve "authentication" --k 10 --synthesize-context
|
|
2033
|
+
Example: agentdb reflexion retrieve "bug-fix" --filters '{"success":true,"reward":{"$gte":0.8}}'
|
|
1085
2034
|
|
|
1086
2035
|
agentdb reflexion critique-summary <task> [only-failures]
|
|
1087
2036
|
Get aggregated critique lessons
|
|
@@ -1109,9 +2058,18 @@ ${colors.bright}DATABASE COMMANDS:${colors.reset}
|
|
|
1109
2058
|
Show database statistics
|
|
1110
2059
|
|
|
1111
2060
|
${colors.bright}HOOKS INTEGRATION COMMANDS:${colors.reset}
|
|
1112
|
-
agentdb query --
|
|
2061
|
+
agentdb query --query <query> [--domain <domain>] [--k <k>] [--min-confidence <conf>] [--format json] [--synthesize-context] [--filters <json>]
|
|
1113
2062
|
Semantic search across stored episodes and patterns
|
|
1114
|
-
|
|
2063
|
+
Options:
|
|
2064
|
+
--query <q> Query string (required)
|
|
2065
|
+
--domain <d> Domain filter (e.g., "successful-edits")
|
|
2066
|
+
--k <n> Number of results (default: 5)
|
|
2067
|
+
--min-confidence <c> Minimum confidence threshold (default: 0.0)
|
|
2068
|
+
--format <f> Output format: json|text (default: json)
|
|
2069
|
+
--synthesize-context Generate coherent summary with patterns and insights
|
|
2070
|
+
--filters <json> MongoDB-style metadata filters
|
|
2071
|
+
Example: agentdb query --query "authentication" --k 5 --min-confidence 0.8 --synthesize-context
|
|
2072
|
+
Example: agentdb query --query "bug-fix" --filters '{"metadata.priority":"high"}' --synthesize-context
|
|
1115
2073
|
|
|
1116
2074
|
agentdb store-pattern --type <type> --domain <domain> --pattern <json> --confidence <conf>
|
|
1117
2075
|
Store a learned pattern for future retrieval
|
|
@@ -1129,6 +2087,23 @@ ${colors.bright}ENVIRONMENT:${colors.reset}
|
|
|
1129
2087
|
AGENTDB_PATH Database file path (default: ./agentdb.db)
|
|
1130
2088
|
|
|
1131
2089
|
${colors.bright}EXAMPLES:${colors.reset}
|
|
2090
|
+
# QUIC Sync: Multi-agent coordination
|
|
2091
|
+
# On server machine:
|
|
2092
|
+
agentdb sync start-server --port 4433 --auth-token secret123
|
|
2093
|
+
|
|
2094
|
+
# On client machines:
|
|
2095
|
+
agentdb sync connect 192.168.1.100 4433 --auth-token secret123
|
|
2096
|
+
agentdb sync push --server 192.168.1.100:4433 --incremental
|
|
2097
|
+
agentdb sync pull --server 192.168.1.100:4433 --incremental
|
|
2098
|
+
agentdb sync status
|
|
2099
|
+
|
|
2100
|
+
# Vector Search: Direct similarity queries
|
|
2101
|
+
agentdb init ./vectors.db --dimension 768 --preset medium
|
|
2102
|
+
agentdb vector-search ./vectors.db "[0.1,0.2,0.3]" -k 10 -m cosine -f json
|
|
2103
|
+
agentdb export ./vectors.db ./backup.json
|
|
2104
|
+
agentdb import ./backup.json ./new-vectors.db
|
|
2105
|
+
agentdb stats ./vectors.db
|
|
2106
|
+
|
|
1132
2107
|
# Reflexion: Store and retrieve episodes
|
|
1133
2108
|
agentdb reflexion store "session-1" "implement_auth" 0.95 true "Used OAuth2"
|
|
1134
2109
|
agentdb reflexion retrieve "authentication" 10 0.8
|