diff --git a/webview-ui/src/components/chat/ChatTextArea.tsx b/webview-ui/src/components/chat/ChatTextArea.tsx index 654f2e1011e..c2e9bd92cab 100644 --- a/webview-ui/src/components/chat/ChatTextArea.tsx +++ b/webview-ui/src/components/chat/ChatTextArea.tsx @@ -106,11 +106,16 @@ export const ChatTextArea = forwardRef( } = useExtensionState() // Find the ID and display text for the currently selected API configuration. - const { currentConfigId, displayName } = useMemo(() => { + const { currentConfigId, displayName, tooltipContent } = useMemo(() => { const currentConfig = listApiConfigMeta?.find((config) => config.name === currentApiConfigName) + const configName = currentApiConfigName || "" + const modelId = currentConfig?.modelId return { currentConfigId: currentConfig?.id || "", - displayName: currentApiConfigName || "", // Use the name directly for display. + displayName: modelId ? `${configName} · ${modelId}` : configName, + tooltipContent: modelId + ? `${configName}${currentConfig?.apiProvider ? ` (${currentConfig.apiProvider})` : ""} · ${modelId}` + : configName, } }, [listApiConfigMeta, currentApiConfigName]) @@ -1310,7 +1315,7 @@ export const ChatTextArea = forwardRef( value={currentConfigId} displayName={displayName} disabled={selectApiConfigDisabled} - title={t("chat:selectApiConfig")} + title={tooltipContent || t("chat:selectApiConfig")} onChange={handleApiConfigChange} triggerClassName="min-w-[28px] text-ellipsis overflow-hidden flex-shrink" listApiConfigMeta={listApiConfigMeta || []} diff --git a/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx index 0b63a68f4ec..8e2128a6940 100644 --- a/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/ChatTextArea.spec.tsx @@ -1057,6 +1057,39 @@ describe("ChatTextArea", () => { expect(apiConfigDropdown).toHaveAttribute("disabled") }) + it("should display model ID alongside config name when modelId is available", () => { + ;(useExtensionState as ReturnType).mockReturnValue({ + filePaths: [], + openedTabs: [], + taskHistory: [], + cwd: "/test/workspace", + currentApiConfigName: "my-config", + listApiConfigMeta: [ + { id: "cfg1", name: "my-config", apiProvider: "anthropic", modelId: "claude-sonnet-4-20250514" }, + ], + }) + + render() + const apiConfigDropdown = getApiConfigDropdown() + expect(apiConfigDropdown).toHaveTextContent("my-config · claude-sonnet-4-20250514") + }) + + it("should display only config name when modelId is not available", () => { + ;(useExtensionState as ReturnType).mockReturnValue({ + filePaths: [], + openedTabs: [], + taskHistory: [], + cwd: "/test/workspace", + currentApiConfigName: "my-config", + listApiConfigMeta: [{ id: "cfg1", name: "my-config" }], + }) + + render() + const apiConfigDropdown = getApiConfigDropdown() + expect(apiConfigDropdown).toHaveTextContent("my-config") + expect(apiConfigDropdown).not.toHaveTextContent("·") + }) + describe("enter key behavior", () => { it("should send on Enter and allow newline on Shift+Enter in default mode", () => { const onSend = vi.fn()