Spaces:
Sleeping
Sleeping
| """ | |
| Configuration management for D'n'D Campaign Manager | |
| Handles API keys, model settings, and application config | |
| """ | |
| import os | |
| from pathlib import Path | |
| from typing import Optional | |
| from pydantic import BaseModel, Field | |
| from dotenv import load_dotenv | |
| # Load environment variables | |
| load_dotenv() | |
| class ModelConfig(BaseModel): | |
| """Configuration for AI models""" | |
| # Primary model for generation | |
| primary_provider: str = Field(default="anthropic", description="anthropic, openai, or google") | |
| primary_model: str = Field(default="claude-3-haiku-20240307", description="Model name") | |
| # Memory model for long context | |
| memory_provider: str = Field(default="google", description="Provider for campaign memory") | |
| memory_model: str = Field(default="gemini-2.0-flash-exp", description="2M token context model") | |
| # Temperature settings | |
| creative_temp: float = Field(default=0.9, description="For character/story generation") | |
| balanced_temp: float = Field(default=0.7, description="For general tasks") | |
| precise_temp: float = Field(default=0.3, description="For rules/stats") | |
| # Token limits | |
| max_tokens_generation: int = Field(default=2000, description="For content generation") | |
| max_tokens_memory: int = Field(default=1000000, description="For memory queries") | |
| class DatabaseConfig(BaseModel): | |
| """Database configuration""" | |
| db_type: str = Field(default="sqlite", description="Database type") | |
| db_path: Path = Field(default=Path("data/dnd_campaign_manager.db"), description="SQLite path") | |
| def ensure_db_dir(self): | |
| """Ensure database directory exists""" | |
| self.db_path.parent.mkdir(parents=True, exist_ok=True) | |
| class MCPConfig(BaseModel): | |
| """MCP Server configuration""" | |
| server_name: str = Field(default="dnd-campaign-manager", description="MCP server name") | |
| server_version: str = Field(default="2.0.0", description="MCP server version") | |
| # MCP tools to expose | |
| enable_character_tools: bool = Field(default=True, description="Character creation tools") | |
| enable_campaign_tools: bool = Field(default=True, description="Campaign management tools") | |
| enable_npc_tools: bool = Field(default=True, description="NPC generation tools") | |
| enable_loot_tools: bool = Field(default=True, description="Loot generation tools") | |
| enable_encounter_tools: bool = Field(default=True, description="Encounter generation tools") | |
| # MCP resources to expose | |
| enable_character_resources: bool = Field(default=True, description="Character data resources") | |
| enable_campaign_resources: bool = Field(default=True, description="Campaign data resources") | |
| class AppConfig(BaseModel): | |
| """Application configuration""" | |
| app_name: str = Field(default="D'n'D Campaign Manager", description="Application name") | |
| app_version: str = Field(default="2.0.0", description="Application version") | |
| # Gradio settings | |
| gradio_share: bool = Field(default=False, description="Enable Gradio sharing") | |
| gradio_server_name: str = Field(default="0.0.0.0", description="Server host") | |
| gradio_server_port: int = Field(default=7860, description="Server port") | |
| # Data persistence | |
| enable_persistence: bool = Field(default=True, description="Save data to database") | |
| auto_backup: bool = Field(default=True, description="Auto-backup campaigns") | |
| backup_interval_hours: int = Field(default=24, description="Backup interval") | |
| # Feature flags | |
| enable_image_generation: bool = Field(default=True, description="Character portraits") | |
| enable_voice_generation: bool = Field(default=False, description="NPC voices (future)") | |
| enable_music_generation: bool = Field(default=False, description="Background music (future)") | |
| class Config: | |
| """Main configuration class""" | |
| def __init__(self): | |
| # API Keys | |
| self.anthropic_api_key: Optional[str] = os.getenv("ANTHROPIC_API_KEY") | |
| self.openai_api_key: Optional[str] = os.getenv("OPENAI_API_KEY") | |
| self.google_api_key: Optional[str] = os.getenv("GOOGLE_API_KEY") | |
| self.huggingface_api_key: Optional[str] = os.getenv("HUGGINGFACE_API_KEY") | |
| # Sub-configurations | |
| self.model = ModelConfig() | |
| self.database = DatabaseConfig() | |
| self.mcp = MCPConfig() | |
| self.app = AppConfig() | |
| # Validate configuration | |
| self._validate() | |
| def _validate(self): | |
| """Validate configuration and API keys""" | |
| # Don't fail startup on missing keys - just warn | |
| # The UI will show appropriate error messages when features are used | |
| if not self.anthropic_api_key and self.model.primary_provider == "anthropic": | |
| print("⚠️ Warning: ANTHROPIC_API_KEY not found in environment") | |
| print(" Configure API keys in Settings → Variables and secrets") | |
| if not self.google_api_key and self.model.memory_provider == "google": | |
| print("⚠️ Warning: GOOGLE_API_KEY not found for memory model") | |
| # Ensure database directory exists | |
| self.database.ensure_db_dir() | |
| def has_any_api_key(self) -> bool: | |
| """Check if at least one API key is configured""" | |
| return bool( | |
| self.anthropic_api_key or | |
| self.openai_api_key or | |
| self.google_api_key | |
| ) | |
| def get_available_providers(self) -> list[str]: | |
| """Get list of providers with configured API keys""" | |
| providers = [] | |
| if self.anthropic_api_key: | |
| providers.append("anthropic") | |
| if self.openai_api_key: | |
| providers.append("openai") | |
| if self.google_api_key: | |
| providers.append("google") | |
| return providers | |
| def get_model_config(self, task_type: str = "balanced") -> dict: | |
| """Get model configuration for specific task type""" | |
| temp_map = { | |
| "creative": self.model.creative_temp, | |
| "balanced": self.model.balanced_temp, | |
| "precise": self.model.precise_temp | |
| } | |
| return { | |
| "model": self.model.primary_model, | |
| "temperature": temp_map.get(task_type, self.model.balanced_temp), | |
| "max_tokens": self.model.max_tokens_generation | |
| } | |
| def get_memory_config(self) -> dict: | |
| """Get configuration for memory/context model""" | |
| return { | |
| "model": self.model.memory_model, | |
| "temperature": self.model.balanced_temp, | |
| "max_tokens": self.model.max_tokens_memory | |
| } | |
| # Global configuration instance | |
| config = Config() | |
| # Export commonly used values | |
| ANTHROPIC_API_KEY = config.anthropic_api_key | |
| GOOGLE_API_KEY = config.google_api_key | |
| OPENAI_API_KEY = config.openai_api_key | |
| HUGGINGFACE_API_KEY = config.huggingface_api_key | |
| DB_PATH = config.database.db_path | |
| MCP_SERVER_NAME = config.mcp.server_name | |
| # Data directories | |
| DATA_DIR = Path("data") | |
| CAMPAIGNS_DIR = DATA_DIR / "campaigns" | |
| CHARACTERS_DIR = DATA_DIR / "characters" | |
| TEMPLATES_DIR = DATA_DIR / "templates" | |
| # Ensure directories exist | |
| for directory in [DATA_DIR, CAMPAIGNS_DIR, CHARACTERS_DIR, TEMPLATES_DIR]: | |
| directory.mkdir(parents=True, exist_ok=True) | |