#!/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())