""" Environment variable handler for GAIA configuration. This module handles the loading of environment variables for GAIA configuration, providing a structured way to override default configuration values with environment variables. """ import os from typing import Dict, Any, Optional # Try to load dotenv for development environments try: from dotenv import load_dotenv load_dotenv(verbose=False) except ImportError: # No-op implementation when dotenv is not available def load_dotenv(*args, **kwargs): pass # Environment variable mapping to configuration paths ENV_CONFIG_MAPPING = { # API Keys "OPENAI_API_KEY": "api.openai.api_key", "OPENAI_API_BASE": "api.openai.api_base", "SERPER_API_KEY": "api.serper.api_key", "SERPER_API_URL": "api.serper.api_url", "PERPLEXITY_API_KEY": "api.perplexity.api_key", "PERPLEXITY_API_URL": "api.perplexity.api_url", "SUPABASE_KEY": "api.supabase.key", "SUPABASE_URL": "api.supabase.url", "HF_TOKEN": "api.huggingface.token", # Model Configuration "GAIA_DEFAULT_MODEL": "models.default_model", "GAIA_EMBEDDING_MODEL": "models.embedding_model", "GAIA_FALLBACK_MODEL": "models.fallback_model", "GAIA_VISION_MODEL": "models.vision_model", "GAIA_REASONING_MODEL": "models.reasoning_model", "GAIA_MODEL_TEMPERATURE": "models.temperature", "GAIA_MODEL_MAX_TOKENS": "models.max_tokens", # Tool Configuration "GAIA_WEB_SEARCH_RESULT_COUNT": "tools.web_search.result_count", "GAIA_WEB_SEARCH_TIMEOUT": "tools.web_search.timeout", "GAIA_ARXIV_MAX_RESULTS": "tools.arxiv.max_results", "GAIA_DUCKDUCKGO_TIMEOUT": "tools.duckduckgo.timeout", "GAIA_DUCKDUCKGO_MAX_RESULTS": "tools.duckduckgo.max_results", "GAIA_PERPLEXITY_TIMEOUT": "tools.perplexity.timeout", "GAIA_PERPLEXITY_MODEL": "tools.perplexity.model", # Memory Settings "GAIA_MEMORY_ENABLED": "memory.enabled", "GAIA_MEMORY_TABLE_NAME": "memory.table_name", "GAIA_MEMORY_TTL": "memory.ttl", "GAIA_MEMORY_CACHE_SIZE": "memory.cache_size", "GAIA_MEMORY_MAX_ENTRIES": "memory.max_entries", # Agent Settings "GAIA_MAX_ITERATIONS": "agent.max_iterations", "GAIA_VERBOSE": "agent.verbose", "GAIA_TIMEOUT": "agent.timeout", "GAIA_MAX_RETRIES": "agent.max_retries", "GAIA_RETRY_DELAY": "agent.retry_delay", # Logging Configuration "GAIA_LOG_LEVEL": "logging.level", "GAIA_LOG_FILE": "logging.file", "GAIA_LOG_FORMAT": "logging.format", } def get_env_value(env_var: str, default=None) -> Any: """ Get an environment variable value with type conversion. Args: env_var: The environment variable name default: Default value if environment variable is not set Returns: The environment variable value with appropriate type conversion """ value = os.getenv(env_var) if value is None: return default # Convert boolean strings if value.lower() in ("true", "yes", "1", "on"): return True if value.lower() in ("false", "no", "0", "off"): return False # Convert numeric strings try: if "." in value: return float(value) return int(value) except ValueError: # If conversion fails, return as string return value def load_env_config() -> Dict[str, Any]: """ Load configuration from environment variables. Returns: Dict containing configuration values from environment variables """ env_config = {} # Process each environment variable in the mapping for env_var, config_path in ENV_CONFIG_MAPPING.items(): value = get_env_value(env_var) if value is not None: # Split the config path and build the nested dictionary parts = config_path.split(".") current = env_config # Navigate to the correct nested level for i, part in enumerate(parts): if i == len(parts) - 1: # Last part is the key to set current[part] = value else: # Create the nested dict if it doesn't exist if part not in current: current[part] = {} current = current[part] return env_config