UNPKG

@codai/cbd

Version:

Codai Better Database - High-Performance Vector Memory System with HPKV-inspired architecture and MCP server

151 lines 5.35 kB
/** * CBD Vector Store Implementation * High-performance vector storage and similarity search */ export class FaissVectorStore { index; // Will be initialized with faiss-node metadata = new Map(); dimensions; initialized = false; constructor(dimensions = 1536) { this.dimensions = dimensions; } async initialize() { try { // For now, use the in-memory vector store until FAISS integration is properly set up this.index = new InMemoryVectorIndex(this.dimensions); console.log(`🔍 Initialized in-memory vector store with ${this.dimensions} dimensions`); this.initialized = true; } catch (error) { console.error('Failed to initialize vector store:', error); this.index = new InMemoryVectorIndex(this.dimensions); this.initialized = true; } } async addVector(id, vector, metadata) { if (!this.initialized) await this.initialize(); if (vector.length !== this.dimensions) { throw new Error(`Vector dimension mismatch: expected ${this.dimensions}, got ${vector.length}`); } try { if (this.index.add) { // FAISS implementation this.index.add(vector); } else { // Fallback implementation this.index.addVector(id, vector); } if (metadata) { this.metadata.set(id, metadata); } } catch (error) { throw new Error(`Failed to add vector ${id}: ${error}`); } } async searchSimilar(queryVector, options = {}) { if (!this.initialized) await this.initialize(); const { topK = 10, minScore = 0.0, includeMetadata = true } = options; if (queryVector.length !== this.dimensions) { throw new Error(`Query vector dimension mismatch: expected ${this.dimensions}, got ${queryVector.length}`); } try { let results = []; if (this.index.search) { // FAISS implementation const searchResults = this.index.search(queryVector, topK); results = searchResults.labels.map((label, index) => ({ id: label.toString(), score: searchResults.distances[index], metadata: includeMetadata ? this.metadata.get(label.toString()) : undefined })); } else { // Fallback implementation results = this.index.search(queryVector, topK, minScore); if (includeMetadata) { results = results.map(result => ({ ...result, metadata: this.metadata.get(result.id) || undefined })); } } return results.filter(r => r.score >= minScore); } catch (error) { throw new Error(`Vector search failed: ${error}`); } } async removeVector(id) { if (!this.initialized) await this.initialize(); try { this.metadata.delete(id); // Note: FAISS doesn't support easy removal, would need index rebuilding // For now, just remove metadata return true; } catch (error) { console.error(`Failed to remove vector ${id}:`, error); return false; } } async getVector(_id) { if (!this.initialized) await this.initialize(); // This would require storing vectors separately for retrieval // FAISS doesn't provide easy vector retrieval by ID return null; } } /** * Fallback in-memory vector store for when FAISS is not available */ class InMemoryVectorIndex { vectors = new Map(); dimensions; constructor(dimensions) { this.dimensions = dimensions; console.log(`📋 Initialized in-memory vector index with ${dimensions} dimensions`); } addVector(id, vector) { this.vectors.set(id, vector); } search(queryVector, topK, minScore = 0.0) { const results = []; for (const [id, vector] of this.vectors.entries()) { const score = this.cosineSimilarity(queryVector, vector); if (score >= minScore) { results.push({ id, score, metadata: undefined }); } } return results .sort((a, b) => b.score - a.score) .slice(0, topK); } cosineSimilarity(a, b) { if (a.length !== b.length || a.length !== this.dimensions) return 0; let dotProduct = 0; let normA = 0; let normB = 0; for (let i = 0; i < a.length; i++) { const aVal = a[i]; const bVal = b[i]; if (aVal !== undefined && bVal !== undefined) { dotProduct += aVal * bVal; normA += aVal * aVal; normB += bVal * bVal; } } if (normA === 0 || normB === 0) return 0; return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); } } export { InMemoryVectorIndex }; //# sourceMappingURL=VectorStore.js.map