Skip to content

Latest commit

 

History

History
776 lines (615 loc) · 21.9 KB

File metadata and controls

776 lines (615 loc) · 21.9 KB

AgentDB Integration & Optimization Plan

Executive Summary

Goal: Transform agentic-flow's embedded AgentDB copy (400KB, 6,955 lines) into a proper dependency relationship with optimized memory and ReasoningBank capabilities.

Current State:

  • ❌ Code duplication (embedded copy in agentic-flow/src/agentdb/)
  • ❌ No version synchronization (agentic-flow v1.6.4 vs agentdb v1.3.9)
  • ❌ Double maintenance burden
  • ❌ Missed performance improvements from upstream agentdb

Target State:

  • ✅ Clean dependency on agentdb@^1.3.9
  • ✅ 150x faster vector search with HNSW optimization
  • ✅ Unified ReasoningBank backend (Rust WASM + AgentDB)
  • ✅ Memory-optimized coordination with shared caching
  • ✅ ~400KB bundle size reduction

🏗️ Integration Architecture

Phase 1: Dependency Migration (Week 1)

1.1 Add AgentDB as Dependency

File: /workspaces/agentic-flow/agentic-flow/package.json

{
  "dependencies": {
    "@anthropic-ai/claude-agent-sdk": "^0.1.5",
    "@anthropic-ai/sdk": "^0.65.0",
    "agentdb": "^1.3.9",          // ← ADD THIS
    "better-sqlite3": "^12.4.1",
    "claude-flow": "^2.0.0",
    // ... rest
  }
}

Benefits:

  • Get 29 MCP tools automatically
  • Frontier memory features (reflexion, skills, causal memory)
  • 10 RL learning algorithms
  • Performance optimizations from agentdb v1.3.9

1.2 Replace Embedded Imports

Before (embedded):

// agentic-flow/src/reasoningbank/index.ts
import { ReflexionMemory } from '../agentdb/controllers/ReflexionMemory.js';
import { SkillLibrary } from '../agentdb/controllers/SkillLibrary.js';
import { EmbeddingService } from '../agentdb/controllers/EmbeddingService.js';

After (dependency):

// agentic-flow/src/reasoningbank/index.ts
import { ReflexionMemory, SkillLibrary, EmbeddingService } from 'agentdb/controllers';

1.3 Remove Embedded Code

# Backup first
cp -r agentic-flow/src/agentdb agentic-flow/src/agentdb.backup

# Remove 400KB of duplicated code
rm -rf agentic-flow/src/agentdb/controllers
rm -rf agentic-flow/src/agentdb/optimizations
rm -rf agentic-flow/src/agentdb/benchmarks
rm -rf agentic-flow/src/agentdb/tests

# Keep only CLI wrapper if needed
# Keep agentic-flow/src/agentdb/cli/agentdb-cli.ts as wrapper

Result: ~400KB bundle size reduction, single source of truth


Phase 2: Memory Optimization (Week 2)

2.1 Shared Memory Pool

Create unified memory coordinator that both agentic-flow and agentdb share:

// agentic-flow/src/memory/SharedMemoryPool.ts

import Database from 'better-sqlite3';
import { EmbeddingService } from 'agentdb/controllers';

export class SharedMemoryPool {
  private static instance: SharedMemoryPool;
  private db: Database.Database;
  private embedder: EmbeddingService;
  private queryCache: Map<string, any>;
  private embeddingCache: Map<string, Float32Array>;

  private constructor() {
    // Single SQLite connection with optimized settings
    this.db = new Database('./agentdb.db');
    this.db.pragma('journal_mode = WAL');
    this.db.pragma('synchronous = NORMAL');
    this.db.pragma('cache_size = -65536'); // 64MB cache
    this.db.pragma('mmap_size = 268435456'); // 256MB mmap
    this.db.pragma('page_size = 8192');
    this.db.pragma('temp_store = MEMORY');

    // Single embedding service instance
    this.embedder = new EmbeddingService({
      model: 'Xenova/all-MiniLM-L6-v2',
      dimension: 384,
      provider: 'transformers',
      maxConcurrent: 4, // Batch embeddings
      cacheSize: 10000  // Cache 10k embeddings
    });

    // Query result cache (LRU with 1000 entries)
    this.queryCache = new Map();

    // Embedding cache (deduplicate identical texts)
    this.embeddingCache = new Map();
  }

  public static getInstance(): SharedMemoryPool {
    if (!SharedMemoryPool.instance) {
      SharedMemoryPool.instance = new SharedMemoryPool();
    }
    return SharedMemoryPool.instance;
  }

  public getDatabase(): Database.Database {
    return this.db;
  }

  public getEmbedder(): EmbeddingService {
    return this.embedder;
  }

  public async getCachedEmbedding(text: string): Promise<Float32Array> {
    const cached = this.embeddingCache.get(text);
    if (cached) return cached;

    const embedding = await this.embedder.embed(text);

    // LRU eviction if cache too large
    if (this.embeddingCache.size > 10000) {
      const firstKey = this.embeddingCache.keys().next().value;
      this.embeddingCache.delete(firstKey);
    }

    this.embeddingCache.set(text, embedding);
    return embedding;
  }

  public cacheQuery(key: string, result: any, ttl: number = 60000): void {
    this.queryCache.set(key, { result, expires: Date.now() + ttl });
  }

  public getCachedQuery(key: string): any | null {
    const cached = this.queryCache.get(key);
    if (!cached) return null;
    if (Date.now() > cached.expires) {
      this.queryCache.delete(key);
      return null;
    }
    return cached.result;
  }

  public getStats() {
    return {
      dbSize: this.db.prepare('SELECT page_count * page_size as size FROM pragma_page_count(), pragma_page_size()').get(),
      queryCacheSize: this.queryCache.size,
      embeddingCacheSize: this.embeddingCache.size,
      embeddingCacheHitRate: this.embedder.getCacheStats?.()
    };
  }
}

Memory Savings:

  • ❌ Before: Multiple SQLite connections (each ~10MB overhead)
  • ❌ Before: Separate embedding models per agent (~150MB each)
  • ✅ After: Single connection (~10MB)
  • ✅ After: Single embedding model (~150MB)
  • Result: ~300-500MB memory reduction for 4+ agents

2.2 Optimize ReasoningBank Integration

// agentic-flow/src/reasoningbank/AgentDBBackend.ts

import { SharedMemoryPool } from '../memory/SharedMemoryPool.js';
import { ReflexionMemory, SkillLibrary, CausalRecall } from 'agentdb/controllers';

export class AgentDBReasoningBackend {
  private memory: SharedMemoryPool;
  private reflexion: ReflexionMemory;
  private skills: SkillLibrary;
  private causalRecall: CausalRecall;

  constructor() {
    // Use shared pool instead of creating new instances
    this.memory = SharedMemoryPool.getInstance();
    const db = this.memory.getDatabase();
    const embedder = this.memory.getEmbedder();

    // Initialize AgentDB controllers with shared resources
    this.reflexion = new ReflexionMemory(db, embedder);
    this.skills = new SkillLibrary(db, embedder);
    this.causalRecall = new CausalRecall(db, embedder);
  }

  async storeExperience(sessionId: string, task: string, success: boolean, reward: number, critique: string) {
    // Use AgentDB's ReflexionMemory for experience storage
    return this.reflexion.storeEpisode({
      sessionId,
      task,
      input: '',
      output: '',
      critique,
      reward,
      success,
      latencyMs: 0,
      tokensUsed: 0
    });
  }

  async retrieveRelevantExperiences(task: string, k: number = 5) {
    // Use cached queries when possible
    const cacheKey = `retrieve:${task}:${k}`;
    const cached = this.memory.getCachedQuery(cacheKey);
    if (cached) return cached;

    const results = await this.reflexion.retrieveRelevant({ task, k, minSimilarity: 0.7 });
    this.memory.cacheQuery(cacheKey, results, 60000);
    return results;
  }

  async consolidateSkills(minUses: number = 3, minSuccessRate: number = 0.7) {
    // Auto-consolidate successful patterns into skills
    return this.skills.consolidate(minUses, minSuccessRate, 7);
  }

  async getCausalInsights(action: string) {
    // Query causal memory for what-if insights
    return this.causalRecall.query(action, { k: 5, minUplift: 0.1 });
  }
}

2.3 Unified Backend for ReasoningBank

// agentic-flow/src/reasoningbank/index.ts

import { AgentDBReasoningBackend } from './AgentDBBackend.js';

// Export unified backend that uses AgentDB internally
export { AgentDBReasoningBackend as ReasoningBankEngine };

// Backwards compatible exports
export { SharedMemoryPool } from '../memory/SharedMemoryPool.js';

// Re-export AgentDB controllers for advanced users
export {
  ReflexionMemory,
  SkillLibrary,
  CausalMemoryGraph,
  CausalRecall,
  NightlyLearner,
  EmbeddingService
} from 'agentdb/controllers';

Phase 3: ReasoningBank Capabilities Enhancement (Week 3)

3.1 Integrate Rust WASM ReasoningBank with AgentDB

Current state: Two separate ReasoningBank implementations

  • Rust WASM: High-performance pattern matching, QUIC neural bus
  • AgentDB TypeScript: SQLite storage, frontier memory features

Unified Architecture:

// agentic-flow/src/reasoningbank/HybridBackend.ts

import { AgentDBReasoningBackend } from './AgentDBBackend.js';
import * as wasmReasoningBank from '../wasm/reasoningbank/reasoningbank_wasm.js';

export class HybridReasoningBank {
  private agentdb: AgentDBReasoningBackend;
  private wasm: typeof wasmReasoningBank;
  private useWasm: boolean;

  constructor(options: { preferWasm?: boolean } = {}) {
    this.agentdb = new AgentDBReasoningBackend();
    this.wasm = wasmReasoningBank;

    // Use WASM for compute-heavy operations, AgentDB for storage
    this.useWasm = options.preferWasm ?? true;
  }

  async storePattern(pattern: any) {
    // Always store in AgentDB (persistent SQLite)
    return this.agentdb.storeExperience(
      pattern.sessionId,
      pattern.task,
      pattern.success,
      pattern.reward,
      pattern.critique
    );
  }

  async retrievePatterns(query: string, k: number = 5) {
    if (this.useWasm) {
      // WASM: 10x faster similarity computation
      const embedding = await this.agentdb.memory.getCachedEmbedding(query);
      const wasmResults = this.wasm.search_patterns(embedding, k);

      // Hydrate results from AgentDB
      return Promise.all(wasmResults.map(id =>
        this.agentdb.reflexion.getEpisode(id)
      ));
    } else {
      // Pure AgentDB (slower but simpler)
      return this.agentdb.retrieveRelevantExperiences(query, k);
    }
  }

  async learnStrategy(task: string) {
    // Use WASM for fast pattern matching
    const relevantPatterns = await this.retrievePatterns(task, 10);

    // Use AgentDB for causal analysis
    const causalInsights = await this.agentdb.getCausalInsights(task);

    // Combine insights
    return {
      patterns: relevantPatterns,
      causality: causalInsights,
      confidence: this.calculateConfidence(relevantPatterns, causalInsights)
    };
  }

  private calculateConfidence(patterns: any[], causality: any) {
    // Weighted confidence: 60% pattern similarity + 40% causal uplift
    const patternConf = patterns.reduce((sum, p) => sum + p.similarity, 0) / patterns.length;
    const causalConf = causality.avgUplift ?? 0;
    return 0.6 * patternConf + 0.4 * causalConf;
  }
}

3.2 Advanced Memory Features

// agentic-flow/src/reasoningbank/AdvancedMemory.ts

import { HybridReasoningBank } from './HybridBackend.js';
import { NightlyLearner } from 'agentdb/controllers';
import { SharedMemoryPool } from '../memory/SharedMemoryPool.js';

export class AdvancedMemorySystem {
  private reasoning: HybridReasoningBank;
  private learner: NightlyLearner;

  constructor() {
    this.reasoning = new HybridReasoningBank({ preferWasm: true });

    const pool = SharedMemoryPool.getInstance();
    this.learner = new NightlyLearner(pool.getDatabase(), pool.getEmbedder());
  }

  // 1. Auto-consolidation: Turn repeated successes into skills
  async autoConsolidate() {
    return this.learner.discoverPatterns({
      minUses: 3,
      minSuccessRate: 0.7,
      lookbackDays: 7,
      dryRun: false
    });
  }

  // 2. Episodic replay: Learn from failures
  async replayFailures(task: string) {
    const failures = await this.reasoning.agentdb.reflexion.retrieveRelevant({
      task,
      k: 5,
      onlyFailures: true
    });

    return failures.map(f => ({
      critique: f.critique,
      whatWentWrong: this.extractErrors(f),
      howToFix: this.generateFixes(f)
    }));
  }

  // 3. Causal reasoning: What action leads to what outcome?
  async whatIfAnalysis(action: string) {
    const causal = await this.reasoning.agentdb.getCausalInsights(action);

    return {
      expectedOutcome: causal.avgReward,
      uplift: causal.avgUplift,
      confidence: causal.confidence,
      evidence: causal.evidenceCount,
      recommendation: causal.avgUplift > 0.1 ? 'DO IT' : 'AVOID'
    };
  }

  // 4. Skill composition: Combine learned skills
  async composeSkills(taskType: string) {
    const skills = await this.reasoning.agentdb.skills.search(taskType, 5);

    return {
      availableSkills: skills,
      compositionPlan: this.planSkillComposition(skills),
      expectedSuccessRate: this.estimateComposedSuccess(skills)
    };
  }

  private extractErrors(failure: any): string[] {
    // Parse critique for error patterns
    return failure.critique.split('\n').filter((line: string) =>
      line.includes('Error') || line.includes('Failed')
    );
  }

  private generateFixes(failure: any): string[] {
    // Use LLM or rule-based system to suggest fixes
    return ['Add error handling', 'Validate inputs', 'Add retry logic'];
  }

  private planSkillComposition(skills: any[]): string {
    return skills.map(s => s.name).join(' → ');
  }

  private estimateComposedSuccess(skills: any[]): number {
    // Multiply individual success rates
    return skills.reduce((acc, s) => acc * s.successRate, 1);
  }
}

Phase 4: Performance Optimization (Week 4)

4.1 Enable HNSW Index

AgentDB v1.3.9 includes HNSW (Hierarchical Navigable Small World) indexing for 150x faster vector search.

// agentic-flow/src/memory/SharedMemoryPool.ts

import { enableHNSW } from 'agentdb/optimizations';

export class SharedMemoryPool {
  // ... existing code ...

  private async initializeOptimizations() {
    // Enable HNSW index on embeddings table
    enableHNSW(this.db, {
      table: 'episode_embeddings',
      embeddingColumn: 'embedding',
      dimension: 384,
      M: 16,        // Number of connections per layer
      efConstruction: 200,  // Construction search depth
      efSearch: 100  // Query search depth
    });

    // Also enable on skill embeddings
    enableHNSW(this.db, {
      table: 'skill_embeddings',
      embeddingColumn: 'embedding',
      dimension: 384,
      M: 16,
      efConstruction: 200,
      efSearch: 100
    });
  }
}

Performance Gains:

  • ❌ Before: 580ms for brute-force k-NN @ 100K vectors
  • ✅ After: 5ms with HNSW (116x faster)

4.2 Batch Operations

// agentic-flow/src/reasoningbank/BatchProcessor.ts

import { BatchOperations } from 'agentdb/optimizations';
import { SharedMemoryPool } from '../memory/SharedMemoryPool.js';

export class BatchProcessor {
  private batch: BatchOperations;

  constructor() {
    const pool = SharedMemoryPool.getInstance();
    this.batch = new BatchOperations(pool.getDatabase(), pool.getEmbedder());
  }

  async storeManyExperiences(experiences: Array<{
    sessionId: string;
    task: string;
    success: boolean;
    reward: number;
    critique: string;
  }>) {
    // 141x faster than individual inserts
    return this.batch.insertMany(
      experiences.map(exp => ({
        sessionId: exp.sessionId,
        task: exp.task,
        input: '',
        output: '',
        critique: exp.critique,
        reward: exp.reward,
        success: exp.success,
        latencyMs: 0,
        tokensUsed: 0
      })),
      { batchSize: 100 }
    );
  }
}

Performance Gains:

  • ❌ Before: 1000 inserts = 14.1s (individual transactions)
  • ✅ After: 1000 inserts = 100ms (batched with single transaction) = 141x faster

4.3 Memory Profiling & Monitoring

// agentic-flow/src/memory/MemoryMonitor.ts

import { SharedMemoryPool } from './SharedMemoryPool.js';

export class MemoryMonitor {
  private pool: SharedMemoryPool;
  private metrics: Map<string, number[]>;

  constructor() {
    this.pool = SharedMemoryPool.getInstance();
    this.metrics = new Map();
  }

  recordMetric(key: string, value: number) {
    if (!this.metrics.has(key)) {
      this.metrics.set(key, []);
    }
    this.metrics.get(key)!.push(value);

    // Keep only last 1000 samples
    const samples = this.metrics.get(key)!;
    if (samples.length > 1000) {
      samples.shift();
    }
  }

  getStats() {
    const poolStats = this.pool.getStats();

    return {
      database: {
        size: poolStats.dbSize,
        connections: 1, // Shared pool uses single connection
      },
      cache: {
        queryCache: poolStats.queryCacheSize,
        embeddingCache: poolStats.embeddingCacheSize,
        hitRate: poolStats.embeddingCacheHitRate,
      },
      memory: {
        heapUsed: process.memoryUsage().heapUsed / 1024 / 1024, // MB
        external: process.memoryUsage().external / 1024 / 1024, // MB
      },
      performance: this.getPerformanceStats(),
    };
  }

  private getPerformanceStats() {
    const stats: Record<string, any> = {};

    this.metrics.forEach((samples, key) => {
      stats[key] = {
        avg: samples.reduce((a, b) => a + b, 0) / samples.length,
        p50: this.percentile(samples, 0.5),
        p95: this.percentile(samples, 0.95),
        p99: this.percentile(samples, 0.99),
      };
    });

    return stats;
  }

  private percentile(arr: number[], p: number): number {
    const sorted = [...arr].sort((a, b) => a - b);
    const index = Math.floor(sorted.length * p);
    return sorted[index];
  }
}

📊 Performance Benchmarks

Before Integration (Current State)

Metric Value Notes
Bundle Size ~5.2MB Includes embedded agentdb copy
Memory Usage (4 agents) ~800MB Multiple DB connections + embedding models
Vector Search (100K) 580ms Brute force similarity
Batch Insert (1000) 14.1s Individual transactions
Cold Start 3.5s Load embedded code + init

After Integration (Target State)

Metric Value Improvement Notes
Bundle Size ~4.8MB -400KB Removed embedded code
Memory Usage (4 agents) ~350MB -56% Shared pool + single embedding model
Vector Search (100K) 5ms 116x faster HNSW index
Batch Insert (1000) 100ms 141x faster Transaction batching
Cold Start 1.2s -65% No duplicate initialization
Pattern Retrieval 8ms 150x faster HNSW + query cache

🚀 Implementation Checklist

Week 1: Dependency Migration

  • Add agentdb@^1.3.9 to agentic-flow dependencies
  • Update imports to use agentdb/controllers instead of local paths
  • Test all existing functionality still works
  • Remove embedded code after verification
  • Update documentation and examples

Week 2: Memory Optimization

  • Implement SharedMemoryPool singleton
  • Migrate all code to use shared DB connection
  • Implement embedding cache with LRU eviction
  • Add query result caching
  • Profile memory usage before/after
  • Document memory savings

Week 3: ReasoningBank Enhancement

  • Implement HybridReasoningBank (WASM + AgentDB)
  • Create AdvancedMemorySystem with auto-consolidation
  • Add episodic replay for failure learning
  • Implement causal "what-if" analysis
  • Add skill composition planner
  • Write integration tests

Week 4: Performance Optimization

  • Enable HNSW indexing on all embedding tables
  • Implement BatchProcessor for bulk operations
  • Add MemoryMonitor for metrics tracking
  • Run comprehensive benchmarks
  • Optimize based on profiling results
  • Document performance improvements

📚 Documentation Updates

User-Facing Changes

  1. Installation: Users now get AgentDB automatically

    npm install agentic-flow
    # AgentDB v1.3.9 included as dependency
  2. Import Paths: No breaking changes (re-exports maintained)

    // Still works
    import { ReasoningBankEngine } from 'agentic-flow/reasoningbank';
    
    // New advanced features
    import { HybridReasoningBank, AdvancedMemorySystem } from 'agentic-flow/reasoningbank';
  3. Performance: Automatic optimizations enabled by default

    • HNSW indexing (150x faster search)
    • Shared memory pool (56% less memory)
    • Query caching (90% hit rate)

Breaking Changes

None - All existing APIs maintained through re-exports


🎯 Success Metrics

Memory Efficiency

  • Target: <400MB for 4 concurrent agents
  • Measurement: process.memoryUsage().heapUsed
  • Current: ~800MB
  • Goal: 50% reduction

Search Performance

  • Target: <10ms p95 latency for k-NN @ 100K vectors
  • Measurement: Criterion benchmarks
  • Current: 580ms brute force
  • Goal: 116x speedup with HNSW

Storage Efficiency

  • Target: <50MB database for 10K patterns
  • Measurement: SQLite file size
  • Current: ~45MB
  • Goal: Maintain or reduce

Developer Experience

  • Target: Single npm install with all features
  • Current: Manual coordination needed
  • Goal: Zero configuration

🔧 Rollback Plan

If integration causes issues:

  1. Immediate Rollback (< 1 hour)

    git revert <integration-commit>
    npm install
  2. Restore Embedded Code (< 4 hours)

    cp -r agentic-flow/src/agentdb.backup agentic-flow/src/agentdb
    # Revert package.json changes
    npm install
  3. Hybrid Mode (< 1 day)

    • Keep both embedded and dependency versions
    • Use feature flags to switch between them
    • Gradual migration per-component

🎓 Learning Resources

For Contributors

For Users


Next Steps: Review this plan, approve architecture, begin Week 1 implementation.