🛠️ fix: Improve SSE Handling and Fix Typo in sendEmail Template (#1245)

* fix: typo for passwordReset.handlebars

* fix(useSSE): prevent unnecessary JSON.parse abort error, handle immediate abort-submit gracefully by reverting to previous state before immediate abort-submit, add showStopButton state to explicitly render disabled sendButton when message generation is cancelled, filter undefined messages and replace undefined convo for cancelHandler
This commit is contained in:
Danny Avila 2023-11-30 10:23:57 -05:00 committed by GitHub
parent e13b146d6d
commit 166a4fa44f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 17 deletions

View file

@ -8,7 +8,7 @@ async function abortMessage(req, res) {
const { abortKey } = req.body; const { abortKey } = req.body;
if (!abortControllers.has(abortKey) && !res.headersSent) { if (!abortControllers.has(abortKey) && !res.headersSent) {
return res.status(404).send('Request not found'); return res.status(404).send({ message: 'Request not found' });
} }
const { abortController } = abortControllers.get(abortKey); const { abortController } = abortControllers.get(abortKey);

View file

@ -185,7 +185,7 @@ const resetPassword = async (userId, token, password) => {
{ {
name: user.name, name: user.name,
}, },
'resetPassword.handlebars', 'passwordReset.handlebars',
); );
await passwordResetToken.deleteOne(); await passwordResetToken.deleteOne();

View file

@ -19,6 +19,8 @@ export default function ChatForm({ index = 0 }) {
handleStopGenerating, handleStopGenerating,
filesLoading, filesLoading,
setFilesLoading, setFilesLoading,
showStopButton,
setShowStopButton,
} = useChatContext(); } = useChatContext();
const submitMessage = () => { const submitMessage = () => {
@ -46,10 +48,10 @@ export default function ChatForm({ index = 0 }) {
endpoint={conversation?.endpoint} endpoint={conversation?.endpoint}
/> />
<AttachFile endpoint={conversation?.endpoint ?? ''} /> <AttachFile endpoint={conversation?.endpoint ?? ''} />
{isSubmitting ? ( {isSubmitting && showStopButton ? (
<StopButton stop={handleStopGenerating} /> <StopButton stop={handleStopGenerating} setShowStopButton={setShowStopButton} />
) : ( ) : (
<SendButton text={text} disabled={filesLoading} /> <SendButton text={text} disabled={filesLoading || isSubmitting} />
)} )}
</div> </div>
</div> </div>

View file

@ -1,4 +1,4 @@
export default function StopButton({ stop }) { export default function StopButton({ stop, setShowStopButton }) {
return ( return (
<div className="absolute bottom-0 right-2 top-0 p-1 md:right-3 md:p-2"> <div className="absolute bottom-0 right-2 top-0 p-1 md:right-3 md:p-2">
<div className="flex h-full"> <div className="flex h-full">
@ -7,7 +7,10 @@ export default function StopButton({ stop }) {
type="button" type="button"
className="border-gizmo-gray-950 rounded-full border-2 p-1 dark:border-gray-200" className="border-gizmo-gray-950 rounded-full border-2 p-1 dark:border-gray-200"
aria-label="Stop generating" aria-label="Stop generating"
onClick={stop} onClick={(e) => {
setShowStopButton(false);
stop(e);
}}
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View file

@ -25,6 +25,7 @@ import store from '~/store';
// this to be set somewhere else // this to be set somewhere else
export default function useChatHelpers(index = 0, paramId: string | undefined) { export default function useChatHelpers(index = 0, paramId: string | undefined) {
const [files, setFiles] = useRecoilState(store.filesByIndex(index)); const [files, setFiles] = useRecoilState(store.filesByIndex(index));
const [showStopButton, setShowStopButton] = useState(true);
const [filesLoading, setFilesLoading] = useState(false); const [filesLoading, setFilesLoading] = useState(false);
const setFilesToDelete = useSetFilesToDelete(); const setFilesToDelete = useSetFilesToDelete();
@ -130,6 +131,7 @@ export default function useChatHelpers(index = 0, paramId: string | undefined) {
isEdited = false, isEdited = false,
} = {}, } = {},
) => { ) => {
setShowStopButton(true);
if (!!isSubmitting || text === '') { if (!!isSubmitting || text === '') {
return; return;
} }
@ -369,5 +371,7 @@ export default function useChatHelpers(index = 0, paramId: string | undefined) {
invalidateConvos, invalidateConvos,
filesLoading, filesLoading,
setFilesLoading, setFilesLoading,
showStopButton,
setShowStopButton,
}; };
} }

View file

@ -17,7 +17,7 @@ import useChatHelpers from './useChatHelpers';
import useSetStorage from './useSetStorage'; import useSetStorage from './useSetStorage';
type TResData = { type TResData = {
plugin: TResPlugin; plugin?: TResPlugin;
final?: boolean; final?: boolean;
initial?: boolean; initial?: boolean;
requestMessage: TMessage; requestMessage: TMessage;
@ -91,16 +91,19 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
const { requestMessage, responseMessage, conversation } = data; const { requestMessage, responseMessage, conversation } = data;
const { messages, isRegenerate = false } = submission; const { messages, isRegenerate = false } = submission;
const convoUpdate = conversation ?? submission.conversation;
// update the messages // update the messages
if (isRegenerate) { if (isRegenerate) {
setMessages([...messages, responseMessage]); const messagesUpdate = [...messages, responseMessage].filter((msg) => msg);
setMessages(messagesUpdate);
} else { } else {
setMessages([...messages, requestMessage, responseMessage]); const messagesUpdate = [...messages, requestMessage, responseMessage].filter((msg) => msg);
setMessages(messagesUpdate);
} }
setIsSubmitting(false);
// refresh title // refresh title
if (requestMessage.parentMessageId == '00000000-0000-0000-0000-000000000000') { if (requestMessage?.parentMessageId == '00000000-0000-0000-0000-000000000000') {
setTimeout(() => { setTimeout(() => {
invalidateConvos(); invalidateConvos();
}, 2000); }, 2000);
@ -114,12 +117,14 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
setConversation((prevState) => { setConversation((prevState) => {
const update = { const update = {
...prevState, ...prevState,
...conversation, ...convoUpdate,
}; };
setStorage(update); setStorage(update);
return update; return update;
}); });
setIsSubmitting(false);
}; };
const createdHandler = (data: TResData, submission: TSubmission) => { const createdHandler = (data: TResData, submission: TSubmission) => {
@ -176,7 +181,6 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
} else { } else {
setMessages([...messages, requestMessage, responseMessage]); setMessages([...messages, requestMessage, responseMessage]);
} }
setIsSubmitting(false);
// refresh title // refresh title
if (requestMessage.parentMessageId == '00000000-0000-0000-0000-000000000000') { if (requestMessage.parentMessageId == '00000000-0000-0000-0000-000000000000') {
@ -199,6 +203,8 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
setStorage(update); setStorage(update);
return update; return update;
}); });
setIsSubmitting(false);
}; };
const errorHandler = (data: TResData, submission: TSubmission) => { const errorHandler = (data: TResData, submission: TSubmission) => {
@ -210,11 +216,13 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
error: true, error: true,
parentMessageId: message?.messageId, parentMessageId: message?.messageId,
}); });
setIsSubmitting(false);
setMessages([...messages, message, errorResponse]); setMessages([...messages, message, errorResponse]);
if (data.conversationId && paramId === 'new') { if (data.conversationId && paramId === 'new') {
newConversation({ template: { conversationId: data.conversationId } }); newConversation({ template: { conversationId: data.conversationId } });
} }
setIsSubmitting(false);
return; return;
}; };
@ -240,7 +248,7 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
.catch((error) => { .catch((error) => {
console.error('Error aborting request'); console.error('Error aborting request');
console.error(error); console.error(error);
// errorHandler({ text: 'Error aborting request' }, { ...submission, message }); setIsSubmitting(false);
}); });
return; return;
}; };
@ -324,7 +332,6 @@ export default function useSSE(submission: TSubmission | null, index = 0) {
const e = new Event('cancel'); const e = new Event('cancel');
events.dispatchEvent(e); events.dispatchEvent(e);
} }
setIsSubmitting(false);
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [submission]); }, [submission]);