feat: remove model-name entry from onboarding to match connect-only settings

Onboarding still asked for a model name for openrouter/aigateway/ollama/
openai-compatible. It now mirrors the settings dialog: entering a key (or
base URL) is enough and the model is resolved silently from the fetched
list (same precedence), with openai-compatible keeping a visible Model
field as its escape hatch. Save payload shape and multi-provider flow
unchanged.
This commit is contained in:
Prakhar Pandey 2026-07-14 13:10:52 +05:30
parent e74ce4e9a5
commit 7ddc82f25d
2 changed files with 27 additions and 19 deletions

View file

@ -42,14 +42,11 @@ export function LlmSetupStep({ state }: LlmSetupStepProps) {
} = state
const isMoreProvider = moreProviders.some(p => p.id === llmProvider)
// Hosted providers (openai/anthropic/google) get a default model, so we only
// ask for a model on providers that truly need one (local/custom/gateway),
// or as a fallback if no model is set yet.
// Hosted providers (openai/anthropic/google) fetch their models from the API
// key on test, so they never need a manual model field. Only local/custom/
// gateway providers, where the user must specify a model, show the input.
const hostedProviders: LlmProviderFlavor[] = ["openai", "anthropic", "google"]
const showModelInput = !hostedProviders.includes(llmProvider)
// Connect-only, mirroring Settings: entering a key (or base URL) is enough
// and the model is resolved silently at save. openai-compatible is the sole
// exception with a visible Model field — its /models endpoint often doesn't
// exist, so a typed value must be able to win.
const showModelInput = llmProvider === "openai-compatible"
const renderProviderCard = (provider: typeof primaryProviders[0], index: number) => {
const isSelected = llmProvider === provider.id
@ -150,9 +147,9 @@ export function LlmSetupStep({ state }: LlmSetupStepProps) {
{/* Provider configuration */}
<div className="space-y-4">
{/* Cloud providers get a default model auto-selected; only local/custom
providers (no catalog) need a model here. Users can pick any of the
provider's models later in the chat view. */}
{/* Every provider resolves its model silently at save. openai-compatible
alone keeps this field, since its /models is unreliable and a typed
value must win; leaving it blank auto-selects from the fetched list. */}
{showModelInput && (
<div className="space-y-2">
<label className="text-xs font-medium text-muted-foreground">
@ -167,7 +164,7 @@ export function LlmSetupStep({ state }: LlmSetupStepProps) {
<Input
value={activeConfig.model}
onChange={(e) => updateProviderConfig(llmProvider, { model: e.target.value })}
placeholder="Enter model"
placeholder="Model ID (leave empty to auto-select)"
/>
)}
{modelsError && (

View file

@ -457,13 +457,24 @@ export function useOnboardingState(open: boolean, onComplete: (opts?: { startTou
return false
}
const preferred = preferredDefaults[llmProvider]
// A model the user explicitly entered always wins — this used to prefer
// catalog[0], which silently replaced the user's Ollama model with
// whatever model the local server happened to list first.
const model = modelInputShown
? (typed || catalog[0] || "")
: ((preferred && catalog.includes(preferred) && preferred) || catalog[0] || typed || "")
// Resolve the model silently — same precedence as the settings dialog's
// resolvedModel, so onboarding no longer asks users to type one.
// openai-compatible keeps a visible Model field (its /models is
// unreliable), so a typed value there wins; otherwise the typed/saved
// model if the fetched list still has it, else the flavor's preferred
// default, else the first fetched id. An empty list falls back to
// whatever was typed/seeded.
let model: string
if (llmProvider === "openai-compatible" && typed) {
model = typed
} else if (catalog.length > 0) {
const preferred = preferredDefaults[llmProvider]
model = (typed && catalog.includes(typed))
? typed
: ((preferred && catalog.includes(preferred)) ? preferred : catalog[0])
} else {
model = typed
}
// `models` is the user's curated assistant-model list (shown in Settings),
// NOT the full provider catalog. Onboarding seeds it with just the selected