diff --git a/surfsense_web/components/settings/model-connections/connect-fields.tsx b/surfsense_web/components/settings/model-connections/connect-fields.tsx index 6ef7a8408..9febb8a1e 100644 --- a/surfsense_web/components/settings/model-connections/connect-fields.tsx +++ b/surfsense_web/components/settings/model-connections/connect-fields.tsx @@ -1,4 +1,5 @@ import { Eye, EyeOff } from "lucide-react"; +import type { ReactNode } from "react"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { DialogFooter } from "@/components/ui/dialog"; @@ -9,25 +10,27 @@ import { Spinner } from "@/components/ui/spinner"; interface ApiBaseUrlFieldProps { value: string; onChange: (value: string) => void; - optional?: boolean; /** Placeholder, typically the provider's prefilled default base URL. */ placeholder?: string; + hint?: ReactNode; } /** Shared API Base URL input. The prefilled default is passed in via `value`. */ -export function ApiBaseUrlField({ value, onChange, optional, placeholder }: ApiBaseUrlFieldProps) { +export function ApiBaseUrlField({ + value, + onChange, + placeholder, + hint, +}: ApiBaseUrlFieldProps) { return (
- + onChange(event.target.value)} placeholder={placeholder || "https://api.example.com/v1"} /> -

- Local URLs are tested from the backend container, so use host.docker.internal instead of - localhost. -

+ {hint ?

{hint}

: null}
); } diff --git a/surfsense_web/components/settings/model-connections/default-connect-form.tsx b/surfsense_web/components/settings/model-connections/default-connect-form.tsx index 768c0b5da..ce638f5e6 100644 --- a/surfsense_web/components/settings/model-connections/default-connect-form.tsx +++ b/surfsense_web/components/settings/model-connections/default-connect-form.tsx @@ -2,6 +2,19 @@ import { useEffect, useState } from "react"; import { ApiBaseUrlField, ApiKeyField } from "./connect-fields"; import type { ProviderConnectFormProps } from "./provider-metadata"; +function baseUrlHint(provider: string) { + if (provider === "ollama_chat" || provider === "lm_studio") { + return "For local servers, use host.docker.internal instead of localhost."; + } + if (provider === "openai_compatible") { + return "Enter the full endpoint URL."; + } + if (provider === "openai" || provider === "anthropic" || provider === "openrouter") { + return "Override only if you route through a proxy or gateway."; + } + return undefined; +} + /** * Connect form for OpenAI-compatible / native key providers (OpenAI, Anthropic, * OpenRouter, OpenAI-Compatible, LM Studio, Ollama, …). The base URL is @@ -16,6 +29,7 @@ export function DefaultConnectForm({ const [baseUrl, setBaseUrl] = useState(defaultBaseUrl); const [apiKey, setApiKey] = useState(""); const isOllama = provider === "ollama_chat"; + const hint = baseUrlHint(provider); const canSubmit = !(baseUrlRequired && !baseUrl.trim()); useEffect(() => { @@ -27,8 +41,8 @@ export function DefaultConnectForm({ (null); const [currentDraft, setCurrentDraft] = useState({ base_url: null, api_key: null, @@ -99,12 +100,20 @@ export function ProviderConnectDialog({ return ( - + { + event.preventDefault(); + titleRef.current?.focus(); + }} + >
{providerIcon(provider, "size-5")}
- Connect {meta.name} + + Connect {meta.name} + {meta.subtitle}