import { Autocomplete, AutocompleteItem, AutocompleteSection, } from "@nextui-org/react"; import React from "react"; import { useTranslation } from "react-i18next"; import { I18nKey } from "#/i18n/declaration"; import { mapProvider } from "#/utils/map-provider"; import { VERIFIED_MODELS, VERIFIED_PROVIDERS } from "#/utils/verified-models"; import { extractModelAndProvider } from "#/utils/extract-model-and-provider"; interface ModelSelectorProps { isDisabled?: boolean; models: Record; currentModel?: string; } export function ModelSelector({ isDisabled, models, currentModel, }: ModelSelectorProps) { const [, setLitellmId] = React.useState(null); const [selectedProvider, setSelectedProvider] = React.useState( null, ); const [selectedModel, setSelectedModel] = React.useState(null); React.useEffect(() => { if (currentModel) { // runs when resetting to defaults const { provider, model } = extractModelAndProvider(currentModel); setLitellmId(currentModel); setSelectedProvider(provider); setSelectedModel(model); } }, [currentModel]); const handleChangeProvider = (provider: string) => { setSelectedProvider(provider); setSelectedModel(null); const separator = models[provider]?.separator || ""; setLitellmId(provider + separator); }; const handleChangeModel = (model: string) => { const separator = models[selectedProvider || ""]?.separator || ""; let fullModel = selectedProvider + separator + model; if (selectedProvider === "openai") { // LiteLLM lists OpenAI models without the openai/ prefix fullModel = model; } setLitellmId(fullModel); setSelectedModel(model); }; const clear = () => { setSelectedProvider(null); setLitellmId(null); }; const { t } = useTranslation(); return (
{ if (e?.toString()) handleChangeProvider(e.toString()); }} onInputChange={(value) => !value && clear()} defaultSelectedKey={selectedProvider ?? undefined} selectedKey={selectedProvider} inputProps={{ classNames: { inputWrapper: "bg-[#27272A] rounded-md text-sm px-3 py-[10px]", }, }} > {Object.keys(models) .filter((provider) => VERIFIED_PROVIDERS.includes(provider)) .map((provider) => ( {mapProvider(provider)} ))} {Object.keys(models) .filter((provider) => !VERIFIED_PROVIDERS.includes(provider)) .map((provider) => ( {mapProvider(provider)} ))}
{ if (e?.toString()) handleChangeModel(e.toString()); }} isDisabled={isDisabled || !selectedProvider} selectedKey={selectedModel} defaultSelectedKey={selectedModel ?? undefined} inputProps={{ classNames: { inputWrapper: "bg-[#27272A] rounded-md text-sm px-3 py-[10px]", }, }} > {models[selectedProvider || ""]?.models .filter((model) => VERIFIED_MODELS.includes(model)) .map((model) => ( {model} ))} {models[selectedProvider || ""]?.models .filter((model) => !VERIFIED_MODELS.includes(model)) .map((model) => ( {model} ))}
); }