TenderIQ / README.md
JaydeepR's picture
Add HuggingFace Space, YouTube, and GitHub links to README
c7cacf2
metadata
title: TenderIQ
emoji: ⚖️
colorFrom: blue
colorTo: indigo
sdk: docker
pinned: true
license: agpl-3.0
short_description: Explainable AI for Government Tender Evaluation

TenderIQ — Explainable AI for Tender Evaluation

Built for the CRPF Hackathon, Theme 3 — AI-Based Tender Evaluation and Eligibility Analysis for Government Procurement

Demo GitHub Video

TenderIQ automates the eligibility evaluation of bidders against government tender criteria. It extracts structured criteria from any tender PDF, processes bidder documents through a three-tier OCR pipeline, evaluates each (bidder × criterion) pair using a language model with combined confidence scoring, and surfaces ambiguous cases for human review — all with a complete, exportable audit trail.


The Problem

A procurement committee today manually reads hundreds of pages of tender documents and bidder submissions, cross-checks financial statements, certificates, and project records, and decides whether each bidder meets each criterion. For one tender this can take 3–5 days. Two evaluators regularly reach different conclusions on the same documents. There is no consistent audit trail.

TenderIQ reduces this to minutes, with every decision traceable to a specific document, page, and model version.


Key Features

Feature Detail
Criterion extraction DeepSeek LLM reads the tender PDF and returns each criterion as structured JSON — category, mandatory flag, threshold rule, source clause, and retrieval query hints
Three-tier OCR PyMuPDF for typed PDFs → Tesseract for scans → DeepSeek Vision LLM when Tesseract confidence < 65%. Every page records which tier read it
Semantic evidence retrieval sentence-transformers all-MiniLM-L6-v2 indexes all bidder document chunks; top-k retrieval feeds the evaluator
Safety threshold rule A borderline not_eligible verdict at medium confidence (0.55–0.80) is automatically downgraded to needs_review — never silent disqualification
Human review queue Flagged verdicts surface with full evidence, source snippet, and OCR tier badge. Officers Approve / Edit & Approve / Reject with one click
Interpretability tab Plain-English per-criterion breakdown with inline PDF page previews and an LLM-powered Q&A ("Why was this bidder rejected?")
Audit log Every action — extraction, OCR invocation, evaluation, human review — logged to SQLite with timestamp, model version, actor, and payload. CSV export
Pre-computed fallback If the API is unavailable, pre-computed JSON is served transparently. Sidebar shows an amber dot. Demo always works

Quick Start

Without an API key (pre-computed demo)

git clone <repo-url> && cd TenderIQ
pip install -r requirements.txt
streamlit run app.py

Open http://localhost:8501, go to the Overview tab, and click Load Pre-computed Demo. All tabs populate instantly with realistic results for three mock bidders.

With a live API key

cp .env.example .env
# Edit .env and set: DEEPSEEK_API_KEY=your_key_here
streamlit run app.py

The sidebar turns 🟢. Then:

  1. Tender Analysis → select a tender (mock or real CRPF tender) → Extract Criteria
  2. Remove any criteria you don't want evaluated using the × button
  3. Bidder EvaluationRun Evaluation
  4. Review flagged verdicts in Human Review
  5. Export the full activity log from Audit Log

Tesseract (for OCR on scanned documents)

# Linux / Streamlit Cloud — handled automatically via packages.txt
apt install tesseract-ocr poppler-utils

# Windows
# Download installer from https://github.com/UB-Mannheim/tesseract/wiki
# Add to PATH, then restart the app

Tesseract is optional. If unavailable, the OCR pipeline falls through to the DeepSeek Vision LLM tier.


Demo Scenarios

Three mock bidders are included, each designed to exercise a different path through the pipeline:

Bidder Company Outcome Why
Bidder A Apex Constructions Pvt. Ltd. ✅ Eligible All 4 mandatory criteria met, typed PDFs, high confidence
Bidder B BuildRight Enterprises ❌ Not Eligible C1 fails — average turnover INR 1.5 Cr vs 5 Cr threshold
Bidder C Shree Constructions & Services ⚠️ Needs Review Turnover certificate submitted as a blurry, rotated scan — Tesseract confidence ~55% triggers Vision LLM; combined confidence routes to human review

Two real CRPF tenders from crpf.gov.in are also included in data/tender/real_tenders/ for live testing.


Architecture

Tender PDF ──► DeepSeek LLM ──► Criteria (JSON)
                                      │
Bidder Docs ──► 3-tier OCR ──► Chunks ──► Vector Index
                │                              │
                │                    semantic search
                │                              │
                └──────────────► DeepSeek LLM (evaluate)
                                      │
                            combined confidence
                                      │
                        ┌─────────────┴─────────────┐
                    eligible /                 needs_review
                  not_eligible              ──► Human Review Queue
                        │                              │
                        └──────────── Audit Log ───────┘

Full module documentation: ARCHITECTURE.md


Project Structure

TenderIQ/
├── app.py                        # Streamlit entry point, 6 tabs, sidebar
├── core/
│   ├── config.py                 # Constants, paths, thresholds
│   ├── schemas.py                # Pydantic: Criterion, Evidence, Verdict, AuditEntry
│   ├── prompts.py                # LLM prompt strings
│   ├── llm_client.py             # DeepSeek wrapper — chat_json, chat_vision, LLMUnavailable
│   ├── pdf_utils.py              # PyMuPDF: extract_pages, render_page_to_image
│   ├── ocr_pipeline.py           # 3-tier OCR orchestrator with MD5 cache
│   ├── chunker.py                # Tender and bidder document chunking
│   ├── vectorstore.py            # In-memory vector store (sentence-transformers + BM25 fallback)
│   ├── criteria_extractor.py     # Stage 1: tender PDF → List[Criterion]
│   ├── bidder_processor.py       # Stage 2: bidder docs → indexed chunks
│   ├── evaluator.py              # Stage 3: per-criterion verdict + confidence
│   ├── audit.py                  # SQLite audit log
│   └── fallback.py               # Pre-computed JSON fallback
├── ui/
│   ├── tab_overview.py           # Hero, KPIs, pipeline diagram, demo CTA
│   ├── tab_tender.py             # Upload tender, extract + discard criteria
│   ├── tab_bidders.py            # Evaluation table with bidder toggles
│   ├── tab_review.py             # Human review queue — Approve / Edit / Reject
│   ├── tab_audit.py              # Audit log table + CSV export
│   ├── tab_interpretability.py   # Plain-English breakdown + LLM Q&A
│   ├── components.py             # Shared HTML badge/pill/bar components
│   └── styles.py                 # Global CSS injection
├── data/
│   ├── tender/                   # Mock tender PDF + real CRPF tenders
│   ├── bidders/                  # Mock bidder documents (A, B, C)
│   └── precomputed/              # Fallback JSON (criteria + verdicts)
├── scripts/
│   ├── generate_mock_data.py     # Generates all mock PDFs and noisy scan
│   ├── precompute_results.py     # Runs full pipeline, saves fallback JSON
│   ├── generate_deck.py          # Generates pitch deck PDF
│   └── smoke_test.py             # 43-check end-to-end test, exits 0
├── specs/                        # Per-module spec documents
├── deck/                         # Pitch deck PDF
└── ARCHITECTURE.md               # Full architecture reference

Running the Smoke Test

python scripts/smoke_test.py

43 checks covering imports, config, schemas, PDF utils, OCR pipeline, fallback, audit, evaluator threshold logic, and precomputed files. Exits 0 on success (~10 seconds, no API key needed).


Tech Stack

Component Technology
UI & orchestration Streamlit 1.39
LLM (criteria extraction + evaluation) DeepSeek API via OpenAI SDK
OCR Tier 1 PyMuPDF 1.24
OCR Tier 2 Tesseract (pytesseract)
OCR Tier 3 DeepSeek Vision LLM
Semantic retrieval sentence-transformers 2.7 (all-MiniLM-L6-v2)
Data validation Pydantic v2
Audit log SQLite
Mock data generation ReportLab + Pillow + NumPy

Future Work

The current build is scoped to the hackathon prototype. Directions for production:

  • Multi-tender workspace — evaluate the same pool of bidders against multiple tenders simultaneously, with a unified eligibility matrix
  • GeM portal integration — pull live tenders directly from the Government e-Marketplace API instead of uploading PDFs
  • Automated bidder ranking — weighted scoring across criteria to produce an ordered shortlist, not just pass/fail
  • LayoutLM for complex tables — better structured extraction from financial statements with multi-column layouts and merged cells
  • Multi-evaluator workflow — role-based access (Evaluator / Reviewer / Approver) with parallel review and conflict resolution
  • Review queue notifications — email or SMS alerts when verdicts are flagged, so officers don't need to poll the app
  • Bulk bidder upload — ZIP/folder upload for large tenders with many bidders, with background processing and progress tracking
  • Audit export for compliance — structured PDF report per tender, formatted for submission to procurement oversight bodies

Notes

  • PyMuPDF (AGPL) — used under AGPL; acceptable for hackathon use.
  • No auth / multi-user — single hardcoded officer identity in audit entries. Out of scope for this prototype.
  • First run — sentence-transformers downloads all-MiniLM-L6-v2 (~90 MB) on first evaluation. Subsequent runs use the cache.