| """ |
| OpenRouter Chat Endpoints for SAAP Frontend |
| Separate endpoints for OpenRouter-specific chat functionality |
| """ |
|
|
| from fastapi import APIRouter, HTTPException, Depends |
| from typing import Dict, Any |
| import logging |
| import os |
| from datetime import datetime |
|
|
| from services.agent_manager import AgentManagerService |
| from agents.openrouter_saap_agent import OpenRouterSAAPAgent |
|
|
| logger = logging.getLogger(__name__) |
|
|
| |
| openrouter_router = APIRouter(prefix="/api/v1/agents", tags=["OpenRouter"]) |
|
|
| def get_agent_manager() -> AgentManagerService: |
| """Dependency injection for agent manager""" |
| from main import saap_app |
| if not saap_app.agent_manager: |
| raise HTTPException(status_code=503, detail="Agent Manager not initialized") |
| return saap_app.agent_manager |
|
|
| @openrouter_router.post("/{agent_id}/chat/openrouter") |
| async def chat_with_agent_via_openrouter( |
| agent_id: str, |
| message_data: Dict[str, Any], |
| agent_manager: AgentManagerService = Depends(get_agent_manager) |
| ): |
| """ |
| 🚀 NEW: Chat with agent using OpenRouter (Fast, Cost-efficient) |
| Endpoint: POST /api/v1/agents/{agent_id}/chat/openrouter |
| """ |
| try: |
| message = message_data.get("message", "") |
| if not message: |
| raise HTTPException(status_code=400, detail="Message content required") |
|
|
| logger.info(f"🌐 OpenRouter Chat request: {agent_id} - {message[:50]}...") |
|
|
| |
| agent = agent_manager.get_agent(agent_id) |
| if not agent: |
| raise HTTPException(status_code=404, detail=f"Agent '{agent_id}' not found") |
|
|
| |
| api_key = os.getenv("OPENROUTER_API_KEY") |
| if not api_key: |
| raise HTTPException( |
| status_code=500, |
| detail="OpenRouter API key not configured" |
| ) |
|
|
| |
| openrouter_agent = OpenRouterSAAPAgent( |
| agent_id, |
| agent.type.value if agent.type else "Assistant", |
| api_key |
| ) |
|
|
| |
| model_map = { |
| "jane_alesi": os.getenv("JANE_ALESI_MODEL", "openai/gpt-4o-mini"), |
| "john_alesi": os.getenv("JOHN_ALESI_MODEL", "deepseek/deepseek-coder"), |
| "lara_alesi": os.getenv("LARA_ALESI_MODEL", "anthropic/claude-3-haiku") |
| } |
| |
| preferred_model = model_map.get(agent_id, "openai/gpt-4o-mini") |
| openrouter_agent.model_name = preferred_model |
|
|
| |
| response = await openrouter_agent.send_request_to_openrouter( |
| message, |
| max_tokens=1000 |
| ) |
|
|
| if response.get("success"): |
| logger.info(f"✅ OpenRouter chat successful: {agent_id}") |
| |
| return { |
| "success": True, |
| "agent_id": agent_id, |
| "provider": "OpenRouter", |
| "model": preferred_model, |
| "message": message, |
| "response": { |
| "content": response.get("response", ""), |
| "provider": f"OpenRouter ({preferred_model})", |
| "response_time": response.get("response_time", 0), |
| "tokens_used": response.get("token_count", 0), |
| "cost_estimate": response.get("cost_estimate", 0.0) |
| }, |
| "timestamp": datetime.utcnow().isoformat() |
| } |
| else: |
| logger.error(f"❌ OpenRouter chat failed: {response.get('error')}") |
| |
| return { |
| "success": False, |
| "agent_id": agent_id, |
| "provider": "OpenRouter", |
| "error": response.get("error", "Unknown OpenRouter error"), |
| "timestamp": datetime.utcnow().isoformat() |
| } |
|
|
| except HTTPException: |
| raise |
| except Exception as e: |
| logger.error(f"❌ OpenRouter endpoint error: {e}") |
| |
| return { |
| "success": False, |
| "agent_id": agent_id, |
| "provider": "OpenRouter", |
| "error": f"OpenRouter endpoint error: {str(e)}", |
| "timestamp": datetime.utcnow().isoformat() |
| } |
|
|
| @openrouter_router.post("/{agent_id}/chat/compare") |
| async def compare_providers( |
| agent_id: str, |
| message_data: Dict[str, Any], |
| agent_manager: AgentManagerService = Depends(get_agent_manager) |
| ): |
| """ |
| 🆚 Compare colossus vs OpenRouter performance side-by-side |
| """ |
| try: |
| message = message_data.get("message", "") |
| if not message: |
| raise HTTPException(status_code=400, detail="Message content required") |
|
|
| logger.info(f"🆚 Provider comparison request: {agent_id}") |
|
|
| |
| import asyncio |
| |
| |
| async def colossus_request(): |
| try: |
| return await agent_manager.send_message_to_agent(agent_id, message) |
| except Exception as e: |
| return {"error": f"colossus error: {str(e)}", "provider": "colossus"} |
|
|
| |
| async def openrouter_request(): |
| try: |
| agent = agent_manager.get_agent(agent_id) |
| if not agent: |
| return {"error": "Agent not found", "provider": "OpenRouter"} |
| |
| api_key = os.getenv("OPENROUTER_API_KEY") |
| if not api_key: |
| return {"error": "API key not configured", "provider": "OpenRouter"} |
|
|
| openrouter_agent = OpenRouterSAAPAgent(agent_id, "Assistant", api_key) |
| response = await openrouter_agent.send_request_to_openrouter(message) |
| |
| return { |
| "provider": "OpenRouter", |
| "content": response.get("response", ""), |
| "response_time": response.get("response_time", 0), |
| "success": response.get("success", False), |
| "error": response.get("error") if not response.get("success") else None |
| } |
| |
| except Exception as e: |
| return {"error": f"OpenRouter error: {str(e)}", "provider": "OpenRouter"} |
|
|
| |
| colossus_result, openrouter_result = await asyncio.gather( |
| colossus_request(), |
| openrouter_request(), |
| return_exceptions=True |
| ) |
|
|
| return { |
| "success": True, |
| "comparison": { |
| "colossus": colossus_result, |
| "openrouter": openrouter_result, |
| "performance_winner": ( |
| "OpenRouter" if ( |
| openrouter_result.get("response_time", float('inf')) < |
| colossus_result.get("response_time", float('inf')) |
| ) else "colossus" |
| ) |
| }, |
| "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)}") |
|
|
| @openrouter_router.get("/{agent_id}/openrouter/status") |
| async def openrouter_status(agent_id: str): |
| """ |
| ℹ️ Get OpenRouter availability status for specific agent |
| """ |
| try: |
| api_key = os.getenv("OPENROUTER_API_KEY") |
| if not api_key: |
| return { |
| "available": False, |
| "error": "OpenRouter API key not configured", |
| "timestamp": datetime.utcnow().isoformat() |
| } |
|
|
| |
| test_agent = OpenRouterSAAPAgent(agent_id, "Test", api_key) |
| health = await test_agent.health_check() |
|
|
| return { |
| "available": health["status"] == "healthy", |
| "model": test_agent.model_name, |
| "response_time": health.get("response_time"), |
| "error": health.get("error"), |
| "timestamp": datetime.utcnow().isoformat() |
| } |
|
|
| except Exception as e: |
| return { |
| "available": False, |
| "error": str(e), |
| "timestamp": datetime.utcnow().isoformat() |
| } |