feat: retry send

This commit is contained in:
archer 2023-09-07 17:06:17 +08:00
parent 6f2d556a87
commit 1b7f87752a
No known key found for this signature in database
GPG Key ID: 569A5660D2379E28
9 changed files with 67 additions and 47 deletions

View File

@ -63,10 +63,8 @@
"online": "Online Chat", "online": "Online Chat",
"share": "Share", "share": "Share",
"test": "Test Chat " "test": "Test Chat "
} },
}, "retry": "Retry"
"commom": {
"Password inconsistency": "Password inconsistency"
}, },
"common": { "common": {
"Add": "Add", "Add": "Add",
@ -80,7 +78,8 @@
"Filed is repeated": "", "Filed is repeated": "",
"Input": "Input", "Input": "Input",
"Output": "Output", "Output": "Output",
"export": "" "export": "",
"Password inconsistency": "Password inconsistency"
}, },
"dataset": { "dataset": {
"Confirm to delete the data": "Confirm to delete the data?", "Confirm to delete the data": "Confirm to delete the data?",

View File

@ -63,10 +63,8 @@
"online": "在线使用", "online": "在线使用",
"share": "外部链接调用", "share": "外部链接调用",
"test": "测试" "test": "测试"
} },
}, "retry": "重新生成"
"commom": {
"Password inconsistency": "两次密码不一致"
}, },
"common": { "common": {
"Add": "添加", "Add": "添加",
@ -80,7 +78,8 @@
"Filed is repeated": "字段重复了", "Filed is repeated": "字段重复了",
"Input": "输入", "Input": "输入",
"Output": "输出", "Output": "输出",
"export": "" "export": "",
"Password inconsistency": "两次密码不一致"
}, },
"dataset": { "dataset": {
"Confirm to delete the data": "确认删除该数据?", "Confirm to delete the data": "确认删除该数据?",

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { Box, ModalBody, useTheme, ModalHeader, Flex } from '@chakra-ui/react'; import { Box, ModalBody, useTheme, Flex } from '@chakra-ui/react';
import type { ChatHistoryItemResType } from '@/types/chat'; import type { ChatHistoryItemResType } from '@/types/chat';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';

View File

@ -293,7 +293,7 @@ const ChatBox = (
* user confirm send prompt * user confirm send prompt
*/ */
const sendPrompt = useCallback( const sendPrompt = useCallback(
async (variables: Record<string, any> = {}, inputVal = '') => { async (variables: Record<string, any> = {}, inputVal = '', history = chatHistory) => {
if (!onStartChat) return; if (!onStartChat) return;
if (isChatting) { if (isChatting) {
toast({ toast({
@ -314,7 +314,7 @@ const ChatBox = (
} }
const newChatList: ChatSiteItemType[] = [ const newChatList: ChatSiteItemType[] = [
...chatHistory, ...history,
{ {
dataId: nanoid(), dataId: nanoid(),
obj: 'Human', obj: 'Human',
@ -407,6 +407,22 @@ const ChatBox = (
] ]
); );
// retry input
const retryInput = useCallback(
async (index: number) => {
if (!onDelMessage) return;
const delHistory = chatHistory.slice(index);
setChatHistory((state) => (index === 0 ? [] : state.slice(0, index)));
await Promise.all(
delHistory.map((item, i) => onDelMessage({ contentId: item.dataId, index: index + i }))
);
sendPrompt(variables, delHistory[0].value, chatHistory.slice(0, index));
},
[chatHistory, onDelMessage, sendPrompt, variables]
);
// output data // output data
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
getChatHistory: () => chatHistory, getChatHistory: () => chatHistory,
@ -470,7 +486,7 @@ const ChatBox = (
); );
const statusBoxData = useMemo(() => { const statusBoxData = useMemo(() => {
const colorMap = { const colorMap = {
loading: '#67c13b', loading: 'myGray.700',
running: '#67c13b', running: '#67c13b',
finish: 'myBlue.600' finish: 'myBlue.600'
}; };
@ -484,6 +500,7 @@ const ChatBox = (
}; };
}, [chatHistory, isChatting, t]); }, [chatHistory, isChatting, t]);
// page change and abort request
useEffect(() => { useEffect(() => {
return () => { return () => {
controller.current?.abort('leave'); controller.current?.abort('leave');
@ -492,16 +509,7 @@ const ChatBox = (
}; };
}, [router.query]); }, [router.query]);
useEffect(() => { // page destroy and abort request
event.on('guideClick', ({ text }: { text: string }) => {
if (!text) return;
handleSubmit((data) => sendPrompt(data, text))();
});
return () => {
event.off('guideClick');
};
}, [handleSubmit, sendPrompt]);
useEffect(() => { useEffect(() => {
const listen = () => { const listen = () => {
cancelBroadcast(); cancelBroadcast();
@ -513,6 +521,18 @@ const ChatBox = (
}; };
}, []); }, []);
// add guide text listener
useEffect(() => {
event.on('guideClick', ({ text }: { text: string }) => {
if (!text) return;
handleSubmit((data) => sendPrompt(data, text))();
});
return () => {
event.off('guideClick');
};
}, [handleSubmit, sendPrompt]);
return ( return (
<Flex flexDirection={'column'} h={'100%'}> <Flex flexDirection={'column'} h={'100%'}>
<Box ref={ChatBoxRef} flex={'1 0 0'} h={0} w={'100%'} overflow={'overlay'} px={[4, 0]} pb={3}> <Box ref={ChatBoxRef} flex={'1 0 0'} h={0} w={'100%'} overflow={'overlay'} px={[4, 0]} pb={3}>
@ -616,7 +636,7 @@ const ChatBox = (
justifyContent={'flex-end'} justifyContent={'flex-end'}
mr={3} mr={3}
> >
<MyTooltip label={'复制'}> <MyTooltip label={t('common.Copy')}>
<MyIcon <MyIcon
{...controlIconStyle} {...controlIconStyle}
name={'copy'} name={'copy'}
@ -624,8 +644,18 @@ const ChatBox = (
onClick={() => onclickCopy(item.value)} onClick={() => onclickCopy(item.value)}
/> />
</MyTooltip> </MyTooltip>
{!!onDelMessage && (
<MyTooltip label={t('chat.retry')}>
<MyIcon
{...controlIconStyle}
name={'retryLight'}
_hover={{ color: 'green.500' }}
onClick={() => retryInput(index)}
/>
</MyTooltip>
)}
{onDelMessage && ( {onDelMessage && (
<MyTooltip label={'删除'}> <MyTooltip label={t('common.Delete')}>
<MyIcon <MyIcon
{...controlIconStyle} {...controlIconStyle}
mr={0} mr={0}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1694067364830"
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5118"
xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
<path
d="M727.950222 274.773333l-55.296-9.329777a38.741333 38.741333 0 0 0-12.856889 76.344888l193.308445 32.597334c1.991111 0.113778 1.991111 0.113778 2.844444 0 2.275556 0.227556 4.266667 0.113778 7.850667-0.284445l0.682667-0.056889a28.216889 28.216889 0 0 0 5.632-0.967111c1.080889 0 1.080889 0 3.185777-0.568889a15.530667 15.530667 0 0 0 4.039111-2.332444l1.137778-0.796444 0.796445-0.398223a28.444444 28.444444 0 0 0 4.152889-2.730666 37.091556 37.091556 0 0 0 6.542222-6.826667l0.796444-0.967111c1.080889-1.422222 1.080889-1.422222 2.161778-3.128889a37.432889 37.432889 0 0 0 3.697778-9.557333c0.568889-1.194667 0.568889-1.194667 1.137778-3.128889 0.113778-1.763556 0.113778-1.763556 0-2.503111v0.910222a36.579556 36.579556 0 0 0-0.341334-10.24l-0.113778-0.967111a22.755556 22.755556 0 0 0-0.682666-3.982222c0-1.080889 0-1.080889-0.568889-3.128889l-68.494222-183.751111a38.798222 38.798222 0 0 0-49.777778-22.755556 38.798222 38.798222 0 0 0-22.755556 49.777778l16.270223 43.804444A397.880889 397.880889 0 0 0 512 113.777778C292.408889 113.777778 113.777778 292.408889 113.777778 512s178.631111 398.222222 398.222222 398.222222 398.222222-178.631111 398.222222-398.222222a38.684444 38.684444 0 1 0-77.368889 0c0 176.924444-143.928889 320.853333-320.853333 320.853333S191.146667 688.924444 191.146667 512 335.075556 191.146667 512 191.146667c80.099556 0 157.070222 29.980444 215.950222 83.626666z"
p-id="5119"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -79,7 +79,8 @@ const map = {
promotionLight: require('./icons/light/promotion.svg').default, promotionLight: require('./icons/light/promotion.svg').default,
logsLight: require('./icons/light/logs.svg').default, logsLight: require('./icons/light/logs.svg').default,
badLight: require('./icons/light/bad.svg').default, badLight: require('./icons/light/bad.svg').default,
markLight: require('./icons/light/mark.svg').default markLight: require('./icons/light/mark.svg').default,
retryLight: require('./icons/light/retry.svg').default
}; };
export type IconName = keyof typeof map; export type IconName = keyof typeof map;

View File

@ -25,7 +25,7 @@ const UpdatePswModal = ({ onClose }: { onClose: () => void }) => {
const { mutate: onSubmit, isLoading } = useRequest({ const { mutate: onSubmit, isLoading } = useRequest({
mutationFn: (data: FormType) => { mutationFn: (data: FormType) => {
if (data.newPsw !== data.confirmPsw) { if (data.newPsw !== data.confirmPsw) {
return Promise.reject(t('commom.Password inconsistency')); return Promise.reject(t('common.Password inconsistency'));
} }
return updatePasswordByOld(data); return updatePasswordByOld(data);
}, },

View File

@ -48,24 +48,7 @@ const ChatItemSchema = new Schema({
} }
}, },
[TaskResponseKeyEnum.responseData]: { [TaskResponseKeyEnum.responseData]: {
type: [ type: Array,
{
moduleName: String,
price: String,
model: String,
tokens: Number,
question: String,
answer: String,
temperature: Number,
maxToken: Number,
quoteList: Array,
completeMessages: Array,
similarity: Number,
limit: Number,
cqList: Array,
cqResult: String
}
],
default: [] default: []
} }
}); });

View File

@ -44,7 +44,7 @@ export class SSEParseData {
data: parseData data: parseData
}; };
} catch (error) { } catch (error) {
if (typeof item.data === 'string' && !item.data.startsWith(": ping")) { if (typeof item.data === 'string' && !item.data.startsWith(': ping')) {
this.storeReadData += item.data; this.storeReadData += item.data;
} else { } else {
this.storeReadData = ''; this.storeReadData = '';