"""Shared configuration — the SINGLE SOURCE OF TRUTH for both build_index.py and app.py. Keeping these constants in one module guarantees the offline corpus and the live query are embedded with the *same* model. If they ever diverge, the query vector and the corpus vectors live in different spaces and every retrieval result is silently wrong. """ # --- Embedding models ---------------------------------------------------------------- # We build & ship artifacts for BOTH models so the Space can switch between them live. # model_key -> (display label, HuggingFace model name). The key is used in artifact # filenames (embeddings_.npy, umap_.joblib, umap_coords_.npy), so keep it # filesystem-safe. Add a model here + rebuild to offer it in the UI. EMBEDDING_MODELS = { "general": ("General — MiniLM-L6 (384-dim)", "sentence-transformers/all-MiniLM-L6-v2"), "biomedical": ("Biomedical — S-PubMedBert (768-dim)", "pritamdeka/S-PubMedBert-MS-MARCO"), } DEFAULT_MODEL_KEY = "general" # --- Reranker (cross-encoder, runtime only) ------------------------------------------ # A cross-encoder scores (query, document) PAIRS jointly — more accurate than the # bi-encoder dense retrieval, but it can't be precomputed, so it only runs on a shortlist. RERANKER_MODEL = "cross-encoder/ms-marco-MiniLM-L-6-v2" # Biomedical alternative: "ncbi/MedCPT-Cross-Encoder" RERANK_CANDIDATES = 30 # size of the hybrid shortlist fed to the reranker # --- Corpus (offline build only) ----------------------------------------------------- # Europe PMC search query. See https://europepmc.org/Help for the query syntax. EUROPE_PMC_QUERY = ( "microRNA AND disease AND HAS_ABSTRACT:Y AND LANG:eng " "AND (FIRST_PDATE:[2018-01-01 TO 2025-12-31])" ) TARGET_N = 4000 # number of abstracts to fetch & index # --- Retrieval ----------------------------------------------------------------------- RRF_K = 60 # Reciprocal Rank Fusion constant (standard default) # --- Paths --------------------------------------------------------------------------- DATA_DIR = "./data"