import ModalFooter from '@/components/modal-footer'; import SealInput from '@/components/seal-form/seal-input'; import SealSelect from '@/components/seal-form/seal-select'; import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import { convertFileSize } from '@/utils'; import { useIntl } from '@umijs/max'; import { Divider, Drawer, Form } from 'antd'; import _ from 'lodash'; import { memo, useCallback, useEffect, useState } from 'react'; import { queryHuggingfaceModelFiles, queryHuggingfaceModels } from '../apis'; import { modelSourceMap } from '../config'; import { FormData, ListItem } from '../config/types'; import HFModelFile from './hf-model-file'; import SearchModel from './search-model'; type AddModalProps = { title: string; action: PageActionType; open: boolean; data?: ListItem; source: string; onOk: (values: FormData) => void; onCancel: () => void; }; const sourceOptions = [ { label: 'Hugging Face', value: modelSourceMap.huggingface_value, key: 'huggingface' }, { label: 'Ollama Library', value: modelSourceMap.ollama_library_value, key: 'ollama_library' } ]; const AddModal: React.FC = (props) => { console.log('addmodel===='); const { title, action, open, source, onOk, onCancel } = props || {}; const [form] = Form.useForm(); const intl = useIntl(); const modelSource = Form.useWatch('source', form); const huggingfaceRepoId = Form.useWatch('huggingface_repo_id', form); const [loading, setLoading] = useState(false); const [repoOptions, setRepoOptions] = useState< { label: string; value: string }[] >([]); const [fileOptions, setFileOptions] = useState< { label: string; value: string }[] >([]); const initFormValue = () => { form.setFieldsValue({ source: props.source, replicas: 1 }); }; useEffect(() => { initFormValue(); console.log('source========', props.source); }, [open]); const fileNamLabel = (item: any) => { return ( {item.path} ({convertFileSize(item.size)}) ); }; const handleFetchModelFiles = async (repo: string) => { try { setLoading(true); const res = await queryHuggingfaceModelFiles({ repo }); const list = _.filter(res, (file: any) => { return _.endsWith(file.path, '.gguf'); }).map((item: any) => { return { label: fileNamLabel(item), value: item.path, size: item.size }; }); setFileOptions(list); setLoading(false); } catch (error) { setFileOptions([]); setLoading(false); } }; const handleRepoOnBlur = (e: any) => { const repo = form.getFieldValue('huggingface_repo_id'); handleFetchModelFiles(repo); }; const handleSelectModelFile = useCallback((item: any) => { form.setFieldValue('huggingface_filename', item.path); }, []); const handleOnSearchRepo = async (text: string) => { try { const params = { search: { query: text, tags: ['gguf'] } }; const models = await queryHuggingfaceModels(params); const list = _.map(models || [], (item: any) => { return { ...item, value: item.name, label: item.name }; }); setRepoOptions(list); } catch (error) { setRepoOptions([]); } }; const debounceSearch = _.debounce((text: string) => { handleOnSearchRepo(text); }, 300); const renderHuggingfaceFields = () => { return ( <> name="huggingface_repo_id" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.repoid' }) } ) } ]} > name="huggingface_filename" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.filename' }) } ) } ]} > ); }; const renderS3Fields = () => { return ( <> name="s3_address" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.s3address' }) } ) } ]} > ); }; const renderOllamaModelFields = () => { return ( <> name="ollama_library_model_name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.table.name' }) } ) } ]} > ); }; const renderFieldsBySource = () => { switch (props.source) { case modelSourceMap.huggingface_value: return renderHuggingfaceFields(); case modelSourceMap.ollama_library_value: return renderOllamaModelFields(); case modelSourceMap.s3_value: return renderS3Fields(); default: return null; } }; const handleOnSelectModel = useCallback((item: any) => { const repo = item.name; if (form.getFieldValue('source') === modelSourceMap.huggingface_value) { form.setFieldValue('huggingface_repo_id', repo); } else { form.setFieldValue('ollama_library_model_name', repo); } }, []); const handleSumit = () => { form.submit(); }; return ( } >

Configuration

name="name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'common.table.name' }) } ) } ]} > name="source" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.select' }, { name: intl.formatMessage({ id: 'models.form.source' }) } ) } ]} > { } {renderFieldsBySource()} name="replicas" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.replicas' }) } ) } ]} > name="description">
); }; export default memo(AddModal);