Spaces:
Running
Running
| from fastapi import APIRouter, Body, HTTPException | |
| from app.config import get_settings | |
| from app.llm.improved_gemini_client import ImprovedGeminiClient | |
| from app.llm.improved_ollama_client import ImprovedOllamaClient | |
| from app.llm.improved_vllm_client import ImprovedVllmClient | |
| from app.models.default_personas import get_default_personas | |
| from app.core.bootstrap import chat_orchestrator, llm, current_provider, available_providers | |
| from pydantic import BaseModel | |
| import os | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| router = APIRouter() | |
| def create_llm_client(provider: str = None): | |
| global current_provider | |
| if provider is None: | |
| provider = current_provider | |
| if provider == "gemini": | |
| try: | |
| return ImprovedGeminiClient(model_name=os.getenv("GEMINI_MODEL")) | |
| except ValueError as e: | |
| logger.warning(f"Gemini API key not found, falling back to Ollama: {e}") | |
| return ImprovedOllamaClient(model_name="llama3.2:1b") | |
| elif provider == "ollama": | |
| return ImprovedOllamaClient(model_name="llama3.2:1b") | |
| elif provider == "vllm": | |
| settings = get_settings() | |
| if not settings.llm.vllm.api_url: | |
| raise ValueError("No vLLM endpoint configured. Set llm.vllm.api_url in your config.") | |
| return ImprovedVllmClient( | |
| api_url=settings.llm.vllm.api_url, | |
| api_key=settings.llm.vllm.api_key, | |
| ) | |
| else: | |
| raise ValueError(f"Unknown provider: {provider}") | |
| # NOTE: Personas and `llm` are already created and registered by | |
| # app/core/bootstrap.py with the correct ResilientLLMClient wrapping | |
| # (primary vLLM + OpenAI fallback). Re-registering them here at module | |
| # import time replaces them with a raw vLLM client that lacks the | |
| # fallback wrapper AND lacks the api_username/api_key wiring, breaking | |
| # both auth and failover. Bootstrap already handles initial setup. | |
| class ProviderSwitch(BaseModel): | |
| provider: str | |
| async def get_current_provider(): | |
| return { | |
| "current_provider": current_provider, | |
| "available_providers": available_providers, | |
| "model_info": { | |
| "name": llm.model_name if hasattr(llm, 'model_name') else "gemini-2.0-flash", | |
| "provider": current_provider | |
| } | |
| } | |
| async def switch_provider(provider_data: ProviderSwitch): | |
| global current_provider, llm | |
| if provider_data.provider not in available_providers: | |
| raise HTTPException(status_code=400, detail=f"Unknown provider: {provider_data.provider}. Available: {available_providers}") | |
| try: | |
| from app.core.bootstrap import ( | |
| create_orchestrator_llm, | |
| create_persona_llm, | |
| ) | |
| current_provider = provider_data.provider | |
| new_llm = create_orchestrator_llm() | |
| llm = new_llm | |
| chat_orchestrator.llm_client = new_llm | |
| persona_llm = create_persona_llm() | |
| new_personas = get_default_personas(persona_llm) | |
| chat_orchestrator.personas.clear() | |
| for persona in new_personas: | |
| chat_orchestrator.register_persona(persona) | |
| return { | |
| "message": f"Successfully switched to {current_provider}", | |
| "current_provider": current_provider, | |
| "model_info": { | |
| "name": new_llm.model_name if hasattr(new_llm, 'model_name') else "gemini-2.0-flash", | |
| "provider": current_provider | |
| } | |
| } | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Failed to switch to {provider_data.provider}: {str(e)}") | |
| async def switch_model(model_name: str = Body(...)): | |
| if "gemini" in model_name.lower(): | |
| return await switch_provider(ProviderSwitch(provider="gemini")) | |
| else: | |
| return await switch_provider(ProviderSwitch(provider="ollama")) | |
| async def get_current_model(): | |
| model_name = llm.model_name if hasattr(llm, 'model_name') else "gemini-2.0-flash" | |
| return { | |
| "model": model_name, | |
| "provider": current_provider | |
| } | |