/** Tokenise text into lowercase content tokens (drops stopwords + length<3). */ export declare function tokenize(text: string): string[]; export interface CorpusStats { /** docFreq: how many documents contain each token */ df: Map; /** idf: log((N - df + 0.5) / (df + 0.5) + 1) — BM25's smoothed IDF */ idf: Map; /** averageDocumentLength in tokens */ avgDocLen: number; /** total docs in corpus */ N: number; } /** Build BM25 corpus statistics from a set of tokenised documents. */ export declare function buildCorpusStats(tokenisedDocs: string[][]): CorpusStats; /** * Type penalty for meta-commits — multiplies the hybrid score by `factor` * when the document's name matches the meta-commit regex (release bumps, * merge commits, badge updates, etc.). These commits bundle every issue * number from a release window and steal top-1 from real work commits. * * Defaults: factor 0.5, regex covers `chore(release)`, `Merge `, `bump `, * `[Dream Cycle]`, `publish 3.x.y`. Tune via env or call site. */ export declare const META_COMMIT_REGEX: RegExp; export declare function typePenalty(name: string | undefined, factor?: number, regex?: RegExp): number; /** * BM25 score of one document against a query. * Standard Okapi formula with k1=1.5 and b=0.75. */ export declare function bm25Score(queryTokens: string[], docTokens: string[], stats: CorpusStats, k1?: number, b?: number): number; /** * Min-max normalise a score vector to [0, 1]. * Returns the original vector if it is constant (avoid divide-by-zero). */ export declare function normalise(scores: number[]): number[]; /** * Combine cosine and BM25 scores. Both vectors must be aligned by docIndex. * Returns hybridScores[] aligned to the same index. * alpha controls the cosine weight; (1-alpha) is the BM25 weight. */ export declare function hybridScores(cosine: number[], bm25: number[], alpha?: number): number[]; /** * Multi-field BM25 score — treats subject and body as separate fields with * independent token frequencies, then combines `subjectWeight * subjectBM25 * + bodyWeight * bodyBM25`. Subject (commit title / pattern name) carries * the high-signal tokens (file names, action verbs, ADR refs); body is * often boilerplate. Default 3:1 weight reflects that asymmetry. * * Caller must build separate CorpusStats for subjects and bodies (their * IDF distributions differ — subjects are short, bodies long). */ export declare function multiFieldBM25(queryTokens: string[], subjectTokens: string[], bodyTokens: string[], subjectStats: CorpusStats, bodyStats: CorpusStats, subjectWeight?: number, bodyWeight?: number): number; /** * Cosine similarity between two equal-length numeric vectors. * Returns 0 if either has zero norm. */ export declare function cosineSim(a: number[], b: number[]): number; /** * Maximal Marginal Relevance rerank. * * Greedy selection: at each step pick the candidate that maximises * lambda * relevance(c) - (1-lambda) * max(similarity(c, picked)) * * lambda=1.0 → pure relevance (no diversity adjustment) * lambda=0.0 → pure diversity * * Default lambda=0.5 balances both. */ export declare function mmrRerank(candidates: Array, k: number, lambda?: number): Array; //# sourceMappingURL=hybrid-retrieval.d.ts.map