"""Configuration management using pydantic-settings.""" from typing import Literal from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Application settings loaded from environment variables.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, ) # Discord Configuration discord_token: str = Field(..., description="Discord bot token") # AI Provider Configuration ai_provider: Literal["openai", "openrouter", "anthropic", "gemini"] = Field( "openai", description="Which AI provider to use" ) ai_model: str = Field("gpt-4o", description="AI model to use") ai_max_tokens: int = Field(1024, ge=100, le=4096, description="Max tokens for AI response") ai_temperature: float = Field(0.7, ge=0.0, le=2.0, description="AI temperature") # Provider API Keys openai_api_key: str | None = Field(None, description="OpenAI API key") openrouter_api_key: str | None = Field(None, description="OpenRouter API key") anthropic_api_key: str | None = Field(None, description="Anthropic API key") gemini_api_key: str | None = Field(None, description="Google Gemini API key") # Logging log_level: str = Field("INFO", description="Logging level") # Bot Identity bot_name: str = Field("AI Bot", description="Bot display name") bot_personality: str = Field( "helpful and friendly", description="Bot personality description for system prompt", ) bot_description: str = Field( "I'm an AI assistant here to help you.", description="Bot description shown when mentioned without a message", ) bot_status: str = Field( "for mentions", description="Bot status message (shown as 'Watching ...')", ) # System Prompt (optional override) system_prompt: str | None = Field( None, description="Custom system prompt. If not set, a default is generated from bot_name and bot_personality", ) # Conversation Settings max_conversation_history: int = Field( 20, description="Max messages to keep in conversation memory per user" ) def get_api_key(self) -> str: """Get the API key for the configured provider.""" key_map = { "openai": self.openai_api_key, "openrouter": self.openrouter_api_key, "anthropic": self.anthropic_api_key, "gemini": self.gemini_api_key, } key = key_map.get(self.ai_provider) if not key: raise ValueError( f"No API key configured for provider '{self.ai_provider}'. " f"Set {self.ai_provider.upper()}_API_KEY in your environment." ) return key # Global settings instance settings = Settings()