#!/usr/bin/env python3 """ Initialize characters in the database from configuration """ import asyncio import sys import os from pathlib import Path from dotenv import load_dotenv # Load environment variables load_dotenv() # Add src to Python path sys.path.insert(0, str(Path(__file__).parent.parent / "src")) from database.models import Character, Base from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker from sqlalchemy import select import yaml import logging # Setup basic logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def load_character_config(): """Load character configuration from YAML file""" config_path = Path(__file__).parent.parent / "config" / "characters.yaml" if not config_path.exists(): raise FileNotFoundError(f"Character config file not found: {config_path}") with open(config_path, 'r') as file: return yaml.safe_load(file) async def init_characters(): """Initialize characters from configuration""" try: # Get database URL from environment and convert to async format database_url = os.getenv("DATABASE_URL", "sqlite+aiosqlite:///fishbowl_test.db") if database_url.startswith("postgresql://"): database_url = database_url.replace("postgresql://", "postgresql+asyncpg://") logger.info(f"Connecting to database: {database_url.split('@')[0]}@...") # Create engine and session engine = create_async_engine(database_url, echo=False) session_factory = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False) logger.info("Loading character configuration...") character_config = load_character_config() async with session_factory() as session: for char_data in character_config.get('characters', []): # Check if character already exists query = select(Character).where(Character.name == char_data['name']) existing = await session.scalar(query) if existing: logger.info(f"Character '{char_data['name']}' already exists, skipping...") continue # Create system prompt system_prompt = f"""You are {char_data['name']}. Personality: {char_data['personality']} Speaking Style: {char_data['speaking_style']} Background: {char_data['background']} Interests: {', '.join(char_data['interests'])} Always respond as {char_data['name']}, staying true to your personality and speaking style. Be natural, engaging, and authentic in all your interactions.""" # Create character character = Character( name=char_data['name'], personality=char_data['personality'], system_prompt=system_prompt, interests=char_data['interests'], speaking_style=char_data['speaking_style'], background=char_data['background'], avatar_url=char_data.get('avatar_url', ""), is_active=True ) session.add(character) logger.info(f"Created character: {char_data['name']}") await session.commit() logger.info("✅ Character initialization completed successfully!") await engine.dispose() except Exception as e: logger.error(f"Failed to initialize characters: {e}") raise if __name__ == "__main__": asyncio.run(init_characters())