mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🛠️ 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:
parent
e13b146d6d
commit
166a4fa44f
6 changed files with 33 additions and 17 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue