"use client"; import { AlertTriangle } from "lucide-react"; import { useRouter } from "next/navigation"; import { useProviderHealthQuery } from "@/app/api/queries/useProviderHealthQuery"; import type { ModelProvider } from "@/app/settings/_helpers/model-helpers"; import { Banner, BannerIcon, BannerTitle } from "@/components/ui/banner"; import { cn } from "@/lib/utils"; import { useChat } from "@/contexts/chat-context"; import { Button } from "./ui/button"; interface ProviderHealthBannerProps { className?: string; } // Custom hook to check provider health status export function useProviderHealth() { const { hasChatError } = useChat(); const { data: health, isLoading, isFetching, error, isError, } = useProviderHealthQuery({ test_completion: hasChatError, // Use test_completion=true when chat errors occur }); const isHealthy = health?.status === "healthy" && !isError; // Only consider unhealthy if backend is up but provider validation failed // Don't show banner if backend is unavailable const isUnhealthy = health?.status === "unhealthy" || health?.status === "error"; const isBackendUnavailable = health?.status === "backend-unavailable" || isError; return { health, isLoading, isFetching, error, isError, isHealthy, isUnhealthy, isBackendUnavailable, }; } const providerTitleMap: Record = { openai: "OpenAI", anthropic: "Anthropic", ollama: "Ollama", watsonx: "IBM watsonx.ai", }; export function ProviderHealthBanner({ className }: ProviderHealthBannerProps) { const { isLoading, isHealthy, isUnhealthy, health } = useProviderHealth(); const router = useRouter(); // Only show banner when provider is unhealthy (not when backend is unavailable) if (isLoading || isHealthy) { return null; } if (isUnhealthy) { const llmProvider = health?.llm_provider || health?.provider; const embeddingProvider = health?.embedding_provider; const llmError = health?.llm_error; const embeddingError = health?.embedding_error; // Determine which provider has the error let errorProvider: string | undefined; let errorMessage: string; if (llmError && embeddingError) { // Both have errors - show combined message errorMessage = health?.message || "Provider validation failed"; errorProvider = undefined; // Don't link to a specific provider } else if (llmError) { // Only LLM has error errorProvider = llmProvider; errorMessage = llmError; } else if (embeddingError) { // Only embedding has error errorProvider = embeddingProvider; errorMessage = embeddingError; } else { // Fallback to original message errorMessage = health?.message || "Provider validation failed"; errorProvider = llmProvider; } const providerTitle = errorProvider ? providerTitleMap[errorProvider as ModelProvider] || errorProvider : "Provider"; const settingsUrl = errorProvider ? `/settings?setup=${errorProvider}` : "/settings"; return ( {llmError && embeddingError ? ( <>Provider errors - {errorMessage} ) : ( <> {providerTitle} error - {errorMessage} )} ); } return null; }