build-small-hackathon/legislation-explainer
2
1"""Configuration constants for the NITA bill Gradio app."""2 3from __future__ import annotations4 5import os6import warnings7from dataclasses import dataclass8from pathlib import Path9from typing import Literal, Optional10 11from dotenv import load_dotenv12 13_PROJECT_ROOT = Path(__file__).resolve().parent14while _PROJECT_ROOT.name and _PROJECT_ROOT.name not in {"", "."}:15 if (_PROJECT_ROOT / "pyproject.toml").exists():16 break17 if _PROJECT_ROOT.parent == _PROJECT_ROOT:18 break19 _PROJECT_ROOT = _PROJECT_ROOT.parent20 21load_dotenv(dotenv_path=_PROJECT_ROOT / ".env", override=False)22 23# Hugging Face tokenizers can emit fork/parallelism warnings in Gradio dev24# servers. Default this off unless the environment explicitly overrides it.25os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")26 27# Suppress a known huggingface_hub deprecation warning emitted during first-time28# model/tokenizer downloads. It is noisy but not actionable for app users.29warnings.filterwarnings(30 "ignore",31 message=r"`resume_download` is deprecated and will be removed in version 1\.0\.0\.",32 category=FutureWarning,33)34 35SUPPORTED_PROVIDERS = ["qwen", "openai", "anthropic", "gemini", "cohere"]36DEFAULT_PROVIDER: str = "qwen"37DEFAULT_QWEN_MODEL = "Qwen/Qwen3-14B:cheapest"38DEFAULT_CHUNK_TOKENIZER_MODEL = "sentence-transformers/all-MiniLM-L6-v2"39DEFAULT_FALLBACK_EMBEDDING_MODEL = "sentence-transformers/all-MiniLM-L6-v2"40OPENAI_REASONING_EFFORT = "medium"41ANTHROPIC_THINKING_BUDGET = 204842DEFAULT_CHUNK_SIZE = 35043DEFAULT_CHUNK_OVERLAP = 6044SCAN_CHUNK_SIZE = 120045SCAN_CHUNK_OVERLAP = 15046SCAN_MAX_WINDOWS = 4047SCAN_TOP_K = 548SCAN_BATCH_SIZE = 649TOP_K_RETRIEVAL = 550MAX_UPLOAD_SIZE_MB = 2551TIMEOUT_SECONDS = 3052 53ProviderLiteral = Literal["qwen", "openai", "anthropic", "gemini", "cohere"]54 55# Conservative full-document QA input budgets derived from provider/model56# context-window docs, with headroom reserved for prompts and outputs.57PROVIDER_FULL_DOCUMENT_QA_TOKEN_BUDGETS: dict[ProviderLiteral, int] = {58 "qwen": 24_000,59 "openai": 900_000,60 "anthropic": 900_000,61 "gemini": 900_000,62 "cohere": 220_000,63}64 65 66@dataclass(frozen=True)67class ProviderConfig:68 name: ProviderLiteral69 key_prefix: Optional[str]70 display_name: str71 instructions: str72 73 74def _read_env_key(var_name: str) -> Optional[str]:75 value = os.getenv(var_name)76 if value is None:77 return None78 sanitized = value.strip().strip('"').strip("'")79 return sanitized or None80 81 82OPENAI_API_KEY: Optional[str] = _read_env_key("OPENAI_API_KEY")83ANTHROPIC_API_KEY: Optional[str] = _read_env_key("ANTHROPIC_API_KEY")84GEMINI_API_KEY: Optional[str] = _read_env_key("GEMINI_API_KEY")85COHERE_API_KEY: Optional[str] = _read_env_key("COHERE_API_KEY")86DEFAULT_COHERE_KEY: Optional[str] = _read_env_key("DEFAULT_COHERE_KEY")87HF_TOKEN: Optional[str] = _read_env_key("HF_TOKEN")88 89 90PROVIDER_METADATA: list[ProviderConfig] = [91 ProviderConfig(92 name="qwen",93 key_prefix=None,94 display_name="Qwen3 14B",95 instructions=(96 "Use your Hugging Face token for the router-backed Qwen model. Leave blank to use HF_TOKEN from .env if configured."97 ),98 ),99 ProviderConfig(100 name="openai",101 key_prefix="sk-",102 display_name="OpenAI GPT-5.5",103 instructions=(104 "Enter your OpenAI API key. Leave blank to use OPENAI_API_KEY from .env if configured."105 ),106 ),107 ProviderConfig(108 name="anthropic",109 key_prefix="sk-ant-",110 display_name="Anthropic Claude Sonnet 4.6",111 instructions=(112 "Provide your Anthropic API key. Leave blank to use ANTHROPIC_API_KEY from .env if configured."113 ),114 ),115 ProviderConfig(116 name="gemini",117 key_prefix=None,118 display_name="Google Gemini 2.5 Flash",119 instructions=(120 "Use your Gemini API key. Leave blank to use the built-in GEMINI_API_KEY if configured."121 ),122 ),123 ProviderConfig(124 name="cohere",125 key_prefix=None,126 display_name="Cohere Command A Reasoning",127 instructions=(128 "Use your Cohere API key with Command R access. Leave blank to use COHERE_API_KEY or "129 "DEFAULT_COHERE_KEY if configured."130 ),131 ),132]133 134 135APP_TITLE = "Legislation Explainer"136APP_DESCRIPTION = (137 "A Gradio policy assistant for public-interest legislation. "138 "Upload or link to a bill, generate a structured review, and ask grounded follow-up questions."139)140 