'use client'; import { startTransition, useMemo, useOptimistic, useState } from 'react'; import { saveChatModelAsCookie } from '@/app/(chat)/actions'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { chatModels } from '@/lib/ai/models'; import { cn } from '@/lib/utils'; import { CheckCircleFillIcon, ChevronDownIcon } from './icons'; import { entitlementsByUserType } from '@/lib/ai/entitlements'; import type { Session } from 'next-auth'; export function ModelSelector({ session, selectedModelId, className, }: { session: Session; selectedModelId: string; } & React.ComponentProps) { const [open, setOpen] = useState(false); const [optimisticModelId, setOptimisticModelId] = useOptimistic(selectedModelId); const userType = session.user.type; const { availableChatModelIds } = entitlementsByUserType[userType]; const availableChatModels = chatModels.filter((chatModel) => availableChatModelIds.includes(chatModel.id), ); const selectedChatModel = useMemo( () => availableChatModels.find( (chatModel) => chatModel.id === optimisticModelId, ), [optimisticModelId, availableChatModels], ); return ( {availableChatModels.map((chatModel) => { const { id } = chatModel; return ( { setOpen(false); startTransition(() => { setOptimisticModelId(id); saveChatModelAsCookie(id); }); }} data-active={id === optimisticModelId} asChild > ); })} ); }