From f7596e0551b0ce85689b89cd5d0775b58a4a6476 Mon Sep 17 00:00:00 2001 From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 15:20:40 +0000 Subject: [PATCH] fix(vscode): show default fallback model in small model selector when not configured Display 'kilo-auto/small (default)' as an italic placeholder in the small model selector trigger when no model is explicitly configured, so users can see which model is actually being used for background tasks. Closes #8087 --- .../tests/unit/model-selector-utils.test.ts | 38 +++++++++++++++++++ .../src/components/settings/ModelsTab.tsx | 3 +- .../src/components/shared/ModelSelector.tsx | 12 +++++- .../components/shared/model-selector-utils.ts | 3 +- .../kilo-vscode/webview-ui/src/i18n/en.ts | 2 + 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/kilo-vscode/tests/unit/model-selector-utils.test.ts b/packages/kilo-vscode/tests/unit/model-selector-utils.test.ts index ec29af0b2cb..71a3ce2d921 100644 --- a/packages/kilo-vscode/tests/unit/model-selector-utils.test.ts +++ b/packages/kilo-vscode/tests/unit/model-selector-utils.test.ts @@ -165,4 +165,42 @@ describe("buildTriggerLabel", () => { const raw = { providerID: "", modelID: "claude-3-5-sonnet" } expect(buildTriggerLabel(undefined, undefined, undefined, raw, false, "", true, labels)).toBe("Select model") }) + + it("returns placeholder when allowClear, no selection, and placeholder is provided", () => { + expect( + buildTriggerLabel( + undefined, + undefined, + undefined, + null, + true, + "Not set", + true, + labels, + "kilo-auto/small (default)", + ), + ).toBe("kilo-auto/small (default)") + }) + + it("returns clearLabel when allowClear, no selection, and no placeholder", () => { + expect(buildTriggerLabel(undefined, undefined, undefined, null, true, "Not set", true, labels, undefined)).toBe( + "Not set", + ) + }) + + it("prefers resolved name over placeholder when value is selected", () => { + expect( + buildTriggerLabel( + "Claude Haiku", + "anthropic", + "Anthropic", + null, + true, + "Not set", + true, + labels, + "kilo-auto/small (default)", + ), + ).toBe("Anthropic / Claude Haiku") + }) }) diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx index ee0eb3f56ac..5faa7b55f4c 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/ModelsTab.tsx @@ -59,8 +59,9 @@ const ModelsTab: Component = () => { onSelect={handleModelSelect("small_model")} placement="bottom-start" allowClear - clearLabel={language.t("settings.providers.notSet")} + clearLabel={language.t("settings.providers.smallModel.notSet")} includeAutoSmall + placeholder={language.t("settings.providers.smallModel.default")} /> diff --git a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx index 115a4bce587..06c2571de60 100644 --- a/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/shared/ModelSelector.tsx @@ -49,6 +49,8 @@ export interface ModelSelectorBaseProps { clearLabel?: string /** Include the kilo-auto/small model in the list — defaults to false */ includeAutoSmall?: boolean + /** Placeholder shown on the trigger when no value is selected (e.g. default fallback model) */ + placeholder?: string } export const ModelSelectorBase: Component = (props) => { @@ -294,8 +296,11 @@ export const ModelSelectorBase: Component = (props) => { noProviders: language.t("dialog.model.noProviders"), notSet: language.t("dialog.model.notSet"), }, + props.placeholder, ) + const isPlaceholder = () => !props.value?.providerID && !!props.placeholder + return ( = (props) => { }} trigger={ <> - {triggerLabel()} + + {triggerLabel()} + diff --git a/packages/kilo-vscode/webview-ui/src/components/shared/model-selector-utils.ts b/packages/kilo-vscode/webview-ui/src/components/shared/model-selector-utils.ts index 270c03b0d8f..b53482b1e45 100644 --- a/packages/kilo-vscode/webview-ui/src/components/shared/model-selector-utils.ts +++ b/packages/kilo-vscode/webview-ui/src/components/shared/model-selector-utils.ts @@ -48,6 +48,7 @@ export function buildTriggerLabel( clearLabel: string, hasProviders: boolean, labels: { select: string; noProviders: string; notSet: string }, + placeholder?: string, ): string { if (resolvedName) { if (providerID === KILO_GATEWAY_ID) return stripSubProviderPrefix(resolvedName) @@ -57,6 +58,6 @@ export function buildTriggerLabel( if (raw?.providerID && raw?.modelID) { return raw.providerID === KILO_GATEWAY_ID ? raw.modelID : `${raw.providerID} / ${raw.modelID}` } - if (allowClear) return clearLabel || labels.notSet + if (allowClear) return placeholder || clearLabel || labels.notSet return hasProviders ? labels.select : labels.noProviders } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/en.ts b/packages/kilo-vscode/webview-ui/src/i18n/en.ts index 52e1f8216c1..270e552056e 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/en.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/en.ts @@ -1217,6 +1217,8 @@ export const dict = { "settings.providers.smallModel.title": "Small Model", "settings.providers.smallModel.description": "Lightweight model for title generation, commit message generation, prompt enhancement, and other quick tasks", + "settings.providers.smallModel.default": "kilo-auto/small (default)", + "settings.providers.smallModel.notSet": "Not set (use kilo-auto/small)", "settings.providers.modeModels": "Model per Mode", "settings.providers.modeModels.description": "Override the default model for specific modes. If not set, the global default model is used.",