fix: miss model file path in cloning

This commit is contained in:
jialin
2026-02-11 11:05:43 +08:00
parent 3f90642726
commit 2ba94f7524
13 changed files with 129 additions and 52 deletions
@@ -273,7 +273,11 @@ const AddModal: React.FC<AddModalProps> = ({
<Tag
variant="filled"
color="error"
style={{ padding: '6px 8px', marginBottom: 16 }}
style={{
padding: '6px 8px',
marginBottom: 16,
width: '100%'
}}
>
{intl.formatMessage({ id: 'apikeys.table.save.tips' })}
</Tag>
@@ -281,14 +285,7 @@ const AddModal: React.FC<AddModalProps> = ({
<SealInput.Input
label={intl.formatMessage({ id: 'apikeys.form.apikey' })}
value={apikeyValue}
addAfter={
<CopyButton
text={apikeyValue}
shape="default"
size="middle"
type="text"
></CopyButton>
}
addAfter={<CopyButton text={apikeyValue}></CopyButton>}
></SealInput.Input>
</Form.Item>
)}
@@ -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<string, number> = 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',
@@ -269,7 +269,7 @@ const AddModal: FC<AddModalProps> = (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<AddModalProps> = (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<AddModalProps> = (props) => {
};
const handleSetIsGGUF = async (flag: boolean) => {
console.log('isgguf==================>', flag);
setIsGGUF(flag);
};
@@ -593,6 +592,7 @@ const AddModal: FC<AddModalProps> = (props) => {
onCollapse={setCollapsed}
collapsed={collapsed}
modelSource={props.source}
isGGUF={isGGUF}
setIsGGUF={handleSetIsGGUF}
></ModelCard>
{isGGUF && (
+7 -13
View File
@@ -46,7 +46,6 @@ const MarkDownTitle: React.FC<{
loading: boolean;
onCollapse: () => void;
}> = ({ collapsed, loading, onCollapse }) => {
const intl = useIntl();
return (
<MkdTitle onClick={onCollapse}>
<span>
@@ -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<any>(null);
@@ -82,7 +82,6 @@ const ModelCard: React.FC<{
const axiosTokenRef = useRef<any>(null);
const loadConfigTokenRef = useRef<any>(null);
const loadConfigJsonTokenRef = useRef<any>(null);
const [isGGUFModel, setIsGGUFModel] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(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}
</ThemeTag>
)}
{isGGUFModel && (
{isGGUF && (
<ThemeTag className="tag-item" color="magenta" opacity={0.65}>
GGUF
</ThemeTag>
@@ -347,7 +341,7 @@ const ModelCard: React.FC<{
);
})}
</div>
{readmeText && isGGUFModel && (
{readmeText && isGGUF && (
<div
style={{
borderRadius: 4,
@@ -388,7 +382,7 @@ const ModelCard: React.FC<{
</>
)}
</div>
{!isGGUFModel && (
{!isGGUF && (
<Spin spinning={loading}>
<div style={{ minHeight: 200 }}>
{readmeText && (
@@ -138,6 +138,7 @@ const SearchModel: React.FC<SearchInputProps> = (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 {
+2
View File
@@ -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<boolean>(false);
const { openTips, handleToggleTips, handleCompareEnvs } = useCompareEnvs();
const handleBackendVersionOnChange = (value: any, option: any) => {
if (Object.keys(option.data?.env || {}).length > 0) {
@@ -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<EnvsOverridePopoverProps> = (props) => {
const { open, onToggle } = props;
return (
<Popover
content="override envs"
onOpenChange={onToggle}
trigger={'click'}
styles={{
container: {
width: '100%'
}
}}
>
<Alert
onClick={() => onToggle(!open)}
style={{ marginBlock: 16, cursor: 'pointer' }}
icon={<WarningOutlined />}
type="warning"
showIcon
title={'override envs'}
></Alert>
</Popover>
);
};
export default EnvsOverridePopover;
-13
View File
@@ -171,19 +171,6 @@ const DataForm: React.FC<DataFormProps> = 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 {
+1
View File
@@ -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;
@@ -0,0 +1,52 @@
import { useState } from 'react';
export default function useCompareEnvs() {
const [openTips, setOpenTips] = useState(false);
const [diffEnvs, setDiffEnvs] = useState<{
old: Record<string, any>;
new: Record<string, any>;
} | null>(null);
const handleOpenTips = () => {
setOpenTips(true);
};
const handleCloseTips = () => {
setOpenTips(false);
};
const handleCompareEnvs = (
oldEnvs: Record<string, any>,
newEnvs: Record<string, any>
) => {
const result = {
old: {} as Record<string, any>,
new: {} as Record<string, any>
};
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
};
}
@@ -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`
@@ -85,7 +85,7 @@ const RouteItem: React.FC<TargetItemProps> = ({
<AutoTooltip ghost>{data.name}</AutoTooltip>
</CellContent>
</Col>
<Col span={5} style={{ paddingLeft: 56 }}>
<Col span={5} style={{ paddingLeft: 64 }}>
<CellContent>{renderProviderSource()}</CellContent>
</Col>
<Col span={2}>
@@ -442,7 +442,8 @@ const GroundSTT: React.FC<MessageProps> = forwardRef((props, ref) => {
style={{
position: 'absolute',
top: 20,
right: 2
right: 32,
zIndex: 10
}}
>
<CopyButton text={messageList[0]?.content}></CopyButton>