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;