@@ -2,6 +2,7 @@ import React from "react";
22import AnthropicIcon from "@/browser/assets/icons/anthropic.svg?react" ;
33import OpenAIIcon from "@/browser/assets/icons/openai.svg?react" ;
44import AWSIcon from "@/browser/assets/icons/aws.svg?react" ;
5+ import MuxIcon from "@/browser/assets/icons/mux.svg?react" ;
56import { TooltipWrapper , Tooltip } from "@/browser/components/Tooltip" ;
67import { formatModelDisplayName } from "@/common/utils/ai/modelDisplay" ;
78
@@ -11,46 +12,83 @@ interface ModelDisplayProps {
1112 showTooltip ?: boolean ;
1213}
1314
15+ /**
16+ * Parse a model string into provider and model name.
17+ * Handles mux-gateway format: "mux-gateway:inner-provider/model-name"
18+ * Returns: { provider, modelName, isMuxGateway, innerProvider }
19+ */
20+ function parseModelString ( modelString : string ) : {
21+ provider : string ;
22+ modelName : string ;
23+ isMuxGateway : boolean ;
24+ innerProvider : string ;
25+ } {
26+ const [ provider , rest ] = modelString . includes ( ":" )
27+ ? modelString . split ( ":" , 2 )
28+ : [ "" , modelString ] ;
29+
30+ // Handle mux-gateway format: mux-gateway:anthropic/claude-sonnet-4-5
31+ if ( provider === "mux-gateway" && rest . includes ( "/" ) ) {
32+ const [ innerProvider , modelName ] = rest . split ( "/" , 2 ) ;
33+ return { provider, modelName, isMuxGateway : true , innerProvider } ;
34+ }
35+
36+ return { provider, modelName : rest , isMuxGateway : false , innerProvider : "" } ;
37+ }
38+
39+ /** Get icon component for a provider name */
40+ function getProviderIcon ( provider : string ) : React . ReactNode {
41+ switch ( provider ) {
42+ case "anthropic" :
43+ return < AnthropicIcon /> ;
44+ case "openai" :
45+ return < OpenAIIcon /> ;
46+ case "bedrock" :
47+ return < AWSIcon /> ;
48+ case "mux-gateway" :
49+ return < MuxIcon /> ;
50+ default :
51+ return null ;
52+ }
53+ }
54+
1455/**
1556 * Display a model name with its provider icon.
1657 * Supports format "provider:model-name" (e.g., "anthropic:claude-sonnet-4-5")
58+ * Also supports mux-gateway: "mux-gateway:anthropic/claude-sonnet-4-5"
59+ * -> Shows mux icon + inner provider icon + model name + "(mux gateway)"
1760 *
1861 * Uses standard inline layout for natural text alignment.
1962 * Icon is 1em (matches font size) with vertical-align: middle.
2063 */
2164export const ModelDisplay : React . FC < ModelDisplayProps > = ( { modelString, showTooltip = true } ) => {
22- const [ provider , modelName ] = modelString . includes ( ":" )
23- ? modelString . split ( ":" , 2 )
24- : [ "" , modelString ] ;
65+ const { provider, modelName, isMuxGateway, innerProvider } = parseModelString ( modelString ) ;
2566
26- // Map provider names to their icons
27- const getProviderIcon = ( ) => {
28- switch ( provider ) {
29- case "anthropic" :
30- return < AnthropicIcon /> ;
31- case "openai" :
32- return < OpenAIIcon /> ;
33- case "bedrock" :
34- return < AWSIcon /> ;
35- default :
36- return null ;
37- }
38- } ;
39-
40- const providerIcon = getProviderIcon ( ) ;
67+ // For mux-gateway, show the inner provider's icon (the model's actual provider)
68+ const providerIcon = isMuxGateway ? getProviderIcon ( innerProvider ) : getProviderIcon ( provider ) ;
69+ const muxIcon = isMuxGateway ? getProviderIcon ( "mux-gateway" ) : null ;
4170 const displayName = formatModelDisplayName ( modelName ) ;
71+ const suffix = isMuxGateway ? " (mux gateway)" : "" ;
72+
73+ const iconClass =
74+ "mr-[0.3em] inline-block h-[1.1em] w-[1.1em] align-[-0.19em] [&_svg]:block [&_svg]:h-full [&_svg]:w-full [&_svg_.st0]:fill-current [&_svg_circle]:!fill-current [&_svg_path]:!fill-current [&_svg_rect]:!fill-current" ;
4275
4376 const content = (
4477 < span className = "inline normal-case" data-model-display >
78+ { muxIcon && (
79+ < span className = { iconClass } data-model-icon = "mux" >
80+ { muxIcon }
81+ </ span >
82+ ) }
4583 { providerIcon && (
46- < span
47- className = "mr-[0.3em] inline-block h-[1.1em] w-[1.1em] align-[-0.19em] [&_svg]:block [&_svg]:h-full [&_svg]:w-full [&_svg_.st0]:fill-current [&_svg_circle]:!fill-current [&_svg_path]:!fill-current [&_svg_rect]:!fill-current"
48- data-model-icon
49- >
84+ < span className = { iconClass } data-model-icon >
5085 { providerIcon }
5186 </ span >
5287 ) }
53- < span className = "inline" > { displayName } </ span >
88+ < span className = "inline" >
89+ { displayName }
90+ { suffix }
91+ </ span >
5492 </ span >
5593 ) ;
5694
0 commit comments