Spaces:
Sleeping
Sleeping
| """ | |
| Hybrid API Endpoints for SAAP OpenRouter Integration | |
| Additional endpoints to support multi-provider functionality | |
| """ | |
| from fastapi import APIRouter, HTTPException, Depends | |
| from typing import Dict, Optional, Any | |
| import logging | |
| from datetime import datetime | |
| from services.agent_manager_hybrid import HybridAgentManagerService | |
| logger = logging.getLogger(__name__) | |
| # Router for hybrid endpoints | |
| hybrid_router = APIRouter(prefix="/api/v1/hybrid", tags=["hybrid"]) | |
| def get_hybrid_manager() -> HybridAgentManagerService: | |
| """Dependency to get hybrid agent manager (if available)""" | |
| # This will be injected by main.py if hybrid mode is enabled | |
| return None | |
| # ===================================================== | |
| # PROVIDER COMPARISON & PERFORMANCE ENDPOINTS | |
| # ===================================================== | |
| async def compare_providers( | |
| agent_id: str, | |
| message_data: Dict[str, str], | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π Send same message to both colossus and OpenRouter for comparison | |
| Useful for benchmarking performance and cost analysis | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| try: | |
| message = message_data.get("message", "") | |
| if not message: | |
| raise HTTPException(status_code=400, detail="Message content required") | |
| logger.info(f"π Provider comparison requested for {agent_id}") | |
| # Send to both providers | |
| comparison = await hybrid_manager.compare_providers(agent_id, message) | |
| if "error" in comparison: | |
| return { | |
| "success": False, | |
| "error": comparison["error"], | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| logger.info(f"β Provider comparison completed for {agent_id}") | |
| return { | |
| "success": True, | |
| "comparison": comparison, | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β Provider comparison error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Comparison failed: {str(e)}") | |
| async def get_provider_statistics( | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π Get comprehensive provider performance statistics | |
| Returns success rates, response times, and cost data | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| try: | |
| stats = hybrid_manager.get_provider_stats() | |
| return { | |
| "success": True, | |
| "statistics": stats, | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β Provider stats error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Statistics failed: {str(e)}") | |
| async def get_openrouter_costs( | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π° Get OpenRouter cost summary and budget status | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| if not hybrid_manager.openrouter_client: | |
| raise HTTPException(status_code=503, detail="OpenRouter client not available") | |
| try: | |
| cost_summary = hybrid_manager.openrouter_client.get_cost_summary() | |
| return { | |
| "success": True, | |
| "costs": cost_summary, | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β OpenRouter cost error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Cost summary failed: {str(e)}") | |
| # ===================================================== | |
| # PROVIDER SWITCHING & CONFIGURATION | |
| # ===================================================== | |
| async def set_primary_provider( | |
| config_data: Dict[str, str], | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π Switch primary provider (colossus/openrouter) | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| try: | |
| provider = config_data.get("provider", "") | |
| if provider not in ["colossus", "openrouter"]: | |
| raise HTTPException(status_code=400, detail="Provider must be 'colossus' or 'openrouter'") | |
| success = await hybrid_manager.set_primary_provider(provider) | |
| if success: | |
| return { | |
| "success": True, | |
| "message": f"Primary provider set to {provider}", | |
| "provider": provider, | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| else: | |
| raise HTTPException(status_code=400, detail=f"Failed to switch to {provider}") | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"β Provider switch error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Provider switch failed: {str(e)}") | |
| async def get_hybrid_status( | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| βΉοΈ Get hybrid system configuration and status | |
| """ | |
| if not hybrid_manager: | |
| return { | |
| "hybrid_enabled": False, | |
| "message": "Hybrid mode not available", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| try: | |
| # Check provider availability | |
| providers_status = { | |
| "colossus": { | |
| "available": hybrid_manager.colossus_client is not None, | |
| "status": hybrid_manager.colossus_connection_status if hasattr(hybrid_manager, 'colossus_connection_status') else "unknown" | |
| }, | |
| "openrouter": { | |
| "available": hybrid_manager.openrouter_client is not None, | |
| "status": "unknown" | |
| } | |
| } | |
| # Test OpenRouter if available | |
| if hybrid_manager.openrouter_client: | |
| try: | |
| or_health = await hybrid_manager.openrouter_client.health_check() | |
| providers_status["openrouter"]["status"] = or_health.get("status", "unknown") | |
| providers_status["openrouter"]["daily_cost"] = or_health.get("daily_cost", 0) | |
| providers_status["openrouter"]["budget_remaining"] = or_health.get("budget_remaining", 0) | |
| except Exception as e: | |
| providers_status["openrouter"]["status"] = f"error: {e}" | |
| return { | |
| "hybrid_enabled": True, | |
| "primary_provider": hybrid_manager.primary_provider, | |
| "failover_enabled": hybrid_manager.enable_failover, | |
| "cost_comparison_enabled": hybrid_manager.enable_cost_comparison, | |
| "providers": providers_status, | |
| "loaded_agents": len(hybrid_manager.agents), | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β Hybrid status error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Status check failed: {str(e)}") | |
| # ===================================================== | |
| # OPTIONAL: DIRECT PROVIDER ENDPOINTS | |
| # ===================================================== | |
| async def chat_with_colossus( | |
| agent_id: str, | |
| message_data: Dict[str, str], | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π€ Direct chat with agent via colossus (bypass primary provider setting) | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| try: | |
| message = message_data.get("message", "") | |
| if not message: | |
| raise HTTPException(status_code=400, detail="Message content required") | |
| # Force colossus provider | |
| response = await hybrid_manager.send_message_to_agent(agent_id, message, "colossus") | |
| if "error" in response: | |
| return { | |
| "success": False, | |
| "error": response["error"], | |
| "provider": "colossus", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| return { | |
| "success": True, | |
| "agent_id": agent_id, | |
| "message": message, | |
| "response": response, | |
| "provider": "colossus", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β colossus chat error: {e}") | |
| raise HTTPException(status_code=500, detail=f"colossus chat failed: {str(e)}") | |
| async def chat_with_openrouter( | |
| agent_id: str, | |
| message_data: Dict[str, str], | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π Direct chat with agent via OpenRouter (bypass primary provider setting) | |
| """ | |
| if not hybrid_manager: | |
| raise HTTPException(status_code=503, detail="Hybrid mode not enabled") | |
| if not hybrid_manager.openrouter_client: | |
| raise HTTPException(status_code=503, detail="OpenRouter client not available") | |
| try: | |
| message = message_data.get("message", "") | |
| if not message: | |
| raise HTTPException(status_code=400, detail="Message content required") | |
| # Force OpenRouter provider | |
| response = await hybrid_manager.send_message_to_agent(agent_id, message, "openrouter") | |
| if "error" in response: | |
| return { | |
| "success": False, | |
| "error": response["error"], | |
| "provider": "openrouter", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| return { | |
| "success": True, | |
| "agent_id": agent_id, | |
| "message": message, | |
| "response": response, | |
| "provider": "openrouter", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| except Exception as e: | |
| logger.error(f"β OpenRouter chat error: {e}") | |
| raise HTTPException(status_code=500, detail=f"OpenRouter chat failed: {str(e)}") | |
| # ===================================================== | |
| # HEALTH CHECK FOR HYBRID SYSTEM | |
| # ===================================================== | |
| async def hybrid_health_check( | |
| hybrid_manager: HybridAgentManagerService = Depends(get_hybrid_manager) | |
| ): | |
| """ | |
| π₯ Comprehensive health check for hybrid system | |
| """ | |
| if not hybrid_manager: | |
| return { | |
| "status": "hybrid_disabled", | |
| "message": "Hybrid mode not enabled - using standard mode", | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| try: | |
| health_status = { | |
| "status": "healthy", | |
| "providers": {}, | |
| "agents_loaded": len(hybrid_manager.agents), | |
| "primary_provider": hybrid_manager.primary_provider, | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| # Check colossus | |
| if hybrid_manager.colossus_client: | |
| try: | |
| # Test colossus connection if method available | |
| if hasattr(hybrid_manager, '_test_colossus_connection'): | |
| await hybrid_manager._test_colossus_connection() | |
| health_status["providers"]["colossus"] = { | |
| "status": getattr(hybrid_manager, 'colossus_connection_status', 'unknown'), | |
| "available": True | |
| } | |
| except Exception as e: | |
| health_status["providers"]["colossus"] = { | |
| "status": f"error: {e}", | |
| "available": False | |
| } | |
| else: | |
| health_status["providers"]["colossus"] = { | |
| "status": "not_configured", | |
| "available": False | |
| } | |
| # Check OpenRouter | |
| if hybrid_manager.openrouter_client: | |
| try: | |
| or_health = await hybrid_manager.openrouter_client.health_check() | |
| health_status["providers"]["openrouter"] = { | |
| "status": or_health.get("status", "unknown"), | |
| "available": or_health.get("status") == "healthy", | |
| "daily_cost": or_health.get("daily_cost", 0), | |
| "budget_remaining": or_health.get("budget_remaining", 0) | |
| } | |
| except Exception as e: | |
| health_status["providers"]["openrouter"] = { | |
| "status": f"error: {e}", | |
| "available": False | |
| } | |
| else: | |
| health_status["providers"]["openrouter"] = { | |
| "status": "not_configured", | |
| "available": False | |
| } | |
| # Overall health status | |
| provider_count = sum(1 for p in health_status["providers"].values() if p["available"]) | |
| if provider_count == 0: | |
| health_status["status"] = "unhealthy" | |
| health_status["message"] = "No providers available" | |
| elif provider_count == 1: | |
| health_status["status"] = "degraded" | |
| health_status["message"] = "Only one provider available" | |
| else: | |
| health_status["status"] = "healthy" | |
| health_status["message"] = "All providers operational" | |
| return health_status | |
| except Exception as e: | |
| logger.error(f"β Hybrid health check error: {e}") | |
| return { | |
| "status": "error", | |
| "error": str(e), | |
| "timestamp": datetime.utcnow().isoformat() | |
| } | |
| # Export router for main.py integration | |
| __all__ = ["hybrid_router", "get_hybrid_manager"] |