Merge branch 'main' into docs-install-options

This commit is contained in:
Mendon Kissling 2025-11-06 16:45:27 -05:00
commit eff2362214
5 changed files with 79 additions and 21 deletions

View file

@ -1,4 +1,29 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# --- support 'curl ... | bash' without breaking TUI --------------------------
# If this script is being read from a PIPE (curl | bash), slurp it to a temp file
# and re-exec from that file. After that, it's safe to reattach to /dev/tty.
if [ -p /dev/stdin ]; then
tmp="$(mktemp -t openrag.XXXXXX)"
# Read the entire piped script into the temp file
cat > "$tmp"
chmod +x "$tmp"
exec bash "$tmp" "$@"
fi
# Now we are running from a real file, not stdin. It is safe to reattach.
# (Only if not already attached to a TTY)
if [ ! -t 0 ] || [ ! -t 1 ] || [ ! -t 2 ]; then
if [ -e /dev/tty ]; then
exec </dev/tty >/dev/tty 2>&1
else
echo "This installer needs an interactive terminal. Try: bash <(curl -fsSL ...)" >&2
exit 1
fi
fi
set -euo pipefail set -euo pipefail
say() { printf "%s\n" "$*" >&2; } say() { printf "%s\n" "$*" >&2; }

View file

@ -23,8 +23,12 @@ export function useProviderHealth() {
} = useProviderHealthQuery(); } = useProviderHealthQuery();
const isHealthy = health?.status === "healthy" && !isError; 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 = const isUnhealthy =
health?.status === "unhealthy" || health?.status === "error" || isError; health?.status === "unhealthy" || health?.status === "error";
const isBackendUnavailable =
health?.status === "backend-unavailable" || isError;
return { return {
health, health,
@ -34,17 +38,23 @@ export function useProviderHealth() {
isError, isError,
isHealthy, isHealthy,
isUnhealthy, isUnhealthy,
isBackendUnavailable,
}; };
} }
export function ProviderHealthBanner({ className }: ProviderHealthBannerProps) { export function ProviderHealthBanner({ className }: ProviderHealthBannerProps) {
const { isLoading, isHealthy, error } = useProviderHealth(); const { isLoading, isHealthy, isUnhealthy, health } = useProviderHealth();
const router = useRouter(); const router = useRouter();
const { data: settings = {} } = useGetSettingsQuery(); const { data: settings = {} } = useGetSettingsQuery();
if (!isHealthy && !isLoading) { // Only show banner when provider is unhealthy (not when backend is unavailable)
const errorMessage = error?.message || "Provider validation failed"; if (isLoading || isHealthy) {
return null;
}
if (isUnhealthy) {
const errorMessage = health?.message || "Provider validation failed";
const settingsUrl = settings.provider?.model_provider const settingsUrl = settings.provider?.model_provider
? `/settings?setup=${settings.provider?.model_provider}` ? `/settings?setup=${settings.provider?.model_provider}`
: "/settings"; : "/settings";

View file

@ -12,7 +12,7 @@ export interface ProviderHealthDetails {
} }
export interface ProviderHealthResponse { export interface ProviderHealthResponse {
status: "healthy" | "unhealthy" | "error"; status: "healthy" | "unhealthy" | "error" | "backend-unavailable";
message: string; message: string;
provider: string; provider: string;
details?: ProviderHealthDetails; details?: ProviderHealthDetails;
@ -38,21 +38,44 @@ export const useProviderHealthQuery = (
const queryClient = useQueryClient(); const queryClient = useQueryClient();
async function checkProviderHealth(): Promise<ProviderHealthResponse> { async function checkProviderHealth(): Promise<ProviderHealthResponse> {
const url = new URL("/api/provider/health", window.location.origin); try {
const url = new URL("/api/provider/health", window.location.origin);
// Add provider query param if specified
if (params?.provider) {
url.searchParams.set("provider", params.provider);
}
const response = await fetch(url.toString()); // Add provider query param if specified
if (params?.provider) {
if (response.ok) { url.searchParams.set("provider", params.provider);
return await response.json(); }
} else {
// For 400 and 503 errors, still parse JSON for error details const response = await fetch(url.toString());
const errorData = await response.json().catch(() => ({}));
throw new Error(`${providerTitleMap[errorData.provider as ModelProvider] || "Provider"} error: ${errorData.message || "Failed to check provider health"}`); if (response.ok) {
return await response.json();
} else if (response.status === 503) {
// Backend is up but provider validation failed
const errorData = await response.json().catch(() => ({}));
return {
status: "unhealthy",
message: errorData.message || "Provider validation failed",
provider: errorData.provider || params?.provider || "unknown",
details: errorData.details,
};
} else {
// Other backend errors (400, etc.) - treat as provider issues
const errorData = await response.json().catch(() => ({}));
return {
status: "error",
message: errorData.message || "Failed to check provider health",
provider: errorData.provider || params?.provider || "unknown",
details: errorData.details,
};
}
} catch (error) {
// Network error - backend is likely down, don't show provider banner
return {
status: "backend-unavailable",
message: error instanceof Error ? error.message : "Connection failed",
provider: params?.provider || "unknown",
};
} }
} }

View file

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "openrag" name = "openrag"
version = "0.1.30" version = "0.1.31"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"

2
uv.lock generated
View file

@ -2352,7 +2352,7 @@ wheels = [
[[package]] [[package]]
name = "openrag" name = "openrag"
version = "0.1.30" version = "0.1.31"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "agentd" }, { name = "agentd" },