From f4996026cf77fc2454649dcc970dbb19640de29d Mon Sep 17 00:00:00 2001 From: Vasily Zubarev Date: Sat, 4 Apr 2026 14:09:43 +0200 Subject: [PATCH] fix: show LLM choice only in self-hosted mode --- components/settings/llm-settings-form.tsx | 102 ++++++++++------------ 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/components/settings/llm-settings-form.tsx b/components/settings/llm-settings-form.tsx index 961d379..0dbb19e 100644 --- a/components/settings/llm-settings-form.tsx +++ b/components/settings/llm-settings-form.tsx @@ -6,36 +6,25 @@ import { FormError } from "@/components/forms/error" import { FormTextarea } from "@/components/forms/simple" import { Button } from "@/components/ui/button" import { Card, CardTitle } from "@/components/ui/card" +import config from "@/lib/config" +import { PROVIDERS } from "@/lib/llm-providers" import { Field } from "@/prisma/client" +import type { DragEndEvent } from "@dnd-kit/core" +import { closestCenter, DndContext, PointerSensor, useSensor, useSensors } from "@dnd-kit/core" +import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable" import { CircleCheckBig, Edit, GripVertical } from "lucide-react" import Link from "next/link" -import { useState, useActionState } from "react" -import { - DndContext, - closestCenter, - PointerSensor, - useSensor, - useSensors -} from "@dnd-kit/core" -import type { DragEndEvent } from "@dnd-kit/core"; -import { - arrayMove, - SortableContext, - useSortable, - verticalListSortingStrategy -} from "@dnd-kit/sortable" -import { PROVIDERS } from "@/lib/llm-providers"; - +import { useActionState, useState } from "react" function getInitialProviderOrder(settings: Record) { let order: string[] = [] if (!settings.llm_providers) { - order = ['openai', 'google', 'mistral', 'openai_compatible'] + order = ["openai", "google", "mistral", "openai_compatible"] } else { - order = settings.llm_providers.split(",").map(p => p.trim()) + order = settings.llm_providers.split(",").map((p) => p.trim()) } // Remove duplicates and keep only valid providers - return order.filter((key, idx) => PROVIDERS.some(p => p.key === key) && order.indexOf(key) === idx) + return order.filter((key, idx) => PROVIDERS.some((p) => p.key === key) && order.indexOf(key) === idx) } export default function LLMSettingsForm({ @@ -56,9 +45,7 @@ export default function LLMSettingsForm({ values[provider.key] = { apiKey: settings[provider.apiKeyName], model: settings[provider.modelName] || provider.defaultModelName, - baseUrl: provider.baseUrlName - ? (settings[provider.baseUrlName] || provider.defaultBaseUrl || "") - : "", + baseUrl: provider.baseUrlName ? settings[provider.baseUrlName] || provider.defaultBaseUrl || "" : "", } }) return values @@ -77,20 +64,20 @@ export default function LLMSettingsForm({ return ( <>
+ {config.selfHosted.isEnabled && ( +
+ + + Drag provider blocks to reorder. First is highest priority. +
+ )} -
- - - - Drag provider blocks to reorder. First is highest priority. - -
- + {config.selfHosted.isEnabled && } >; - providerValues: Record; - handleProviderValueChange: (providerKey: string, field: "apiKey" | "model" | "baseUrl", value: string) => void; -}; + providerOrder: string[] + setProviderOrder: React.Dispatch> + providerValues: Record + handleProviderValueChange: (providerKey: string, field: "apiKey" | "model" | "baseUrl", value: string) => void +} -function DndProviderBlocks({ providerOrder, setProviderOrder, providerValues, handleProviderValueChange }: DndProviderBlocksProps) { +function DndProviderBlocks({ + providerOrder, + setProviderOrder, + providerValues, + handleProviderValueChange, +}: DndProviderBlocksProps) { const sensors = useSensors(useSensor(PointerSensor)) function handleDragEnd(event: DragEndEvent) { const { active, over } = event @@ -176,17 +168,17 @@ function DndProviderBlocks({ providerOrder, setProviderOrder, providerValues, ha } type SortableProviderBlockProps = { - id: string; - idx: number; - providerKey: string; - value: { apiKey: string; model: string; baseUrl: string }; - handleValueChange: (providerKey: string, field: "apiKey" | "model" | "baseUrl", value: string) => void; -}; + id: string + idx: number + providerKey: string + value: { apiKey: string; model: string; baseUrl: string } + handleValueChange: (providerKey: string, field: "apiKey" | "model" | "baseUrl", value: string) => void +} function SortableProviderBlock({ id, idx, providerKey, value, handleValueChange }: SortableProviderBlockProps) { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id }) - const provider = PROVIDERS.find(p => p.key === providerKey) + const provider = PROVIDERS.find((p) => p.key === providerKey) if (!provider) return null return (
handleValueChange(provider.key, "apiKey", e.target.value)} + onChange={(e) => handleValueChange(provider.key, "apiKey", e.target.value)} className="flex-1 border rounded px-2 py-1" placeholder={provider.baseUrlName ? "API key (optional)" : "API key"} /> @@ -223,7 +215,7 @@ function SortableProviderBlock({ id, idx, providerKey, value, handleValueChange type="text" name={provider.modelName} value={value.model} - onChange={e => handleValueChange(provider.key, "model", e.target.value)} + onChange={(e) => handleValueChange(provider.key, "model", e.target.value)} className="flex-1 border rounded px-2 py-1" placeholder="Model name" /> @@ -233,7 +225,7 @@ function SortableProviderBlock({ id, idx, providerKey, value, handleValueChange type="text" name={provider.baseUrlName} value={value.baseUrl} - onChange={e => handleValueChange(provider.key, "baseUrl", e.target.value)} + onChange={(e) => handleValueChange(provider.key, "baseUrl", e.target.value)} className="w-full border rounded px-2 py-1" placeholder="Base URL (e.g. http://localhost:11434/v1)" /> @@ -241,11 +233,7 @@ function SortableProviderBlock({ id, idx, providerKey, value, handleValueChange {provider.apiDoc && ( Get your API key from{" "} - + {provider.apiDocLabel}