- Update docker-start.sh to force correct profiles (qdrant, admin) - Fix PostgreSQL port mapping from 5432 to 15432 across all configs - Resolve MCP import conflicts by renaming src/mcp to src/mcp_servers - Fix admin interface StaticFiles mount syntax error - Update LLM client to support both Ollama and OpenAI-compatible APIs - Configure host networking for Discord bot container access - Correct database connection handling for async context managers - Update environment variables and Docker compose configurations - Add missing production dependencies and Dockerfile improvements
102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
#!/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()) |