import ModalFooter from '@/components/modal-footer'; import { PageActionType } from '@/config/types'; import { CloseOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Button, Drawer } from 'antd'; import { debounce } from 'lodash'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { backendOptionsMap, modelSourceMap } from '../config'; import { FormData, ListItem } from '../config/types'; import ColumnWrapper from './column-wrapper'; import DataForm from './data-form'; import HFModelFile from './hf-model-file'; import ModelCard from './model-card'; import SearchModel from './search-model'; import Separator from './separator'; import TitleWrapper from './title-wrapper'; type AddModalProps = { title: string; action: PageActionType; open: boolean; data?: ListItem; source: string; width?: string | number; onOk: (values: FormData) => void; onCancel: () => void; }; const steps = [ { element: '#filterGGUF', popover: { title: '筛选模型', description: 'Select a model from the list' } }, { element: '#backend-field', popover: { title: '选择推理后端', description: 'Select a model from the list' } } ]; const AddModal: React.FC = (props) => { const { title, open, onOk, onCancel, source, action, width = 600 } = props || {}; const SEARCH_SOURCE = [ modelSourceMap.huggingface_value, modelSourceMap.modelscope_value ]; // const { start } = useDriver({ // steps, // id: 'deploy-model' // }); const form = useRef({}); const intl = useIntl(); const [selectedModel, setSelectedModel] = useState({}); const [collapsed, setCollapsed] = useState(false); const [loadingModel, setLoadingModel] = useState(false); const [isGGUF, setIsGGUF] = useState(false); const modelFileRef = useRef(null); const [loadfinish, setLoadfinish] = useState(false); const handleSelectModelFile = useCallback((item: any) => { form.current?.setFieldValue?.('file_name', item.fakeName); setLoadfinish(true); }, []); const handleOnSelectModel = (item: any) => { setSelectedModel(item); }; const handleSumit = () => { form.current?.submit?.(); }; const debounceFetchModelFiles = debounce(() => { modelFileRef.current?.fetchModelFiles?.(); }, 300); const handleSetIsGGUF = (flag: boolean) => { setIsGGUF(flag); if (flag) { debounceFetchModelFiles(); } }; const handleBackendChange = (backend: string) => { if (backend === backendOptionsMap.vllm) { setIsGGUF(false); } if (backend === backendOptionsMap.llamaBox) { setIsGGUF(true); } }; const handleCancel = useCallback(() => { onCancel?.(); }, [onCancel]); useEffect(() => { handleSelectModelFile({ fakeName: '' }); }, [selectedModel]); useEffect(() => { if (!open) { setIsGGUF(false); form.current?.setFieldValue?.('backend', backendOptionsMap.vllm); } else if (source === modelSourceMap.ollama_library_value) { form.current?.setFieldValue?.('backend', backendOptionsMap.llamaBox); setIsGGUF(true); } return () => { setSelectedModel({}); }; }, [open, source]); // useEffect(() => { // if (open && loadfinish) { // setTimeout(() => { // start(); // }, 1000); // } // }, [loadfinish, open]); return ( {title} } open={open} onClose={handleCancel} destroyOnClose={true} closeIcon={false} maskClosable={false} keyboard={false} styles={{ body: { height: 'calc(100vh - 57px)', padding: '16px 0', overflowX: 'hidden' }, content: { borderRadius: '6px 0 0 6px' } }} width={width} footer={false} >
{SEARCH_SOURCE.includes(props.source) && ( <>
{isGGUF && ( )}
)} } > <> {SEARCH_SOURCE.includes(source) && ( {intl.formatMessage({ id: 'models.form.configurations' })} )}
); }; export default memo(AddModal);