openai passes proxies= to httpx internally; httpx>=0.28 dropped that
parameter. Pinning httpx<0.28.0 is the definitive fix.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix openai/httpx proxies incompatibility on HuggingFace
openai==1.51.0 passes proxies= to httpx which httpx>=0.28 dropped.
Unpinning to openai>=1.55.0 which removed that argument.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shorten HuggingFace Space short_description to under 60 chars
Streamlit app on port 7860 with Tesseract + Poppler system deps.
Update README frontmatter: sdk: docker.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove internal planning docs from repo, gitignore them
- Add scripts/make_v1-6.py for generating all 6 presentation variants
- Remove old deck/TenderIQ_Pitch.pdf (superseded)
- Ignore deck/*.pptx and deck/*.pdf — generated locally, not tracked
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add presentation_creation.md — full brief for 6 PPT/PDF variants
README: complete rewrite with problem statement, feature table, quick start
(with and without API key), demo scenario table, architecture diagram,
full project structure, tech stack table, and future work section.
Cleanup:
- Remove chromadb==0.5.5 from requirements.txt (replaced by pure-Python vectorstore)
- Remove .gitkeep from data/bidders/* and data/tender/ (directories now populated)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix nested expander: show reason/snippet inline inside criteria toggle
tab_tender.py: add × button per criterion (columns layout, one per row).
Clicking removes that criterion from session_state and reruns — evaluation
will only run against the remaining criteria.
tab_bidders.py: wrap all criteria rows in st.expander("View all N criteria").
Bidder card header (name, overall verdict, pass/total) always visible when
collapsed; all criterion rows appear on expand.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix empty source_type from LLM crashing Pydantic Source validation
All HTML components now use:
- var(--text-color) for all text (adapts to Streamlit theme)
- var(--secondary-background-color) for card backgrounds
- rgba(r,g,b,0.08-0.15) tints for verdict/category badge backgrounds
- rgba(128,128,128,0.1-0.2) for borders and dividers
- Vibrant accent colors (#22C55E #EF4444 #F59E0B #3B82F6) for verdict states
Removed base="light" from config.toml so dark mode works properly.
Fixed duplicate key in config.toml.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sentence-transformers 3.x imports SentenceTransformerTrainer at package level,
which drags in tensorflow, which fails due to a protobuf version conflict in
this environment. Pinned to 2.7.0 (last version without trainer import).
vectorstore.py now uses sentence-transformers all-MiniLM-L6-v2 as primary
(cosine similarity) with BM25 keyword retrieval as automatic fallback if the
model fails to load. Public API unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Force light theme base to fix dark-mode text visibility
- core/vectorstore.py: switch to EphemeralClient (in-memory) — eliminates
ChromaDB 0.5.x tenant/SQLite compatibility error entirely; index rebuilds
on each evaluation run so persistence is not needed
- data/tender/real_tenders/: two real CRPF tender PDFs downloaded from
crpf.gov.in (Bhopal water tanks NIT-71 Aug-2025, J&K office repair Jan-2026)
- ui/tab_tender.py: pre-loaded tender selector with tabs (pre-loaded vs upload);
real tenders shown with green badge; active tender name always displayed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix ChromaDB tenant error on stale .chroma directory
When the .chroma directory exists from an older ChromaDB version, PersistentClient
raises ValueError about missing default_tenant. Catch it, wipe the directory,
and recreate — data is regenerated on the next evaluation run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
UI revamp: inline styles throughout, Inter font, reliable badge system
Root cause of previous bad UI: CSS class selectors (.tiq-badge etc.) defined
in the global style block don't reliably cascade into Streamlit markdown
containers. Fix: 100% inline styles on every HTML component — no CSS classes.
- ui/styles.py: simplified to page-chrome only (sidebar, tabs, buttons,
metrics) — nothing that requires class inheritance
- ui/components.py: verdict_pill/category_badge/ocr_tier_badge/confidence_bar
all use pure inline styles; color-coded confidence bar (green/amber/red)
- ui/tab_overview.py: hero banner, numbered pipeline stage cards, stat_card KPIs
- ui/tab_bidders.py: CSS grid verdict table, bidder header with pass/total,
styled reason/snippet callout boxes, clean dividers
- ui/tab_review.py: amber summary banner, styled evidence cards, clean layout
- ui/tab_interpretability.py: coloured verdict status cards, inline source
citation chip, styled Q&A answer box
- app.py: glowing connection dot, cleaner sidebar branding, Inter font via
Google Fonts …
Final sweep: beautiful UI, pitch deck, HF README, ARCHITECTURE.md
Implements the end-to-end smoke test covering: imports, config, schemas, mock
data, pdf_utils, chunker, OCR pipeline, fallback, audit, evaluator threshold
logic, and precomputed files. All 43 checks pass. README covers local quickstart,
pre-computed mode, live API mode, and project structure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements specs/12_precompute.md. precompute_results.py runs full pipeline
when API key is available. Four JSON files committed as fallback: criteria.json
(5 criteria), eval_bidder_a.json (all eligible), eval_bidder_b.json (C1
not_eligible), eval_bidder_c.json (C1 needs_review from low-quality scan).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 10: audit and fallback spec — documenting already-implemented modules
Adds specs/10_audit_and_fallback.md. Both modules were implemented in Step 6
to unblock the criteria extractor. Spec records the SQLite schema, action
vocabulary, filter API, and fallback safety net behavior.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 9: evaluator — per-criterion verdict with threshold safety rules
Implements specs/09_evaluator.md. Combined confidence formula weighs LLM
confidence against OCR tier quality. Safety rules prevent silent disqualification:
not_eligible at medium confidence (0.55-0.80) is downgraded to needs_review.
Falls back to precomputed on LLMUnavailable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 8: vector store and bidder processor — ChromaDB indexing and retrieval
Implements specs/06_vectorstore_and_bidder_processor.md. get_client cached
with st.cache_resource; upsert deduplicates via sha256 IDs. process_bidder
runs OCR pipeline per file, chunks, and indexes with bidder_id metadata.
gather_evidence queries top-k chunks for a criterion's query_hints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 7: OCR pipeline — 3-tier extraction with caching
Implements specs/07_criteria_extractor.md. extract_criteria calls DeepSeek
with the full tender text and parses Criterion objects; falls back to
hardcoded precomputed criteria on LLMUnavailable. audit.py writes to SQLite;
fallback.py loads precomputed JSON or hardcoded defaults. Tab 2 renders
criteria cards with category/mandatory badges and rule details.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 5: pdf_utils and chunker — PyMuPDF extraction and text chunking
Implements specs/03_pdf_utils_and_chunker.md. extract_pages returns per-page
dicts; is_text_pdf uses avg-chars heuristic; render_page_to_image produces PIL
images for OCR. chunk_tender splits on clause headings up to 2000 chars;
chunk_bidder emits one chunk per ExtractedPage with full OCR metadata.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 4: LLM client — DeepSeek wrapper with retry and LLMUnavailable
Implements specs/02_llm_client.md. chat_json uses response_format=json_object
and retries on 5xx/connection errors with exponential backoff; chat_vision
base64-encodes images for multimodal calls. Raises LLMUnavailable on missing
key, auth failure, or exhausted retries.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 3: config, schemas, and prompts spec — all validated
Implements specs/11_mock_data.md. Generates crpf_construction_tender.pdf with
5 criteria (C1-C5), typed PDFs for Bidder A (eligible) and B (ineligible),
and Bidder C docs including a GaussianBlur+noise-degraded turnover_certificate_scan.png
for the OCR demo path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 1: project skeleton — all stubs, directory structure, and entry point
Creates every file listed in specs/00_skeleton.md: app.py with 5-tab Streamlit
shell, all core/ and ui/ stubs importable without logic, data/scripts/assets
directory tree, requirements.txt, packages.txt, .env.example.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Initial commit: source docs, implementation plan, and skeleton spec