/** * Phase 3: Hybrid Search Engine — vector embedding layer + RRF fusion. * * This module provides: * - **Symbol embeddings**: a lightweight character n-gram TF-IDF representation * of each symbol's text (name + signature + doc comment), producing a fixed * 384-dimensional float32 vector. No native deps (no ONNX runtime). Designed * to be swapped for a real transformer embedding model in a future phase * without changing the storage or fusion interface. * - **Cosine similarity**: ranks symbols by vector proximity to a query vector. * - **Reciprocal Rank Fusion (RRF)**: merges the ranked lists from BM25/FTS5 * trigram search and vector search into a single result set. * * The RRF formula (k=60, following the original Cormack et al. 2009 paper): * RRF_Score(d) = 1/(k + Rank_BM25(d)) + 1/(k + Rank_Vector(d)) * where a missing rank from either source is treated as infinity (contributes 0). */ /** The constant k in the RRF formula — the standard value from the literature. */ export declare const RRF_K = 60; /** * P4.11: opt-in gate for the vector embedding layer. Default OFF. * * The 384-dim char-trigram embedding is lexical similarity — it duplicates * what the FTS5 trigram tokenizer already provides — while costing ~1.5 KB * of BLOB per symbol on every insert and an embedText() pass per symbol even * when the table is unavailable. With the gate off, ranking is BM25/FTS-only * (identical result set; the vector layer only re-ordered FTS candidates). * Set WRONGSTACK_INDEX_VECTORS=1 to restore the hybrid RRF path; a force * reindex repopulates the table for pre-existing symbols. */ export declare function vectorEmbeddingEnabled(): boolean; /** Fixed vector dimensionality. 384 matches the proposal's spec. */ export declare const VECTOR_DIMENSIONS = 384; /** * Compute a fixed-dimensional embedding of a text string using character * n-gram hashing (the "hashing trick"). * * Each n-gram is hashed to a bucket in [0, VECTOR_DIMENSIONS). The bucket's * float32 value is incremented by the n-gram's term frequency. After all * n-grams are counted, the vector is L2-normalized so cosine similarity * reduces to a dot product. * * This is NOT a semantic embedding — it captures **lexical similarity** * (shared substrings). A real embedding model would be dropped in here * without changing the storage or fusion interface. */ export declare function embedText(text: string): Float32Array; /** Cosine similarity between two L2-normalized vectors (reduces to dot product). */ export declare function cosineSimilarity(a: Float32Array, b: Float32Array): number; /** Serialize a Float32Array to a Buffer for SQLite BLOB storage. */ export declare function encodeVector(vec: Float32Array): Buffer; /** Deserialize a BLOB from SQLite back to a Float32Array. */ export declare function decodeVector(buf: Buffer | Uint8Array): Float32Array; /** * Rank map: symbolId → rank (0-based). Lower rank = more relevant. * Built from a search result list (already sorted by relevance). */ type RankMap = Map; /** Build a RankMap from a sorted result list. */ export declare function buildRankMap(sortedIds: number[]): RankMap; /** * Reciprocal Rank Fusion — merge two ranked lists into a single fused ranking. * * Each symbol's RRF score is the sum of 1/(k + rank) from each source. * Symbols only in one list still contribute 1/(k + rank) from that source. * Symbols in neither list are absent from the output. * * @param bm25Ranks - rank map from BM25/FTS5 trigram search * @param vectorRanks - rank map from vector similarity search * @param k - the RRF constant (default 60, per Cormack et al.) * @returns sorted [symbolId, rrfScore] pairs, descending by score */ export declare function reciprocalRankFusion(bm25Ranks: RankMap, vectorRanks: RankMap, k?: number): Array<[number, number]>; export {}; //# sourceMappingURL=vector-search.d.ts.map