From 2ba94f75242a6173f14cb885177d72c43b5ac289 Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 11 Feb 2026 11:04:24 +0800 Subject: [PATCH] fix: miss model file path in cloning --- .../components/add-apikey-modal/index.tsx | 15 +++--- .../benchmark/hooks/use-column-settings.tsx | 11 +--- .../llmodels/components/deploy-modal.tsx | 6 +-- src/pages/llmodels/components/model-card.tsx | 20 +++---- .../llmodels/components/search-model.tsx | 1 + src/pages/llmodels/forms/backend.tsx | 2 + .../llmodels/forms/envs-override-popover.tsx | 36 +++++++++++++ src/pages/llmodels/forms/index.tsx | 13 ----- src/pages/llmodels/hooks/index.ts | 1 + src/pages/llmodels/hooks/use-compare-envs.ts | 52 +++++++++++++++++++ .../llmodels/hooks/use-edit-deployment.ts | 19 ++++++- .../model-routes/components/route-targets.tsx | 2 +- .../playground/components/ground-stt.tsx | 3 +- 13 files changed, 129 insertions(+), 52 deletions(-) create mode 100644 src/pages/llmodels/forms/envs-override-popover.tsx create mode 100644 src/pages/llmodels/hooks/use-compare-envs.ts diff --git a/src/pages/api-keys/components/add-apikey-modal/index.tsx b/src/pages/api-keys/components/add-apikey-modal/index.tsx index e291128c..55882d11 100644 --- a/src/pages/api-keys/components/add-apikey-modal/index.tsx +++ b/src/pages/api-keys/components/add-apikey-modal/index.tsx @@ -273,7 +273,11 @@ const AddModal: React.FC = ({ {intl.formatMessage({ id: 'apikeys.table.save.tips' })} @@ -281,14 +285,7 @@ const AddModal: React.FC = ({ - } + addAfter={} > )} diff --git a/src/pages/benchmark/hooks/use-column-settings.tsx b/src/pages/benchmark/hooks/use-column-settings.tsx index 98a85b1d..2cf801e5 100644 --- a/src/pages/benchmark/hooks/use-column-settings.tsx +++ b/src/pages/benchmark/hooks/use-column-settings.tsx @@ -8,7 +8,6 @@ import { Typography } from 'antd'; import dayjs from 'dayjs'; import _, { round } from 'lodash'; import React from 'react'; -import styled from 'styled-components'; import { BenchmarkStatus, BenchmarkStatusLabelMap, @@ -16,6 +15,7 @@ import { } from '../config'; import { BenchmarkListItem as ListItem } from '../config/types'; +// sort by this order const allFields = [ 'cluster_id', 'model_name', @@ -45,15 +45,6 @@ const fieldSortPos: Record = Object.fromEntries( allFields.map((field, index) => [field, index + 1]) ); -const SubTitleWrapper = styled.span.attrs({ - className: 'sub-title' -})` - display: list-item; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -`; - const defaultColumns: string[] = [ 'model_name', 'dataset_name', diff --git a/src/pages/llmodels/components/deploy-modal.tsx b/src/pages/llmodels/components/deploy-modal.tsx index ee325c32..675ceb66 100644 --- a/src/pages/llmodels/components/deploy-modal.tsx +++ b/src/pages/llmodels/components/deploy-modal.tsx @@ -269,7 +269,7 @@ const AddModal: FC = (props) => { huggingface_filename: item.fakeName, model_scope_file_path: item.fakeName, backend_parameters: [], - backend_version: '', + backend_version: null, backend: modelInfo.backend, env: { ...modelInfo.env @@ -315,7 +315,7 @@ const AddModal: FC = (props) => { handleCancelFiles(); if ( _.isEmpty(item) || - (item.isGGUF === selectedModel.isGGUF && item.name === selectedModel.name) + (item.isGGUF === selectedModel.isGGUF && item.name === selectedModel.name) // --- because sometimes has the same model name with different isGGUF value ) { return; } @@ -420,7 +420,6 @@ const AddModal: FC = (props) => { }; const handleSetIsGGUF = async (flag: boolean) => { - console.log('isgguf==================>', flag); setIsGGUF(flag); }; @@ -593,6 +592,7 @@ const AddModal: FC = (props) => { onCollapse={setCollapsed} collapsed={collapsed} modelSource={props.source} + isGGUF={isGGUF} setIsGGUF={handleSetIsGGUF} > {isGGUF && ( diff --git a/src/pages/llmodels/components/model-card.tsx b/src/pages/llmodels/components/model-card.tsx index 28fbaad4..083ac76c 100644 --- a/src/pages/llmodels/components/model-card.tsx +++ b/src/pages/llmodels/components/model-card.tsx @@ -46,7 +46,6 @@ const MarkDownTitle: React.FC<{ loading: boolean; onCollapse: () => void; }> = ({ collapsed, loading, onCollapse }) => { - const intl = useIntl(); return ( @@ -68,12 +67,13 @@ const MarkDownTitle: React.FC<{ const ModelCard: React.FC<{ onCollapse: (flag: boolean) => void; setIsGGUF: (flag: boolean) => void; + isGGUF?: boolean; selectedModel: any; collapsed: boolean; loadingModel?: boolean; modelSource: string; }> = (props) => { - const { onCollapse, setIsGGUF, collapsed, modelSource } = props; + const { onCollapse, setIsGGUF, collapsed, modelSource, isGGUF } = props; const intl = useIntl(); const requestSource = useRequestToken(); const [modelData, setModelData] = useState(null); @@ -82,7 +82,6 @@ const ModelCard: React.FC<{ const axiosTokenRef = useRef(null); const loadConfigTokenRef = useRef(null); const loadConfigJsonTokenRef = useRef(null); - const [isGGUFModel, setIsGGUFModel] = useState(false); const [loading, setLoading] = useState(false); const modelTags = useMemo(() => { @@ -169,8 +168,7 @@ const ModelCard: React.FC<{ setReadmeText(newReadme); handleOnCollapse(newReadme); const isGGUF = modelcard.tags?.includes('gguf'); - setIsGGUF(isGGUF); - setIsGGUFModel(isGGUF); + setIsGGUF(isGGUF || props.selectedModel?.isGGUF); } catch (error) { setModelData(null); setReadmeText(null); @@ -198,8 +196,7 @@ const ModelCard: React.FC<{ data?.Data?.Tags, (tag: string) => tag?.indexOf('gguf') > -1 ); - setIsGGUF(isGGUF); - setIsGGUFModel(isGGUF); + setIsGGUF(isGGUF || props.selectedModel?.isGGUF); } catch (error) { setModelData(null); setReadmeText(null); @@ -290,11 +287,8 @@ const ModelCard: React.FC<{ useEffect(() => { if (!props.selectedModel.name) return; - getModelCardData(); - setIsGGUFModel(props.selectedModel.isGGUF); setModelData(() => ({ - ...modelData, id: props.selectedModel.name, name: props.selectedModel.name, isGGUF: props.selectedModel.isGGUF @@ -328,7 +322,7 @@ const ModelCard: React.FC<{ {modelType} )} - {isGGUFModel && ( + {isGGUF && ( GGUF @@ -347,7 +341,7 @@ const ModelCard: React.FC<{ ); })} - {readmeText && isGGUFModel && ( + {readmeText && isGGUF && (
)}
- {!isGGUFModel && ( + {!isGGUF && (
{readmeText && ( diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx index ebb8f45d..8210c1c8 100644 --- a/src/pages/llmodels/components/search-model.tsx +++ b/src/pages/llmodels/components/search-model.tsx @@ -138,6 +138,7 @@ const SearchModel: React.FC = (props) => { const handleOnSelectModel = (model: any, manual?: boolean) => { const item = model || {}; + // because need cancel the fetch file request when select another model, so check the empty model in the parent level handler. if (!item.evaluated || item.isGGUF) { onSelectModel(item, manual); } else { diff --git a/src/pages/llmodels/forms/backend.tsx b/src/pages/llmodels/forms/backend.tsx index 1d842e1e..5a710af4 100644 --- a/src/pages/llmodels/forms/backend.tsx +++ b/src/pages/llmodels/forms/backend.tsx @@ -9,6 +9,7 @@ import styled from 'styled-components'; import { backendTipsList } from '../config'; import { backendOptionsMap } from '../config/backend-parameters'; import { useFormContext } from '../config/form-context'; +import useCompareEnvs from '../hooks/use-compare-envs'; const CaretDownWrapper = styled.span` display: flex; @@ -36,6 +37,7 @@ const BackendFields: React.FC = () => { } = useFormContext(); const backend = Form.useWatch('backend', form); const [showDeprecated, setShowDeprecated] = React.useState(false); + const { openTips, handleToggleTips, handleCompareEnvs } = useCompareEnvs(); const handleBackendVersionOnChange = (value: any, option: any) => { if (Object.keys(option.data?.env || {}).length > 0) { diff --git a/src/pages/llmodels/forms/envs-override-popover.tsx b/src/pages/llmodels/forms/envs-override-popover.tsx new file mode 100644 index 00000000..e1cbfd4d --- /dev/null +++ b/src/pages/llmodels/forms/envs-override-popover.tsx @@ -0,0 +1,36 @@ +import { WarningOutlined } from '@ant-design/icons'; +import { Alert, Popover } from 'antd'; +import React from 'react'; + +interface EnvsOverridePopoverProps { + open: boolean; + dataList: any[]; + onToggle: (open: boolean) => void; +} + +const EnvsOverridePopover: React.FC = (props) => { + const { open, onToggle } = props; + return ( + + onToggle(!open)} + style={{ marginBlock: 16, cursor: 'pointer' }} + icon={} + type="warning" + showIcon + title={'override envs'} + > + + ); +}; + +export default EnvsOverridePopover; diff --git a/src/pages/llmodels/forms/index.tsx b/src/pages/llmodels/forms/index.tsx index 67b5bc1f..50dc3ad6 100644 --- a/src/pages/llmodels/forms/index.tsx +++ b/src/pages/llmodels/forms/index.tsx @@ -171,19 +171,6 @@ const DataForm: React.FC = forwardRef((props, ref) => { }; }; - const checkIsGGUF = () => { - const huggingface_filename = form.getFieldValue('huggingface_filename'); - const model_scope_model_id = form.getFieldValue('model_scope_model_id'); - const local_path = form.getFieldValue('local_path'); - - if (local_path) { - const isEndwithGGUF = _.endsWith(local_path, '.gguf'); - const isBlobFile = local_path.split('/').pop().includes('sha256'); - return isEndwithGGUF || isBlobFile; - } - return huggingface_filename || model_scope_model_id; - }; - const updateFieldsOnGGUF = () => { // when isGGUF is true, set distributed_inference_across_workers and cpu_offloading to true return { diff --git a/src/pages/llmodels/hooks/index.ts b/src/pages/llmodels/hooks/index.ts index 4318f504..aab1cb89 100644 --- a/src/pages/llmodels/hooks/index.ts +++ b/src/pages/llmodels/hooks/index.ts @@ -522,6 +522,7 @@ export const useSelectModel = (data: { gpuOptions: any[] }) => { flatBackendOptions?: any[]; } ) => { + console.log('options==========', options); const { source, defaultBackend, flatBackendOptions } = options; let name = _.split(selectModel.name, '/').slice(-1)[0]; const reg = /(-gguf)$/i; diff --git a/src/pages/llmodels/hooks/use-compare-envs.ts b/src/pages/llmodels/hooks/use-compare-envs.ts new file mode 100644 index 00000000..33615db0 --- /dev/null +++ b/src/pages/llmodels/hooks/use-compare-envs.ts @@ -0,0 +1,52 @@ +import { useState } from 'react'; + +export default function useCompareEnvs() { + const [openTips, setOpenTips] = useState(false); + const [diffEnvs, setDiffEnvs] = useState<{ + old: Record; + new: Record; + } | null>(null); + + const handleOpenTips = () => { + setOpenTips(true); + }; + + const handleCloseTips = () => { + setOpenTips(false); + }; + + const handleCompareEnvs = ( + oldEnvs: Record, + newEnvs: Record + ) => { + const result = { + old: {} as Record, + new: {} as Record + }; + + Object.keys(oldEnvs).forEach((key) => { + if (key in newEnvs && oldEnvs[key] !== newEnvs[key]) { + result.old[key] = oldEnvs[key]; + result.new[key] = newEnvs[key]; + } + }); + + setDiffEnvs(result); + if (Object.keys(result.old).length > 0) { + handleOpenTips(); + } + }; + + const handleToggleTips = () => { + setOpenTips(!openTips); + }; + + return { + openTips, + diffEnvs, + handleOpenTips, + handleCloseTips, + handleCompareEnvs, + handleToggleTips + }; +} diff --git a/src/pages/llmodels/hooks/use-edit-deployment.ts b/src/pages/llmodels/hooks/use-edit-deployment.ts index 24274bd5..cd2140c0 100644 --- a/src/pages/llmodels/hooks/use-edit-deployment.ts +++ b/src/pages/llmodels/hooks/use-edit-deployment.ts @@ -1,6 +1,7 @@ import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import { useIntl } from '@umijs/max'; +import _ from 'lodash'; import { useState } from 'react'; import { ListItem } from '../config/types'; @@ -27,12 +28,26 @@ const useEditDeployment = () => { title: '' }); + const checkIsGGUF = (row: ListItem): boolean => { + const huggingface_filename = row.huggingface_filename; + const model_scope_file_path = row.model_scope_file_path; + const local_path = row.local_path || ''; + + if (local_path) { + const isEndwithGGUF = _.endsWith(local_path, '.gguf'); + const isBlobFile = local_path.split('/').pop()?.includes('sha256'); + return isEndwithGGUF || isBlobFile; + } + + return Boolean(huggingface_filename || model_scope_file_path); + }; + const openEditModal = (formData: any, row: ListItem) => { setOpenModalStatus({ open: true, action: PageAction.EDIT, currentData: { - isGGUF: false, + isGGUF: checkIsGGUF(row), data: formData, row: row, realAction: PageAction.EDIT @@ -46,7 +61,7 @@ const useEditDeployment = () => { open: true, action: PageAction.EDIT, currentData: { - isGGUF: false, + isGGUF: checkIsGGUF(row), data: { ...formData, name: `${formData.name}-copy` diff --git a/src/pages/model-routes/components/route-targets.tsx b/src/pages/model-routes/components/route-targets.tsx index 85eeec9d..8944fa5c 100644 --- a/src/pages/model-routes/components/route-targets.tsx +++ b/src/pages/model-routes/components/route-targets.tsx @@ -85,7 +85,7 @@ const RouteItem: React.FC = ({ {data.name} - + {renderProviderSource()} diff --git a/src/pages/playground/components/ground-stt.tsx b/src/pages/playground/components/ground-stt.tsx index fdf99739..ad7e36c6 100644 --- a/src/pages/playground/components/ground-stt.tsx +++ b/src/pages/playground/components/ground-stt.tsx @@ -442,7 +442,8 @@ const GroundSTT: React.FC = forwardRef((props, ref) => { style={{ position: 'absolute', top: 20, - right: 2 + right: 32, + zIndex: 10 }} >