Spaces:
Sleeping
Sleeping
File size: 5,497 Bytes
b95549b 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 b95549b 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 2a7fd26 50fcf88 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field, field_validator
from typing import Optional
import os
from .definitions import MAX_FILE_SIZE, MAX_TOTAL_SIZE, ALLOWED_TYPES
def _default_chroma_path() -> str:
if os.environ.get("SPACE_ID"): # Hugging Face Spaces
return os.environ.get("CHROMA_DB_PATH", "/tmp/chroma_db")
return os.environ.get("CHROMA_DB_PATH", "./chroma_db")
def _is_hf() -> bool:
return os.environ.get("SPACE_ID") is not None
class Settings(BaseSettings):
"""
Application parameters loaded from environment variables.
For local development:
Create a .env file in the project root with your configuration:
GOOGLE_API_KEY=your_api_key_here
For Hugging Face Spaces:
Add GOOGLE_API_KEY as a secret in Space Settings > Repository secrets
"""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
case_sensitive=False,
)
# File upload parameters with defaults from definitions
MAX_FILE_SIZE: int = MAX_FILE_SIZE
MAX_TOTAL_SIZE: int = MAX_TOTAL_SIZE
ALLOWED_TYPES: list = ALLOWED_TYPES
# API keys - REQUIRED, must be set via environment variable or HF Secrets
GOOGLE_API_KEY: str = Field(
..., # Required field
description="Google API key for Gemini models",
)
# Database parameters
CHROMA_DB_PATH: str = Field(default_factory=_default_chroma_path)
# Chunking parameters
CHUNK_SIZE: int = 2000
CHUNK_OVERLAP: int = 100
# Retriever parameters
VECTOR_SEARCH_K: int = 25
VECTOR_SEARCH_K_CHROMA: int = 15 # Fixed typo: was VECTOR_Search_K_CHROMA
VECTOR_FETCH_K: int = 35
VECTOR_SCORE_THRESHOLD: float = 0.3
BM25_SEARCH_K: int = 8
HYBRID_RETRIEVER_WEIGHTS: list = [0.4, 0.6] # [BM25 weight, Vector weight]
CHROMA_COLLECTION_NAME: str = "documents"
# Workflow parameters
MAX_RESEARCH_ATTEMPTS: int = 5
ENABLE_QUERY_REWRITING: bool = True
MAX_QUERY_REWRITES: int = 1
RELEVANCE_CHECK_K: int = 20
# Research agent parameters
RESEARCH_TOP_K: int = 15
RESEARCH_MAX_CONTEXT_CHARS: int = Field(default_factory=lambda: 800_000 if _is_hf() else 8000000000)
RESEARCH_MAX_OUTPUT_TOKENS: int = 500
NUM_RESEARCH_CANDIDATES: int = 2 # Number of research questions to generate
# Verification parameters
VERIFICATION_MAX_CONTEXT_CHARS: int = Field(default_factory=lambda: 300_000 if _is_hf() else 800000000)
VERIFICATION_MAX_OUTPUT_TOKENS: int = 300
# Logging parameters
LOG_LEVEL: str = "INFO"
# Cache parameters
CACHE_DIR: str = "document_cache"
CACHE_EXPIRE_DAYS: int = 7
# LLM parameters
LLM_MAX_RETRIES: int = 3
LLM_RETRY_DELAY: float = 1.0
LLM_MODEL_NAME: str = "gemini-2.5-flash-lite" # Default model for all agents
# Agent-specific LLM models (override LLM_MODEL_NAME if needed)
RESEARCH_AGENT_MODEL: str = "gemini-2.5-flash-lite"
VERIFICATION_AGENT_MODEL: str = "gemini-2.5-flash-lite"
RELEVANCE_CHECKER_MODEL: str = "gemini-2.5-flash-lite"
# Chart extraction parameters
ENABLE_CHART_EXTRACTION: bool = True
CHART_VISION_MODEL: str = "gemini-2.5-flash-lite"
CHART_MAX_TOKENS: int = 1500
CHART_DPI: int = Field(default_factory=lambda: 110 if _is_hf() else 110) # Lower DPI saves memory
CHART_BATCH_SIZE: int = Field(default_factory=lambda: 1 if _is_hf() else 1) # Process pages in batches
CHART_MAX_IMAGE_SIZE: int = Field(default_factory=lambda: 1200 if _is_hf() else 1200) # Max dimension for images
# Local chart detection parameters (cost optimization)
CHART_USE_LOCAL_DETECTION: bool = Field(default_factory=lambda: True if _is_hf() else True) # Use OpenCV first (FREE)
CHART_MIN_CONFIDENCE: float = 0.4 # Only analyze charts with confidence > 40%
CHART_SKIP_GEMINI_DETECTION: bool = True # Skip Gemini for detection, only use for analysis
CHART_GEMINI_FALLBACK_ENABLED: bool = False # Optional: Use Gemini if local fails
# Gemini batch processing parameters (speed optimization - 2-3× faster)
CHART_GEMINI_BATCH_SIZE: int = 1 # Analyze 1 chart per API call (reduced from 2 for reliability)
CHART_ENABLE_BATCH_ANALYSIS: bool = True # Enable batch processing for speed
@field_validator("GOOGLE_API_KEY")
@classmethod
def validate_api_key(cls, v: str) -> str:
"""Validate that API key is provided and not a placeholder."""
if not v or v.strip() == "":
raise ValueError("GOOGLE_API_KEY is required. Set it in your .env file or HF Secrets.")
if v.startswith("your_") or v == "YOUR_API_KEY_HERE":
raise ValueError("Please replace the placeholder GOOGLE_API_KEY with your actual API key.")
return v
def _get_parameters():
"""Get parameters instance with helpful error messages."""
is_hf_space = os.environ.get("SPACE_ID") is not None
try:
return Settings()
except Exception as e:
import sys
print(f"⚠️ Configuration Error: {e}", file=sys.stderr)
if is_hf_space:
print("💡 Tip: Add GOOGLE_API_KEY in Space Settings > Repository secrets", file=sys.stderr)
else:
print("💡 Tip: Create a .env file with GOOGLE_API_KEY=your_api_key", file=sys.stderr)
raise
# Create parameters instance
parameters = _get_parameters()
|