from typing import Any, cast from fastapi import APIRouter, HTTPException, Query from ...config.logfire_config import get_logger from ...services.ollama.embedding_router import embedding_router from ...services.ollama.model_discovery_service import model_discovery_service from ...services.ollama.routing.vector_normalization import VectorNormalization from .schemas import EmbeddingRouteRequest, EmbeddingRouteResponse logger = get_logger(__name__) router = APIRouter() @router.post("/embedding/route", response_model=EmbeddingRouteResponse) async def analyze_embedding_route_endpoint(request: EmbeddingRouteRequest) -> EmbeddingRouteResponse: """Analyze optimal routing for embedding operations.""" try: logger.info(f"Analyzing embedding route for {request.model_name} on {request.instance_url}") routing_decision = await embedding_router.route_embedding( model_name=request.model_name, instance_url=request.instance_url, text_content=request.text_sample ) performance_score = VectorNormalization.calculate_performance_score(routing_decision.dimensions) return EmbeddingRouteResponse( target_column=routing_decision.target_column, model_name=routing_decision.model_name, instance_url=routing_decision.instance_url, dimensions=routing_decision.dimensions, confidence=routing_decision.confidence, fallback_applied=routing_decision.fallback_applied, routing_strategy=routing_decision.routing_strategy, performance_score=performance_score, ) except Exception as e: logger.error(f"Error analyzing embedding route: {e}") raise HTTPException(status_code=500, detail=f"Embedding route analysis failed: {str(e)}") from e @router.get("/embedding/routes") async def get_available_embedding_routes_endpoint( instance_urls: list[str] = Query(..., description="Ollama instance URLs"), sort_by_performance: bool = Query(True, description="Sort by performance score"), ) -> dict[str, Any]: """Get all available embedding routes across multiple instances.""" try: logger.info(f"Getting embedding routes for {len(instance_urls)} instances") routes = await embedding_router.get_available_embedding_routes(instance_urls) route_data = [] for route in routes: route_data.append( { "model_name": route.model_name, "instance_url": route.instance_url, "dimensions": route.dimensions, "column_name": route.column_name, "performance_score": route.performance_score, "index_type": embedding_router.get_optimal_index_type(route.dimensions), } ) dimension_stats: dict[int, dict[str, Any]] = {} for route in routes: dim = route.dimensions if dim not in dimension_stats: dimension_stats[dim] = {"count": 0, "models": [], "avg_performance": 0.0} stats_entry = dimension_stats[dim] stats_entry["count"] += 1 cast(list[str], stats_entry["models"]).append(route.model_name) stats_entry["avg_performance"] += float(route.performance_score) for dim_data in dimension_stats.values(): if dim_data["count"] > 0: dim_data["avg_performance"] /= dim_data["count"] return { "total_routes": len(routes), "routes": route_data, "dimension_analysis": dimension_stats, "routing_statistics": embedding_router.get_routing_statistics(), } except Exception as e: logger.error(f"Error getting embedding routes: {e}") raise HTTPException(status_code=500, detail=f"Failed to get embedding routes: {str(e)}") from e @router.delete("/cache") async def clear_ollama_cache_endpoint() -> dict[str, str]: """Clear all Ollama-related caches.""" try: logger.info("Clearing Ollama caches") model_discovery_service.model_cache.clear() model_discovery_service.capability_cache.clear() model_discovery_service.health_cache.clear() embedding_router.clear_routing_cache() return {"message": "All Ollama caches cleared successfully"} except Exception as e: logger.error(f"Error clearing caches: {e}") raise HTTPException(status_code=500, detail=f"Failed to clear caches: {str(e)}") from e