fix: backend edit format

This commit is contained in:
jialin
2025-10-15 12:18:50 +08:00
parent f02b972dc0
commit 4196351e48
19 changed files with 147 additions and 59 deletions
@@ -127,6 +127,7 @@ const SealTextArea: React.FC<InputTextareaProps & SealFormItemProps> = (
> >
<Input.TextArea <Input.TextArea
{...rest} {...rest}
placeholder={placeholder}
spellCheck={rest.spellCheck ?? false} spellCheck={rest.spellCheck ?? false}
autoSize={autoSize} autoSize={autoSize}
ref={inputRef} ref={inputRef}
+1 -1
View File
@@ -11,7 +11,7 @@ export default {
'backend.builtin': 'Built-in', 'backend.builtin': 'Built-in',
'backend.custom': 'Custom', 'backend.custom': 'Custom',
'backend.isDefault': 'Default', 'backend.isDefault': 'Default',
'backend.availableFrameworks': 'Available Frameworks', 'backend.availableFrameworks': 'Supported Frameworks',
'backend.addVersion': 'Add Version', 'backend.addVersion': 'Add Version',
'backend.filter.framework': 'Filter by Framework', 'backend.filter.framework': 'Filter by Framework',
'backend.export.yaml': 'Export YAML', 'backend.export.yaml': 'Export YAML',
+3 -1
View File
@@ -187,5 +187,7 @@ export default {
'models.form.extendedkvcache': 'Enable Extended KV Cache', 'models.form.extendedkvcache': 'Enable Extended KV Cache',
'models.form.chunkSize': 'Size Of Cache Chunks', 'models.form.chunkSize': 'Size Of Cache Chunks',
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL' 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'
}; };
+1 -1
View File
@@ -11,7 +11,7 @@ export default {
'backend.builtin': 'Built-in', 'backend.builtin': 'Built-in',
'backend.custom': 'Custom', 'backend.custom': 'Custom',
'backend.isDefault': 'Default', 'backend.isDefault': 'Default',
'backend.availableFrameworks': 'Available Frameworks', 'backend.availableFrameworks': 'Supported Frameworks',
'backend.addVersion': 'Add Version', 'backend.addVersion': 'Add Version',
'backend.filter.framework': 'Filter by Framework', 'backend.filter.framework': 'Filter by Framework',
'backend.export.yaml': 'Export YAML', 'backend.export.yaml': 'Export YAML',
+5 -2
View File
@@ -184,7 +184,9 @@ export default {
'models.form.extendedkvcache': 'Enable Extended KV Cache', 'models.form.extendedkvcache': 'Enable Extended KV Cache',
'models.form.chunkSize': 'Size Of Cache Chunks', 'models.form.chunkSize': 'Size Of Cache Chunks',
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL' 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -212,6 +214,7 @@ export default {
// 22. 'models.form.extendedkvcache': 'Enable Extended KV Cache', // 22. 'models.form.extendedkvcache': 'Enable Extended KV Cache',
// 23. 'models.form.chunkSize': 'Size Of Cache Chunks', // 23. 'models.form.chunkSize': 'Size Of Cache Chunks',
// 24. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', // 24. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
// 25. 'models.form.remoteURL': 'Remote Storage URL' // 25. 'models.form.remoteURL': 'Remote Storage URL',
// 26. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+1 -1
View File
@@ -11,7 +11,7 @@ export default {
'backend.builtin': 'Built-in', 'backend.builtin': 'Built-in',
'backend.custom': 'Custom', 'backend.custom': 'Custom',
'backend.isDefault': 'Default', 'backend.isDefault': 'Default',
'backend.availableFrameworks': 'Available Frameworks', 'backend.availableFrameworks': 'Supported Frameworks',
'backend.addVersion': 'Add Version', 'backend.addVersion': 'Add Version',
'backend.filter.framework': 'Filter by Framework', 'backend.filter.framework': 'Filter by Framework',
'backend.export.yaml': 'Export YAML', 'backend.export.yaml': 'Export YAML',
+5 -2
View File
@@ -187,7 +187,9 @@ export default {
'models.form.extendedkvcache': 'Enable Extended KV Cache', 'models.form.extendedkvcache': 'Enable Extended KV Cache',
'models.form.chunkSize': 'Size Of Cache Chunks', 'models.form.chunkSize': 'Size Of Cache Chunks',
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
'models.form.remoteURL': 'Remote Storage URL' 'models.form.remoteURL': 'Remote Storage URL',
'models.form.runCommandPlaceholder':
'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -207,5 +209,6 @@ export default {
// 14. 'models.form.extendedkvcache': 'Enable Extended KV Cache', // 14. 'models.form.extendedkvcache': 'Enable Extended KV Cache',
// 15. 'models.form.chunkSize': 'Size Of Cache Chunks', // 15. 'models.form.chunkSize': 'Size Of Cache Chunks',
// 16. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)', // 16. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
// 17. 'models.form.remoteURL': 'Remote Storage URL' // 17. 'models.form.remoteURL': 'Remote Storage URL',
// 18. 'models.form.runCommandPlaceholder': 'e.g., vllm serve Qwen/Qwen2.5-1.5B-Instruct';
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+1 -1
View File
@@ -11,7 +11,7 @@ export default {
'backend.builtin': '内置', 'backend.builtin': '内置',
'backend.custom': '自定义', 'backend.custom': '自定义',
'backend.isDefault': '默认', 'backend.isDefault': '默认',
'backend.availableFrameworks': '可用框架', 'backend.availableFrameworks': '支持框架',
'backend.addVersion': '添加版本', 'backend.addVersion': '添加版本',
'backend.filter.framework': '按框架过滤', 'backend.filter.framework': '按框架过滤',
'backend.export.yaml': '导出 YAML', 'backend.export.yaml': '导出 YAML',
+3 -1
View File
@@ -177,5 +177,7 @@ export default {
'models.form.extendedkvcache': '启用扩展 KV 缓存', 'models.form.extendedkvcache': '启用扩展 KV 缓存',
'models.form.chunkSize': '缓存分块大小', 'models.form.chunkSize': '缓存分块大小',
'models.form.maxCPUSize': 'CPU 缓存最大占用 (GiB)', 'models.form.maxCPUSize': 'CPU 缓存最大占用 (GiB)',
'models.form.remoteURL': '远程存储地址' 'models.form.remoteURL': '远程存储地址',
'models.form.runCommandPlaceholder':
'例如,vllm serve Qwen/Qwen2.5-1.5B-Instruct'
}; };
+19 -12
View File
@@ -57,10 +57,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
const onOk = () => { const onOk = () => {
if (activeKey === 'yaml') { if (activeKey === 'yaml') {
const content = editorRef.current?.getContent(); const content = editorRef.current?.getContent();
const valid = editorRef.current?.validate(); onSubmitYaml({ content: content });
if (valid) {
onSubmitYaml({ content: content });
}
} else { } else {
formRef.current?.submit(); formRef.current?.submit();
} }
@@ -104,30 +101,40 @@ const AddModal: React.FC<AddModalProps> = (props) => {
); );
const builtInVersions = Object.keys( const builtInVersions = Object.keys(
values.build_in_version_configs || {} values.built_in_version_configs || {}
).map((key) => ({ ).map((key) => ({
version_no: key, version_no: key,
image_name: values.build_in_version_configs?.[key]?.image_name, image_name: values.built_in_version_configs?.[key]?.image_name,
run_command: values.build_in_version_configs?.[key]?.run_command, run_command: values.built_in_version_configs?.[key]?.run_command,
is_default: key === values.default_version, is_default: key === values.default_version,
build_in_frameworks: built_in_frameworks:
values.build_in_version_configs?.[key]?.build_in_frameworks || [], values.built_in_version_configs?.[key]?.built_in_frameworks || [],
is_built_in: true is_built_in: true
})); }));
return { return {
...values, ...values,
version_configs: versionConfigs, version_configs: versionConfigs,
build_in_version_configs: builtInVersions built_in_version_configs: builtInVersions
}; };
}; };
// built-in backend does not allow to edit default_version // built-in backend does not allow to edit default_version
const initYamlContent = (values: any) => { const initYamlContent = (values: any) => {
const copyValues = structuredClone(values);
copyValues.version_configs = _.mapValues(
copyValues.version_configs || {},
(v: any) => {
return _.omit(v, ['built_in_frameworks']);
}
);
if (currentData?.is_built_in) { if (currentData?.is_built_in) {
return json2Yaml(_.pick(values, backendFields)); return json2Yaml(_.pick(copyValues, backendFields));
} }
return json2Yaml(_.pick(values, [...backendFields, 'default_version'])); return json2Yaml(
_.pick(copyValues, [...backendFields, 'default_version'])
);
}; };
if (action === PageAction.EDIT && open) { if (action === PageAction.EDIT && open) {
@@ -20,8 +20,8 @@ const VersionInfoModal: React.FC<VersionInfoModalProps> = ({
useEffect(() => { useEffect(() => {
if (open && currentData) { if (open && currentData) {
// add is_built_in field to build_in_version_configs // add is_built_in field to built_in_version_configs
const builtInVersions = currentData.build_in_version_configs || {}; const builtInVersions = currentData.built_in_version_configs || {};
for (const key in builtInVersions) { for (const key in builtInVersions) {
if (builtInVersions?.hasOwnProperty(key)) { if (builtInVersions?.hasOwnProperty(key)) {
@@ -41,7 +41,7 @@ const VersionInfoModal: React.FC<VersionInfoModalProps> = ({
run_command: value.run_command, run_command: value.run_command,
is_default: key === currentData.default_version, is_default: key === currentData.default_version,
availableFrameworks: [ availableFrameworks: [
...(value.build_in_frameworks || []), ...(value.built_in_frameworks || []),
...(value.custom_framework ? [value.custom_framework] : []) ...(value.custom_framework ? [value.custom_framework] : [])
], ],
is_built_in: value.is_built_in || false is_built_in: value.is_built_in || false
+3 -3
View File
@@ -114,7 +114,7 @@ export const backendFields = [
'health_check_path', 'health_check_path',
'default_run_command', 'default_run_command',
'version_configs', 'version_configs',
'default_backend_parameters' 'default_backend_param'
]; ];
export const frameworks = [ export const frameworks = [
{ {
@@ -148,6 +148,8 @@ backend_name: SGLang
description: SGLang backend description: SGLang backend
default_version: v0.5.1 default_version: v0.5.1
health_check_path: /health health_check_path: /health
default_backend_param:
- --host
default_run_command: run sglang default_run_command: run sglang
version_configs: version_configs:
v0.0.1: v0.0.1:
@@ -158,6 +160,4 @@ version_configs:
image_name: lm/sglang image_name: lm/sglang
run_command: run_command:
custom_framework: custom_framework:
default_backend_parameters:
- --host
`; `;
+55 -5
View File
@@ -14,6 +14,17 @@
"type": "string", "type": "string",
"description": "default backend version" "description": "default backend version"
}, },
"is_built_in": {
"type": "boolean",
"description": "is built-in backend"
},
"default_backend_param": {
"type": "array",
"items": {
"type": "string"
},
"description": "default backend parameter"
},
"default_run_command": { "default_run_command": {
"type": ["string", "null"], "type": ["string", "null"],
"description": "default start command" "description": "default start command"
@@ -48,12 +59,51 @@
"additionalProperties": false, "additionalProperties": false,
"description": "multiple backend versions" "description": "multiple backend versions"
}, },
"default_backend_parameters": { "built_in_version_configs": {
"type": "array", "type": "object",
"items": { "patternProperties": {
"type": "string" "^[a-zA-Z0-9._-]+$": {
"type": "object",
"properties": {
"image_name": {
"type": "string",
"description": "image name"
},
"run_command": {
"type": ["string", "null"],
"description": "start command"
},
"custom_framework": {
"type": ["string", "null"],
"description": "custom framework"
},
"built_in_frameworks": {
"type": "array",
"items": {
"type": "string"
},
"description": "built-in frameworks"
}
},
"required": ["image_name", "run_command"],
"additionalProperties": false
}
}, },
"description": "default backend parameters" "additionalProperties": false,
"description": "multiple backend versions"
},
"framework_index_map": {
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"description": "framework to version mapping"
} }
}, },
"required": ["backend_name", "default_version", "version_configs"], "required": ["backend_name", "default_version", "version_configs"],
@@ -5,6 +5,13 @@
"type": ["string", "null"], "type": ["string", "null"],
"description": "backend description" "description": "backend description"
}, },
"default_backend_param": {
"type": "array",
"items": {
"type": "string"
},
"description": "default backend parameter"
},
"default_run_command": { "default_run_command": {
"type": ["string", "null"], "type": ["string", "null"],
"description": "default start command" "description": "default start command"
@@ -38,13 +45,6 @@
}, },
"additionalProperties": false, "additionalProperties": false,
"description": "multiple backend versions" "description": "multiple backend versions"
},
"default_backend_parameters": {
"type": "array",
"items": {
"type": "string"
},
"description": "default backend parameters"
} }
}, },
"required": ["version_configs"], "required": ["version_configs"],
@@ -9,6 +9,13 @@
"type": "string", "type": "string",
"description": "default backend version" "description": "default backend version"
}, },
"default_backend_param": {
"type": "array",
"items": {
"type": "string"
},
"description": "default backend parameter"
},
"default_run_command": { "default_run_command": {
"type": ["string", "null"], "type": ["string", "null"],
"description": "default start command" "description": "default start command"
@@ -42,13 +49,6 @@
}, },
"additionalProperties": false, "additionalProperties": false,
"description": "multiple backend versions" "description": "multiple backend versions"
},
"default_backend_parameters": {
"type": "array",
"items": {
"type": "string"
},
"description": "default backend parameters"
} }
}, },
"required": ["default_version", "version_configs"], "required": ["default_version", "version_configs"],
+2 -2
View File
@@ -2,7 +2,7 @@ export interface VersionConfigs {
image_name: string; image_name: string;
run_command: string; run_command: string;
is_default: boolean; is_default: boolean;
build_in_frameworks?: string[]; built_in_frameworks?: string[];
custom_framework?: string; custom_framework?: string;
version_no?: string; version_no?: string;
is_built_in?: boolean; is_built_in?: boolean;
@@ -29,6 +29,6 @@ export interface ListItem extends FormData {
is_built_in?: boolean; is_built_in?: boolean;
created_at?: string; created_at?: string;
updated_at?: string; updated_at?: string;
build_in_version_configs?: Record<string, VersionConfigs>; built_in_version_configs?: Record<string, VersionConfigs>;
framework_index_map?: Record<string, string[]>; framework_index_map?: Record<string, string[]>;
} }
@@ -90,6 +90,15 @@ export const VersionItem: React.FC<VersionItemProps> = ({ data }) => {
{intl.formatMessage({ id: 'backend.builtin' })} {intl.formatMessage({ id: 'backend.builtin' })}
</ThemeTag> </ThemeTag>
)} )}
{!data.is_built_in && data.is_default && (
<ThemeTag
color="geekblue"
className="font-400"
style={{ marginRight: 0 }}
>
{intl.formatMessage({ id: 'backend.isDefault' })}
</ThemeTag>
)}
</div> </div>
<RowWrapper> <RowWrapper>
{data.image_name && ( {data.image_name && (
+18 -10
View File
@@ -62,7 +62,7 @@ const BackendList = () => {
currentData?: Partial<ListItem>; currentData?: Partial<ListItem>;
}>({ open: false }); }>({ open: false });
// build_in_version_configs is read-only, but needs to be included when updating // built_in_version_configs is read-only, but needs to be included when updating
const handleOnSubmit = async (values: FormData) => { const handleOnSubmit = async (values: FormData) => {
try { try {
if (openModalStatus.action === 'create') { if (openModalStatus.action === 'create') {
@@ -70,9 +70,10 @@ const BackendList = () => {
} else { } else {
await updateBackend(openModalStatus.currentData!.id!, { await updateBackend(openModalStatus.currentData!.id!, {
data: { data: {
build_in_version_configs: built_in_version_configs:
openModalStatus.currentData?.build_in_version_configs, openModalStatus.currentData?.built_in_version_configs,
..._.omit(values, ['build_in_version_configs']) ..._.omit(values, ['built_in_version_configs']),
health_check_path: values.health_check_path || null
} }
}); });
} }
@@ -85,7 +86,7 @@ const BackendList = () => {
} catch (error) {} } catch (error) {}
}; };
// build_in_version_configs needs to be included when updating from YAML, but not allowed to be changed // built_in_version_configs needs to be included when updating from YAML, but not allowed to be changed
const handleOnSubmitYaml = async (values: { content: string }) => { const handleOnSubmitYaml = async (values: { content: string }) => {
try { try {
if (openModalStatus.action === 'create') { if (openModalStatus.action === 'create') {
@@ -95,8 +96,8 @@ const BackendList = () => {
const yamlContent = json2Yaml({ const yamlContent = json2Yaml({
backend_name: openModalStatus.currentData?.backend_name, backend_name: openModalStatus.currentData?.backend_name,
default_version: openModalStatus.currentData?.default_version, default_version: openModalStatus.currentData?.default_version,
build_in_version_configs: built_in_version_configs:
openModalStatus.currentData?.build_in_version_configs, openModalStatus.currentData?.built_in_version_configs,
...jsonData ...jsonData
}); });
await updateBackendFromYAML(openModalStatus.currentData!.id!, { await updateBackendFromYAML(openModalStatus.currentData!.id!, {
@@ -122,7 +123,6 @@ const BackendList = () => {
}; };
const handleOnSelect = (item: any) => { const handleOnSelect = (item: any) => {
console.log('selected item:', item);
if (item.action === 'edit') { if (item.action === 'edit') {
setOpenModalStatus({ setOpenModalStatus({
open: true, open: true,
@@ -134,8 +134,16 @@ const BackendList = () => {
name: item.data.backend_name name: item.data.backend_name
}); });
} else if (item.action === 'export') { } else if (item.action === 'export') {
// Export YAML action const currentData = structuredClone(item.data);
exportYAML(item.data);
currentData.version_configs = _.mapValues(
currentData.version_configs,
(v: any) => {
return _.omit(v, ['built_in_frameworks']);
}
);
exportYAML(_.omit(currentData, ['id', 'created_at', 'updated_at']));
} else if (item.action === 'view_versions') { } else if (item.action === 'view_versions') {
setOpenVersionInfoModal({ setOpenVersionInfoModal({
open: true, open: true,
+3
View File
@@ -143,6 +143,9 @@ const BackendFields: React.FC = () => {
scaleSize={true} scaleSize={true}
allowClear allowClear
label={intl.formatMessage({ id: 'backend.runCommand' })} label={intl.formatMessage({ id: 'backend.runCommand' })}
placeholder={intl.formatMessage({
id: 'models.form.runCommandPlaceholder'
})}
></SealInput.TextArea> ></SealInput.TextArea>
</Form.Item> </Form.Item>
</> </>