Source code for cadrumo.application.corpus_search._retrieval
"""Corpus retrieval: exact citation short-circuit over an FTS5 lexical ranking.The grounding search runs two cooperating retrievers, neither of which needs amodel:* an exact-citation short-circuit — when the query IS a citation id (``ley-58-2003:art-27.2``), it resolves directly through the structured lookup, no ranking needed;* the FTS5 lexical index (:mod:`~application.corpus_search.lexical_index`) for exact and stemmed in-prose recall, ranked by BM25 over the diacritic-folded and Spanish-stemmed columns.The shipped product carries no semantic runtime: nothing here loads anembedding model, computes or consumes vectors, or reaches the network. Semanticrecall re-enters the product, if ever, only as laundered precompiled dataproduced by the dev-side oracle."""from__future__importannotationsfrompathlibimportPathfrom.citation_lookupimportCitationLookupfrom.errorsimportCorpusSearchInputErrorfrom.lexical_indeximportsearch_lexicalfrom.modelsimportRetrievalHit,RetrievalMode,RetrievalResponse
[docs]defrun_retrieval(query:str,*,database_path:Path,citation_lookup:CitationLookup|None=None,limit:int=10,)->RetrievalResponse:"""Run grounding retrieval for ``query`` and return a typed response. Args: query: The free-text query, or an exact citation id. database_path: A lexical index built by ``build_lexical_index``. citation_lookup: Optional catalogue lookup enabling the exact-citation short-circuit. limit: Maximum number of ranked hits to return. Returns: A :class:`RetrievalResponse` — a citation resolution, or the ranked lexical hits. Raises: CorpusSearchInputError: If ``query`` is blank or ``limit`` is not positive. """cleaned=query.strip()ifnotcleaned:raiseCorpusSearchInputError(reason="query_empty",context={"query":query})iflimit<=0:raiseCorpusSearchInputError(reason="limit_not_positive",context={"limit":limit})ifcitation_lookupisnotNoneandcleanedinset(citation_lookup.citation_ids):returnRetrievalResponse(query=cleaned,mode=RetrievalMode.CITATION,citation=citation_lookup.resolve(cleaned),)hits=tuple(RetrievalHit(chunk_id=hit.chunk_id,corpus_ref=hit.corpus_ref,doc_title=hit.doc_title,text=hit.text,score=hit.score,rank=rank,lexical_rank=rank,)forrank,hitinenumerate(search_lexical(database_path,cleaned,limit=limit)))returnRetrievalResponse(query=cleaned,mode=RetrievalMode.LEXICAL_ONLY,hits=hits)