Fix Docker startup script and complete application deployment
- 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
This commit is contained in:
@@ -5,70 +5,94 @@ 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.connection import init_database, get_db_session
|
||||
from database.models import Character
|
||||
from utils.config import get_character_settings
|
||||
from utils.logging import setup_logging
|
||||
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
|
||||
|
||||
logger = setup_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:
|
||||
logger.info("Initializing database connection...")
|
||||
await init_database()
|
||||
# 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_settings = get_character_settings()
|
||||
character_config = load_character_config()
|
||||
|
||||
async with get_db_session() as session:
|
||||
for char_config in character_settings.characters:
|
||||
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_config.name)
|
||||
query = select(Character).where(Character.name == char_data['name'])
|
||||
existing = await session.scalar(query)
|
||||
|
||||
if existing:
|
||||
logger.info(f"Character '{char_config.name}' already exists, skipping...")
|
||||
logger.info(f"Character '{char_data['name']}' already exists, skipping...")
|
||||
continue
|
||||
|
||||
# Create system prompt
|
||||
system_prompt = f"""You are {char_config.name}.
|
||||
system_prompt = f"""You are {char_data['name']}.
|
||||
|
||||
Personality: {char_config.personality}
|
||||
Personality: {char_data['personality']}
|
||||
|
||||
Speaking Style: {char_config.speaking_style}
|
||||
Speaking Style: {char_data['speaking_style']}
|
||||
|
||||
Background: {char_config.background}
|
||||
Background: {char_data['background']}
|
||||
|
||||
Interests: {', '.join(char_config.interests)}
|
||||
Interests: {', '.join(char_data['interests'])}
|
||||
|
||||
Always respond as {char_config.name}, staying true to your personality and speaking style.
|
||||
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_config.name,
|
||||
personality=char_config.personality,
|
||||
name=char_data['name'],
|
||||
personality=char_data['personality'],
|
||||
system_prompt=system_prompt,
|
||||
interests=char_config.interests,
|
||||
speaking_style=char_config.speaking_style,
|
||||
background=char_config.background,
|
||||
avatar_url=char_config.avatar_url or "",
|
||||
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_config.name}")
|
||||
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}")
|
||||
|
||||
Reference in New Issue
Block a user