feat: backend entrypoint
This commit is contained in:
@@ -84,7 +84,8 @@ const AddModal: React.FC<AddModalProps> = (props) => {
|
||||
acc[curr.version_no] = {
|
||||
custom_framework: curr.custom_framework,
|
||||
image_name: curr.image_name,
|
||||
run_command: curr.run_command
|
||||
run_command: curr.run_command,
|
||||
entrypoint: curr.entrypoint
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
|
||||
@@ -4,6 +4,7 @@ export interface VersionConfigs {
|
||||
is_default: boolean;
|
||||
built_in_frameworks?: string[];
|
||||
custom_framework?: string;
|
||||
entrypoint?: string;
|
||||
version_no?: string;
|
||||
is_built_in?: boolean;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import CollapsibleContainer from '@/components/collapse-container';
|
||||
import BaseSelect from '@/components/seal-form/base/select';
|
||||
import SealInput from '@/components/seal-form/seal-input';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import SealTextArea from '@/components/seal-form/seal-textarea';
|
||||
import { PageActionType } from '@/config/types';
|
||||
import useAppUtils from '@/hooks/use-app-utils';
|
||||
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
@@ -342,14 +343,36 @@ const VersionsForm: React.FC<AddModalProps> = ({
|
||||
required
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name={[name, 'entrypoint']}>
|
||||
<SealInput.TextArea
|
||||
allowClear
|
||||
description={intl.formatMessage({
|
||||
id: 'backend.entrypoint.tips'
|
||||
})}
|
||||
label={intl.formatMessage({
|
||||
id: 'backend.replaceEntrypoint'
|
||||
})}
|
||||
></SealInput.TextArea>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name={[name, 'run_command']}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<SealInput.TextArea
|
||||
<SealTextArea
|
||||
allowClear
|
||||
alwaysFocus={true}
|
||||
description={intl.formatMessage({
|
||||
id: 'backend.form.defaultExecuteCommand.tips'
|
||||
})}
|
||||
placeholder={intl.formatMessage(
|
||||
{ id: 'common.help.eg' },
|
||||
{
|
||||
content:
|
||||
'vllm serve {{model_path}} --port {{port}} --host {{worker_ip}} --served-model-name {{model_name}}'
|
||||
}
|
||||
)}
|
||||
label={intl.formatMessage({ id: 'backend.runCommand' })}
|
||||
></SealInput.TextArea>
|
||||
></SealTextArea>
|
||||
</Form.Item>
|
||||
</CollapsibleContainer>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,8 @@ interface AddWorkerContextProps {
|
||||
clusterLoading?: boolean;
|
||||
provider: ProviderType;
|
||||
stepList: string[];
|
||||
actionSource?: 'modal' | 'page';
|
||||
onCancel?: () => void;
|
||||
onClusterChange?: (value: number, row?: any) => void;
|
||||
collapseKey: Set<string>;
|
||||
onToggle: (open: boolean, key: string) => void;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import AlertInfoBlock from '@/components/alert-info/block';
|
||||
import AlertBlockInfo from '@/components/alert-info/block';
|
||||
import useAddWorkerMessage from '@/pages/cluster-management/hooks/use-add-worker-message';
|
||||
import { ExclamationCircleFilled } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
@@ -36,6 +36,7 @@ type AddWorkerProps = {
|
||||
clusterLoading?: boolean;
|
||||
stepList: StepName[];
|
||||
onClusterChange?: (value: number, row?: any) => void;
|
||||
onCancel?: () => void;
|
||||
registrationInfo: {
|
||||
token: string;
|
||||
image: string;
|
||||
@@ -57,6 +58,7 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
clusterList,
|
||||
clusterLoading,
|
||||
stepList = [],
|
||||
onCancel,
|
||||
onClusterChange
|
||||
} = props || {};
|
||||
const intl = useIntl();
|
||||
@@ -82,12 +84,28 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
// this effect is only triggered when used in cluster create page
|
||||
console.log('actionSource:', actionSource);
|
||||
if (actionSource === 'page') {
|
||||
createModelsChunkRequest();
|
||||
}
|
||||
}, [actionSource]);
|
||||
|
||||
const renderMessage = (count: number) => {
|
||||
if (count === 1) {
|
||||
return intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success_single'
|
||||
},
|
||||
{ count: addedCount }
|
||||
);
|
||||
}
|
||||
return intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success_multiple'
|
||||
},
|
||||
{ count: addedCount }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<AddWorkerContext.Provider
|
||||
value={{
|
||||
@@ -96,7 +114,9 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
provider,
|
||||
stepList: stepList,
|
||||
collapseKey,
|
||||
actionSource,
|
||||
onToggle,
|
||||
onCancel,
|
||||
onClusterChange: handleOnClusterChange,
|
||||
registrationInfo,
|
||||
summary,
|
||||
@@ -110,7 +130,7 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
)}
|
||||
{stepList.includes(StepNamesMap.SelectCluster) &&
|
||||
!clusterList?.length && (
|
||||
<AlertInfoBlock
|
||||
<AlertBlockInfo
|
||||
maxHeight={200}
|
||||
style={{ marginBottom: 8 }}
|
||||
type="warning"
|
||||
@@ -118,7 +138,7 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
message={intl.formatMessage({
|
||||
id: 'resources.worker.noCluster.tips'
|
||||
})}
|
||||
></AlertInfoBlock>
|
||||
></AlertBlockInfo>
|
||||
)}
|
||||
|
||||
{/* render the steps only when there is at least one cluster available or cluster selection is not required */}
|
||||
@@ -142,14 +162,14 @@ const AddWorkerSteps: React.FC<AddWorkerProps> = (props) => {
|
||||
)}
|
||||
{addedCount > 0 && (
|
||||
<Alert
|
||||
style={{ width: 'max-content' }}
|
||||
message={intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success'
|
||||
},
|
||||
{ count: addedCount }
|
||||
)}
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
borderColor: 'var(--ant-color-success)',
|
||||
width: '100%'
|
||||
}}
|
||||
type="success"
|
||||
message={renderMessage(addedCount)}
|
||||
closable
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ScrollerModal from '@/components/scroller-modal';
|
||||
import useAddWorkerMessage from '@/pages/cluster-management/hooks/use-add-worker-message';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Alert, Button } from 'antd';
|
||||
import { Alert } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { queryClusterToken } from '../../apis';
|
||||
@@ -100,6 +100,23 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
const renderMessage = (count: number) => {
|
||||
if (count === 1) {
|
||||
return intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success_single'
|
||||
},
|
||||
{ count: addedCount }
|
||||
);
|
||||
}
|
||||
return intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success_multiple'
|
||||
},
|
||||
{ count: addedCount }
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<ScrollerModal
|
||||
title={title}
|
||||
@@ -115,32 +132,23 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
|
||||
maxContentHeight={'max(calc(100vh - 200px), 600px)'}
|
||||
footer={
|
||||
<Footer>
|
||||
<span className="tips">
|
||||
{addedCount > 0 && (
|
||||
<Alert
|
||||
message={intl.formatMessage(
|
||||
{
|
||||
id: 'clusters.addworker.message.success'
|
||||
},
|
||||
{ count: addedCount }
|
||||
)}
|
||||
type="success"
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={onCancel}
|
||||
style={{
|
||||
minWidth: 88
|
||||
}}
|
||||
>
|
||||
{intl.formatMessage({ id: 'common.button.done' })}
|
||||
</Button>
|
||||
{addedCount > 0 && (
|
||||
<Alert
|
||||
style={{
|
||||
textAlign: 'left',
|
||||
borderColor: 'var(--ant-color-success)',
|
||||
width: '100%'
|
||||
}}
|
||||
type="success"
|
||||
message={renderMessage(addedCount)}
|
||||
closable
|
||||
/>
|
||||
)}
|
||||
</Footer>
|
||||
}
|
||||
>
|
||||
<AddWorkerStep
|
||||
onCancel={onCancel}
|
||||
actionSource={'modal'}
|
||||
stepList={stepList}
|
||||
provider={provider}
|
||||
|
||||
@@ -29,6 +29,8 @@ const Box = styled.div`
|
||||
const ButtonWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
width: 100%;
|
||||
`;
|
||||
@@ -41,7 +43,8 @@ const StepCollapse: React.FC<StepItemProps> = ({
|
||||
...rest
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
const { collapseKey, onToggle, stepList } = useAddWorkerContext();
|
||||
const { collapseKey, onToggle, stepList, actionSource, onCancel } =
|
||||
useAddWorkerContext();
|
||||
|
||||
const handleOnNext = async () => {
|
||||
const res = await beforeNext?.();
|
||||
@@ -51,8 +54,16 @@ const StepCollapse: React.FC<StepItemProps> = ({
|
||||
onToggle(true, nextName);
|
||||
};
|
||||
|
||||
const handleOnPrevious = () => {
|
||||
// find the previous step and open it
|
||||
const previousName = stepList[stepList.indexOf(name) - 1];
|
||||
onToggle(true, previousName);
|
||||
};
|
||||
|
||||
const isLastStep = stepList.indexOf(name) === stepList.length - 1;
|
||||
|
||||
const isFirstStep = stepList.indexOf(name) === 0;
|
||||
|
||||
return (
|
||||
<Box
|
||||
className={
|
||||
@@ -75,13 +86,31 @@ const StepCollapse: React.FC<StepItemProps> = ({
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
{!isLastStep && (
|
||||
<ButtonWrapper>
|
||||
|
||||
<ButtonWrapper>
|
||||
{!isFirstStep && (
|
||||
<Button onClick={handleOnPrevious}>
|
||||
{intl.formatMessage({ id: 'common.button.prev' })}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!isLastStep && (
|
||||
<Button type="primary" onClick={handleOnNext}>
|
||||
{intl.formatMessage({ id: 'common.button.next' })}
|
||||
</Button>
|
||||
</ButtonWrapper>
|
||||
)}
|
||||
)}
|
||||
{isLastStep && actionSource === 'modal' && (
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={onCancel}
|
||||
style={{
|
||||
minWidth: 88
|
||||
}}
|
||||
>
|
||||
{intl.formatMessage({ id: 'common.button.done' })}
|
||||
</Button>
|
||||
)}
|
||||
</ButtonWrapper>
|
||||
</CollapsibleContainer>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -25,7 +25,7 @@ const ClusterAdvanceConfig: React.FC<{
|
||||
return editorRef.current?.getValue();
|
||||
},
|
||||
setYamlValue: (values: any) => {
|
||||
editorRef.current?.setValue(values);
|
||||
editorRef.current?.setValue(values || yamlTemplate);
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import AlertBlockInfo from '@/components/alert-info/block';
|
||||
import {
|
||||
CheckCircleFilled,
|
||||
CloseOutlined,
|
||||
LoadingOutlined,
|
||||
WarningFilled
|
||||
} from '@ant-design/icons';
|
||||
import { CloseOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import { isArray } from 'lodash';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
@@ -98,16 +93,6 @@ const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
|
||||
return '';
|
||||
}, [message, show, handleLinkMessage]);
|
||||
|
||||
const renderIcon = useMemo(() => {
|
||||
if (type === 'transition') {
|
||||
return <LoadingOutlined />;
|
||||
}
|
||||
if (type === 'success') {
|
||||
return <CheckCircleFilled />;
|
||||
}
|
||||
return <WarningFilled />;
|
||||
}, [type]);
|
||||
|
||||
return (
|
||||
show &&
|
||||
!!message && (
|
||||
@@ -118,7 +103,6 @@ const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
|
||||
title={title}
|
||||
contentStyle={contentStyle}
|
||||
type={type || 'warning'}
|
||||
icon={renderIcon}
|
||||
style={{
|
||||
paddingInlineEnd: showClose ? 20 : 16
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user