/** * HybridBackend - Combines SQLite (structured queries) + AgentDB (vector search) * * Per ADR-009: "HybridBackend (SQLite + AgentDB) as default" * - SQLite for: Structured queries, ACID transactions, exact matches * - AgentDB for: Semantic search, vector similarity, RAG * * @module v3/memory/hybrid-backend */ import { EventEmitter } from 'node:events'; import { IMemoryBackend, MemoryEntry, MemoryEntryUpdate, MemoryQuery, SearchOptions, SearchResult, BackendStats, HealthCheckResult, EmbeddingGenerator } from './types.js'; import { SQLiteBackend, SQLiteBackendConfig } from './sqlite-backend.js'; import { AgentDBBackend, AgentDBBackendConfig } from './agentdb-backend.js'; /** * Configuration for HybridBackend */ export interface HybridBackendConfig { /** SQLite configuration */ sqlite?: Partial; /** AgentDB configuration */ agentdb?: Partial; /** Default namespace */ defaultNamespace?: string; /** Embedding generator function */ embeddingGenerator?: EmbeddingGenerator; /** Query routing strategy */ routingStrategy?: 'auto' | 'sqlite-first' | 'agentdb-first'; /** Enable dual-write (write to both backends) */ dualWrite?: boolean; /** Semantic search threshold for hybrid queries */ semanticThreshold?: number; /** Maximum results to fetch from each backend in hybrid queries */ hybridMaxResults?: number; } /** * Structured Query Interface * Optimized for SQLite's strengths */ export interface StructuredQuery { /** Exact key match */ key?: string; /** Key prefix match */ keyPrefix?: string; /** Namespace filter */ namespace?: string; /** Owner filter */ ownerId?: string; /** Type filter */ type?: string; /** Time range filters */ createdAfter?: number; createdBefore?: number; updatedAfter?: number; updatedBefore?: number; /** Pagination */ limit?: number; offset?: number; } /** * Semantic Query Interface * Optimized for AgentDB's vector search */ export interface SemanticQuery { /** Content to search for (will be embedded) */ content?: string; /** Pre-computed embedding */ embedding?: Float32Array; /** Number of results */ k?: number; /** Similarity threshold (0-1) */ threshold?: number; /** Additional filters */ filters?: Partial; } /** * Hybrid Query Interface * Combines structured + semantic search */ export interface HybridQuery { /** Semantic component */ semantic: SemanticQuery; /** Structured component */ structured?: StructuredQuery; /** How to combine results */ combineStrategy?: 'union' | 'intersection' | 'semantic-first' | 'structured-first'; /** Weights for score combination */ weights?: { semantic: number; structured: number; }; } /** * HybridBackend Implementation * * Intelligently routes queries between SQLite and AgentDB: * - Exact matches, prefix queries → SQLite * - Semantic search, similarity → AgentDB * - Complex hybrid queries → Both backends with intelligent merging */ export declare class HybridBackend extends EventEmitter implements IMemoryBackend { private sqlite; private agentdb; private config; private initialized; private stats; constructor(config?: HybridBackendConfig); /** * Initialize both backends */ initialize(): Promise; /** * Shutdown both backends */ shutdown(): Promise; /** * Store in both backends (dual-write for consistency) */ store(entry: MemoryEntry): Promise; /** * Get from AgentDB (has caching enabled) */ get(id: string): Promise; /** * Get by key (SQLite optimized for exact matches) */ getByKey(namespace: string, key: string): Promise; /** * Update in both backends */ update(id: string, update: MemoryEntryUpdate): Promise; /** * Delete from both backends */ delete(id: string): Promise; /** * Query routing - semantic goes to AgentDB, structured to SQLite */ query(query: MemoryQuery): Promise; /** * Structured queries (SQL) * Routes to SQLite for optimal performance */ queryStructured(query: StructuredQuery): Promise; /** * Semantic queries (vector) * Routes to AgentDB for HNSW-based vector search */ querySemantic(query: SemanticQuery): Promise; /** * Hybrid queries (combine both) * Intelligently merges results from both backends */ queryHybrid(query: HybridQuery): Promise; /** * Semantic vector search (routes to AgentDB) */ search(embedding: Float32Array, options: SearchOptions): Promise; /** * Bulk insert to both backends */ bulkInsert(entries: MemoryEntry[]): Promise; /** * Bulk delete from both backends */ bulkDelete(ids: string[]): Promise; /** * Count entries (use SQLite for efficiency) */ count(namespace?: string): Promise; /** * List namespaces (use SQLite) */ listNamespaces(): Promise; /** * Clear namespace in both backends */ clearNamespace(namespace: string): Promise; /** * Get combined statistics from both backends */ getStats(): Promise; /** * Health check for both backends */ healthCheck(): Promise; /** * Auto-route queries based on properties */ private autoRoute; /** * Internal hybrid query implementation */ private queryHybridInternal; /** * Combine results using union (all unique results) */ private combineUnion; /** * Combine results using intersection (only common results) */ private combineIntersection; /** * Semantic-first: Prefer semantic results, add structured if not present */ private combineSemanticFirst; /** * Structured-first: Prefer structured results, add semantic if not present */ private combineStructuredFirst; /** * Record feedback for a memory entry. * Delegates to AgentDB's recordFeedback when available. * Gracefully degrades to a no-op when AgentDB is unavailable. */ recordFeedback(entryId: string, feedback: { score: number; label?: string; context?: Record; }): Promise; /** * Verify a witness chain for a memory entry. * Delegates to AgentDB's verifyWitnessChain when available. */ verifyWitnessChain(entryId: string): Promise<{ valid: boolean; chainLength: number; errors: string[]; }>; /** * Get the witness chain for a memory entry. * Delegates to AgentDB's getWitnessChain when available. */ getWitnessChain(entryId: string): Promise>; /** * Get underlying backends for advanced operations */ getSQLiteBackend(): SQLiteBackend; getAgentDBBackend(): AgentDBBackend; } export default HybridBackend; //# sourceMappingURL=hybrid-backend.d.ts.map