improve message interruption and retry for Chat page

This commit is contained in:
josc146 2023-10-27 12:13:05 +08:00
parent c87de93498
commit d43954cc88

View File

@ -65,7 +65,7 @@ export type ConversationMessage = {
content: string; content: string;
} }
let chatSseController: AbortController | null = null; let chatSseControllers: { [id: string]: AbortController } = {};
const MoreUtilsButton: FC<{ uuid: string, setEditing: (editing: boolean) => void }> = observer(({ const MoreUtilsButton: FC<{ uuid: string, setEditing: (editing: boolean) => void }> = observer(({
uuid, uuid,
@ -174,6 +174,10 @@ const ChatMessageItem: FC<{
messageItem.sender === botName && uuid !== welcomeUuid && messageItem.sender === botName && uuid !== welcomeUuid &&
<ToolTipButton desc={t('Retry')} size="small" appearance="subtle" <ToolTipButton desc={t('Retry')} size="small" appearance="subtle"
icon={<SyncIcon />} onClick={() => { icon={<SyncIcon />} onClick={() => {
if (uuid in chatSseControllers) {
chatSseControllers[uuid].abort();
delete chatSseControllers[uuid];
}
onSubmit(null, uuid, null, uuid, false); onSubmit(null, uuid, null, uuid, false);
}} /> }} />
} }
@ -195,15 +199,7 @@ const ChatPanel: FC = observer(() => {
const currentConfig = commonStore.getCurrentModelConfig(); const currentConfig = commonStore.getCurrentModelConfig();
const apiParams = currentConfig.apiParameters; const apiParams = currentConfig.apiParameters;
const port = apiParams.apiPort; const port = apiParams.apiPort;
const generating: boolean = Object.keys(chatSseControllers).length > 0;
let lastMessageId: string;
let generating: boolean = false;
if (commonStore.conversationOrder.length > 0) {
lastMessageId = commonStore.conversationOrder[commonStore.conversationOrder.length - 1];
const lastMessage = commonStore.conversation[lastMessageId];
if (lastMessage.sender === botName)
generating = !lastMessage.done;
}
useEffect(() => { useEffect(() => {
if (inputRef.current) if (inputRef.current)
@ -314,7 +310,8 @@ const ChatPanel: FC = observer(() => {
commonStore.setConversationOrder(commonStore.conversationOrder); commonStore.setConversationOrder(commonStore.conversationOrder);
setTimeout(scrollToBottom); setTimeout(scrollToBottom);
let answer = ''; let answer = '';
chatSseController = new AbortController(); const chatSseController = new AbortController();
chatSseControllers[answerId] = chatSseController;
fetchEventSource( // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/chat/completions fetchEventSource( // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/chat/completions
commonStore.settings.apiUrl ? commonStore.settings.apiUrl ?
commonStore.settings.apiUrl + '/v1/chat/completions' : commonStore.settings.apiUrl + '/v1/chat/completions' :
@ -368,6 +365,8 @@ const ChatPanel: FC = observer(() => {
} }
}, },
onclose() { onclose() {
if (answerId! in chatSseControllers)
delete chatSseControllers[answerId!];
console.log('Connection closed'); console.log('Connection closed');
}, },
onerror(err) { onerror(err) {
@ -398,8 +397,12 @@ const ChatPanel: FC = observer(() => {
size={mq ? 'large' : 'small'} shape="circular" appearance="subtle" title={t('Clear')} size={mq ? 'large' : 'small'} shape="circular" appearance="subtle" title={t('Clear')}
contentText={t('Are you sure you want to clear the conversation? It cannot be undone.')} contentText={t('Are you sure you want to clear the conversation? It cannot be undone.')}
onConfirm={() => { onConfirm={() => {
if (generating) if (generating) {
chatSseController?.abort(); for (const id in chatSseControllers) {
chatSseControllers[id].abort();
}
chatSseControllers = {};
}
commonStore.setConversation({}); commonStore.setConversation({});
commonStore.setConversationOrder([]); commonStore.setConversationOrder([]);
}} /> }} />
@ -503,13 +506,14 @@ const ChatPanel: FC = observer(() => {
size={mq ? 'large' : 'small'} shape="circular" appearance="subtle" size={mq ? 'large' : 'small'} shape="circular" appearance="subtle"
onClick={(e) => { onClick={(e) => {
if (generating) { if (generating) {
chatSseController?.abort(); for (const id in chatSseControllers) {
if (lastMessageId) { chatSseControllers[id].abort();
commonStore.conversation[lastMessageId].type = MessageType.Error; commonStore.conversation[id].type = MessageType.Error;
commonStore.conversation[lastMessageId].done = true; commonStore.conversation[id].done = true;
commonStore.setConversation(commonStore.conversation);
commonStore.setConversationOrder([...commonStore.conversationOrder]);
} }
chatSseControllers = {};
commonStore.setConversation(commonStore.conversation);
commonStore.setConversationOrder([...commonStore.conversationOrder]);
} else { } else {
handleKeyDownOrClick(e); handleKeyDownOrClick(e);
} }