Spaces:
Sleeping
Sleeping
Commit History
-
Add hybrid retrieval (TF-IDF + embeddings), OCR, A/B eval, and answer trust/UX
Aissugur Kurganbekov +1: Claude Opus 4.8Smarter retrieval: - Hybrid dense+lexical retrieval: fuse TF-IDF with fastembed vectors via Reciprocal Rank Fusion (retrieval.hybrid_rank), wired into answering. The abstention gate still runs on TF-IDF so grounding stays conservative. Graceful fallback to pure TF-IDF when fastembed/the model is unavailable. - Store chunk vectors on Chunk.embedding (new column); idempotent ensure_schema() migration adds it to existing SQLite DBs on startup. - OCR fallback for scanned/image PDFs (PyMuPDF + pytesseract), graceful when the Tesseract binary is absent; tesseract-ocr added to the Docker image. - A/B eval harness (app.ab_eval / eval_cli --ab) comparing TF-IDF vs hybrid. Answer trust / UX: - answer_question now returns answer metadata (confidence, question_type, top_score, term coverage, chunk counts, latency); AskResponse.metadata and Citation.match_text added. - Frontend: confidence meter, exact source-span highlighting, and a printable one-page evidence report. Verified: 4…f65a6b3
-
Harden FlashRank reranking (review-driven) and wire it into the image
Aissugur Kurganbekov +1: Claude Opus 4.8Adversarial multi-agent review follow-up to the second-stage reranker: - answering.py: pool_k = max(TOP_K, RERANK_CANDIDATES) so a mis-set RERANK_CANDIDATES can never shrink the abstention gate's top-K (the abstention decision stays provably on the TF-IDF top-K). - reranking.py: guard the one-time, network-bound ranker construction with a double-checked threading.Lock — concurrent first /ask requests no longer race into two parallel model downloads; bounds-check the result->chunk remap so a changed flashrank result schema can't IndexError. - Dockerfile: flashrank ships via requirements.txt; keep the optional LLM SDKs (openai/anthropic) explicit. Verified: 28 tests pass; golden eval unchanged (7/7, 100% citation coverage, 0 unsupported, evidence-match 1.0); proved enabled-without-flashrank cites the identical set as a no-rerank build, so abstention and eval are preserved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>1b671d1 -
Add single-container build for Hugging Face Spaces deploy
Aissugur Kurganbekov +1: Claude Opus 4.8One image where FastAPI serves both the built React app and the API, so the app runs on a single port with one public URL (no CORS, no laptop). - app/server.py: parent app that mounts the existing API under /api and serves the Vite build (copied to ./static) at /. Tests, local dev, and the existing two-container docker-compose are untouched. - Dockerfile (repo root): multi-stage — build the frontend, then a Python image that serves it via app.server:root on port 7860, as UID 1000. - README front-matter (sdk: docker, app_port: 7860) so HF Spaces builds it. - .dockerignore + gitignore the local backend/static build artifact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>81e0253