/** * BetterSqlite3Backend - Native SQLite with FTS5 Trigram and sqlite-vec * * Production-grade backend using better-sqlite3 (native SQLite). * Provides: * - FTS5 with trigram tokenizer for CJK (Japanese, Chinese, Korean) * - BM25 ranking for relevance scoring * - sqlite-vec for persisted vector search (no rebuild on startup) * - 10x faster than sql.js for large datasets * - Proper word segmentation for all languages * * Requires: * - Node.js environment (no browser support) * - npm install better-sqlite3 sqlite-vec * * @module @agentkits/memory/better-sqlite3-backend */ import { EventEmitter } from 'node:events'; import type Database from 'better-sqlite3'; import { IMemoryBackend, MemoryEntry, MemoryEntryUpdate, MemoryQuery, SearchOptions, SearchResult, BackendStats, HealthCheckResult, EmbeddingGenerator } from './types.js'; /** * Configuration for BetterSqlite3 Backend */ export interface BetterSqlite3BackendConfig { /** Path to SQLite database file (:memory: for in-memory) */ databasePath: string; /** Enable query optimization and WAL mode */ optimize: boolean; /** Default namespace */ defaultNamespace: string; /** Embedding generator for semantic search */ embeddingGenerator?: EmbeddingGenerator; /** Maximum entries before auto-cleanup */ maxEntries: number; /** Enable verbose logging */ verbose: boolean; /** * FTS5 tokenizer to use * - 'trigram': Best for CJK (Japanese, Chinese, Korean) - works with all languages * - 'unicode61': Standard tokenizer, good for English/Latin * - 'porter': Stemming for English */ ftsTokenizer: 'trigram' | 'unicode61' | 'porter'; /** Path to custom SQLite extension (e.g., lindera for advanced Japanese) */ extensionPath?: string; /** Custom tokenizer name when using extension (e.g., 'lindera_tokenizer') */ customTokenizer?: string; /** Enable sqlite-vec for vector search (default: true) */ enableVectorSearch?: boolean; /** Vector dimensions for sqlite-vec (default: 384) */ vectorDimensions?: number; } /** * BetterSqlite3 Backend for Production Memory Storage * * Features: * - Native SQLite performance (10x faster than sql.js) * - FTS5 with trigram tokenizer for CJK language support * - BM25 relevance ranking * - WAL mode for concurrent reads * - Optional extension loading (lindera, ICU, etc.) */ export declare class BetterSqlite3Backend extends EventEmitter implements IMemoryBackend { private config; private db; private initialized; private ftsAvailable; private vectorAvailable; private stats; constructor(config?: Partial); /** * Initialize the BetterSqlite3 backend */ initialize(): Promise; /** * Create the database schema */ private createSchema; /** * Create FTS5 virtual table with appropriate tokenizer */ private createFtsTable; /** * Get the active tokenizer being used */ getActiveTokenizer(): string; /** * Check if FTS5 is available and CJK optimized */ isFtsAvailable(): boolean; /** * Check if CJK is optimally supported (trigram or lindera) */ isCjkOptimized(): boolean; /** * Check if vector search is available (sqlite-vec loaded) */ isVectorAvailable(): boolean; /** * Initialize sqlite-vec extension and create vector table */ private initializeSqliteVec; /** * Shutdown the backend */ shutdown(): Promise; /** * Store a memory entry */ store(entry: MemoryEntry): Promise; /** * Retrieve a memory entry by ID */ get(id: string): Promise; /** * Retrieve a memory entry by key within a namespace */ getByKey(namespace: string, key: string): Promise; /** * Update a memory entry */ update(id: string, update: MemoryEntryUpdate): Promise; /** * Delete a memory entry */ delete(id: string): Promise; /** * Query memory entries */ query(query: MemoryQuery): Promise; /** * Full-text search using FTS5 */ searchFts(query: string, options?: { namespace?: string; limit?: number; }): Promise; /** * LIKE-based search fallback */ private searchLike; /** * Sanitize query for FTS5 */ private sanitizeFtsQuery; /** * Semantic vector search using sqlite-vec (KNN) or brute-force fallback */ search(embedding: Float32Array, options: SearchOptions): Promise; /** * Fast KNN search using sqlite-vec */ private searchWithSqliteVec; /** * Brute-force vector search fallback */ private searchBruteForce; /** * Calculate cosine similarity between two vectors */ private cosineSimilarity; /** * Bulk insert entries */ bulkInsert(entries: MemoryEntry[]): Promise; /** * Bulk delete entries */ bulkDelete(ids: string[]): Promise; /** * Get entry count */ count(namespace?: string): Promise; /** * List all namespaces */ listNamespaces(): Promise; /** * Clear all entries in a namespace */ clearNamespace(namespace: string): Promise; /** * Get backend statistics */ getStats(): Promise; /** * Perform health check */ healthCheck(): Promise; /** * Get the underlying database for advanced operations */ getDatabase(): Database.Database | null; /** * Rebuild FTS index */ rebuildFtsIndex(): Promise; /** * Convert database row to MemoryEntry */ private rowToEntry; /** * Migrate existing embeddings to sqlite-vec index. * Call this to index entries that have embeddings but are not yet in the vector index. * * @returns Number of entries migrated */ migrateEmbeddingsToVec(): Promise<{ migrated: number; skipped: number; errors: number; }>; /** * Check if migration is needed (entries with embeddings not in sqlite-vec) */ needsMigration(): Promise<{ needed: boolean; count: number; }>; } /** * Create a BetterSqlite3 backend with default CJK support */ export declare function createBetterSqlite3Backend(config?: Partial): BetterSqlite3Backend; /** * Create a BetterSqlite3 backend with lindera extension for advanced Japanese */ export declare function createJapaneseOptimizedBackend(config: Partial & { linderaPath: string; }): BetterSqlite3Backend; export default BetterSqlite3Backend; //# sourceMappingURL=better-sqlite3-backend.d.ts.map