import AlertBlockInfo from '@/components/alert-info/block'; import IconFont from '@/components/icon-font'; import ModalFooter from '@/components/modal-footer'; import SealAutoComplete from '@/components/seal-form/auto-complete'; 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 { useIntl } from '@umijs/max'; import { Form, Modal, Tooltip, Typography } from 'antd'; import _ from 'lodash'; import React, { useEffect, useMemo, useRef, useState } from 'react'; import { backendOptionsMap, modelSourceMap, ollamaModelOptions } from '../config'; import { FormData, ListItem } from '../config/types'; import AdvanceConfig from './advance-config'; import ColumnWrapper from './column-wrapper'; type AddModalProps = { title: string; action: PageActionType; open: boolean; updateFormInitials: { data?: ListItem; gpuOptions: any[]; isGGUF: boolean; }; onOk: (values: FormData) => void; onCancel: () => void; }; const SEARCH_SOURCE = [ modelSourceMap.huggingface_value, modelSourceMap.modelscope_value ]; const sourceOptions = [ { label: 'Hugging Face', value: modelSourceMap.huggingface_value, key: 'huggingface' }, { label: 'Ollama Library', value: modelSourceMap.ollama_library_value, key: 'ollama_library' }, { label: 'ModelScope', value: modelSourceMap.modelscope_value, key: 'model_scope' }, { label: 'models.form.localPath', value: modelSourceMap.local_path_value, locale: true, key: 'local_path' } ]; const UpdateModal: React.FC = (props) => { const { title, action, open, onOk, onCancel, updateFormInitials: { gpuOptions, isGGUF, data: formData } } = props || {}; const [form] = Form.useForm(); const intl = useIntl(); const localPathCache = useRef(''); const [warningStatus, setWarningStatus] = useState<{ show: boolean; message: string; }>({ show: false, message: '' }); const handleSetGPUIds = (backend: string) => { if (backend === backendOptionsMap.llamaBox) { return; } const gpuids = form.getFieldValue(['gpu_selector', 'gpu_ids']); if (!gpuids?.length) { return; } if (gpuids.length > 1 && Array.isArray(gpuids[0])) { form.setFieldValue(['gpu_selector', 'gpu_ids'], [gpuids[0]]); } }; const updateShowWarning = () => { const backend = form.getFieldValue?.('backend'); const localPath = form.getFieldValue?.('local_path'); if (formData?.source !== modelSourceMap.local_path_value || !localPath) { return; } if (localPath.endsWith('.gguf') && backend !== backendOptionsMap.llamaBox) { setWarningStatus({ show: true, message: 'models.form.backend.warning' }); } else if ( !localPath.endsWith('.gguf') && backend === backendOptionsMap.llamaBox ) { setWarningStatus({ show: true, message: 'models.form.backend.warning.llamabox' }); } else { setWarningStatus({ show: false, message: '' }); } }; const handleBackendChange = (val: string) => { if (val === backendOptionsMap.llamaBox) { form.setFieldsValue({ distributed_inference_across_workers: true, cpu_offloading: true }); } form.setFieldValue('backend_version', ''); handleSetGPUIds(val); updateShowWarning(); }; const handleOnFocus = () => { localPathCache.current = form.getFieldValue('local_path'); }; const handleLocalPathBlur = (e: any) => { const value = e.target.value; if (value === localPathCache.current && value) { return; } const isEndwithGGUF = _.endsWith(value, '.gguf'); let backend = backendOptionsMap.llamaBox; if (!isEndwithGGUF) { backend = backendOptionsMap.vllm; } handleBackendChange?.(backend); form.setFieldValue('backend', backend); }; const renderHuggingfaceFields = () => { return ( <> name="repo_id" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.repoid' }) } ) } ]} > {isGGUF && ( name="file_name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.filename' }) } ) } ]} > )} ); }; 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' }) } ) } ]} > {intl.formatMessage({ id: 'model.form.ollama.model' })}{' '} } required > ); }; const renderLocalPathFields = () => { return ( <> name="local_path" key="local_path" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.filePath' }) } ) } ]} > ); }; const renderFieldsBySource = useMemo(() => { if (SEARCH_SOURCE.includes(formData?.source || '')) { return renderHuggingfaceFields(); } if (formData?.source === modelSourceMap.ollama_library_value) { return renderOllamaModelFields(); } if (formData?.source === modelSourceMap.local_path_value) { return renderLocalPathFields(); } return null; }, [formData?.source, isGGUF, intl]); const handleSumit = () => { form.submit(); }; const generateGPUIds = (data: FormData) => { const gpu_ids = _.get(data, 'gpu_selector.gpu_ids', []); if (!gpu_ids.length) { return {}; } const result = _.reduce( gpu_ids, (acc: string[], item: string | string[], index: number) => { if (Array.isArray(item)) { acc.push(item[1]); } else if (index === 1) { acc.push(item); } return acc; }, [] ); if (result.length) { return { gpu_selector: { gpu_ids: result } }; } return {}; }; const handleOk = (formdata: FormData) => { let obj = {}; if ( [backendOptionsMap.vllm, backendOptionsMap.voxBox].includes( formdata.backend ) ) { obj = { distributed_inference_across_workers: false, cpu_offloading: false }; } if (formdata.scheduleType === 'manual') { const gpuSelector = generateGPUIds(formdata); onOk({ ..._.omit(formdata, ['scheduleType']), categories: formdata.categories ? [formdata.categories] : [], worker_selector: null, gpu_selector: formdata.gpu_selector?.gpu_ids?.length ? { gpu_ids: formdata.gpu_selector.gpu_ids } : null, ...obj, ...gpuSelector }); } else { onOk({ ..._.omit(formdata, ['scheduleType']), categories: formdata.categories ? [formdata.categories] : [], gpu_selector: null, ...obj }); } }; const handleOnClose = () => { onCancel?.(); }; useEffect(() => { if (open && formData) { form.setFieldsValue(formData); } if (!open) { setWarningStatus({ show: false, message: '' }); } }, [open, formData]); return ( } > {warningStatus.show && ( )} } >
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' }) } ) } ]} > {action === PageAction.EDIT && ( )} {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 UpdateModal;