/** * Corpus search dispatcher — picks the retrieval strategy and returns * ranked hits with a stable tie-break. No synthesis here: the answer * flagship builds on top of this. * * Modes: * - semantic : dense cosine only (pre-slice-3 behavior) * - lexical : BM25 only, never calls embed * - hybrid : RRF-fused semantic + lexical, default mode * - fact : hybrid + exact-substring boost + short-chunk preference * - title_path : pure metadata (lexical with body weight = 0), no embed * * Mode choice controls whether the query is embedded at all; `lexical` * and `title_path` skip the embed round-trip entirely, so the model * mismatch check only fires on modes that actually touch the embed rail. * * Tie-break: score desc, then (path asc, chunk_index asc). Zero-score * chunks are dropped before top_k slicing. */ import type { OllamaClient } from "../ollama.js"; import type { ChunkType } from "./chunker.js"; import type { CorpusFile } from "./storage.js"; export type SearchMode = "semantic" | "lexical" | "hybrid" | "fact" | "title_path"; export declare const DEFAULT_SEARCH_MODE: SearchMode; export declare const SEARCH_MODES: readonly SearchMode[]; export interface CorpusHit { id: string; path: string; score: number; chunk_index: number; char_start: number; char_end: number; heading_path: string[]; chunk_type: ChunkType; title: string | null; preview?: string; } export interface SearchParams { corpus: CorpusFile; query: string; model: string; mode?: SearchMode; top_k?: number; preview_chars?: number; client: OllamaClient; } /** * True iff the query is null, empty, or whitespace-only. Every search mode * needs a query with at least one non-whitespace character — BM25 and the * embed tier both return meaningless results for whitespace. Rather than * silently returning 0 hits (which looks indistinguishable from "no * matches"), callers get a fast-path empty result and the tool layer * annotates the envelope so the user sees WHY retrieval was zero. */ export declare function isEmptyQuery(query: string | null | undefined): boolean; export declare function searchCorpus(params: SearchParams): Promise; //# sourceMappingURL=searcher.d.ts.map