fix: ui conflicts in update of multiple evalute result
This commit is contained in:
@@ -3,7 +3,7 @@ import { Typography } from 'antd';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import OverlayScroller from '../overlay-scroller';
|
import OverlayScroller, { OverlayScrollerOptions } from '../overlay-scroller';
|
||||||
import './block.less';
|
import './block.less';
|
||||||
interface AlertInfoProps {
|
interface AlertInfoProps {
|
||||||
type: Global.MessageType;
|
type: Global.MessageType;
|
||||||
@@ -15,6 +15,7 @@ interface AlertInfoProps {
|
|||||||
contentStyle?: React.CSSProperties;
|
contentStyle?: React.CSSProperties;
|
||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
|
overlayScrollerProps?: OverlayScrollerOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TitleWrapper = styled.div`
|
const TitleWrapper = styled.div`
|
||||||
@@ -41,7 +42,8 @@ const AlertInfo: React.FC<AlertInfoProps> = (props) => {
|
|||||||
title,
|
title,
|
||||||
contentStyle,
|
contentStyle,
|
||||||
icon,
|
icon,
|
||||||
maxHeight = 86
|
maxHeight = 86,
|
||||||
|
overlayScrollerProps = {}
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -67,7 +69,11 @@ const AlertInfo: React.FC<AlertInfoProps> = (props) => {
|
|||||||
{title && (
|
{title && (
|
||||||
<TitleWrapper className="title-text">{title}</TitleWrapper>
|
<TitleWrapper className="title-text">{title}</TitleWrapper>
|
||||||
)}
|
)}
|
||||||
<OverlayScroller maxHeight={maxHeight} style={{ ...contentStyle }}>
|
<OverlayScroller
|
||||||
|
maxHeight={maxHeight}
|
||||||
|
style={{ ...contentStyle }}
|
||||||
|
{...overlayScrollerProps}
|
||||||
|
>
|
||||||
<ContentWrapper
|
<ContentWrapper
|
||||||
$hasTitle={!!title}
|
$hasTitle={!!title}
|
||||||
className={classNames('content', type)}
|
className={classNames('content', type)}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
padding-inline: 6px;
|
padding-inline: 6px;
|
||||||
border-bottom: 1px solid var(--ant-color-split);
|
border: 1px solid var(--ant-color-split);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
td {
|
td {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
padding-inline: 6px;
|
padding-inline: 6px;
|
||||||
border-bottom: 1px solid var(--ant-color-split);
|
border: 1px solid var(--ant-color-split);
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ const Wrapper = styled.div<{ $maxHeight?: number }>`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// export OverlayScrollerOptions
|
||||||
|
export type { OverlayScrollerOptions };
|
||||||
|
|
||||||
export const OverlayScroller: React.FC<
|
export const OverlayScroller: React.FC<
|
||||||
OverlayScrollerOptions & {
|
OverlayScrollerOptions & {
|
||||||
maxHeight?: number;
|
maxHeight?: number;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
backendLabelMap,
|
backendLabelMap,
|
||||||
backendOptionsMap,
|
backendOptionsMap,
|
||||||
backendParamsHolderTips,
|
backendParamsHolderTips,
|
||||||
|
getBackendParamsTips,
|
||||||
modelCategories,
|
modelCategories,
|
||||||
placementStrategyOptions
|
placementStrategyOptions
|
||||||
} from '../config';
|
} from '../config';
|
||||||
@@ -120,37 +121,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
|||||||
}, [backend]);
|
}, [backend]);
|
||||||
|
|
||||||
const backendParamsTips = useMemo(() => {
|
const backendParamsTips = useMemo(() => {
|
||||||
if (backend === backendOptionsMap.llamaBox) {
|
return getBackendParamsTips(backend);
|
||||||
return {
|
|
||||||
backend: 'llama-box',
|
|
||||||
releases: 'https://github.com/gpustack/llama-box/releases',
|
|
||||||
link: 'https://github.com/gpustack/llama-box?tab=readme-ov-file#usage',
|
|
||||||
version: 'v0.0.140'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (backend === backendOptionsMap.vllm) {
|
|
||||||
return {
|
|
||||||
backend: 'vLLM',
|
|
||||||
releases: 'https://github.com/vllm-project/vllm/releases',
|
|
||||||
link: 'https://docs.vllm.ai/en/stable/serving/openai_compatible_server.html#cli-reference',
|
|
||||||
version: 'v0.8.5'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (backend === backendOptionsMap.ascendMindie) {
|
|
||||||
return {
|
|
||||||
backend: 'Ascend MindIE',
|
|
||||||
releases: '',
|
|
||||||
link: 'http://docs.gpustack.ai/latest/user-guide/inference-backends/#parameters-reference_2',
|
|
||||||
version: '1.0.0'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
backend: 'vox-box',
|
|
||||||
releases: 'https://github.com/gpustack/vox-box/releases',
|
|
||||||
link: '',
|
|
||||||
version: 'v0.0.13'
|
|
||||||
};
|
|
||||||
}, [backend]);
|
}, [backend]);
|
||||||
|
|
||||||
const handleWorkerLabelsChange = useCallback(
|
const handleWorkerLabelsChange = useCallback(
|
||||||
|
|||||||
@@ -9,7 +9,13 @@ const ColumnWrapper: React.FC<any> = ({
|
|||||||
paddingBottom = 50
|
paddingBottom = 50
|
||||||
}) => {
|
}) => {
|
||||||
const scroller = React.useRef<any>(null);
|
const scroller = React.useRef<any>(null);
|
||||||
const { initialize } = useOverlayScroller();
|
const { initialize } = useOverlayScroller({
|
||||||
|
options: {
|
||||||
|
scrollbars: {
|
||||||
|
autoHide: 'move'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (scroller.current) {
|
if (scroller.current) {
|
||||||
|
|||||||
@@ -119,6 +119,11 @@ const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
|
|||||||
contentStyle={contentStyle}
|
contentStyle={contentStyle}
|
||||||
type={type || 'warning'}
|
type={type || 'warning'}
|
||||||
icon={renderIcon}
|
icon={renderIcon}
|
||||||
|
overlayScrollerProps={{
|
||||||
|
scrollbars: {
|
||||||
|
autoHide: 'move'
|
||||||
|
}
|
||||||
|
}}
|
||||||
></AlertBlockInfo>
|
></AlertBlockInfo>
|
||||||
{showClose && !['transition'].includes(type) && (
|
{showClose && !['transition'].includes(type) && (
|
||||||
<CloseWrapper className="close-wrapper">
|
<CloseWrapper className="close-wrapper">
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ const resetFieldsByModel = [
|
|||||||
|
|
||||||
const resetFieldsByFile = [
|
const resetFieldsByFile = [
|
||||||
'cpu_offloading',
|
'cpu_offloading',
|
||||||
'distributed_inference_across_workers',
|
'distributed_inference_across_workers'
|
||||||
'backend_parameters'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ModalFooterStyle = {
|
const ModalFooterStyle = {
|
||||||
@@ -99,11 +98,12 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
setWarningStatus,
|
setWarningStatus,
|
||||||
handleBackendChangeBefore,
|
handleBackendChangeBefore,
|
||||||
cancelEvaluate,
|
cancelEvaluate,
|
||||||
handleOnValuesChange,
|
handleOnValuesChange: handleOnValuesChangeBefore,
|
||||||
handleEvaluateOnChange,
|
handleEvaluateOnChange,
|
||||||
warningStatus,
|
warningStatus,
|
||||||
submitAnyway
|
submitAnyway
|
||||||
} = useCheckCompatibility();
|
} = useCheckCompatibility();
|
||||||
|
|
||||||
const { onSelectModel } = useSelectModel({ gpuOptions: props.gpuOptions });
|
const { onSelectModel } = useSelectModel({ gpuOptions: props.gpuOptions });
|
||||||
const form = useRef<any>({});
|
const form = useRef<any>({});
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
@@ -118,7 +118,22 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
model: false,
|
model: false,
|
||||||
file: false
|
file: false
|
||||||
});
|
});
|
||||||
|
const evaluateStateRef = useRef<{ state: 'model' | 'file' | 'form' }>({
|
||||||
|
state: 'form'
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state target to distinguish the evaluate state
|
||||||
|
*/
|
||||||
|
const setEvaluteState = (state: 'model' | 'file' | 'form') => {
|
||||||
|
evaluateStateRef.current.state = state;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param flag set the evaluate status of the model or file
|
||||||
|
*/
|
||||||
const setIsHolderRef = (flag: Record<string, boolean>) => {
|
const setIsHolderRef = (flag: Record<string, boolean>) => {
|
||||||
isHolderRef.current = {
|
isHolderRef.current = {
|
||||||
...isHolderRef.current,
|
...isHolderRef.current,
|
||||||
@@ -126,6 +141,15 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleOnValuesChange = (data: {
|
||||||
|
changedValues: any;
|
||||||
|
allValues: any;
|
||||||
|
source: SourceType;
|
||||||
|
}) => {
|
||||||
|
setEvaluteState('form');
|
||||||
|
handleOnValuesChangeBefore(data);
|
||||||
|
};
|
||||||
|
|
||||||
const getDefaultSpec = (item: any) => {
|
const getDefaultSpec = (item: any) => {
|
||||||
const defaultSpec = item.evaluateResult?.default_spec || {};
|
const defaultSpec = item.evaluateResult?.default_spec || {};
|
||||||
return _.omit(defaultSpec, [
|
return _.omit(defaultSpec, [
|
||||||
@@ -145,6 +169,10 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
const handleSelectModelFile = async (item: any, evaluate?: boolean) => {
|
const handleSelectModelFile = async (item: any, evaluate?: boolean) => {
|
||||||
form.current?.form?.resetFields(resetFieldsByFile);
|
form.current?.form?.resetFields(resetFieldsByFile);
|
||||||
const modelInfo = onSelectModel(selectedModel, props.source);
|
const modelInfo = onSelectModel(selectedModel, props.source);
|
||||||
|
|
||||||
|
/** display the selected model file information, but not
|
||||||
|
* unitl the evaluate result is ready
|
||||||
|
*/
|
||||||
form.current?.setFieldsValue?.({
|
form.current?.setFieldsValue?.({
|
||||||
file_name: item.fakeName,
|
file_name: item.fakeName,
|
||||||
...modelInfo,
|
...modelInfo,
|
||||||
@@ -158,6 +186,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (item.fakeName) {
|
if (item.fakeName) {
|
||||||
|
setEvaluteState('file');
|
||||||
const evaluateRes = await handleEvaluateOnChange?.({
|
const evaluateRes = await handleEvaluateOnChange?.({
|
||||||
changedValues: {},
|
changedValues: {},
|
||||||
allValues: form.current?.form?.getFieldsValue?.(),
|
allValues: form.current?.form?.getFieldsValue?.(),
|
||||||
@@ -166,31 +195,55 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
const defaultSpec = getDefaultSpec({
|
const defaultSpec = getDefaultSpec({
|
||||||
evaluateResult: evaluateRes
|
evaluateResult: evaluateRes
|
||||||
});
|
});
|
||||||
console.log('defaultSpec', defaultSpec);
|
|
||||||
|
/**
|
||||||
|
* do not reset backend_parameters when select a model file
|
||||||
|
*/
|
||||||
|
|
||||||
|
const formBackendParameters =
|
||||||
|
form.current?.getFieldValue?.('backend_parameters') || [];
|
||||||
|
|
||||||
form.current?.setFieldsValue?.({
|
form.current?.setFieldsValue?.({
|
||||||
file_name: item.fakeName,
|
file_name: item.fakeName,
|
||||||
...defaultSpec,
|
...defaultSpec,
|
||||||
...modelInfo,
|
...modelInfo,
|
||||||
|
backend_parameters:
|
||||||
|
formBackendParameters.length > 0
|
||||||
|
? formBackendParameters
|
||||||
|
: defaultSpec.backend_parameters || [],
|
||||||
categories: getCategory(item)
|
categories: getCategory(item)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnSelectModel = (item: any, evaluate?: boolean) => {
|
const handleOnSelectModel = (item: any, evaluate?: boolean) => {
|
||||||
|
// when select a model not from the evaluate result,
|
||||||
|
if (!evaluate) {
|
||||||
|
setEvaluteState('model');
|
||||||
setSelectedModel(item);
|
setSelectedModel(item);
|
||||||
form.current?.form?.resetFields(resetFieldsByModel);
|
form.current?.form?.resetFields(resetFieldsByModel);
|
||||||
|
const modelInfo = onSelectModel(item, props.source);
|
||||||
|
form.current?.setFieldsValue?.({
|
||||||
|
...modelInfo,
|
||||||
|
categories: getCategory(item)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!item.isGGUF) {
|
if (!item.isGGUF) {
|
||||||
setIsGGUF(false);
|
setIsGGUF(false);
|
||||||
const modelInfo = onSelectModel(item, props.source);
|
const modelInfo = onSelectModel(item, props.source);
|
||||||
if (!isHolderRef.current.model) {
|
if (
|
||||||
|
!isHolderRef.current.model &&
|
||||||
|
evaluateStateRef.current.state === 'model'
|
||||||
|
) {
|
||||||
handleShowCompatibleAlert(item.evaluateResult);
|
handleShowCompatibleAlert(item.evaluateResult);
|
||||||
}
|
|
||||||
form.current?.setFieldsValue?.({
|
form.current?.setFieldsValue?.({
|
||||||
...getDefaultSpec(item),
|
...getDefaultSpec(item),
|
||||||
...modelInfo,
|
...modelInfo,
|
||||||
categories: getCategory(item)
|
categories: getCategory(item)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnOk = async (allValues: FormData) => {
|
const handleOnOk = async (allValues: FormData) => {
|
||||||
|
|||||||
@@ -416,35 +416,6 @@ export const setbackendParameters = (data: any) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVllmCliArgs = (inputString: string) => {
|
|
||||||
const arrayOutput = inputString
|
|
||||||
.split(/\s*\[\s*|\s*\]\s*/g) // Split by '[' or ']', removing extra spaces
|
|
||||||
.filter((item) => item) // Remove empty items
|
|
||||||
.map((item) => item.trim()); // Trim spaces around each item
|
|
||||||
|
|
||||||
const result = arrayOutput.map((item) => {
|
|
||||||
const parts = item.split(' ');
|
|
||||||
const label = parts[0].trim(); // Remove leading dashes
|
|
||||||
const value = parts[0].trim();
|
|
||||||
|
|
||||||
if (parts.length === 1) {
|
|
||||||
return { label, value, options: [] };
|
|
||||||
} else if (parts.length > 1) {
|
|
||||||
const optionPart = parts[1];
|
|
||||||
if (optionPart.startsWith('{') && optionPart.endsWith('}')) {
|
|
||||||
const options = optionPart
|
|
||||||
.slice(1, -1)
|
|
||||||
.split(',')
|
|
||||||
.map((opt) => opt.trim());
|
|
||||||
return { label, value, options };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { label, value, options: [] }; // Fallback
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const modelLabels = [
|
export const modelLabels = [
|
||||||
{ label: 'Image', value: 'image_only' },
|
{ label: 'Image', value: 'image_only' },
|
||||||
{ label: 'Text-to-speech', value: 'text_to_speech' },
|
{ label: 'Text-to-speech', value: 'text_to_speech' },
|
||||||
@@ -519,3 +490,37 @@ export const formFields = [
|
|||||||
'scheduleType',
|
'scheduleType',
|
||||||
'restart_on_error'
|
'restart_on_error'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const getBackendParamsTips = (backend: string) => {
|
||||||
|
if (backend === backendOptionsMap.llamaBox) {
|
||||||
|
return {
|
||||||
|
backend: 'llama-box',
|
||||||
|
releases: 'https://github.com/gpustack/llama-box/releases',
|
||||||
|
link: 'https://github.com/gpustack/llama-box?tab=readme-ov-file#usage',
|
||||||
|
version: 'v0.0.140'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (backend === backendOptionsMap.vllm) {
|
||||||
|
return {
|
||||||
|
backend: 'vLLM',
|
||||||
|
releases: 'https://github.com/vllm-project/vllm/releases',
|
||||||
|
link: 'https://docs.vllm.ai/en/stable/serving/openai_compatible_server.html#cli-reference',
|
||||||
|
version: 'v0.8.5'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (backend === backendOptionsMap.ascendMindie) {
|
||||||
|
return {
|
||||||
|
backend: 'Ascend MindIE',
|
||||||
|
releases: '',
|
||||||
|
link: 'http://docs.gpustack.ai/latest/user-guide/inference-backends/#parameters-reference_2',
|
||||||
|
version: '1.0.0'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
backend: 'vox-box',
|
||||||
|
releases: 'https://github.com/gpustack/vox-box/releases',
|
||||||
|
link: '',
|
||||||
|
version: 'v0.0.13'
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ const options = [
|
|||||||
label: '--host',
|
label: '--host',
|
||||||
value: '--host'
|
value: '--host'
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '--port',
|
|
||||||
value: '--port'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '--timeout',
|
label: '--timeout',
|
||||||
value: '--timeout'
|
value: '--timeout'
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: var(--font-size-base);
|
font-size: var(--font-size-base);
|
||||||
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
|||||||
Reference in New Issue
Block a user