@@ -16,6 +16,7 @@ import {
1616 type ChangeEvent ,
1717 type Dispatch ,
1818 memo ,
19+ type ReactNode ,
1920 type SetStateAction ,
2021 useCallback ,
2122 useEffect ,
@@ -52,6 +53,7 @@ import {
5253 PromptInputTools ,
5354} from "../ai-elements/prompt-input" ;
5455import { Button } from "../ui/button" ;
56+ import { Tooltip , TooltipContent , TooltipTrigger } from "../ui/tooltip" ;
5557import { PaperclipIcon , StopIcon } from "./icons" ;
5658import { PreviewAttachment } from "./preview-attachment" ;
5759import {
@@ -695,6 +697,22 @@ function ModelSelectorOption({
695697 setOpen : Dispatch < SetStateAction < boolean > > ;
696698} ) {
697699 const [ logoProvider ] = model . id . split ( "/" ) ;
700+ const maybeWithTooltip = ( icon : ReactNode , label : string ) => {
701+ if ( ! curated ) {
702+ return icon ;
703+ }
704+
705+ return (
706+ < Tooltip >
707+ < TooltipTrigger asChild >
708+ < span className = "inline-flex" > { icon } </ span >
709+ </ TooltipTrigger >
710+ < TooltipContent side = "top" sideOffset = { 8 } >
711+ { label }
712+ </ TooltipContent >
713+ </ Tooltip >
714+ ) ;
715+ } ;
698716 const handleSelect = useCallback ( ( ) => {
699717 if ( ! curated ) {
700718 return ;
@@ -709,33 +727,60 @@ function ModelSelectorOption({
709727 } , 50 ) ;
710728 } , [ curated , model . id , onModelChange , setOpen ] ) ;
711729
712- return (
730+ const option = (
713731 < ModelSelectorItem
732+ aria-disabled = { ! curated }
714733 className = { cn (
715- "flex w-full" ,
734+ "flex w-full transition-colors " ,
716735 model . id === selectedModelId &&
717736 "border-b border-dashed border-foreground/50" ,
718- ! curated && "opacity-40 cursor-default"
737+ curated
738+ ? "data-[selected=true]:bg-muted data-[selected=true]:text-foreground"
739+ : "cursor-not-allowed opacity-40 data-[selected=true]:bg-transparent data-[selected=true]:opacity-60 data-[selected=true]:ring-1 data-[selected=true]:ring-muted-foreground/30 data-[selected=true]:ring-inset"
719740 ) }
720741 onSelect = { handleSelect }
721742 value = { model . id }
722743 >
723744 < ModelSelectorLogo provider = { logoProvider } />
724745 < ModelSelectorName > { model . name } </ ModelSelectorName >
725746 < div className = "ml-auto flex items-center gap-2 text-foreground/70" >
726- { capabilities ?. [ model . id ] ?. tools ? (
727- < WrenchIcon className = "size-3.5" />
728- ) : null }
729- { capabilities ?. [ model . id ] ?. vision ? (
730- < EyeIcon className = "size-3.5" />
731- ) : null }
732- { capabilities ?. [ model . id ] ?. reasoning ? (
733- < BrainIcon className = "size-3.5" />
734- ) : null }
747+ { capabilities ?. [ model . id ] ?. tools
748+ ? maybeWithTooltip (
749+ < WrenchIcon className = "size-3.5" /> ,
750+ "Supports tool use"
751+ )
752+ : null }
753+ { capabilities ?. [ model . id ] ?. vision
754+ ? maybeWithTooltip (
755+ < EyeIcon className = "size-3.5" /> ,
756+ "Supports vision"
757+ )
758+ : null }
759+ { capabilities ?. [ model . id ] ?. reasoning
760+ ? maybeWithTooltip (
761+ < BrainIcon className = "size-3.5" /> ,
762+ "Supports reasoning"
763+ )
764+ : null }
735765 { ! curated && < LockIcon className = "size-3 text-muted-foreground/50" /> }
736766 </ div >
737767 </ ModelSelectorItem >
738768 ) ;
769+
770+ if ( curated ) {
771+ return option ;
772+ }
773+
774+ return (
775+ < Tooltip >
776+ < TooltipTrigger asChild >
777+ < div className = "w-full cursor-not-allowed" > { option } </ div >
778+ </ TooltipTrigger >
779+ < TooltipContent side = "right" sideOffset = { 8 } >
780+ This model is not available in the demo.
781+ </ TooltipContent >
782+ </ Tooltip >
783+ ) ;
739784}
740785
741786function PureModelSelectorCompact ( {
@@ -775,7 +820,7 @@ function PureModelSelectorCompact({
775820 < ModelSelectorName > { selectedModel . name } </ ModelSelectorName >
776821 </ Button >
777822 </ ModelSelectorTrigger >
778- < ModelSelectorContent >
823+ < ModelSelectorContent commandDefaultValue = { selectedModel . id } >
779824 < ModelSelectorInput placeholder = "Search models..." />
780825 < ModelSelectorList >
781826 { ( ( ) => {
0 commit comments