""" Configuration for LangGraph agents. Loads environment variables and manages settings. """ import os from dotenv import load_dotenv from typing import Optional load_dotenv() class AgentConfig: """Configuration for bird classification agents.""" # Modal Bird classifier (Phase 1) MODAL_MCP_URL: str = os.getenv("MODAL_MCP_URL", "") BIRD_CLASSIFIER_API_KEY: str = os.getenv("BIRD_CLASSIFIER_API_KEY", "") # eBird Server (Phase 2 - deprecated, replaced by Nuthatch) EBIRD_API_KEY: str = os.getenv("EBIRD_API_KEY", "") # For Cornell eBird API calls EBIRD_BASE_URL: str = os.getenv("EBIRD_BASE_URL", "https://api.ebird.org/v2") # Cornell eBird API endpoint EBIRD_MCP_URL: str = os.getenv("EBIRD_MCP_URL", "http://localhost:8000/mcp") # MCP server endpoint EBIRD_USE_STDIO: bool = os.getenv("EBIRD_USE_STDIO", "false").lower() == "true" EBIRD_MCP_AUTH_KEY: Optional[str] = os.getenv("EBIRD_MCP_AUTH_KEY") # For HTTP transport auth (legacy: MCP_API_KEY) # Nuthatch Server (Phase 2.5 - species reference database) NUTHATCH_API_KEY: str = os.getenv("NUTHATCH_API_KEY", "") # For Nuthatch API calls NUTHATCH_BASE_URL: str = os.getenv("NUTHATCH_BASE_URL", "https://nuthatch.lastelm.software/v2") # Nuthatch API endpoint NUTHATCH_MCP_URL: str = os.getenv("NUTHATCH_MCP_URL", "http://localhost:8001/mcp") # MCP server endpoint NUTHATCH_USE_STDIO: bool = os.getenv("NUTHATCH_USE_STDIO", "true").lower() == "true" NUTHATCH_MCP_AUTH_KEY: Optional[str] = os.getenv("NUTHATCH_MCP_AUTH_KEY") # For HTTP transport # LLM Settings OPENAI_API_KEY: str = os.getenv("OPENAI_API_KEY", "") # For dev/testing with backend-provided key DEFAULT_OPENAI_MODEL: str = os.getenv("DEFAULT_OPENAI_MODEL", "gpt-4o-mini") DEFAULT_HF_MODEL: str = os.getenv("DEFAULT_HF_MODEL", "Qwen/Qwen2.5-Coder-32B-Instruct") # Anthropic Settings ANTHROPIC_API_KEY: str = os.getenv("ANTHROPIC_API_KEY", "") DEFAULT_ANTHROPIC_MODEL: str = os.getenv("DEFAULT_ANTHROPIC_MODEL", "claude-sonnet-4-5-20250929") ANTHROPIC_TEMPERATURE: float = float(os.getenv("ANTHROPIC_TEMPERATURE", "0.0")) # Provider-specific temperature settings OPENAI_TEMPERATURE: float = float(os.getenv("OPENAI_TEMPERATURE", "0.0")) HF_TEMPERATURE: float = float(os.getenv("HF_TEMPERATURE", "0.1")) # Agent Settings MAX_ITERATIONS: int = int(os.getenv("AGENT_MAX_ITERATIONS", "10")) TIMEOUT: int = int(os.getenv("AGENT_TIMEOUT", "120")) @classmethod def print_config(cls) -> None: """Print current configuration (hiding sensitive data).""" print("\n" + "="*70) print("Agent Configuration") print("="*70) print(f"[MODAL URL]: {cls.MODAL_MCP_URL}") print(f"[MODAL API KEY]: {cls.BIRD_CLASSIFIER_API_KEY[:20]}..." if cls.BIRD_CLASSIFIER_API_KEY else "[MODAL API KEY]: Not set") print(f"[NUTHATCH STDIO]: {cls.NUTHATCH_USE_STDIO}") print(f"[NUTHATCH URL]: {cls.NUTHATCH_MCP_URL}") print(f"[NUTHATCH API KEY]: {'✅ Set' if cls.NUTHATCH_API_KEY else '❌ Not set'}") print(f"[OPENAI MODEL]: {cls.DEFAULT_OPENAI_MODEL}") print(f"[OPENAI TEMP]: {cls.OPENAI_TEMPERATURE}") print(f"[HF MODEL]: {cls.DEFAULT_HF_MODEL}") print(f"[HF TEMP]: {cls.HF_TEMPERATURE}") print(f"[ANTHROPIC_MODEL]: {cls.DEFAULT_ANTHROPIC_MODEL}") print(f"[ANTHROPIC_TEMP]: {cls.ANTHROPIC_TEMPERATURE}") print("="*70 + "\n")