fix: the fields for trigger checking

This commit is contained in:
jialin
2025-04-03 18:08:43 +08:00
parent 939f46c7e6
commit b6136a092d
22 changed files with 226 additions and 73 deletions
+19
View File
@@ -27,6 +27,21 @@
border-color: var(--ant-geekblue-3); border-color: var(--ant-geekblue-3);
} }
&.success {
border: 1px solid var(--color-progress-green);
color: var(--color-progress-green);
.title-text {
color: var(--color-progress-green);
}
.content.success {
color: var(--color-progress-green);
font-weight: var(--font-weight-normal);
opacity: 0.85;
}
}
.title { .title {
position: absolute; position: absolute;
left: 0; left: 0;
@@ -48,6 +63,10 @@
&.transition { &.transition {
color: var(--ant-geekblue-7); color: var(--ant-geekblue-7);
} }
&.success {
color: var(--color-progress-green);
}
} }
.text { .text {
+10 -3
View File
@@ -6,7 +6,7 @@ import styled from 'styled-components';
import OverlayScroller from '../overlay-scroller'; import OverlayScroller from '../overlay-scroller';
import './block.less'; import './block.less';
interface AlertInfoProps { interface AlertInfoProps {
type: 'danger' | 'warning' | 'transition' | 'info'; type: Global.MessageType;
message: React.ReactNode; message: React.ReactNode;
rows?: number; rows?: number;
icon?: React.ReactNode; icon?: React.ReactNode;
@@ -62,9 +62,16 @@ const AlertInfo: React.FC<AlertInfoProps> = (props) => {
{icon ?? <WarningFilled />} {icon ?? <WarningFilled />}
</span> </span>
</div> </div>
{title && <TitleWrapper>{title}</TitleWrapper>} {title && (
<TitleWrapper className="title-text">{title}</TitleWrapper>
)}
<OverlayScroller maxHeight={80} style={{ ...contentStyle }}> <OverlayScroller maxHeight={80} style={{ ...contentStyle }}>
<ContentWrapper $hasTitle={!!title}>{message}</ContentWrapper> <ContentWrapper
$hasTitle={!!title}
className={classNames('content', type)}
>
{message}
</ContentWrapper>
</OverlayScroller> </OverlayScroller>
</Typography.Paragraph> </Typography.Paragraph>
</div> </div>
+2
View File
@@ -42,6 +42,8 @@ declare namespace Global {
} }
type SearchParams = Pagination & { search?: string }; type SearchParams = Pagination & { search?: string };
type MessageType = 'transition' | 'warning' | 'danger' | 'success' | 'info';
} }
interface Window { interface Window {
+4 -1
View File
@@ -126,5 +126,8 @@ export default {
'models.form.restart.onerror': 'Auto-Restart On Error', 'models.form.restart.onerror': 'Auto-Restart On Error',
'models.form.restart.onerror.tips': 'models.form.restart.onerror.tips':
'When an error occurs, it will automatically attempt to restart.', 'When an error occurs, it will automatically attempt to restart.',
'models.form.check.params': 'Checking configuration...' 'models.form.check.params': 'Checking configuration...',
'models.form.check.passed': 'Check Compatibility Passed',
'models.form.check.claims':
'The model requires approximately {vram} VRAM and {ram} RAM.'
}; };
+7 -2
View File
@@ -123,7 +123,10 @@ export default {
'models.form.restart.onerror': 'Auto-Restart On Error', 'models.form.restart.onerror': 'Auto-Restart On Error',
'models.form.restart.onerror.tips': 'models.form.restart.onerror.tips':
'When an error occurs, it will automatically attempt to restart.', 'When an error occurs, it will automatically attempt to restart.',
'models.form.check.params': 'Checking configuration...' 'models.form.check.params': 'Checking configuration...',
'models.form.check.passed': 'Check Compatibility Passed',
'models.form.check.claims':
'The model requires approximately {vram} VRAM and {ram} RAM.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -136,5 +139,7 @@ export default {
// 7. 'models.form.restart.onerror.tips', // 7. 'models.form.restart.onerror.tips',
// 8. 'models.form.check.params', // 8. 'models.form.check.params',
// 9. 'models.form.partialoffload.tips', // 9. 'models.form.partialoffload.tips',
// 10. 'models.form.distribution.tips // 10. 'models.form.distribution.tips,
// 11. 'models.form.check.passed',
// 12. 'models.form.check.claims',
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+7 -2
View File
@@ -126,10 +126,15 @@ export default {
'models.form.restart.onerror': 'Автоперезапуск при ошибке', 'models.form.restart.onerror': 'Автоперезапуск при ошибке',
'models.form.restart.onerror.tips': 'models.form.restart.onerror.tips':
'При возникновении ошибки система автоматически попытается перезапуститься.', 'При возникновении ошибки система автоматически попытается перезапуститься.',
'models.form.check.params': 'Проверка конфигурации...' 'models.form.check.params': 'Проверка конфигурации...',
'models.form.check.passed': 'Check Compatibility Passed',
'models.form.check.claims':
'The model requires approximately {vram} VRAM and {ram} RAM.'
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'models.form.partialoffload.tips', // 1. 'models.form.partialoffload.tips',
// 2. 'models.form.distribution.tips // 2. 'models.form.distribution.tips,
// 3. 'models.form.check.passed',
// 4. 'models.form.check.claims',
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+1 -1
View File
@@ -75,5 +75,5 @@ export default {
}; };
// ========== To-Do: Translate Keys (Remove After Translation) ========== // ========== To-Do: Translate Keys (Remove After Translation) ==========
// 1. 'resources.filter.path' // 1. 'resources.filter.path',
// ========== End of To-Do List ========== // ========== End of To-Do List ==========
+3 -1
View File
@@ -120,5 +120,7 @@ export default {
'models.form.incompatible': '检测到不兼容', 'models.form.incompatible': '检测到不兼容',
'models.form.restart.onerror': '错误时重启', 'models.form.restart.onerror': '错误时重启',
'models.form.restart.onerror.tips': '当发生错误时,将自动尝试恢复', 'models.form.restart.onerror.tips': '当发生错误时,将自动尝试恢复',
'models.form.check.params': '正在校验配置...' 'models.form.check.params': '正在校验配置...',
'models.form.check.passed': '兼容性检查通过',
'models.form.check.claims': '该模型大约需要 {vram} 显存和 {ram} 内存.'
}; };
+1 -1
View File
@@ -237,7 +237,7 @@ const Catalog: React.FC = () => {
allowClear allowClear
showSearch={false} showSearch={false}
placeholder={intl.formatMessage({ id: 'models.filter.category' })} placeholder={intl.formatMessage({ id: 'models.filter.category' })}
style={{ width: 230 }} style={{ width: 180 }}
size="large" size="large"
maxTagCount={1} maxTagCount={1}
onChange={handleCategoryChange} onChange={handleCategoryChange}
@@ -162,14 +162,18 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
const handleSelectorOnBlur = () => { const handleSelectorOnBlur = () => {
const workerSelector = form.getFieldValue('worker_selector'); const workerSelector = form.getFieldValue('worker_selector');
onValuesChange?.({}, form.getFieldsValue()); // check if all keys have values
const hasEmptyValue = _.some(_.keys(workerSelector), (k: string) => {
return !workerSelector[k];
});
if (!hasEmptyValue) {
onValuesChange?.({}, form.getFieldsValue());
}
}; };
const handleBackendVersionOnBlur = () => { const handleBackendVersionOnBlur = () => {
const backendVersion = form.getFieldValue('backend_version'); const backendVersion = form.getFieldValue('backend_version');
if (backendVersion) { onValuesChange?.({}, form.getFieldsValue());
onValuesChange?.({}, form.getFieldsValue());
}
}; };
const collapseItems = useMemo(() => { const collapseItems = useMemo(() => {
@@ -1,5 +1,6 @@
import AlertBlockInfo from '@/components/alert-info/block'; import AlertBlockInfo from '@/components/alert-info/block';
import { import {
CheckCircleFilled,
CloseOutlined, CloseOutlined,
LoadingOutlined, LoadingOutlined,
WarningFilled WarningFilled
@@ -13,7 +14,7 @@ interface CompatibilityAlertProps {
show: boolean; show: boolean;
title?: string; title?: string;
isHtml?: boolean; isHtml?: boolean;
type?: 'danger' | 'warning' | 'transition'; type?: Global.MessageType;
message: string | string[]; message: string | string[];
}; };
contentStyle?: React.CSSProperties; contentStyle?: React.CSSProperties;
@@ -28,7 +29,7 @@ const DivWrapper = styled.div`
const CloseWrapper = styled.div` const CloseWrapper = styled.div`
position: absolute; position: absolute;
top: 6px; top: 10px;
right: 18px; right: 18px;
cursor: pointer; cursor: pointer;
background-color: var(--ant-color-warning-bg); background-color: var(--ant-color-warning-bg);
@@ -43,7 +44,7 @@ const MessageWrapper = styled.div`
const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => { const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
const { warningStatus, contentStyle, showClose, onClose } = props; const { warningStatus, contentStyle, showClose, onClose } = props;
const { title, show, message, isHtml, type } = warningStatus; const { title, show, message, isHtml, type = 'warning' } = warningStatus;
const renderMessage = useMemo(() => { const renderMessage = useMemo(() => {
if (!message || !show) { if (!message || !show) {
@@ -73,6 +74,16 @@ const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
return ''; return '';
}, [message, show]); }, [message, show]);
const renderIcon = useMemo(() => {
if (type === 'transition') {
return <LoadingOutlined />;
}
if (type === 'success') {
return <CheckCircleFilled />;
}
return <WarningFilled />;
}, [type]);
return ( return (
show && ( show && (
<DivWrapper> <DivWrapper>
@@ -82,9 +93,9 @@ const CompatibilityAlert: React.FC<CompatibilityAlertProps> = (props) => {
title={title} title={title}
contentStyle={contentStyle} contentStyle={contentStyle}
type={type || 'warning'} type={type || 'warning'}
icon={type === 'transition' ? <LoadingOutlined /> : <WarningFilled />} icon={renderIcon}
></AlertBlockInfo> ></AlertBlockInfo>
{showClose && type !== 'transition' && ( {showClose && !['transition', 'success'].includes(type) && (
<CloseWrapper onClick={onClose}> <CloseWrapper onClick={onClose}>
<CloseOutlined /> <CloseOutlined />
</CloseWrapper> </CloseWrapper>
@@ -79,9 +79,8 @@ const AddModal: React.FC<AddModalProps> = (props) => {
width = 600 width = 600
} = props || {}; } = props || {};
const { const {
handleShowCompatibleAlert,
setWarningStatus, setWarningStatus,
handleEvaluate, handleDoEvalute,
generateGPUIds, generateGPUIds,
cancelEvaluate, cancelEvaluate,
submitAnyway, submitAnyway,
@@ -228,17 +227,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
}; };
const handleCheckCompatibility = async (formData: FormData) => { const handleCheckCompatibility = async (formData: FormData) => {
const evalutionData = await handleEvaluate(formData); handleDoEvalute(formData);
if (evalutionData?.compatible) {
setWarningStatus({
show: false,
message: ''
});
} else {
handleShowCompatibleAlert?.(evalutionData);
}
return evalutionData;
}; };
const handleCheckFormData = () => { const handleCheckFormData = () => {
@@ -551,9 +540,12 @@ const AddModal: React.FC<AddModalProps> = (props) => {
<ModalFooter <ModalFooter
onCancel={handleCancel} onCancel={handleCancel}
onOk={handleSumit} onOk={handleSumit}
showOkBtn={!warningStatus.show} showOkBtn={
!warningStatus.show || warningStatus.type === 'success'
}
extra={ extra={
warningStatus.show && ( warningStatus.show &&
warningStatus.type !== 'success' && (
<Button <Button
type="primary" type="primary"
onClick={handleSubmitAnyway} onClick={handleSubmitAnyway}
+11 -2
View File
@@ -78,6 +78,7 @@ const AddModal: FC<AddModalProps> = (props) => {
const { const {
handleShowCompatibleAlert, handleShowCompatibleAlert,
setWarningStatus, setWarningStatus,
handleBackendChangeBefore,
handleOnValuesChange, handleOnValuesChange,
checkTokenRef, checkTokenRef,
warningStatus, warningStatus,
@@ -144,7 +145,12 @@ const AddModal: FC<AddModalProps> = (props) => {
} else { } else {
setIsGGUF(false); setIsGGUF(false);
} }
const data = form.current.form.getFieldsValue?.(); const data = form.current.form.getFieldsValue?.();
const res = handleBackendChangeBefore(data);
if (res.show) {
return;
}
if (data.local_path || props.source !== modelSourceMap.local_path_value) { if (data.local_path || props.source !== modelSourceMap.local_path_value) {
handleOnValuesChange?.({ handleOnValuesChange?.({
changedValues: {}, changedValues: {},
@@ -303,9 +309,12 @@ const AddModal: FC<AddModalProps> = (props) => {
<ModalFooter <ModalFooter
onCancel={handleCancel} onCancel={handleCancel}
onOk={handleSumit} onOk={handleSumit}
showOkBtn={!warningStatus.show} showOkBtn={
!warningStatus.show || warningStatus.type === 'success'
}
extra={ extra={
warningStatus.show && ( warningStatus.show &&
warningStatus.type !== 'success' && (
<Button <Button
type="primary" type="primary"
onClick={handleSubmitAnyway} onClick={handleSubmitAnyway}
@@ -83,6 +83,7 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
}); });
const [sortType, setSortType] = useState<string>('size'); const [sortType, setSortType] = useState<string>('size');
const [current, setCurrent] = useState<string>(''); const [current, setCurrent] = useState<string>('');
const currentPathRef = useRef<string>('');
const modelFilesSortOptions = useRef<any[]>([ const modelFilesSortOptions = useRef<any[]>([
{ {
label: intl.formatMessage({ id: 'models.sort.size' }), label: intl.formatMessage({ id: 'models.sort.size' }),
@@ -100,6 +101,7 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
const handleSelectModelFile = (item: any) => { const handleSelectModelFile = (item: any) => {
props.onSelectFile?.(item); props.onSelectFile?.(item);
setCurrent(item.path); setCurrent(item.path);
currentPathRef.current = item.path;
}; };
const parseFilename = (filename: string) => { const parseFilename = (filename: string) => {
@@ -274,7 +276,13 @@ const HFModelFile: React.FC<HFModelFileProps> = forwardRef((props, ref) => {
evaluateResult: evaluationList[index] evaluateResult: evaluationList[index]
}; };
}); });
handleSelectModelFile(resultList[0]); const currentItem = _.find(
resultList,
(item: any) => item.path === currentPathRef.current
);
if (currentItem) {
handleSelectModelFile(currentItem);
}
setDataSource({ fileList: resultList, loading: false }); setDataSource({ fileList: resultList, loading: false });
setIsEvaluating(false); setIsEvaluating(false);
} catch (error) { } catch (error) {
@@ -18,6 +18,12 @@ const CompatibleTag = styled(Tag)`
background: transparent !important; background: transparent !important;
`; `;
const ClaimTag = styled(Tag)`
margin: 0;
opacity: 0.7;
border-radius: var(--border-radius-base);
`;
const IncompatibleInfo = styled.div` const IncompatibleInfo = styled.div`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -61,6 +61,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
]; ];
const [isEvaluating, setIsEvaluating] = useState<boolean>(false); const [isEvaluating, setIsEvaluating] = useState<boolean>(false);
const [current, setCurrent] = useState<string>(''); const [current, setCurrent] = useState<string>('');
const currentRef = useRef<string>('');
const cacheRepoOptions = useRef<any[]>([]); const cacheRepoOptions = useRef<any[]>([]);
const axiosTokenRef = useRef<any>(null); const axiosTokenRef = useRef<any>(null);
const checkTokenRef = useRef<any>(null); const checkTokenRef = useRef<any>(null);
@@ -100,6 +101,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
const handleOnSelectModel = (item: any) => { const handleOnSelectModel = (item: any) => {
onSelectModel(item); onSelectModel(item);
setCurrent(item.id); setCurrent(item.id);
currentRef.current = item.id;
}; };
// huggeface // huggeface
@@ -222,7 +224,12 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
repoOptions: resultList repoOptions: resultList
}; };
}); });
handleOnSelectModel(resultList[0]); const currentItem = resultList.find(
(item) => item.id === currentRef.current
);
if (currentItem) {
handleOnSelectModel(currentItem);
}
} catch (error) { } catch (error) {
setIsEvaluating(false); setIsEvaluating(false);
} }
@@ -264,9 +271,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
handleOnSelectModel(list[0]); handleOnSelectModel(list[0]);
setLoadingModel?.(false); setLoadingModel?.(false);
timer.current = setTimeout(() => { handleEvaluate(list);
handleEvaluate(list);
}, 200);
} catch (error: any) { } catch (error: any) {
setDataSource({ setDataSource({
repoOptions: [], repoOptions: [],
+1 -1
View File
@@ -740,7 +740,7 @@ const Models: React.FC<ModelsProps> = ({
placeholder={intl.formatMessage({ placeholder={intl.formatMessage({
id: 'models.filter.category' id: 'models.filter.category'
})} })}
style={{ width: 230 }} style={{ width: 180 }}
size="large" size="large"
maxTagCount={1} maxTagCount={1}
onChange={handleCategoryChange} onChange={handleCategoryChange}
+10 -3
View File
@@ -58,7 +58,7 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
const { const {
setWarningStatus, setWarningStatus,
generateGPUIds, generateGPUIds,
handleOnValuesChange, handleBackendChangeBefore,
checkTokenRef, checkTokenRef,
warningStatus warningStatus
} = useCheckCompatibility(); } = useCheckCompatibility();
@@ -68,6 +68,8 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
const localPathCache = useRef<string>(''); const localPathCache = useRef<string>('');
const submitAnyway = useRef<boolean>(false); const submitAnyway = useRef<boolean>(false);
const handleOnValuesChange = (data: any) => {};
// voxbox is not support multi gpu // voxbox is not support multi gpu
const handleSetGPUIds = (backend: string) => { const handleSetGPUIds = (backend: string) => {
const gpuids = form.getFieldValue(['gpu_selector', 'gpu_ids']) || []; const gpuids = form.getFieldValue(['gpu_selector', 'gpu_ids']) || [];
@@ -91,6 +93,10 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
handleSetGPUIds(backend); handleSetGPUIds(backend);
const data = form.getFieldsValue?.(); const data = form.getFieldsValue?.();
const res = handleBackendChangeBefore(data);
if (res.show) {
return;
}
if (data.local_path || data.source !== modelSourceMap.local_path_value) { if (data.local_path || data.source !== modelSourceMap.local_path_value) {
handleOnValuesChange?.({ handleOnValuesChange?.({
changedValues: {}, changedValues: {},
@@ -390,9 +396,10 @@ const UpdateModal: React.FC<AddModalProps> = (props) => {
<ModalFooter <ModalFooter
onCancel={onCancel} onCancel={onCancel}
onOk={handleSumit} onOk={handleSumit}
showOkBtn={!warningStatus.show} showOkBtn={!warningStatus.show || warningStatus.type === 'success'}
extra={ extra={
warningStatus.show && ( warningStatus.show &&
warningStatus.type !== 'success' && (
<Button <Button
type="primary" type="primary"
onClick={handleSubmitAnyway} onClick={handleSubmitAnyway}
+5 -1
View File
@@ -448,6 +448,7 @@ export const modelLabels = [
{ label: 'Embedding', value: 'embedding_only' } { label: 'Embedding', value: 'embedding_only' }
]; ];
// do not trigger form check compatibility
export const excludeFields = [ export const excludeFields = [
'repo_id', 'repo_id',
'file_name', 'file_name',
@@ -464,5 +465,8 @@ export const excludeFields = [
'backend_parameters', 'backend_parameters',
'local_path', 'local_path',
'backend_version', 'backend_version',
'ollama_library_model_name' 'ollama_library_model_name',
'scheduleType',
'placement_strategy',
'backend'
]; ];
+4
View File
@@ -218,4 +218,8 @@ export interface EvaluateResult {
compatibility_messages: string[]; compatibility_messages: string[];
scheduling_messages: string[]; scheduling_messages: string[];
default_spec: Record<string, any>; default_spec: Record<string, any>;
resource_claim?: {
ram: number;
vram: number;
};
} }
+74 -23
View File
@@ -2,6 +2,7 @@ import { createAxiosToken } from '@/hooks/use-chunk-request';
import { queryModelFilesList, queryWorkersList } from '@/pages/resources/apis'; import { queryModelFilesList, queryWorkersList } from '@/pages/resources/apis';
import { WorkerStatusMap } from '@/pages/resources/config'; import { WorkerStatusMap } from '@/pages/resources/config';
import { ListItem as WorkerListItem } from '@/pages/resources/config/types'; import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
import { convertFileSize } from '@/utils';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import _ from 'lodash'; import _ from 'lodash';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
@@ -19,6 +20,15 @@ import {
ListItem ListItem
} from '../config/types'; } from '../config/types';
type MessageStatus = {
show: boolean;
title?: string;
type?: Global.MessageType;
isHtml?: boolean;
message: string | string[];
evaluateResult?: EvaluateResult;
};
export const useGenerateFormEditInitialValues = () => { export const useGenerateFormEditInitialValues = () => {
const gpuDeviceList = useRef<any[]>([]); const gpuDeviceList = useRef<any[]>([]);
const workerList = useRef<any[]>([]); const workerList = useRef<any[]>([]);
@@ -220,12 +230,7 @@ export const useCheckCompatibility = () => {
const submitAnyway = useRef<boolean>(false); const submitAnyway = useRef<boolean>(false);
const requestIdRef = useRef(0); const requestIdRef = useRef(0);
const updateStatusTimer = useRef<any>(null); const updateStatusTimer = useRef<any>(null);
const [warningStatus, setWarningStatus] = useState<{ const [warningStatus, setWarningStatus] = useState<MessageStatus>({
show: boolean;
title?: string;
type?: 'transition' | 'warning' | 'danger';
message: string | string[];
}>({
show: false, show: false,
title: '', title: '',
message: [] message: []
@@ -269,7 +274,9 @@ export const useCheckCompatibility = () => {
} }
}; };
const handleCheckCompatibility = (evaluateResult: EvaluateResult | null) => { const handleCheckCompatibility = (
evaluateResult: EvaluateResult | null
): MessageStatus => {
if (!evaluateResult) { if (!evaluateResult) {
return { return {
show: false, show: false,
@@ -279,11 +286,13 @@ export const useCheckCompatibility = () => {
const { const {
compatible, compatible,
compatibility_messages = [], compatibility_messages = [],
scheduling_messages = [] scheduling_messages = [],
resource_claim
} = evaluateResult || {}; } = evaluateResult || {};
return { const hasClaim = !!resource_claim?.ram || !!resource_claim?.vram;
show: !compatible,
let msgData = {
title: title:
scheduling_messages?.length > 0 scheduling_messages?.length > 0
? compatibility_messages?.join(' ') ? compatibility_messages?.join(' ')
@@ -293,6 +302,24 @@ export const useCheckCompatibility = () => {
? scheduling_messages ? scheduling_messages
: compatibility_messages?.join(' ') : compatibility_messages?.join(' ')
}; };
if (hasClaim) {
const ram = convertFileSize(resource_claim.ram, 1);
const vram = convertFileSize(resource_claim.vram, 1);
msgData = {
title: intl.formatMessage({ id: 'models.form.check.passed' }),
message: intl.formatMessage(
{ id: 'models.form.check.claims' },
{ ram, vram }
)
};
}
return {
show: !compatible || hasClaim,
type: !compatible ? 'warning' : 'success',
isHtml: hasClaim,
...msgData
};
}; };
const handleShowCompatibleAlert = (evaluateResult: EvaluateResult | null) => { const handleShowCompatibleAlert = (evaluateResult: EvaluateResult | null) => {
@@ -387,14 +414,22 @@ export const useCheckCompatibility = () => {
}; };
}; };
const handleDoEvalute = async (formData: FormData) => {
const currentRequestId = updateRequestId();
const evalutionData = await handleEvaluate(formData);
if (currentRequestId === requestIdRef.current) {
handleShowCompatibleAlert?.(evalutionData);
}
return evalutionData;
};
const handleOnValuesChange = async (params: { const handleOnValuesChange = async (params: {
changedValues: any; changedValues: any;
allValues: any; allValues: any;
source: string; source: string;
}) => { }) => {
const { changedValues, allValues, source } = params; const { allValues, source } = params;
console.log('params+++++++', params);
if ( if (
_.isEqual(cacheFormValuesRef.current, allValues) || _.isEqual(cacheFormValuesRef.current, allValues) ||
(allValues.source === modelSourceMap.local_path_value && (allValues.source === modelSourceMap.local_path_value &&
@@ -405,16 +440,30 @@ export const useCheckCompatibility = () => {
cacheFormValuesRef.current = allValues; cacheFormValuesRef.current = allValues;
const data = getSourceRepoConfigValue(source, allValues); const data = getSourceRepoConfigValue(source, allValues);
const gpuSelector = generateGPUIds(data.values); const gpuSelector = generateGPUIds(data.values);
await handleDoEvalute({
const currentRequestId = updateRequestId();
const evalutionData = await handleEvaluate({
...data.values, ...data.values,
...gpuSelector ...gpuSelector
}); });
};
if (currentRequestId === requestIdRef.current) { // trigger from local_path change or backend change
handleShowCompatibleAlert?.(evalutionData); const handleBackendChangeBefore = (params: {
local_path: string;
backend: string;
source: string;
}) => {
const { local_path, backend, source } = params;
const res = handleUpdateWarning?.({
backend,
localPath: local_path,
source: source
});
if (res.show) {
setWarningStatus?.(res);
} }
return res;
}; };
const debounceHandleValuesChange = _.debounce(handleOnValuesChange, 500); const debounceHandleValuesChange = _.debounce(handleOnValuesChange, 500);
@@ -434,13 +483,15 @@ export const useCheckCompatibility = () => {
return { return {
handleShowCompatibleAlert, handleShowCompatibleAlert,
handleUpdateWarning, handleUpdateWarning,
handleOnValuesChange: debounceHandleValuesChange, handleDoEvalute,
warningStatus,
checkTokenRef,
submitAnyway,
generateGPUIds, generateGPUIds,
handleEvaluate, handleEvaluate,
setWarningStatus, setWarningStatus,
cancelEvaluate cancelEvaluate,
handleBackendChangeBefore,
handleOnValuesChange: debounceHandleValuesChange,
warningStatus,
checkTokenRef,
submitAnyway
}; };
}; };
+12 -3
View File
@@ -68,6 +68,8 @@ import {
ListItem as WorkerListItem ListItem as WorkerListItem
} from '../config/types'; } from '../config/types';
const { Paragraph } = Typography;
const filterPattern = /^(.*?)(?:-\d+-of-\d+)?(\.gguf)?$/; const filterPattern = /^(.*?)(?:-\d+-of-\d+)?(\.gguf)?$/;
const PathWrapper = styled.div` const PathWrapper = styled.div`
@@ -115,11 +117,18 @@ const FilesTag = styled(Tag)`
border-radius: var(--border-radius-base); border-radius: var(--border-radius-base);
`; `;
const TypographyPara = styled(Paragraph)`
background: transparent;
color: inherit;
margin-bottom: 0;
font-size: 13px;
`;
const TooltipTitle: React.FC<{ path: string }> = ({ path }) => { const TooltipTitle: React.FC<{ path: string }> = ({ path }) => {
const intl = useIntl(); const intl = useIntl();
return ( return (
<Typography.Paragraph <TypographyPara
style={{ background: 'transparent', color: 'inherit' }} style={{ margin: 0 }}
copyable={{ copyable={{
icon: [ icon: [
<CopyOutlined key="copy-icon" />, <CopyOutlined key="copy-icon" />,
@@ -133,7 +142,7 @@ const TooltipTitle: React.FC<{ path: string }> = ({ path }) => {
}} }}
> >
{path} {path}
</Typography.Paragraph> </TypographyPara>
); );
}; };