import { type ProviderKind, type ResolvedKeybindingsConfig, type ServerProvider, } from "@t3tools/contracts"; import { memo, useEffect, useState } from "react"; import type { VariantProps } from "class-variance-authority"; import { ChevronDownIcon } from "lucide-react"; import { Button, buttonVariants } from "../ui/button"; import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import { cn } from "~/lib/utils"; import { ModelPickerContent } from "./ModelPickerContent"; import { ModelEsque, PROVIDER_ICON_BY_PROVIDER, getTriggerDisplayModelLabel, getTriggerDisplayModelName, } from "./providerIconUtils"; import { setModelPickerOpen } from "../../modelPickerOpenState"; export const ProviderModelPicker = memo(function ProviderModelPicker(props: { provider: ProviderKind; model: string; lockedProvider: ProviderKind | null; providers?: ReadonlyArray; keybindings?: ResolvedKeybindingsConfig; modelOptionsByProvider: Record>; activeProviderIconClassName?: string; compact?: boolean; disabled?: boolean; terminalOpen?: boolean; open?: boolean; triggerVariant?: VariantProps["variant"]; triggerClassName?: string; onOpenChange?: (open: boolean) => void; onProviderModelChange: (provider: ProviderKind, model: string) => void; }) { const [uncontrolledIsMenuOpen, setUncontrolledIsMenuOpen] = useState(false); const activeProvider = props.lockedProvider ?? props.provider; const isMenuOpen = props.open ?? uncontrolledIsMenuOpen; const selectedProviderOptions = props.modelOptionsByProvider[activeProvider]; // If the current slug belongs to a different provider (for example after a provider // switch or disable), prefer the active provider's first option so the trigger icon // and label stay in sync instead of showing a stale foreign slug. const selectedModel = selectedProviderOptions.find((option) => option.slug === props.model) ?? selectedProviderOptions[0]; const ProviderIcon = PROVIDER_ICON_BY_PROVIDER[activeProvider]; const triggerTitle = selectedModel ? getTriggerDisplayModelName(selectedModel) : props.model; const triggerSubtitle = selectedModel?.subProvider; const triggerLabel = selectedModel ? getTriggerDisplayModelLabel(selectedModel) : props.model; const setIsMenuOpen = (open: boolean) => { props.onOpenChange?.(open); if (props.open === undefined) { setUncontrolledIsMenuOpen(open); } }; useEffect(() => { setModelPickerOpen(isMenuOpen); return () => { setModelPickerOpen(false); }; }, [isMenuOpen]); const handleProviderModelChange = (provider: ProviderKind, model: string) => { if (props.disabled) return; props.onProviderModelChange(provider, model); setIsMenuOpen(false); }; return ( { if (props.disabled) { setIsMenuOpen(false); return; } setIsMenuOpen(open); }} > } > setIsMenuOpen(false)} onProviderModelChange={handleProviderModelChange} /> ); });