/** * Local Vector Search Service * * Provides consistent, local semantic search using: * - OpenRouter API for query embeddings (same model as ww-mcp) * - Pure JavaScript cosine similarity (no native dependencies) * - In-memory scar index (loaded once from Supabase) * * Solves the 500-employees-at-8AM problem: * - No Supabase contention (data loaded once at startup) * - Deterministic results (same model + same data = same results) * - Per-container consistency (each loads same data) * * Cache consistency */ import type { Project, RelevantScar } from "../types/index.js"; interface ScarRecord { id: string; title: string; learning_type?: string; description: string; severity: string; counter_arguments?: string[]; project?: string; embedding?: number[]; decay_multiplier?: number; why_this_matters?: string; action_protocol?: string[]; self_check_criteria?: string[]; } /** * Cache metadata for staleness detection */ export interface CacheMetadata { loadedAt: Date; scarCount: number; latestUpdatedAt: string | null; ageMinutes: number; isStale: boolean; } /** * LocalVectorSearch class * * Manages an in-memory index for fast, consistent scar search. * Uses pure JavaScript - no native dependencies. */ export declare class LocalVectorSearch { private scars; private initialized; private initPromise; private project; private loadedAt; private latestUpdatedAt; private staleTtlMinutes; constructor(project?: Project); /** * Set cache TTL for staleness detection */ setTtlMinutes(minutes: number): void; /** * Initialize the search index with scars from Supabase */ initialize(scars: ScarRecord[], latestUpdatedAt?: string): Promise; /** * Force re-initialization with new scars (for flush/refresh) */ reinitialize(scars: ScarRecord[], latestUpdatedAt?: string): Promise; private _doInitialize; /** * Check if the index is ready for queries */ isReady(): boolean; /** * Get the number of indexed scars */ getScarCount(): number; /** * Search for scars similar to the query * * Returns consistent results: same query = same results every time */ search(query: string, k?: number): Promise; /** * Generate embedding for text using the shared embedding service. * Supports multiple providers (OpenAI, OpenRouter, Ollama) via auto-detection. */ private _embed; /** * Clear the index and release memory */ clear(): void; /** * Get cache metadata for status/health checks */ getCacheMetadata(): CacheMetadata | null; /** * Get the latest updated_at timestamp from loaded scars */ getLatestUpdatedAt(): string | null; } /** * Get the LocalVectorSearch instance (unified, cross-project) */ export declare function getLocalVectorSearch(_project?: Project): LocalVectorSearch; /** * Initialize local vector search with scars from Supabase * * Call this once at startup with pre-fetched scars */ export declare function initializeLocalSearch(scars: ScarRecord[], _project?: Project, latestUpdatedAt?: string): Promise; /** * Reinitialize local search (for cache flush/refresh) */ export declare function reinitializeLocalSearch(scars: ScarRecord[], _project?: Project, latestUpdatedAt?: string): Promise; /** * Search for scars using local vector search * * Falls back to empty results if not initialized */ export declare function localScarSearch(query: string, k?: number, _project?: Project): Promise; /** * Check if local search is ready */ export declare function isLocalSearchReady(_project?: Project): boolean; /** * Get cache metadata for a project */ export declare function getCacheMetadata(_project?: Project): CacheMetadata | null; /** * Set cache TTL for a project */ export declare function setCacheTtl(minutes: number, _project?: Project): void; /** * Clear the local search index */ export declare function clearLocalSearch(_project?: Project): void; export {}; //# sourceMappingURL=local-vector-search.d.ts.map