/** * BM25 scoring layer — mirrors agentdb's TextIndex.searchScored() formula. * * Formula: * idf = log((N - df + 0.5) / (df + 0.5) + 1) * norm = k1 * (1 - b + b * (dl / avgdl)) * termScore = idf * tf * (k1 + 1) / (tf + norm) * docScore = Σ termScore (OR semantics — sum across all query terms) * * Defaults: k1 = 1.2, b = 0.75 (Lucene/agentdb defaults) */ import type { SegmentReader } from "./segment.js"; export interface BM25Opts { k1?: number; b?: number; } export interface ScoredDoc { docId: number; score: number; } /** * Pure BM25 term-score function. Mirrors agentdb's formula exactly. * Returns the contribution of one term to a document's score. * * @param tf - term frequency in the document * @param dl - document length (total token count) * @param df - document frequency (number of docs containing this term) * @param N - total number of documents in the index * @param k1 - term saturation parameter (default 1.2) * @param b - length normalization parameter (default 0.75) * @param avgdl - average document length; falls back to 1 if 0 (empty corpus) */ export declare function bm25Score(tf: number, dl: number, df: number, N: number, k1: number, b: number, avgdl: number): number; /** * BM25 ranker — wraps the boolean query iterators and scores each candidate document. * * Usage: * const ranker = new BM25Ranker({ k1: 1.2, b: 0.75 }); * const results = ranker.score(terms, segments, N, totalLen, limit, "or"); * * Supports two modes: * - "or" (default) — union: every docId matching any term is scored. * - "and" — intersection: only docIds present in every term's posting list. * * The caller must supply `N` (total doc count) and `totalLen` (sum of all doc * lengths) because those statistics live in the manifest, not in individual * segments. The segment readers supply per-term `df` and per-doc `dl`. */ export declare class BM25Ranker { private readonly k1; private readonly b; constructor(opts?: BM25Opts); /** * Score documents matching `terms` using the specified boolean mode. * Returns results sorted by score desc, ties broken by numeric docId ascending. * * @param terms - query terms (pre-tokenized) * @param segments - segment readers to search * @param N - total indexed document count * @param totalLen - sum of all document lengths * @param limit - optional cap on results (applied after sorting) * @param mode - "or" (default) for union, "and" for intersection */ score(terms: string[], segments: readonly SegmentReader[], N: number, totalLen: number, limit?: number, mode?: "and" | "or"): ScoredDoc[]; } //# sourceMappingURL=scoring.d.ts.map