import streamlit as st from core import audit from core.config import BIDDER_NAMES from ui.components import stat_card def render() -> None: # Hero — intentional dark gradient, works as a visual anchor in both modes st.markdown( """
CRPF Hackathon · Theme 3

⚖️ TenderIQ

Explainable AI for Government Tender Evaluation — automated eligibility assessment with criterion-level evidence, three-tier OCR, and a complete compliance audit trail.

""", unsafe_allow_html=True, ) # KPIs criteria_count = len(st.session_state.get("criteria") or []) verdicts = st.session_state.get("verdicts", {}) checked = sum(1 for bv in verdicts.values() for _ in bv) audit_count = len(audit.query()) c1, c2, c3, c4 = st.columns(4) with c1: stat_card(criteria_count, "Criteria Extracted", "#3B82F6") with c2: stat_card(len(verdicts), "Bidders Evaluated", "#22C55E") with c3: stat_card(checked, "Criteria Checked", "#8B5CF6") with c4: stat_card(audit_count, "Audit Entries", "#F59E0B") st.divider() # Pipeline stages st.markdown( '

' 'How it works

', unsafe_allow_html=True, ) stages = [ ("#3B82F6", "rgba(37,99,235,0.08)", "1", "Extract Criteria", "DeepSeek reads the tender PDF and returns structured JSON for each criterion — " "category, mandatory flag, rule, source clause, and query hints."), ("#8B5CF6", "rgba(124,58,237,0.08)", "2", "Three-Tier OCR", "📄 PyMuPDF for typed PDFs · 🔍 Tesseract for scans · 👁 DeepSeek Vision LLM " "when Tesseract confidence < 65%. Every page records its tier and confidence."), ("#22C55E", "rgba(34,197,94,0.08)", "3", "Evaluate per Criterion", "Semantic search retrieves the top-k evidence chunks. DeepSeek returns a verdict " "with combined confidence. Safety rule: borderline not-eligible is always " "downgraded to needs-review."), ("#F59E0B", "rgba(245,158,11,0.08)", "4", "Human Review & Audit", "Flagged verdicts surface with full evidence and source citations. Every action " "is logged to SQLite with timestamp, model version, actor, and payload."), ] cols = st.columns(4) for col, (accent, bg, num, title, body) in zip(cols, stages): with col: st.markdown( f"""
{num}
{title}

{body}

""", unsafe_allow_html=True, ) st.divider() col1, col2 = st.columns(2) with col1: with st.container(border=True): st.markdown("**🚀 Pre-computed Demo**") st.caption("Instantly load realistic results for all 3 bidders — no API key needed.") if st.button("Load Pre-computed Demo", type="primary", use_container_width=True): from core.fallback import load_criteria as lc, load_evaluation criteria = lc() st.session_state["criteria"] = [c.model_dump() for c in criteria] vd: dict = {} for bid in BIDDER_NAMES: vd[bid] = [load_evaluation(bid, c.id).model_dump() for c in criteria] st.session_state["verdicts"] = vd st.success("Loaded — navigate to Bidder Evaluation or Interpretability.") st.rerun() with col2: with st.container(border=True): st.markdown("**⚡ Live Pipeline**") st.caption("Set DEEPSEEK_API_KEY in .env, then use the Tender Analysis tab.") st.info("Sidebar shows 🟢 when the API is reachable.")