diff --git a/gui/src/pages/ClaudeCode.tsx b/gui/src/pages/ClaudeCode.tsx index 03e439e61..58517220d 100644 --- a/gui/src/pages/ClaudeCode.tsx +++ b/gui/src/pages/ClaudeCode.tsx @@ -69,7 +69,7 @@ export default function ClaudeCode({ apiBase }: { apiBase: string }) { }, [load]); const modelOptions = useMemo(() => { - const options = (state?.available ?? []).map(m => ({ value: m, label: String(modelLabel(m)) })); + const options = (state?.available ?? []).map(m => ({ value: m, label: modelLabel(m) })); return [{ value: "", label: t("claude.smallFastModelUnsetOption") }, ...options]; }, [state?.available, t]); diff --git a/gui/tests/claudecode-fetch-errors.test.tsx b/gui/tests/claudecode-fetch-errors.test.tsx index f3bd72429..a04e8ba46 100644 --- a/gui/tests/claudecode-fetch-errors.test.tsx +++ b/gui/tests/claudecode-fetch-errors.test.tsx @@ -172,3 +172,34 @@ test("ClaudeCode save treats an empty 200 body as success", async () => { testWindow.close(); } }); + +test("ClaudeCode helper model options render icon-backed model names", async () => { + globalThis.fetch = (async (input) => { + if (String(input).endsWith("/api/claude-code")) { + return Response.json({ ...CLAUDE_OK, available: ["gpt-5.6-luna"] }); + } + return new Response(null, { status: 404 }); + }) as typeof fetch; + + const { container, root, testWindow } = await mountClaudeCode(); + try { + const helperModel = container.querySelector( + '[role="combobox"][aria-label="Background helper model"]', + ); + expect(helperModel).toBeTruthy(); + + await act(async () => { + helperModel!.click(); + await Promise.resolve(); + }); + + const optionText = [...testWindow.document.querySelectorAll('[role="option"]')] + .map(option => option.textContent) + .join("\n"); + expect(optionText).toContain("gpt-5.6-luna"); + expect(optionText).not.toContain("[object Object]"); + } finally { + await act(async () => root.unmount()); + testWindow.close(); + } +});