import React, { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'next-i18next'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import MySelect, { SelectProps } from '@fastgpt/web/components/common/MySelect'; import { HUGGING_FACE_ICON } from '@fastgpt/global/common/system/constants'; import { Box, Flex, HStack } from '@chakra-ui/react'; import Avatar from '@fastgpt/web/components/common/Avatar'; import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; import dynamic from 'next/dynamic'; import { ModelProviderList } from '@fastgpt/global/core/ai/provider'; import MultipleRowSelect from '@fastgpt/web/components/common/MySelect/MultipleRowSelect'; import { getModelFromList } from '@fastgpt/global/core/ai/model'; const ModelPriceModal = dynamic(() => import('@/components/core/ai/ModelTable').then((mod) => mod.ModelPriceModal) ); type Props = SelectProps & { disableTip?: string; }; const OneRowSelector = ({ list, onChange, disableTip, ...props }: Props) => { const { t } = useTranslation(); const { llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList } = useSystemStore(); const avatarSize = useMemo(() => { const size = { sm: '1rem', md: '1.2rem', lg: '1.4rem' }; //@ts-ignore return props.size ? size[props.size] : size['md']; }, [props.size]); const avatarList = useMemo(() => { const allModels = [ ...llmModelList, ...embeddingModelList, ...ttsModelList, ...sttModelList, ...reRankModelList ]; return list .map((item) => { const modelData = getModelFromList(allModels, item.value)!; if (!modelData) return; return { value: item.value, label: ( {modelData.name} ) }; }) .filter(Boolean) as { value: any; label: React.JSX.Element; }[]; }, [ list, llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList, avatarSize ]); return ( {({ onOpen }) => ( { if (e === 'price') { onOpen(); return; } return onChange?.(e); }} /> )} ); }; const MultipleRowSelector = ({ list, onChange, disableTip, placeholder, ...props }: Props) => { const { t } = useTranslation(); const { llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList } = useSystemStore(); const modelList = useMemo(() => { const allModels = [ ...llmModelList, ...embeddingModelList, ...ttsModelList, ...sttModelList, ...reRankModelList ]; return list.map((item) => getModelFromList(allModels, item.value)!).filter(Boolean); }, [llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList, list]); const [value, setValue] = useState([]); const avatarSize = useMemo(() => { const size = { sm: '1rem', md: '1.2rem', lg: '1.4rem' }; //@ts-ignore return props.size ? size[props.size] : size['md']; }, [props.size]); const selectorList = useMemo(() => { const renderList = ModelProviderList.map<{ label: React.JSX.Element; value: string; children: { label: string | React.ReactNode; value: string }[]; }>((provider) => ({ label: ( {t(provider.name as any)} ), value: provider.id, children: [] })); for (const item of list) { const modelData = getModelFromList(modelList, item.value); if (!modelData) continue; const provider = renderList.find((item) => item.value === (modelData?.provider || 'Other')) ?? renderList[renderList.length - 1]; provider.children.push({ label: modelData.name, value: modelData.model }); } return renderList.filter((item) => item.children.length > 0); }, [avatarSize, list, modelList, t]); const onSelect = useCallback( (e: string[]) => { return onChange?.(e[1]); }, [onChange] ); const SelectedModel = useMemo(() => { if (!props.value) return <>{t('common:not_model_config')}; const modelData = getModelFromList(modelList, props.value); if (!modelData) return <>{t('common:not_model_config')}; setValue([modelData.provider, props.value]); return ( {modelData?.name} ); }, [modelList, props.value, t, avatarSize]); return ( ); }; const AIModelSelector = (props: Props) => { return props.list.length > 10 ? ( ) : ( ); }; export default AIModelSelector;