import os from pathlib import Path from typing import Dict, Any from pydantic import Field from pydantic_settings import BaseSettings from dotenv import load_dotenv load_dotenv() class LyraConfig(BaseSettings): # Discord Configuration discord_token: str = Field("", env="DISCORD_TOKEN") discord_guild_id: int = Field(0, env="DISCORD_GUILD_ID") # Database Configuration database_url: str = Field("sqlite:///data/lyra.db", env="DATABASE_URL") redis_url: str = Field("redis://localhost:6379/0", env="REDIS_URL") # Model Configuration model_path: str = Field("./models/checkpoints/lyra_model.pt", env="MODEL_PATH") vocab_size: int = Field(50000, env="VOCAB_SIZE") hidden_size: int = Field(768, env="HIDDEN_SIZE") num_layers: int = Field(12, env="NUM_LAYERS") num_heads: int = Field(12, env="NUM_HEADS") context_length: int = Field(2048, env="CONTEXT_LENGTH") max_memory_gb: float = Field(8.0, env="MAX_MEMORY_GB") # Training Configuration batch_size: int = Field(16, env="BATCH_SIZE") learning_rate: float = Field(5e-5, env="LEARNING_RATE") max_epochs: int = Field(100, env="MAX_EPOCHS") warmup_steps: int = Field(1000, env="WARMUP_STEPS") save_every: int = Field(1000, env="SAVE_EVERY") # Personality Configuration personality_update_frequency: int = Field(100, env="PERSONALITY_UPDATE_FREQUENCY") emotion_decay_rate: float = Field(0.95, env="EMOTION_DECAY_RATE") memory_retention_days: int = Field(30, env="MEMORY_RETENTION_DAYS") # Knowledge Acquisition gutenberg_mirror: str = Field("https://www.gutenberg.org", env="GUTENBERG_MIRROR") scraping_delay: float = Field(1.0, env="SCRAPING_DELAY") max_concurrent_downloads: int = Field(5, env="MAX_CONCURRENT_DOWNLOADS") # Logging log_level: str = Field("INFO", env="LOG_LEVEL") log_file: str = Field("./logs/lyra.log", env="LOG_FILE") # Development debug: bool = Field(False, env="DEBUG") wandb_api_key: str = Field("", env="WANDB_API_KEY") class Config: env_file = ".env" env_file_encoding = "utf-8" @property def project_root(self) -> Path: return Path(__file__).parent.parent @property def data_dir(self) -> Path: return self.project_root / "data" @property def models_dir(self) -> Path: return self.project_root / "models" @property def logs_dir(self) -> Path: return self.project_root / "logs" def ensure_directories(self): """Ensure all required directories exist.""" dirs = [self.data_dir, self.models_dir, self.logs_dir, self.data_dir / "training", self.data_dir / "personality", self.data_dir / "conversations", self.models_dir / "checkpoints", self.models_dir / "configs"] for dir_path in dirs: dir_path.mkdir(parents=True, exist_ok=True) config = LyraConfig()