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