From 15030dacc5e7fc55bd14cc944df76e56c21f7429 Mon Sep 17 00:00:00 2001 From: Finesssee <90105158+Finesssee@users.noreply.github.com> Date: Sat, 9 May 2026 21:47:20 +0700 Subject: [PATCH 1/2] Recognize ACP registry agent icons --- .../ai/components/icons/provider-icons.tsx | 69 ++++++++++++++++--- src/features/ai/tests/provider-icons.test.ts | 21 ++++++ 2 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 src/features/ai/tests/provider-icons.test.ts diff --git a/src/features/ai/components/icons/provider-icons.tsx b/src/features/ai/components/icons/provider-icons.tsx index 0fad5be0f..aaa11d825 100644 --- a/src/features/ai/components/icons/provider-icons.tsx +++ b/src/features/ai/components/icons/provider-icons.tsx @@ -2,6 +2,19 @@ import type { SVGProps } from "react"; import { cn } from "@/utils/cn"; type IconProps = SVGProps & { size?: number }; +export type ProviderIconKind = + | "openai" + | "v0" + | "anthropic" + | "gemini" + | "xai" + | "deepseek" + | "mistral" + | "ollama" + | "openrouter" + | "moonshot" + | "qwen" + | "custom"; const defaultProps = (size = 14, className?: string): SVGProps => ({ width: size, @@ -148,22 +161,16 @@ export function ProviderIcon({ }) { const props = { size, className: cn("shrink-0", className) }; - switch (providerId) { + switch (resolveProviderIconKind(providerId)) { case "openai": - case "codex-cli": return ; case "v0": return ; case "anthropic": - case "claude-code": return ; case "gemini": - case "google": - case "gemini-cli": return ; - case "grok": case "xai": - case "x-ai": return ; case "deepseek": return ; @@ -173,15 +180,57 @@ export function ProviderIcon({ return ; case "openrouter": return ; - case "kimi-cli": + case "moonshot": return ; case "qwen": - case "qwen-code": return ; - case "opencode": case "custom": return ; default: return ; } } + +export function resolveProviderIconKind(providerId: string): ProviderIconKind { + const normalizedId = providerId.toLowerCase(); + + switch (normalizedId) { + case "openai": + case "codex-cli": + case "codex-acp": + return "openai"; + case "v0": + return "v0"; + case "anthropic": + case "claude-code": + case "claude-acp": + return "anthropic"; + case "gemini": + case "google": + case "gemini-cli": + return "gemini"; + case "grok": + case "xai": + case "x-ai": + return "xai"; + case "deepseek": + return "deepseek"; + case "mistral": + case "mistral-vibe": + return "mistral"; + case "ollama": + return "ollama"; + case "openrouter": + return "openrouter"; + case "kimi": + case "kimi-cli": + return "moonshot"; + case "qwen": + case "qwen-code": + return "qwen"; + case "opencode": + case "custom": + default: + return "custom"; + } +} diff --git a/src/features/ai/tests/provider-icons.test.ts b/src/features/ai/tests/provider-icons.test.ts new file mode 100644 index 000000000..9674dc06c --- /dev/null +++ b/src/features/ai/tests/provider-icons.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "vite-plus/test"; +import { resolveProviderIconKind } from "../components/icons/provider-icons"; + +describe("resolveProviderIconKind", () => { + it("recognizes legacy and registry ACP provider ids", () => { + expect(resolveProviderIconKind("codex-cli")).toBe("openai"); + expect(resolveProviderIconKind("codex-acp")).toBe("openai"); + expect(resolveProviderIconKind("claude-code")).toBe("anthropic"); + expect(resolveProviderIconKind("claude-acp")).toBe("anthropic"); + expect(resolveProviderIconKind("gemini-cli")).toBe("gemini"); + expect(resolveProviderIconKind("gemini")).toBe("gemini"); + expect(resolveProviderIconKind("kimi-cli")).toBe("moonshot"); + expect(resolveProviderIconKind("kimi")).toBe("moonshot"); + expect(resolveProviderIconKind("qwen-code")).toBe("qwen"); + expect(resolveProviderIconKind("mistral-vibe")).toBe("mistral"); + }); + + it("falls back to the custom terminal glyph for unknown agent ids", () => { + expect(resolveProviderIconKind("local-agent")).toBe("custom"); + }); +}); From 690b67c9389b4b8884423756a6e8c310b6ed6f58 Mon Sep 17 00:00:00 2001 From: Finesssee <90105158+Finesssee@users.noreply.github.com> Date: Sat, 9 May 2026 21:58:20 +0700 Subject: [PATCH 2/2] Use catalog icons for ACP agents --- .../ai/components/icons/provider-icons.tsx | 38 +++++++++++++++++++ .../components/selectors/agent-selector.tsx | 17 ++++++++- src/features/ai/tests/provider-icons.test.ts | 16 +++++++- .../components/tabs/extensions-settings.tsx | 12 ++++++ 4 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/features/ai/components/icons/provider-icons.tsx b/src/features/ai/components/icons/provider-icons.tsx index aaa11d825..229e029d3 100644 --- a/src/features/ai/components/icons/provider-icons.tsx +++ b/src/features/ai/components/icons/provider-icons.tsx @@ -152,14 +152,38 @@ export function CustomAPIIcon({ size, className, ...props }: IconProps) { export function ProviderIcon({ providerId, + catalogIconUrl, size = 14, className, }: { providerId: string; + catalogIconUrl?: string | null; size?: number; className?: string; }) { const props = { size, className: cn("shrink-0", className) }; + const resolvedCatalogIconUrl = resolveCatalogIconUrl(catalogIconUrl); + + if (resolvedCatalogIconUrl) { + return ( +