from __future__ import annotations import argparse import json import sys from pathlib import Path from rich import print PROJECT_ROOT = Path(__file__).resolve().parents[2] if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) from tools.rag.common import DB_FILE from tools.rag.search_utils import search_database from tools.retrieval.retrieval_contract import error_result def print_results( query: str, response: dict, ) -> None: results = response["results"] print(f"[bold]Dopyt:[/bold] " f"{query}") print(f"[bold]Vyhľadávač:[/bold] " f"{response['engine']}") print(f"[bold]Stratégie:[/bold] " f"{', '.join(response['strategies']) or 'žiadna'}") print(f"[bold]Počet výsledkov:[/bold] " f"{len(results)}") print("\n[bold]Top výsledky:[/bold]\n") for rank, item in enumerate( results, start=1, ): print( f"[cyan]{rank}. " f"Skóre: {item['score']} " f"(BM25: {item['bm25_score']})" f"[/cyan]" ) print(f"[bold]Názov:[/bold] " f"{item['title']}") print(f"[bold]Cesta:[/bold] " f"{item['document_path']}") print(f"[bold]URL:[/bold] " f"{item['source_url']}") print(f"[bold]Chunk:[/bold] " f"{item['chunk_index']}") print(f"[bold]Zhoda:[/bold] " f"{item['match_strategy']}") print(f"[bold]Kategórie:[/bold] " f"{item['categories']}") print(f"[bold]Tagy:[/bold] " f"{item['tags']}") print(f"[bold]Autor:[/bold] " f"{item['author']}") print(f"[bold]Ukážka:[/bold] " f"{item['snippet']}") print("[bold]Text:[/bold]") print((item["text"] or "")[:700]) print("-" * 80) def main() -> None: parser = argparse.ArgumentParser(description=("FTS5 vyhľadávanie " "v SQLite indexe zpwiki.")) parser.add_argument( "query", nargs="+", help="Text, ktorý sa má vyhľadať.", ) parser.add_argument( "--limit", type=int, default=10, help="Počet výsledkov.", ) parser.add_argument( "--published-only", action="store_true", default=True, help=("Vylúči explicitné published=false (predvolené)."), ) parser.add_argument( "--max-per-document", type=int, default=3, help=("Maximálny počet chunkov " "z jedného dokumentu. " "Hodnota 0 vypne limit."), ) parser.add_argument( "--include-unpublished", action="store_false", dest="published_only", help="Výslovne zahrnie aj nepublikované dokumenty.", ) parser.add_argument( "--json", action="store_true", help="Strojový výstup so spoločným kontraktom." ) args = parser.parse_args() query = " ".join(args.query) try: response = search_database( DB_FILE, query, args.limit, published_only=args.published_only, max_per_document=args.max_per_document, ) except Exception as error: if args.json: sys.stdout.write(json.dumps(error_result(error), ensure_ascii=False, indent=2) + "\n") raise SystemExit(1) from error raise SystemExit(str(error)) from error if args.json: sys.stdout.write(json.dumps(response, ensure_ascii=False, indent=2) + "\n") return print_results( query, response, ) if __name__ == "__main__": main()