TypeScript 97.4%
SQL 1%
JavaScript 0.9%
CSS 0.6%
1import type { ProviderId } from "@/lib/ai/core/types";2import { cn } from "@/lib/utils";34/** Monochrome provider glyphs drawn from scratch (no trademarked logos). */5export function ProviderIcon({ provider, className, size = 16 }: { provider: ProviderId | string | null | undefined; className?: string; size?: number }) {6 const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round" as const, strokeLinejoin: "round" as const, "aria-hidden": true };7 const color = (p: string) => ({ color: `var(--p-${p})` });8 switch (provider) {9 case "openai":10 return (11 <svg {...common} className={cn("shrink-0", className)} style={color("openai")}>12 <path d="M12 3.5 19 7.6v8.8L12 20.5 5 16.4V7.6z" />13 <path d="M12 3.5v17M5 7.6l14 8.8M19 7.6 5 16.4" opacity="0.55" />14 </svg>15 );16 case "anthropic":17 return (18 <svg {...common} className={cn("shrink-0", className)} style={color("anthropic")}>19 <path d="M4 19 10.2 5h1.6L18 19h-2.6l-1.3-3.2H9.9L8.6 19z" />20 <path d="M10.6 13.6h3l-1.5-3.8z" opacity="0.55" />21 </svg>22 );23 case "gemini":24 return (25 <svg {...common} className={cn("shrink-0", className)} style={color("gemini")}>26 <path d="M12 3c.6 4.9 4.1 8.4 9 9-4.9.6-8.4 4.1-9 9-.6-4.9-4.1-8.4-9-9 4.9-.6 8.4-4.1 9-9z" />27 </svg>28 );29 case "xai":30 return (31 <svg {...common} className={cn("shrink-0", className)} style={color("xai")}>32 <path d="M5 5l14 14M19 5 5 19" />33 <path d="M12 12l7-7" opacity="0.4" />34 </svg>35 );36 case "mistral":37 // stepped "M" — evokes Mistral's blocky mark without copying it38 return (39 <svg {...common} className={cn("shrink-0", className)} style={color("mistral")} strokeWidth={0} fill="currentColor">40 <rect x="3" y="5" width="3.6" height="14" rx="0.6" />41 <rect x="17.4" y="5" width="3.6" height="14" rx="0.6" />42 <rect x="6.6" y="8" width="3.6" height="4" rx="0.6" opacity="0.8" />43 <rect x="13.8" y="8" width="3.6" height="4" rx="0.6" opacity="0.8" />44 <rect x="10.2" y="11.5" width="3.6" height="4" rx="0.6" opacity="0.6" />45 </svg>46 );47 case "deepseek":48 // a whale-like wave arc49 return (50 <svg {...common} className={cn("shrink-0", className)} style={color("deepseek")}>51 <path d="M3 14c2.5-5 6.5-7 11-6 3.2.7 5.2 2.7 7 5.5-2.2-.4-4 .3-5.4 1.8-1.6-1.4-3.6-2-6-1.6-1.9.3-3.6 1.3-6.6.3z" />52 <path d="M17 11.2h.01" strokeWidth="2.6" />53 <path d="M5 17.5c1.6 1 3.4 1 5.2 0" opacity="0.6" />54 </svg>55 );56 case "kimi":57 // crescent + spark ("moon"shot)58 return (59 <svg {...common} className={cn("shrink-0", className)} style={color("kimi")}>60 <path d="M14.5 3.5a8.5 8.5 0 1 0 6 14.3A9 9 0 0 1 14.5 3.5z" />61 <path d="M6 5.5v3M4.5 7h3" opacity="0.7" />62 </svg>63 );64 case "openrouter":65 // routes converging into one node66 return (67 <svg {...common} className={cn("shrink-0", className)} style={color("openrouter")}>68 <path d="M3 7h5c3 0 3.5 5 6.5 5H21M3 17h5c3 0 3.5-5 6.5-5" />69 <path d="M18.5 9.5 21 12l-2.5 2.5" />70 </svg>71 );72 case "cerebras":73 // wafer / chip74 return (75 <svg {...common} className={cn("shrink-0", className)} style={color("cerebras")}>76 <rect x="6" y="6" width="12" height="12" rx="2" />77 <path d="M9 9h6v6H9z" opacity="0.6" />78 <path d="M9 3v3M15 3v3M9 18v3M15 18v3M3 9h3M3 15h3M18 9h3M18 15h3" />79 </svg>80 );81 case "custom":82 // plug / socket — a server you bring yourself83 return (84 <svg {...common} className={cn("shrink-0", className)} style={color("custom")}>85 <path d="M9 3v4M15 3v4" />86 <path d="M6 7h12v3a6 6 0 0 1-12 0z" />87 <path d="M12 16v5" opacity="0.7" />88 </svg>89 );90 default:91 return (92 <svg {...common} className={cn("shrink-0 text-fg-subtle", className)}>93 <circle cx="12" cy="12" r="8" />94 </svg>95 );96 }97}98