import { type ProviderInstanceId, type ProviderDriverKind, type ResolvedKeybindingsConfig, } from "@t3tools/contracts"; import { memo, useEffect, useMemo, 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 { ProviderInstanceIcon } from "./ProviderInstanceIcon"; import { ModelEsque, getTriggerDisplayModelLabel, getTriggerDisplayModelName, } from "./providerIconUtils"; import { setModelPickerOpen } from "../../modelPickerOpenState"; import type { ProviderInstanceEntry } from "../../providerInstances"; export const ProviderModelPicker = memo(function ProviderModelPicker(props: { /** * The instance currently selected in the composer. Drives the trigger * icon, label and the default-highlighted combobox row. */ activeInstanceId: ProviderInstanceId; model: string; lockedProvider: ProviderDriverKind | null; lockedContinuationGroupKey?: string | null; /** Instance entries rendered in the sidebar + used to resolve display name. */ instanceEntries: ReadonlyArray; keybindings?: ResolvedKeybindingsConfig; modelOptionsByInstance: ReadonlyMap>; activeProviderIconClassName?: string; compact?: boolean; disabled?: boolean; terminalOpen?: boolean; open?: boolean; triggerVariant?: VariantProps["variant"]; triggerClassName?: string; onOpenChange?: (open: boolean) => void; onInstanceModelChange: (instanceId: ProviderInstanceId, model: string) => void; }) { const [uncontrolledIsMenuOpen, setUncontrolledIsMenuOpen] = useState(false); const isMenuOpen = props.open ?? uncontrolledIsMenuOpen; // Resolve the active instance entry by exact routing key. The composer // resolves fallbacks before rendering this component; if the selected // instance disappears, do not infer a replacement from its driver kind. const activeEntry = useMemo(() => { return ( props.instanceEntries.find((entry) => entry.instanceId === props.activeInstanceId) ?? null ); }, [props.activeInstanceId, props.instanceEntries]); const activeInstanceId = props.activeInstanceId; const selectedInstanceOptions = props.modelOptionsByInstance.get(activeInstanceId) ?? []; // If the current slug belongs to a different instance (for example after // a provider switch or disable), prefer the active instance's first // option so the trigger icon and label stay in sync instead of showing // a stale foreign slug. const selectedModel = selectedInstanceOptions.find((option) => option.slug === props.model) ?? selectedInstanceOptions[0]; const triggerTitle = selectedModel ? getTriggerDisplayModelName(selectedModel) : props.model; const triggerSubtitle = selectedModel?.subProvider; const triggerLabel = selectedModel ? getTriggerDisplayModelLabel(selectedModel) : props.model; const duplicateDriverCount = props.instanceEntries.filter( (entry) => activeEntry !== null && entry.driverKind === activeEntry.driverKind, ).length; const showInstanceBadge = Boolean(activeEntry?.accentColor) || duplicateDriverCount > 1; const setIsMenuOpen = (open: boolean) => { props.onOpenChange?.(open); if (props.open === undefined) { setUncontrolledIsMenuOpen(open); } }; useEffect(() => { setModelPickerOpen(isMenuOpen); return () => { setModelPickerOpen(false); }; }, [isMenuOpen]); const handleInstanceModelChange = (instanceId: ProviderInstanceId, model: string) => { if (props.disabled) return; props.onInstanceModelChange(instanceId, model); setIsMenuOpen(false); }; return ( { if (props.disabled) { setIsMenuOpen(false); return; } setIsMenuOpen(open); }} > } > {activeEntry ? ( ) : null} } > {triggerSubtitle ? ( <> {triggerSubtitle} {triggerTitle} ) : ( triggerTitle )} {triggerLabel} setIsMenuOpen(false)} onInstanceModelChange={handleInstanceModelChange} /> ); });