import { Cpu } from "lucide-react";
export interface ProviderIconProps {
provider: string;
size?: "sm" | "md" | "lg";
}
const sizeMap = {
sm: 16,
md: 20,
lg: 24,
};
// Anthropic "A" logo from SimpleIcons
function AnthropicIcon({ size, color, label = "Anthropic" }: { size: number; color: string; label?: string }) {
return (
);
}
// OpenAI flower logo from Iconify/SimpleIcons
function OpenAIIcon({ size, color, label = "OpenAI" }: { size: number; color: string; label?: string }) {
return (
);
}
// Google Gemini sparkle logo from SimpleIcons
function GeminiIcon({ size, color, label = "Google Gemini" }: { size: number; color: string; label?: string }) {
return (
);
}
// Ollama llama head logo from SimpleIcons
function OllamaIcon({ size, color, label = "Ollama" }: { size: number; color: string; label?: string }) {
return (
);
}
// MiniMax logo from SimpleIcons — stylized "M" grid mark
function MiniMaxIcon({ size, color, label = "MiniMax" }: { size: number; color: string; label?: string }) {
return (
);
}
// Z.ai / Zhipu AI logo — stylized "Z" mark from brand identity
function ZaiIcon({ size, color, label = "Z.ai" }: { size: number; color: string; label?: string }) {
return (
);
}
// Kimi / Moonshot AI logo — crescent moon mark from official Moonshot AI brand identity
// Source: https://raw.githubusercontent.com/gilbarbara/logos/master/logos/moonshot-ai.svg
// The moon crescent shape is derived from the official Moonshot AI logo
// For a 24x24 icon, we use a simplified crescent moon path
function KimiIcon({ size, color, label = "Kimi" }: { size: number; color: string; label?: string }) {
return (
);
}
function BedrockIcon({ size, color, label = "Amazon Bedrock" }: { size: number; color: string; label?: string }) {
return (
);
}
function XaiIcon({ size, color, label = "xAI" }: { size: number; color: string; label?: string }) {
return (
);
}
function OpencodeIcon({ size, color, label = "Opencode" }: { size: number; color: string; label?: string }) {
return (
);
}
// OpenRouter ring mark — simplified geometric version of the OpenRouter brand symbol.
function OpenRouterIcon({ size, color, label = "OpenRouter" }: { size: number; color: string; label?: string }) {
return (
);
}
// GitHub logo (Octocat mark) from SimpleIcons.
function GitHubIcon({ size, color, label = "GitHub" }: { size: number; color: string; label?: string }) {
return (
);
}
// Anthropic "A" mark composited with a small terminal "> _" badge in the
// bottom-right, visually signalling "Anthropic, but via the local CLI".
function ClaudeCliIcon({ size, color, label = "Anthropic — via Claude CLI" }: { size: number; color: string; label?: string }) {
return (
);
}
const providerConfig: Record<
string,
{ component: typeof AnthropicIcon; color: string; label?: string }
> = {
// Branded provider colors are tokenized in app/styles.css for theme-system consistency.
anthropic: { component: AnthropicIcon, color: "var(--provider-anthropic)" },
"claude-cli": { component: ClaudeCliIcon, color: "var(--provider-anthropic)", label: "Anthropic — via Claude CLI" },
"pi-claude-cli": { component: ClaudeCliIcon, color: "var(--provider-anthropic)", label: "Anthropic — via Claude CLI" },
openai: { component: OpenAIIcon, color: "var(--provider-openai)" },
"openai-codex": { component: OpenAIIcon, color: "var(--provider-openai)", label: "OpenAI Codex" }, // OpenAI alias
google: { component: GeminiIcon, color: "var(--provider-gemini)" },
gemini: { component: GeminiIcon, color: "var(--provider-gemini)" }, // Gemini alias family
"google-antigravity": { component: GeminiIcon, color: "var(--provider-gemini)", label: "Google Gemini" },
// Monochrome marks use theme-aware text color for dark/light safety.
ollama: { component: OllamaIcon, color: "var(--text)" },
github: { component: GitHubIcon, color: "var(--text)" },
"github-copilot": { component: GitHubIcon, color: "var(--text)", label: "GitHub Copilot" },
// OpenRouter appears in onboarding auth cards and should not fall back to CPU.
openrouter: { component: OpenRouterIcon, color: "var(--provider-openrouter)" },
minimax: { component: MiniMaxIcon, color: "var(--provider-minimax)" },
zai: { component: ZaiIcon, color: "var(--provider-zai)" },
kimi: { component: KimiIcon, color: "var(--provider-kimi)" },
moonshot: { component: KimiIcon, color: "var(--provider-kimi)" }, // Moonshot alias
"kimi-coding": { component: KimiIcon, color: "var(--provider-kimi)", label: "Kimi" }, // Kimi alias
bedrock: { component: BedrockIcon, color: "var(--provider-bedrock)" },
"amazon-bedrock": { component: BedrockIcon, color: "var(--provider-bedrock)", label: "Amazon Bedrock" },
xai: { component: XaiIcon, color: "var(--text)" },
grok: { component: XaiIcon, color: "var(--text)", label: "xAI" },
opencode: { component: OpencodeIcon, color: "var(--provider-opencode)" },
};
export function ProviderIcon({ provider, size = "sm" }: ProviderIconProps) {
const normalizedProvider = provider.toLowerCase();
const config = providerConfig[normalizedProvider];
const IconComponent = config?.component;
const color = config?.color ?? "var(--text-muted)";
const label = config?.label;
const iconSize = sizeMap[size];
return (
{IconComponent ? (
) : (
)}
);
}