import { Box, Flex, HStack, Table, TableContainer, Tbody, Td, Th, Thead, Tr, Switch, ModalBody, Input, ModalFooter, Button, type ButtonProps } from '@chakra-ui/react'; import { useTranslation } from 'next-i18next'; import React, { useMemo, useRef, useState } from 'react'; import MySelect from '@fastgpt/web/components/common/MySelect'; import { ModelTypeEnum } from '@fastgpt/global/core/ai/model'; import Avatar from '@fastgpt/web/components/common/Avatar'; import { useRequest } from '@fastgpt/web/hooks/useRequest'; import { getSystemModelDefaultConfig, putSystemModel } from '@/web/core/ai/config'; import { type SystemModelItemType } from '@fastgpt/service/core/ai/type'; import { useForm } from 'react-hook-form'; import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput'; import MyTextarea from '@/components/common/Textarea/MyTextarea'; import JsonEditor from '@fastgpt/web/components/common/Textarea/JsonEditor'; import MyMenu from '@fastgpt/web/components/common/MyMenu'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import MyModal from '@fastgpt/web/components/common/MyModal'; import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; export const AddModelButton = ({ onCreate, ...props }: { onCreate: (type: ModelTypeEnum) => void } & ButtonProps) => { const { t } = useTranslation(); return ( {t('account:create_model')}} menuList={[ { children: [ { label: t('common:model.type.chat'), onClick: () => onCreate(ModelTypeEnum.llm) }, { label: t('common:model.type.embedding'), onClick: () => onCreate(ModelTypeEnum.embedding) }, { label: t('common:model.type.tts'), onClick: () => onCreate(ModelTypeEnum.tts) }, { label: t('common:model.type.stt'), onClick: () => onCreate(ModelTypeEnum.stt) }, { label: t('common:model.type.reRank'), onClick: () => onCreate(ModelTypeEnum.rerank) } ] } ]} /> ); }; const InputStyles = { maxW: '300px', bg: 'myGray.50', w: '100%', rows: 3 }; export const ModelEditModal = ({ modelData, onSuccess, onClose }: { modelData: SystemModelItemType; onSuccess: () => void; onClose: () => void; }) => { const { t, i18n } = useTranslation(); const { feConfigs, getModelProviders } = useSystemStore(); const { register, getValues, setValue, handleSubmit, watch, reset } = useForm({ defaultValues: modelData }); const isCustom = !!modelData.isCustom; const isLLMModel = modelData?.type === ModelTypeEnum.llm; const isEmbeddingModel = modelData?.type === ModelTypeEnum.embedding; const isTTSModel = modelData?.type === ModelTypeEnum.tts; const isSTTModel = modelData?.type === ModelTypeEnum.stt; const isRerankModel = modelData?.type === ModelTypeEnum.rerank; const provider = watch('provider'); const providerList = useRef<{ label: React.ReactNode; value: string }[]>( getModelProviders(i18n.language).map((item) => ({ label: ( {item.name} ), value: item.id })) ); const priceUnit = useMemo(() => { if (isLLMModel || isEmbeddingModel || isRerankModel) return '/ 1k Tokens'; if (isTTSModel) return `/ 1k ${t('common:unit.character')}`; if (isSTTModel) return `/ 60 ${t('common:unit.seconds')}`; return ''; }, [isLLMModel, isEmbeddingModel, isTTSModel, t, isSTTModel, isRerankModel]); const { runAsync: updateModel, loading: updatingModel } = useRequest( async (data: SystemModelItemType) => { for (const key in data) { // @ts-ignore const val = data[key]; if (val === null || val === undefined || Number.isNaN(val)) { // @ts-ignore data[key] = ''; } } return putSystemModel({ model: data.model, metadata: data }).then(onSuccess); }, { onSuccess: () => { onClose(); }, successToast: t('common:Success') } ); const [key, setKey] = useState(0); const { runAsync: loadDefaultConfig, loading: loadingDefaultConfig } = useRequest( getSystemModelDefaultConfig, { onSuccess(res) { reset({ ...getValues(), ...res }); setTimeout(() => { setKey((prev) => prev + 1); }, 0); } } ); const CustomApi = useMemo( () => ( <> {t('account:model.request_url')} {t('account:model.request_auth')} ), [] ); return ( {priceUnit && feConfigs?.isPlus && ( <> {isLLMModel && ( <> )} )} {isLLMModel && ( <> )} {isEmbeddingModel && ( <> )} {isTTSModel && ( <> )} {!isLLMModel && CustomApi}
{t('account:model.param_name')}
{t('account:model.model_id')} {isCustom ? ( ) : ( modelData?.model )}
{t('common:model.provider')} setValue('provider', value)} list={providerList.current} {...InputStyles} />
{t('account:model.alias')}
{t('account:model.charsPointsPrice')} {priceUnit}
{t('account:model.input_price')} {priceUnit}
{t('account:model.output_price')} {priceUnit}
{t('common:core.ai.Max context')}
{t('account:model.max_quote')}
{t('common:core.chat.response.module maxToken')}
{t('account:model.max_temperature')}
{t('account:model.show_top_p')}
{t('account:model.show_stop_sign')}
{t('account:model.response_format')} { if (!e) { setValue('responseFormatList', []); return; } try { setValue('responseFormatList', JSON.parse(e)); } catch (error) { console.error(error); } }} {...InputStyles} />
{t('account:model.normalization')}
{t('account_model:batch_size')}
{t('account:model.default_token')}
{t('common:core.ai.Max context')}
{t('account:model.defaultConfig')} { if (!e) { setValue('defaultConfig', undefined); return; } try { setValue('defaultConfig', JSON.parse(e)); } catch (error) { console.error(error); } }} {...InputStyles} />
{t('account:model.voices')} { try { setValue('voices', JSON.parse(e)); } catch (error) { console.error(error); } }} {...InputStyles} />
{isLLMModel && ( {feConfigs?.isPlus && ( )} {feConfigs?.isPlus && ( )} {CustomApi}
{t('account:model.param_name')}
{t('account:model.tool_choice')}
{t('account:model.vision')}
{t('account:model.reasoning')}
{t('account:model.censor')}
{t('account:model.dataset_process')}
{t('account:model.used_in_classify')}
{t('account:model.used_in_extract_fields')}
{t('account:model.used_in_tool_call')}
{t('account_model:use_in_eval')}
{t('account:model.default_system_chat_prompt')}
{t('account:model.default_config')} { console.log(e, '==='); if (!e) { setValue('defaultConfig', undefined); return; } try { setValue('defaultConfig', JSON.parse(e.trim())); } catch (error) { console.error(error); } }} {...InputStyles} />
)}
{!modelData.isCustom && ( )}
); }; export default function Dom() { return <>; }