openrag/frontend/components/provider-health-banner.tsx
Lucas Oliveira 37faf94979
feat: adds anthropic provider, splits onboarding editing into two, support provider changing with generic llm and embedding components (#373)
* Added flows with new components

* commented model provider assignment

* Added agent component display name

* commented provider assignment, assign provider on the generic component, assign custom values

* fixed ollama not showing loading steps, fixed loading steps never being removed

* made embedding and llm model optional on onboarding call

* added isEmbedding handling on useModelSelection

* added isEmbedding on onboarding card, separating embedding from non embedding card

* Added one additional step to configure embeddings

* Added embedding provider config

* Changed settings.py to return if not embedding

* Added editing fields to onboarding

* updated onboarding and flows_service to change embedding and llm separately

* updated templates that needs to be changed with provider values

* updated flows with new components

* Changed config manager to not have default models

* Changed flows_service settings

* Complete steps if not embedding

* Add more onboarding steps

* Removed one step from llm steps

* Added Anthropic as a model for the language model on the frontend

* Added anthropic models

* Added anthropic support on Backend

* Fixed provider health and validation

* Format settings

* Change anthropic logo

* Changed button to not jump

* Changed flows service to make anthropic work

* Fixed some things

* add embedding specific global variables

* updated flows

* fixed ingestion flow

* Implemented anthropic on settings page

* add embedding provider logo

* updated backend to work with multiple provider config

* update useUpdateSettings with new settings type

* updated provider health banner to check for health with new api

* changed queries and mutations to use new api

* changed embedding model input to work with new api

* Implemented provider based config on the frontend

* update existing design

* fixed settings configured

* fixed provider health query to include health check for both the providers

* Changed model-providers to show correctly the configured providers

* Updated prompt

* updated openrag agent

* Fixed settings to allow editing providers and changing llm and embedding models

* updated settings

* changed lf ver

* bump openrag version

* added more steps

* update settings to create the global variables

* updated steps

* updated default prompt

---------

Co-authored-by: Sebastián Estévez <estevezsebastian@gmail.com>
2025-11-11 19:22:16 -03:00

125 lines
3.3 KiB
TypeScript

"use client";
import { AlertTriangle } from "lucide-react";
import { useRouter } from "next/navigation";
import type { ModelProvider } from "@/app/settings/helpers/model-helpers";
import { Banner, BannerIcon, BannerTitle } from "@/components/ui/banner";
import { cn } from "@/lib/utils";
import { useProviderHealthQuery } from "@/src/app/api/queries/useProviderHealthQuery";
import { Button } from "./ui/button";
interface ProviderHealthBannerProps {
className?: string;
}
// Custom hook to check provider health status
export function useProviderHealth() {
const {
data: health,
isLoading,
isFetching,
error,
isError,
} = useProviderHealthQuery();
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<ModelProvider, string> = {
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 (
<Banner
className={cn(
"bg-red-50 dark:bg-red-950 text-foreground border-accent-red border-b w-full",
className,
)}
>
<BannerIcon
className="text-accent-red-foreground"
icon={AlertTriangle}
/>
<BannerTitle className="font-medium flex items-center gap-2">
{llmError && embeddingError ? (
<>Provider errors - {errorMessage}</>
) : (
<>
{providerTitle} error - {errorMessage}
</>
)}
</BannerTitle>
<Button size="sm" onClick={() => router.push(settingsUrl)}>
Fix Setup
</Button>
</Banner>
);
}
return null;
}