improve details
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import React, {FC, MouseEventHandler, ReactElement} from 'react';
|
||||
import commonStore, {ModelStatus} from '../stores/commonStore';
|
||||
import {AddToDownloadList, DepCheck, FileExists, InstallPyDep, StartServer} from '../../wailsjs/go/backend_golang/App';
|
||||
import {Button} from '@fluentui/react-components';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import {exit, readRoot, switchModel, updateConfig} from '../apis';
|
||||
import {toast} from 'react-toastify';
|
||||
import React, { FC, MouseEventHandler, ReactElement } from 'react';
|
||||
import commonStore, { ModelStatus } from '../stores/commonStore';
|
||||
import { AddToDownloadList, DepCheck, FileExists, InstallPyDep, StartServer } from '../../wailsjs/go/backend_golang/App';
|
||||
import { Button } from '@fluentui/react-components';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { exit, readRoot, switchModel, updateConfig } from '../apis';
|
||||
import { toast } from 'react-toastify';
|
||||
import manifest from '../../../manifest.json';
|
||||
import {getStrategy, saveCache, toastWithButton} from '../utils';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {ToolTipButton} from './ToolTipButton';
|
||||
import {Play16Regular, Stop16Regular} from '@fluentui/react-icons';
|
||||
import {useNavigate} from 'react-router';
|
||||
import { getStrategy, saveCache, toastWithButton } from '../utils';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ToolTipButton } from './ToolTipButton';
|
||||
import { Play16Regular, Stop16Regular } from '@fluentui/react-icons';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { WindowShow } from '../../wailsjs/runtime/runtime';
|
||||
|
||||
const mainButtonText = {
|
||||
[ModelStatus.Offline]: 'Run',
|
||||
@@ -20,141 +21,157 @@ const mainButtonText = {
|
||||
};
|
||||
|
||||
const iconModeButtonIcon: { [modelStatus: number]: ReactElement } = {
|
||||
[ModelStatus.Offline]: <Play16Regular/>,
|
||||
[ModelStatus.Starting]: <Stop16Regular/>,
|
||||
[ModelStatus.Loading]: <Stop16Regular/>,
|
||||
[ModelStatus.Working]: <Stop16Regular/>
|
||||
[ModelStatus.Offline]: <Play16Regular />,
|
||||
[ModelStatus.Starting]: <Stop16Regular />,
|
||||
[ModelStatus.Loading]: <Stop16Regular />,
|
||||
[ModelStatus.Working]: <Stop16Regular />
|
||||
};
|
||||
|
||||
export const RunButton: FC<{ onClickRun?: MouseEventHandler, iconMode?: boolean }>
|
||||
= observer(({
|
||||
onClickRun,
|
||||
iconMode
|
||||
}) => {
|
||||
const {t} = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
onClickRun,
|
||||
iconMode
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onClickMainButton = async () => {
|
||||
const modelConfig = commonStore.getCurrentModelConfig();
|
||||
const modelName = modelConfig.modelParameters.modelName;
|
||||
const modelPath = `./${manifest.localModelDir}/${modelName}`;
|
||||
const onClickMainButton = async () => {
|
||||
if (commonStore.modelStatus === ModelStatus.Offline) {
|
||||
commonStore.setModelStatus(ModelStatus.Starting);
|
||||
|
||||
if (!commonStore.depComplete) {
|
||||
let depErrorMsg = '';
|
||||
await DepCheck().catch((e) => {
|
||||
depErrorMsg = e.message || e;
|
||||
if (depErrorMsg === 'python zip not found') {
|
||||
toastWithButton(t('Python target not found, would you like to download it?'), t('Download'), () => {
|
||||
toastWithButton(`${t('Downloading')} Python`, t('Check'), () => {
|
||||
navigate({pathname: '/downloads'});
|
||||
}, {autoClose: 3000});
|
||||
AddToDownloadList('python-3.10.11-embed-amd64.zip', 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip');
|
||||
});
|
||||
} else if (depErrorMsg.includes('DepCheck Error')) {
|
||||
toastWithButton(t('Python dependencies are incomplete, would you like to install them?'), t('Install'), () => {
|
||||
InstallPyDep(commonStore.settings.cnMirror);
|
||||
});
|
||||
const modelConfig = commonStore.getCurrentModelConfig();
|
||||
let modelName = ''
|
||||
let modelPath = ''
|
||||
if (modelConfig && modelConfig.modelParameters) {
|
||||
modelName = modelConfig.modelParameters.modelName;
|
||||
modelPath = `./${manifest.localModelDir}/${modelName}`;
|
||||
} else {
|
||||
toast(depErrorMsg, {type: 'error'});
|
||||
toast(t('Model Config Exception'), { type: 'error' });
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (depErrorMsg) {
|
||||
return;
|
||||
}
|
||||
commonStore.setDepComplete(true);
|
||||
saveCache();
|
||||
}
|
||||
|
||||
if (!await FileExists(modelPath)) {
|
||||
toastWithButton(t('Model file not found'), t('Download'), () => {
|
||||
const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl;
|
||||
if (downloadUrl) {
|
||||
toastWithButton(`${t('Downloading')} ${modelName}`, t('Check'), () => {
|
||||
navigate({pathname: '/downloads'});
|
||||
},
|
||||
{autoClose: 3000});
|
||||
AddToDownloadList(modelPath, downloadUrl);
|
||||
} else {
|
||||
toast(t('Can not find download url'), {type: 'error'});
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const port = modelConfig.apiParameters.apiPort;
|
||||
|
||||
if (commonStore.modelStatus === ModelStatus.Offline) {
|
||||
commonStore.setModelStatus(ModelStatus.Starting);
|
||||
await exit(1000).catch(() => {
|
||||
});
|
||||
StartServer(port);
|
||||
|
||||
let timeoutCount = 6;
|
||||
let loading = false;
|
||||
const intervalId = setInterval(() => {
|
||||
readRoot()
|
||||
.then(r => {
|
||||
if (r.ok && !loading) {
|
||||
clearInterval(intervalId);
|
||||
commonStore.setModelStatus(ModelStatus.Loading);
|
||||
loading = true;
|
||||
toast(t('Loading Model'), {type: 'info'});
|
||||
updateConfig({
|
||||
max_tokens: modelConfig.apiParameters.maxResponseToken,
|
||||
temperature: modelConfig.apiParameters.temperature,
|
||||
top_p: modelConfig.apiParameters.topP,
|
||||
presence_penalty: modelConfig.apiParameters.presencePenalty,
|
||||
frequency_penalty: modelConfig.apiParameters.frequencyPenalty
|
||||
if (!commonStore.depComplete) {
|
||||
let depErrorMsg = '';
|
||||
await DepCheck().catch((e) => {
|
||||
depErrorMsg = e.message || e;
|
||||
WindowShow();
|
||||
if (depErrorMsg === 'python zip not found') {
|
||||
toastWithButton(t('Python target not found, would you like to download it?'), t('Download'), () => {
|
||||
toastWithButton(`${t('Downloading')} Python`, t('Check'), () => {
|
||||
navigate({ pathname: '/downloads' });
|
||||
}, { autoClose: 3000 });
|
||||
AddToDownloadList('python-3.10.11-embed-amd64.zip', 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip');
|
||||
});
|
||||
switchModel({
|
||||
model: `${manifest.localModelDir}/${modelConfig.modelParameters.modelName}`,
|
||||
strategy: getStrategy(modelConfig)
|
||||
}).then((r) => {
|
||||
if (r.ok) {
|
||||
commonStore.setModelStatus(ModelStatus.Working);
|
||||
toast(t('Startup Completed'), {type: 'success'});
|
||||
} else if (r.status === 304) {
|
||||
toast(t('Loading Model'), {type: 'info'});
|
||||
} else {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
toast(t('Failed to switch model'), {type: 'error'});
|
||||
}
|
||||
}).catch(() => {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
toast(t('Failed to switch model'), {type: 'error'});
|
||||
} else if (depErrorMsg.includes('DepCheck Error')) {
|
||||
toastWithButton(t('Python dependencies are incomplete, would you like to install them?'), t('Install'), () => {
|
||||
InstallPyDep(commonStore.settings.cnMirror);
|
||||
setTimeout(WindowShow, 1000)
|
||||
});
|
||||
} else {
|
||||
toast(depErrorMsg, { type: 'error' });
|
||||
}
|
||||
}).catch(() => {
|
||||
if (timeoutCount <= 0) {
|
||||
clearInterval(intervalId);
|
||||
});
|
||||
if (depErrorMsg) {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
return;
|
||||
}
|
||||
commonStore.setDepComplete(true);
|
||||
saveCache();
|
||||
}
|
||||
|
||||
if (!await FileExists(modelPath)) {
|
||||
toastWithButton(t('Model file not found'), t('Download'), () => {
|
||||
const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl;
|
||||
if (downloadUrl) {
|
||||
toastWithButton(`${t('Downloading')} ${modelName}`, t('Check'), () => {
|
||||
navigate({ pathname: '/downloads' });
|
||||
},
|
||||
{ autoClose: 3000 });
|
||||
AddToDownloadList(modelPath, downloadUrl);
|
||||
} else {
|
||||
toast(t('Can not find download url'), { type: 'error' });
|
||||
}
|
||||
});
|
||||
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
return;
|
||||
}
|
||||
|
||||
const port = modelConfig.apiParameters.apiPort;
|
||||
|
||||
await exit(1000).catch(() => {
|
||||
});
|
||||
StartServer(port);
|
||||
setTimeout(WindowShow, 1000)
|
||||
|
||||
timeoutCount--;
|
||||
}, 1000);
|
||||
} else {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
exit();
|
||||
}
|
||||
};
|
||||
let timeoutCount = 6;
|
||||
let loading = false;
|
||||
const intervalId = setInterval(() => {
|
||||
readRoot()
|
||||
.then(r => {
|
||||
if (r.ok && !loading) {
|
||||
clearInterval(intervalId);
|
||||
commonStore.setModelStatus(ModelStatus.Loading);
|
||||
loading = true;
|
||||
toast(t('Loading Model'), { type: 'info' });
|
||||
updateConfig({
|
||||
max_tokens: modelConfig.apiParameters.maxResponseToken,
|
||||
temperature: modelConfig.apiParameters.temperature,
|
||||
top_p: modelConfig.apiParameters.topP,
|
||||
presence_penalty: modelConfig.apiParameters.presencePenalty,
|
||||
frequency_penalty: modelConfig.apiParameters.frequencyPenalty
|
||||
});
|
||||
switchModel({
|
||||
model: `${manifest.localModelDir}/${modelConfig.modelParameters.modelName}`,
|
||||
strategy: getStrategy(modelConfig)
|
||||
}).then((r) => {
|
||||
if (r.ok) {
|
||||
commonStore.setModelStatus(ModelStatus.Working);
|
||||
toastWithButton(t('Startup Completed'), t('Chat'), () => {
|
||||
navigate({ pathname: '/chat' });
|
||||
}, { type: 'success', autoClose: 3000 });
|
||||
} else if (r.status === 304) {
|
||||
toast(t('Loading Model'), { type: 'info' });
|
||||
} else {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
toast(t('Failed to switch model'), { type: 'error' });
|
||||
}
|
||||
}).catch(() => {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
toast(t('Failed to switch model'), { type: 'error' });
|
||||
});
|
||||
}
|
||||
}).catch(() => {
|
||||
if (timeoutCount <= 0) {
|
||||
clearInterval(intervalId);
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
}
|
||||
});
|
||||
|
||||
const onClick = async (e: any) => {
|
||||
if (commonStore.modelStatus === ModelStatus.Offline)
|
||||
await onClickRun?.(e);
|
||||
await onClickMainButton();
|
||||
};
|
||||
timeoutCount--;
|
||||
}, 1000);
|
||||
} else {
|
||||
commonStore.setModelStatus(ModelStatus.Offline);
|
||||
exit();
|
||||
}
|
||||
};
|
||||
|
||||
return (iconMode ?
|
||||
const onClick = async (e: any) => {
|
||||
if (commonStore.modelStatus === ModelStatus.Offline)
|
||||
await onClickRun?.(e);
|
||||
await onClickMainButton();
|
||||
};
|
||||
|
||||
return (iconMode ?
|
||||
<ToolTipButton disabled={commonStore.modelStatus === ModelStatus.Starting}
|
||||
icon={iconModeButtonIcon[commonStore.modelStatus]}
|
||||
desc={t(mainButtonText[commonStore.modelStatus])}
|
||||
size="small" onClick={onClick}/>
|
||||
icon={iconModeButtonIcon[commonStore.modelStatus]}
|
||||
desc={t(mainButtonText[commonStore.modelStatus])}
|
||||
size="small" onClick={onClick} />
|
||||
:
|
||||
<Button disabled={commonStore.modelStatus === ModelStatus.Starting} appearance="primary" size="large"
|
||||
onClick={onClick}>
|
||||
onClick={onClick}>
|
||||
{t(mainButtonText[commonStore.modelStatus])}
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user