""" Bot runner for local development. This script is called as a subprocess by the local FastAPI server. It reads configuration from command line arguments and starts the bot. """ import argparse import asyncio import json import os import sys from loguru import logger # Add parent directory (project root) to Python path for imports sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from bot_config import BotConfig def parse_args(): """Parse command line arguments.""" parser = argparse.ArgumentParser(description="Pipecat bot runner") parser.add_argument("--session-id", required=True, help="Session ID for the bot") parser.add_argument("--room-url", required=True, help="Daily room URL") parser.add_argument("--token", required=True, help="Daily room token") # Bot data can be provided as JSON string or file bot_data_group = parser.add_mutually_exclusive_group(required=True) bot_data_group.add_argument("--bot-data", help="JSON bot configuration data") bot_data_group.add_argument( "--bot-config-file", help="Path to JSON bot configuration file" ) parser.add_argument("--bot-name", default="bot", help="Bot name") parser.add_argument("--recording-dir", default="/tmp", help="Recording directory") parser.add_argument( "--local-recording", action="store_true", help="Enable local recording" ) parser.add_argument( "--disable-rtvi", action="store_true", help="Disable RTVI processor and observer", ) return parser.parse_args() async def main(): """Main entry point for the bot runner.""" try: # Parse command line arguments args = parse_args() # Parse and validate bot data try: if args.bot_data: raw_bot_data = json.loads(args.bot_data) elif args.bot_config_file: with open(args.bot_config_file, "r") as f: raw_bot_data = json.load(f) logger.info(f"📄 Loaded bot config from file: {args.bot_config_file}") else: logger.error("❌ No bot data provided") sys.exit(1) except FileNotFoundError as e: logger.error(f"❌ Bot config file not found: {e}") sys.exit(1) except json.JSONDecodeError as e: logger.error(f"❌ Failed to parse bot data JSON: {e}") sys.exit(1) except ValueError as e: logger.error(f"❌ Invalid bot data format: {e}") sys.exit(1) except Exception as e: logger.error(f"❌ Failed to validate bot data: {e}") sys.exit(1) # Create bot config config = BotConfig( session_id=args.session_id, room_url=args.room_url, token=args.token, bot_data=raw_bot_data, bot_name=args.bot_name, recording_dir=args.recording_dir, local_recording=args.local_recording, rtvi_enabled=not args.disable_rtvi, ) logger.info(f"🤖 Starting bot runner for session: {config.session_id}") logger.info(f"🏠 Room URL: {config.room_url}") logger.info(f"📋 Bot name: {config.bot_name}") # Import and run the bot from bot import main as bot_main await bot_main(config) except KeyboardInterrupt: logger.info("🛑 Bot runner interrupted by user") if __name__ == "__main__": # Configure logging logger.remove() # Remove default handler logger.add( sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | bot | {message}", level="INFO", ) # Run the bot asyncio.run(main())