fix: custom backend version suffix

This commit is contained in:
jialin
2025-10-30 19:08:45 +08:00
parent b733b3615d
commit d7ef64746c
19 changed files with 98 additions and 89 deletions
+6 -2
View File
@@ -170,9 +170,13 @@ const Extra = styled.div`
const AddAfter = styled.div`
position: relative;
color: var(--ant-color-text-quaternary);
color: var(--ant-color-text-tertiary);
font-size: var(--font-size-base);
padding-right: calc(var(--ant-padding-sm) - 1px);
padding-inline: calc(var(--ant-padding-sm) - 1px);
height: 100%;
display: flex;
align-items: center;
background-color: var(--ant-color-fill-secondary);
`;
// for wrapper
+3 -1
View File
@@ -19,6 +19,8 @@ export default {
'backend.mode.yaml': 'YAML Mode',
'backend.form.healthCheckPath': 'Health Check Path',
'backend.form.defaultExecuteCommand': 'Default Execution Command',
'backend.form.defaultExecuteCommand.tips':
'{{model_path}} is the model path, and {{port}} is the service port. These variable names cannot be modified.',
'backend.form.defaultBackendParameters': 'Default Backend Parameters',
'backend.form.versionConfig': 'Versions Config',
'backend.form.addParameter': 'Add Parameter',
@@ -27,5 +29,5 @@ export default {
'backend.versionInfo.autoImage': 'Automatically selected at runtime',
'backend.version.rules.builtin': 'Must end with "-custom"',
'backend.version.no.tips':
'Built-in backend versions must end with "-custom".'
'The name of a custom version must end with "-custom."'
};
+3 -1
View File
@@ -19,6 +19,8 @@ export default {
'backend.mode.yaml': 'YAML Mode',
'backend.form.healthCheckPath': 'Health Check Path',
'backend.form.defaultExecuteCommand': 'Default Execution Command',
'backend.form.defaultExecuteCommand.tips':
'{{model_path}} is the model path, and {{port}} is the service port. These variable names cannot be modified.',
'backend.form.defaultBackendParameters': 'Default Backend Parameters',
'backend.form.versionConfig': 'Versions Config',
'backend.form.addParameter': 'Add Parameter',
@@ -27,5 +29,5 @@ export default {
'backend.versionInfo.autoImage': 'Automatically selected at runtime',
'backend.version.rules.builtin': 'Must end with "-custom"',
'backend.version.no.tips':
'Built-in backend versions must end with "-custom".'
'The name of a custom version must end with "-custom."'
};
+5 -2
View File
@@ -19,6 +19,8 @@ export default {
'backend.mode.yaml': 'Режим YAML',
'backend.form.healthCheckPath': 'Путь проверки здоровья',
'backend.form.defaultExecuteCommand': 'Команда выполнения по умолчанию',
'backend.form.defaultExecuteCommand.tips':
'{{model_path}} is the model path, and {{port}} is the service port. These variable names cannot be modified.',
'backend.form.defaultBackendParameters': 'Параметры бэкенда по умолчанию',
'backend.form.versionConfig': 'Конфигурация версий',
'backend.form.addParameter': 'Добавить параметр',
@@ -27,9 +29,10 @@ export default {
'backend.versionInfo.autoImage': 'Автоматически выбор во время запуска',
'backend.version.rules.builtin': 'Должен заканчиваться на "-custom"',
'backend.version.no.tips':
'Built-in backend versions must end with "-custom".'
'The name of a custom version must end with "-custom."'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'backend.version.no.tips': 'Built-in backend versions must end with "-custom".'
// 1. 'backend.form.defaultExecuteCommand.tips': '{{model_path}} is the model path, and {{port}} is the service port. These variable names cannot be modified.'
// 2. 'backend.version.no.tips': 'The name of a custom version must end with "-custom."'
// ========== End of To-Do List ==========
+3 -1
View File
@@ -19,6 +19,8 @@ export default {
'backend.mode.yaml': 'YAML 模式',
'backend.form.healthCheckPath': '健康检查路径',
'backend.form.defaultExecuteCommand': '默认执行命令',
'backend.form.defaultExecuteCommand.tips':
'{{model_path}} 为模型文件路径,{{port}} 为服务端口,这两个变量名不可更改。',
'backend.form.defaultBackendParameters': '默认后端参数',
'backend.form.versionConfig': '版本配置',
'backend.form.addParameter': '添加参数',
@@ -26,5 +28,5 @@ export default {
'backend.noVersion': '未找到版本',
'backend.versionInfo.autoImage': '运行时自动选择',
'backend.version.rules.builtin': '须以 "-custom" 结尾',
'backend.version.no.tips': '内置的后端版本须以 "-custom" 结尾。'
'backend.version.no.tips': '自定义版本名称必须以 "-custom" 结尾。'
};
+20 -2
View File
@@ -53,6 +53,20 @@ const AddModal: React.FC<AddModalProps> = (props) => {
const [yamlContent, setYamlContent] = useState<string>('');
const [formContent, setFormContent] = useState<FormData>({} as FormData);
const genertateCurrentData = (values: ListItem): ListItem => {
const data = { ...values };
data.version_configs = Object.entries(data.version_configs || {}).reduce(
(acc, [key, value]) => {
const version = key.replace(/-custom$/, '');
acc[version] = { ...value };
return acc;
},
{} as any
);
return data;
};
const onOk = () => {
if (activeKey === 'yaml') {
const content = editorRef.current?.getContent();
@@ -90,9 +104,12 @@ const AddModal: React.FC<AddModalProps> = (props) => {
};
useEffect(() => {
const iniFormContent = (values: any) => {
const iniFormContent = (data: ListItem) => {
const values: any = genertateCurrentData(data);
// custom versions
const versionConfigs = Object.keys(values.version_configs || {}).map(
(key) => ({
(key: string) => ({
version_no: key,
image_name: values.version_configs?.[key]?.image_name,
run_command: values.version_configs?.[key]?.run_command,
@@ -101,6 +118,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
})
);
// built-in versions
const builtInVersions = Object.keys(
values.built_in_version_configs || {}
).map((key) => ({
+10 -10
View File
@@ -101,17 +101,17 @@ const ImportYAML: React.FC<ImportYAMLProps> = forwardRef(
const getContent = () => {
try {
const content = editorRef.current?.getValue();
if (actionStatus.isBuiltIn) {
const jsonData = yaml2Json(content);
const exsistingVersions = Object.keys(jsonData.version_configs || {});
const invalidVersion = exsistingVersions.find(
(v) => !v.endsWith('-custom')
);
if (invalidVersion) {
setError(intl.formatMessage({ id: 'backend.version.no.tips' }));
return false;
}
const jsonData = yaml2Json(content);
const exsistingVersions = Object.keys(jsonData.version_configs || {});
const invalidVersion = exsistingVersions.find(
(v) => !v.endsWith('-custom')
);
if (invalidVersion) {
setError(intl.formatMessage({ id: 'backend.version.no.tips' }));
return false;
}
return content;
} catch (error) {
return false;
+4 -4
View File
@@ -150,13 +150,13 @@ default_version: v0.5.1
health_check_path: /v1/models
default_backend_param:
- --host
default_run_command: myBackend serve {{model}} --port {{port}}
default_run_command: myBackend serve {{model_path}} --port {{port}}
version_configs:
v0.0.1:
v0.0.1-custom:
image_name: lm/mybackend:latest
run_command: myBackend serve {{model}} --port {{port}}
run_command: myBackend serve {{model_path}} --port {{port}}
custom_framework: cuda
v0.0.2:
v0.0.2-custom:
image_name: lm/mybackend:test
run_command:
custom_framework:
+4 -1
View File
@@ -53,9 +53,12 @@ const BasicForm: React.FC<AddModalProps> = ({ action }) => {
<SealTextArea
scaleSize={true}
alwaysFocus={true}
description={intl.formatMessage({
id: 'backend.form.defaultExecuteCommand.tips'
})}
placeholder={intl.formatMessage(
{ id: 'common.help.eg' },
{ content: 'vllm serve {{model}} --port {{port}}' }
{ content: 'vllm serve {{model_path}} --port {{port}}' }
)}
autoSize={{ minRows: 2, maxRows: 4 }}
label={intl.formatMessage({
+16 -1
View File
@@ -33,6 +33,21 @@ const BackendForm: React.FC<AddModalProps> = forwardRef(
}
};
const handleOnFinish = (values: FormData) => {
const data = { ...values };
data.version_configs = data.version_configs?.map((item) => {
if (item.version_no) {
return {
...item,
version_no: `${item.version_no}-custom`
};
}
return item;
});
onFinish(data);
};
useEffect(() => {
if (currentData) {
form.setFieldsValue(currentData);
@@ -61,7 +76,7 @@ const BackendForm: React.FC<AddModalProps> = forwardRef(
<Form
name="basicForm"
form={form}
onFinish={onFinish}
onFinish={handleOnFinish}
preserve={false}
scrollToFirstError={true}
initialValues={_.omit(currentData, ['version_configs'])}
+3 -19
View File
@@ -14,11 +14,9 @@ import { ListItem } from '../config/types';
// version must be endwith '-custom'
const pattern = /-custom$/;
const Box = styled.div`
display: grid;
grid-template-columns: 180px 1fr;
grid-template-columns: 200px 1fr;
gap: 16px;
`;
@@ -280,26 +278,12 @@ const VersionsForm: React.FC<AddModalProps> = ({
{
required: true,
message: getRuleMessage(`input`, 'backend.version')
},
currentData?.is_built_in
? {
pattern: pattern,
message: intl.formatMessage({
id: 'backend.version.rules.builtin'
})
}
: {}
}
]}
>
<SealInput.Input
trim
description={
currentData?.is_built_in
? intl.formatMessage({
id: 'backend.version.no.tips'
})
: ''
}
addAfter="-custom"
onChange={handleVersionChange}
label={intl.formatMessage({ id: 'backend.version' })}
required
@@ -12,7 +12,7 @@ import ColumnWrapper from '../../_components/column-wrapper';
import { queryCatalogItemSpec } from '../apis';
import {
defaultFormValues,
deployFormKeyMap,
DeployFormKeyMap,
modelCategoriesMap,
sourceOptions
} from '../config';
@@ -603,7 +603,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
onOk={handleOk}
ref={form}
isGGUF={isGGUF}
formKey={deployFormKeyMap.catalog}
formKey={DeployFormKeyMap.CATALOG}
sourceDisable={false}
sourceList={sourceList}
clusterList={clusterList}
@@ -11,15 +11,15 @@ import _ from 'lodash';
import { FC, useEffect, useMemo, useRef, useState } from 'react';
import styled from 'styled-components';
import ColumnWrapper from '../../_components/column-wrapper';
import { defaultFormValues, deployFormKeyMap, modelSourceMap } from '../config';
import { defaultFormValues, DeployFormKeyMap, modelSourceMap } from '../config';
import { backendOptionsMap } from '../config/backend-parameters';
import { FormData, SourceType } from '../config/types';
import DataForm from '../forms';
import {
MessageStatus,
WarningStausOptions,
useCheckCompatibility,
useSelectModel
useSelectModel,
WarningStausOptions
} from '../hooks';
import useCheckBackend from '../hooks/use-check-backend';
import CompatibilityAlert from './compatible-alert';
@@ -635,7 +635,7 @@ const AddModal: FC<AddModalProps> = (props) => {
</TitleWrapper>
)}
<DataForm
formKey={deployFormKeyMap.deployment}
formKey={DeployFormKeyMap.DEPLOYMENT}
initialValues={initialValues}
source={source}
action={action}
@@ -7,7 +7,7 @@ import _ from 'lodash';
import React, { useEffect, useMemo, useRef } from 'react';
import ColumnWrapper from '../../_components/column-wrapper';
import {
deployFormKeyMap,
DeployFormKeyMap,
DO_NOT_NOTIFY_RECREATE,
ScheduleValueMap
} from '../config';
@@ -290,7 +290,7 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
}
>
<DataForm
formKey={deployFormKeyMap.deployment}
formKey={DeployFormKeyMap.DEPLOYMENT}
initialValues={formData}
source={formData.source || ''}
action={action}
+5 -29
View File
@@ -1,7 +1,6 @@
import { StatusMaps } from '@/config';
import { EditOutlined } from '@ant-design/icons';
import { backendOptionsMap } from './backend-parameters';
import { DeployFormKey } from './types';
export const backendTipsList = [
{
@@ -357,30 +356,6 @@ export const DO_NOT_TRIGGER_CHECK_COMPATIBILITY = [
// ignore to compare old and new data when these fields change in updating model
export const DO_NOT_NOTIFY_RECREATE = ['categories', 'replicas', 'description'];
export const formFields = [
'name',
'model_scope_model_id',
'huggingface_repo_id',
'huggingface_filename',
'model_scope_file_path',
'local_path',
'ollama_library_model_name',
'backend',
'replicas',
'source',
'description',
'worker_selector',
'cpu_offloading',
'distributed_inference_across_workers',
'gpu_selector',
'gpu_ids',
'categories',
'backend_version',
'env',
'scheduleType',
'restart_on_error'
];
export const defaultFormValues = {
replicas: 1,
description: '',
@@ -455,7 +430,8 @@ export const scheduleTypeTips = [
}
];
export const deployFormKeyMap: Record<string, DeployFormKey> = {
deployment: 'deployment',
catalog: 'catalog'
};
// transform to enum type
export enum DeployFormKeyMap {
DEPLOYMENT = 'deployment',
CATALOG = 'catalog'
}
+2 -2
View File
@@ -2,7 +2,7 @@ import SealSelect from '@/components/seal-form/seal-select';
import useAppUtils from '@/hooks/use-app-utils';
import { Form } from 'antd';
import React from 'react';
import { deployFormKeyMap } from '../config';
import { DeployFormKeyMap } from '../config';
import { useCatalogFormContext, useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
@@ -19,7 +19,7 @@ const CatalogForm: React.FC = () => {
} = catalogFormCtx;
if (
formKey !== deployFormKeyMap.catalog &&
formKey !== DeployFormKeyMap.CATALOG &&
!sizeOptions?.length &&
!quantizationOptions?.length
) {
+2 -2
View File
@@ -7,7 +7,7 @@ import _ from 'lodash';
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
import styled from 'styled-components';
import {
deployFormKeyMap,
DeployFormKeyMap,
DO_NOT_NOTIFY_RECREATE,
DO_NOT_TRIGGER_CHECK_COMPATIBILITY,
modelSourceMap,
@@ -132,7 +132,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
if (
modelSourceMap.local_path_value === source ||
action === PageAction.EDIT ||
formKey === deployFormKeyMap.catalog
formKey === DeployFormKeyMap.CATALOG
) {
return {
top: 0,
@@ -5,7 +5,7 @@ import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import _ from 'lodash';
import React, { useRef } from 'react';
import { deployFormKeyMap, localPathTipsList, modelSourceMap } from '../config';
import { DeployFormKeyMap, localPathTipsList, modelSourceMap } from '../config';
import { backendOptionsMap } from '../config/backend-parameters';
import { useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
@@ -28,7 +28,7 @@ const LocalPathForm: React.FC = () => {
if (
![modelSourceMap.local_path_value].includes(source) ||
formKey === deployFormKeyMap.catalog
formKey === DeployFormKeyMap.CATALOG
) {
return null;
}
+2 -2
View File
@@ -4,7 +4,7 @@ import useAppUtils from '@/hooks/use-app-utils';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import React from 'react';
import { deployFormKeyMap, modelSourceMap } from '../config';
import { DeployFormKeyMap, modelSourceMap } from '../config';
import { useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
@@ -21,7 +21,7 @@ const HuggingFaceForm: React.FC = () => {
modelSourceMap.huggingface_value,
modelSourceMap.modelscope_value
].includes(source) ||
formKey === deployFormKeyMap.catalog
formKey === DeployFormKeyMap.CATALOG
) {
return null;
}