Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| SAAP OpenRouter Integration Agent (FREE Fallback) | |
| OpenRouter GLM 4.5 Air (kostenlos) als Fallback für colossus Server | |
| Author: Hanan Wandji Danga | |
| """ | |
| import os | |
| from dotenv import load_dotenv | |
| import requests | |
| import json | |
| import time | |
| import asyncio | |
| import logging | |
| from typing import Dict, List, Optional, Any | |
| # Load environment variables | |
| load_dotenv() | |
| class OpenRouterSAAPAgent: | |
| def __init__(self, agent_name: str, role: str, api_key: Optional[str] = None): | |
| """ | |
| OpenRouter SAAP Agent für GLM 4.5 Air (FREE) als Fallback | |
| Args: | |
| agent_name: Name des Agents | |
| role: Rolle des Agents | |
| api_key: OpenRouter API Key (optional für FREE models) | |
| """ | |
| self.agent_name = agent_name | |
| self.role = role | |
| self.api_key = api_key | |
| self.base_url = "https://openrouter.ai/api/v1" | |
| self.model_name = "deepseek/deepseek-chat" # FREE model | |
| # Fallback models (alle kostenlos) | |
| self.free_models = [ | |
| "deepseek/deepseek-chat", | |
| "microsoft/phi-3-medium-4k-instruct:free", | |
| "microsoft/phi-3-mini-128k-instruct:free", | |
| "huggingface/zephyr-7b-beta:free", | |
| "openchat/openchat-7b:free" | |
| ] | |
| # Agent Context | |
| self.context = self._initialize_context() | |
| # Logging | |
| logging.basicConfig(level=logging.INFO) | |
| self.logger = logging.getLogger(f"OpenRouterSAAP.{agent_name}") | |
| self.logger.info(f"🌐 {agent_name} ({role}) initialized with OpenRouter FREE") | |
| def _initialize_context(self) -> str: | |
| """Rollenspezifischer Kontext""" | |
| contexts = { | |
| "Analyst": """Du bist ein SAAP Analyst Agent. Du spezialisierst dich auf: | |
| - Datenanalyse und Requirements Engineering | |
| - Performance-Bewertung von Multi-Agent-Systemen | |
| - Use Case Definition und Dokumentation | |
| - Optimierungspotentiale identifizieren""", | |
| "Fallback": """Du bist ein SAAP Fallback Agent. Du hilfst bei: | |
| - Backup-Processing wenn primäre Agenten nicht verfügbar sind | |
| - Allgemeine Anfragen beantworten | |
| - System-Stabilität durch Redundanz gewährleisten | |
| - Kontinuität der SAAP-Services sicherstellen""" | |
| } | |
| return contexts.get(self.role, contexts["Fallback"]) | |
| async def send_request_to_openrouter(self, prompt: str, max_tokens: int = 400) -> Dict[str, Any]: | |
| """ | |
| Sendet Request an OpenRouter API (FREE models) | |
| """ | |
| start_time = time.time() | |
| headers = { | |
| "Content-Type": "application/json", | |
| } | |
| # API Key nur wenn vorhanden (für FREE models optional) | |
| if self.api_key: | |
| headers["Authorization"] = f"Bearer {self.api_key}" | |
| payload = { | |
| "model": self.model_name, | |
| "messages": [ | |
| {"role": "system", "content": self.context}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| "max_tokens": max_tokens, | |
| "temperature": 0.7 | |
| } | |
| try: | |
| response = requests.post( | |
| f"{self.base_url}/chat/completions", | |
| headers=headers, | |
| json=payload, | |
| timeout=30 | |
| ) | |
| response_time = time.time() - start_time | |
| if response.status_code == 200: | |
| data = response.json() | |
| response_text = data['choices'][0]['message']['content'] | |
| token_count = data.get('usage', {}).get('total_tokens', 0) | |
| result = { | |
| "success": True, | |
| "response": response_text, | |
| "response_time": round(response_time, 2), | |
| "token_count": token_count, | |
| "model": self.model_name, | |
| "agent_role": self.role, | |
| "provider": "OpenRouter FREE", | |
| "timestamp": time.time() | |
| } | |
| self.logger.info(f"✅ OpenRouter Response: {response_time:.2f}s, FREE model") | |
| return result | |
| else: | |
| # Try fallback models if primary fails | |
| if response.status_code == 429 or response.status_code == 402: # Rate limit or payment | |
| return await self._try_fallback_models(prompt, max_tokens) | |
| error_result = { | |
| "success": False, | |
| "error": f"HTTP {response.status_code}: {response.text}", | |
| "response_time": round(response_time, 2), | |
| "timestamp": time.time() | |
| } | |
| return error_result | |
| except requests.exceptions.RequestException as e: | |
| error_result = { | |
| "success": False, | |
| "error": f"OpenRouter request failed: {str(e)}", | |
| "response_time": round(time.time() - start_time, 2), | |
| "timestamp": time.time() | |
| } | |
| self.logger.error(f"❌ OpenRouter Error: {e}") | |
| return error_result | |
| async def _try_fallback_models(self, prompt: str, max_tokens: int) -> Dict[str, Any]: | |
| """ | |
| Versucht verschiedene FREE models als Fallback | |
| """ | |
| self.logger.info("🔄 Trying fallback models...") | |
| for model in self.free_models[1:]: # Skip first (already tried) | |
| self.logger.info(f"🔄 Trying {model}...") | |
| old_model = self.model_name | |
| self.model_name = model | |
| result = await self.send_request_to_openrouter(prompt, max_tokens) | |
| if result["success"]: | |
| self.logger.info(f"✅ Fallback successful with {model}") | |
| return result | |
| # Restore original model for next attempt | |
| self.model_name = old_model | |
| await asyncio.sleep(1) # Rate limiting | |
| return { | |
| "success": False, | |
| "error": "All fallback models failed", | |
| "timestamp": time.time() | |
| } | |
| async def health_check(self) -> Dict[str, Any]: | |
| """ | |
| Health check für OpenRouter FREE services | |
| """ | |
| try: | |
| test_prompt = "Hello, this is a connection test for SAAP." | |
| result = await self.send_request_to_openrouter(test_prompt, max_tokens=20) | |
| return { | |
| "agent_name": self.agent_name, | |
| "provider": "OpenRouter", | |
| "status": "healthy" if result["success"] else "unhealthy", | |
| "model": self.model_name, | |
| "response_time": result.get("response_time", 0), | |
| "error": result.get("error") if not result["success"] else None, | |
| "timestamp": time.time() | |
| } | |
| except Exception as e: | |
| return { | |
| "agent_name": self.agent_name, | |
| "provider": "OpenRouter", | |
| "status": "error", | |
| "error": str(e), | |
| "timestamp": time.time() | |
| } | |
| # Utility function für SAAP Fallback-System | |
| def create_openrouter_fallback_agent(api_key: Optional[str] = None) -> OpenRouterSAAPAgent: | |
| """ | |
| Erstellt OpenRouter Fallback Agent für SAAP System | |
| """ | |
| return OpenRouterSAAPAgent("fallback_analyst", "Analyst", api_key) | |
| class SAAPHybridSystem: | |
| """ | |
| Hybrid System: colossus (Primary) + OpenRouter (Fallback) | |
| """ | |
| def __init__(self, colossus_api_key: str, openrouter_api_key: Optional[str] = None): | |
| from colossus_saap_agent import ColossusSAAPAgent | |
| self.primary_agent = ColossusSAAPAgent("hybrid_primary", "Coordinator", colossus_api_key) | |
| self.fallback_agent = OpenRouterSAAPAgent("hybrid_fallback", "Fallback", openrouter_api_key) | |
| self.logger = logging.getLogger("SAAPHybrid") | |
| async def process_with_fallback(self, prompt: str, max_tokens: int = 400) -> Dict[str, Any]: | |
| """ | |
| Versucht zuerst colossus, dann OpenRouter als Fallback | |
| """ | |
| self.logger.info("🚀 Processing with hybrid primary/fallback system") | |
| # Try primary (colossus) first | |
| try: | |
| primary_result = await self.primary_agent.send_request_to_colossus(prompt, max_tokens) | |
| if primary_result["success"]: | |
| primary_result["provider"] = "colossus (Primary)" | |
| self.logger.info("✅ Primary (colossus) successful") | |
| return primary_result | |
| else: | |
| self.logger.warning(f"⚠️ Primary failed: {primary_result.get('error')}") | |
| except Exception as e: | |
| self.logger.error(f"❌ Primary system error: {e}") | |
| # Fallback to OpenRouter | |
| self.logger.info("🔄 Switching to OpenRouter fallback...") | |
| fallback_result = await self.fallback_agent.send_request_to_openrouter(prompt, max_tokens) | |
| if fallback_result["success"]: | |
| fallback_result["fallback_used"] = True | |
| fallback_result["provider"] = "OpenRouter (Fallback)" | |
| self.logger.info("✅ Fallback (OpenRouter) successful") | |
| else: | |
| self.logger.error("❌ Both primary and fallback failed") | |
| return fallback_result | |
| if __name__ == "__main__": | |
| # Demo OpenRouter Integration | |
| async def demo_openrouter(): | |
| print("🌐 OpenRouter FREE Model Demo") | |
| # Test OpenRouter agent | |
| agent = OpenRouterSAAPAgent("demo_fallback", "Analyst") | |
| # Health check | |
| health = await agent.health_check() | |
| print(f"Health: {health}") | |
| if health["status"] == "healthy": | |
| # Test query | |
| result = await agent.send_request_to_openrouter( | |
| "Erkläre die Vorteile eines Hybrid-AI-Systems mit Primary und Fallback." | |
| ) | |
| print(f"Response: {result.get('response', 'No response')}") | |
| print(f"Time: {result.get('response_time')}s") | |
| print(f"Model: {result.get('model')}") | |
| # Demo Hybrid System | |
| async def demo_hybrid(): | |
| print("\n🔄 Hybrid System Demo (colossus + OpenRouter)") | |
| COLOSSUS_KEY = os.getenv("COLOSSUS_API_KEY") | |
| if not COLOSSUS_KEY: | |
| print("❌ Error: COLOSSUS_API_KEY not set in environment variables") | |
| print("Please set it in backend/.env file") | |
| return | |
| hybrid = SAAPHybridSystem(COLOSSUS_KEY) | |
| result = await hybrid.process_with_fallback( | |
| "Was sind die Hauptvorteile von Multi-Agent-Systemen?" | |
| ) | |
| print(f"Provider: {result.get('provider', 'Unknown')}") | |
| print(f"Response: {result.get('response', 'No response')[:100]}...") | |
| print(f"Fallback used: {result.get('fallback_used', False)}") | |
| # Run demos | |
| async def run_demos(): | |
| await demo_openrouter() | |
| await demo_hybrid() | |
| asyncio.run(run_demos()) | |