diff --git a/api_service/api_models.py b/api_service/api_models.py index 6ff16f1..6bdc3c2 100644 --- a/api_service/api_models.py +++ b/api_service/api_models.py @@ -66,6 +66,13 @@ class UserSettings(BaseModel): # Theme settings theme: ThemeSettings = Field(default_factory=ThemeSettings) + # Custom bot settings + custom_bot_token: Optional[str] = None + custom_bot_enabled: bool = False + custom_bot_prefix: str = "!" + custom_bot_status_text: str = "!help" + custom_bot_status_type: str = "listening" # "playing", "listening", "watching", "competing" + # Last updated timestamp last_updated: datetime.datetime = Field(default_factory=datetime.datetime.now) diff --git a/api_service/dashboard_api_endpoints.py b/api_service/dashboard_api_endpoints.py index 049dbd3..520e295 100644 --- a/api_service/dashboard_api_endpoints.py +++ b/api_service/dashboard_api_endpoints.py @@ -30,6 +30,14 @@ from api_service.dashboard_models import ( # Import settings_manager for database access (use absolute path) import settings_manager +# Import custom bot manager +import sys +import os +parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +if parent_dir not in sys.path: + sys.path.append(parent_dir) +import custom_bot_manager + # Set up logging log = logging.getLogger(__name__) @@ -84,6 +92,13 @@ class GlobalSettings(BaseModel): max_tokens: Optional[int] = None theme: Optional[ThemeSettings] = None + # Custom bot settings + custom_bot_token: Optional[str] = None + custom_bot_enabled: Optional[bool] = None + custom_bot_prefix: Optional[str] = None + custom_bot_status_text: Optional[str] = None + custom_bot_status_type: Optional[str] = None + # CogInfo and CommandInfo models are now imported from dashboard_models # class CommandInfo(BaseModel): # Removed - Imported from dashboard_models @@ -986,7 +1001,12 @@ async def update_global_settings( system_message=settings.system_message, character=settings.character, character_info=settings.character_info, - custom_instructions=settings.custom_instructions + custom_instructions=settings.custom_instructions, + custom_bot_token=settings.custom_bot_token, + custom_bot_enabled=settings.custom_bot_enabled, + custom_bot_prefix=settings.custom_bot_prefix, + custom_bot_status_text=settings.custom_bot_status_text, + custom_bot_status_type=settings.custom_bot_status_type ) # Add theme settings if provided @@ -1021,6 +1041,172 @@ async def update_global_settings( detail=f"Error updating global settings: {str(e)}" ) +# --- Custom Bot Management Endpoints --- + +class CustomBotStatus(BaseModel): + exists: bool + status: str + error: Optional[str] = None + is_running: bool + +@router.get("/custom-bot/status", response_model=CustomBotStatus) +async def get_custom_bot_status( + _user: dict = Depends(get_dashboard_user) +): + """Get the status of the user's custom bot.""" + try: + user_id = _user.get('user_id') + if not user_id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="User ID not found in session" + ) + + # Get the status from the custom bot manager + bot_status = custom_bot_manager.get_custom_bot_status(user_id) + return CustomBotStatus(**bot_status) + except Exception as e: + log.error(f"Error getting custom bot status: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error getting custom bot status: {str(e)}" + ) + +@router.post("/custom-bot/start", status_code=status.HTTP_200_OK) +async def start_custom_bot( + _user: dict = Depends(get_dashboard_user) +): + """Start the user's custom bot.""" + try: + user_id = _user.get('user_id') + if not user_id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="User ID not found in session" + ) + + # Import the database module for user settings + try: + from api_service.api_server import db + except ImportError: + from api_service.api_server import db + + if not db: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="Database connection not available" + ) + + # Get user settings from the database + user_settings = db.get_user_settings(user_id) + if not user_settings: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="User settings not found" + ) + + # Check if custom bot token is set + if not user_settings.custom_bot_token: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Custom bot token not set. Please set a token first." + ) + + # Create the bot if it doesn't exist + bot_status = custom_bot_manager.get_custom_bot_status(user_id) + if not bot_status["exists"]: + success, message = await custom_bot_manager.create_custom_bot( + user_id=user_id, + token=user_settings.custom_bot_token, + prefix=user_settings.custom_bot_prefix, + status_type=user_settings.custom_bot_status_type, + status_text=user_settings.custom_bot_status_text + ) + + if not success: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error creating custom bot: {message}" + ) + + # Start the bot + success, message = custom_bot_manager.run_custom_bot_in_thread( + user_id=user_id, + token=user_settings.custom_bot_token + ) + + if not success: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error starting custom bot: {message}" + ) + + # Update the enabled status in user settings + user_settings.custom_bot_enabled = True + db.save_user_settings(user_id, user_settings) + + return {"message": "Custom bot started successfully"} + except HTTPException: + # Re-raise HTTP exceptions + raise + except Exception as e: + log.error(f"Error starting custom bot: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error starting custom bot: {str(e)}" + ) + +@router.post("/custom-bot/stop", status_code=status.HTTP_200_OK) +async def stop_custom_bot( + _user: dict = Depends(get_dashboard_user) +): + """Stop the user's custom bot.""" + try: + user_id = _user.get('user_id') + if not user_id: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="User ID not found in session" + ) + + # Import the database module for user settings + try: + from api_service.api_server import db + except ImportError: + from api_service.api_server import db + + if not db: + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="Database connection not available" + ) + + # Stop the bot + success, message = custom_bot_manager.stop_custom_bot(user_id) + + if not success: + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error stopping custom bot: {message}" + ) + + # Update the enabled status in user settings + user_settings = db.get_user_settings(user_id) + if user_settings: + user_settings.custom_bot_enabled = False + db.save_user_settings(user_id, user_settings) + + return {"message": "Custom bot stopped successfully"} + except HTTPException: + # Re-raise HTTP exceptions + raise + except Exception as e: + log.error(f"Error stopping custom bot: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error stopping custom bot: {str(e)}" + ) + # --- Cog and Command Management Endpoints --- # Note: These endpoints have been moved to cog_management_endpoints.py diff --git a/api_service/dashboard_web/custom-bot.html b/api_service/dashboard_web/custom-bot.html new file mode 100644 index 0000000..3065454 --- /dev/null +++ b/api_service/dashboard_web/custom-bot.html @@ -0,0 +1,126 @@ + +
diff --git a/api_service/dashboard_web/index.html b/api_service/dashboard_web/index.html index b4ed6c1..cddd355 100644 --- a/api_service/dashboard_web/index.html +++ b/api_service/dashboard_web/index.html @@ -77,6 +77,10 @@ Theme Settings + + + Custom Bot + Command Customization @@ -526,6 +530,14 @@ + + +