""" Configuration Management Author: @mangubee Date: 2026-01-01 Loads environment variables and defines configuration constants for GAIA agent. Based on Level 5 (Component Selection) and Level 6 (Implementation Framework) decisions. """ import os from typing import Literal from dotenv import load_dotenv # Load environment variables from .env file load_dotenv() # ============================================================================ # CONFIG - All hardcoded values extracted here # ============================================================================ # LLM Configuration (Level 5 - Component Selection) ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY", "") GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY", "") HF_TOKEN = os.getenv("HF_TOKEN", "") HF_VISION_MODEL = os.getenv("HF_VISION_MODEL", "google/gemma-3-27b-it:scaleway") DEFAULT_LLM_MODEL: Literal["gemini", "claude"] = os.getenv("DEFAULT_LLM_MODEL", "gemini") # type: ignore # Tool API Keys (Level 5 - Component Selection) EXA_API_KEY = os.getenv("EXA_API_KEY", "") TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "") DEFAULT_SEARCH_TOOL: Literal["tavily", "exa"] = os.getenv("DEFAULT_SEARCH_TOOL", "tavily") # type: ignore # GAIA API Configuration (Level 7 - Infrastructure) DEFAULT_API_URL = os.getenv("DEFAULT_API_URL", "https://huggingface.co/api/evals") SPACE_ID = os.getenv("SPACE_ID", "") # Agent Behavior (Level 6 - Implementation Framework) MAX_RETRIES = int(os.getenv("MAX_RETRIES", "3")) QUESTION_TIMEOUT = int(os.getenv("QUESTION_TIMEOUT", "1020")) # 17 minutes TOOL_TIMEOUT = int(os.getenv("TOOL_TIMEOUT", "60")) # 1 minute # LangGraph Configuration GRAPH_RECURSION_LIMIT = 25 # ============================================================================ class Settings: """ Configuration settings manager for GAIA agent. Provides access to all configuration constants and validates API keys. """ def __init__(self): self.anthropic_api_key = ANTHROPIC_API_KEY self.google_api_key = GOOGLE_API_KEY self.hf_token = HF_TOKEN self.hf_vision_model = HF_VISION_MODEL self.default_llm_model = DEFAULT_LLM_MODEL self.exa_api_key = EXA_API_KEY self.tavily_api_key = TAVILY_API_KEY self.default_search_tool = DEFAULT_SEARCH_TOOL self.default_api_url = DEFAULT_API_URL self.space_id = SPACE_ID self.max_retries = MAX_RETRIES self.question_timeout = QUESTION_TIMEOUT self.tool_timeout = TOOL_TIMEOUT self.graph_recursion_limit = GRAPH_RECURSION_LIMIT def validate_api_keys(self) -> dict[str, bool]: """ Validate that required API keys are present. Returns: Dict mapping service name to whether API key is present """ return { "anthropic": bool(self.anthropic_api_key), "google": bool(self.google_api_key), "huggingface": bool(self.hf_token), "exa": bool(self.exa_api_key), "tavily": bool(self.tavily_api_key), } def get_llm_api_key(self) -> str: """ Get API key for the currently selected LLM model. Returns: API key string for the selected model Raises: ValueError: If selected model's API key is not configured """ if self.default_llm_model == "claude": if not self.anthropic_api_key: raise ValueError("ANTHROPIC_API_KEY not configured") return self.anthropic_api_key elif self.default_llm_model == "gemini": if not self.google_api_key: raise ValueError("GOOGLE_API_KEY not configured") return self.google_api_key else: raise ValueError(f"Unknown LLM model: {self.default_llm_model}") def get_search_api_key(self) -> str: """ Get API key for the currently selected search tool. Returns: API key string for the selected search tool Raises: ValueError: If selected search tool's API key is not configured """ if self.default_search_tool == "tavily": if not self.tavily_api_key: raise ValueError("TAVILY_API_KEY not configured") return self.tavily_api_key elif self.default_search_tool == "exa": if not self.exa_api_key: raise ValueError("EXA_API_KEY not configured") return self.exa_api_key else: raise ValueError(f"Unknown search tool: {self.default_search_tool}") # Global settings instance settings = Settings()