Spaces:
Sleeping
Sleeping
File size: 7,099 Bytes
71b378e 09d5a09 71b378e 09d5a09 71b378e 09d5a09 71b378e 09d5a09 71b378e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
"""
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)
|