From 01456f95bc5fd41243d02a33fb71abef57eb6c67 Mon Sep 17 00:00:00 2001 From: Christopher Chamaletsos Date: Sun, 15 Mar 2026 20:21:04 +0200 Subject: [PATCH] fix: control UI sends correct provider prefix when switching models The model selector was using just the model ID (e.g. "gpt-5.2") as the option value. When sent to sessions.patch, the server would fall back to the session's current provider ("anthropic") yielding "anthropic/gpt-5.2" instead of "openai/gpt-5.2". Now option values use "provider/model" format, and resolveModelOverrideValue and resolveDefaultModelValue also return the full provider-prefixed key so selected state stays consistent. --- ui/src/ui/app-render.helpers.ts | 19 ++++++++++++++----- ui/src/ui/types.ts | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/ui/src/ui/app-render.helpers.ts b/ui/src/ui/app-render.helpers.ts index 77ba247a26d..db6dfc40861 100644 --- a/ui/src/ui/app-render.helpers.ts +++ b/ui/src/ui/app-render.helpers.ts @@ -529,16 +529,24 @@ function resolveModelOverrideValue(state: AppViewState): string { return ""; } // No local override recorded yet — fall back to server data. + // Include provider prefix so the value matches option keys (provider/model). const activeRow = resolveActiveSessionRow(state); - if (activeRow) { - return typeof activeRow.model === "string" ? activeRow.model.trim() : ""; + if (activeRow && typeof activeRow.model === "string" && activeRow.model.trim()) { + const provider = activeRow.modelProvider?.trim(); + const model = activeRow.model.trim(); + return provider ? `${provider}/${model}` : model; } return ""; } function resolveDefaultModelValue(state: AppViewState): string { - const model = state.sessionsResult?.defaults?.model; - return typeof model === "string" ? model.trim() : ""; + const defaults = state.sessionsResult?.defaults; + const model = defaults?.model; + if (typeof model !== "string" || !model.trim()) { + return ""; + } + const provider = defaults?.modelProvider?.trim(); + return provider ? `${provider}/${model.trim()}` : model.trim(); } function buildChatModelOptions( @@ -563,7 +571,8 @@ function buildChatModelOptions( for (const entry of catalog) { const provider = entry.provider?.trim(); - addOption(entry.id, provider ? `${entry.id} · ${provider}` : entry.id); + const value = provider ? `${provider}/${entry.id}` : entry.id; + addOption(value, provider ? `${entry.id} · ${provider}` : entry.id); } if (currentOverride) { diff --git a/ui/src/ui/types.ts b/ui/src/ui/types.ts index d9764a024e6..82c97c6744a 100644 --- a/ui/src/ui/types.ts +++ b/ui/src/ui/types.ts @@ -316,6 +316,7 @@ export type PresenceEntry = { }; export type GatewaySessionsDefaults = { + modelProvider: string | null; model: string | null; contextTokens: number | null; };