From ab66747e971d91fe4ce60f986631048a3b431457 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Wed, 6 Mar 2024 17:49:53 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20style:=20Improve=20UI=20and=20UX?= =?UTF-8?q?=20with=20Style=20Fixes=20and=20Code=20Refactors=20(#2002)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(useSSE): add useCallback to all event handlers * chore: remove modelName in defaultAssistantFormValues * fix(SidePanel): fix layout shift on chrome my removing sidenav scrollbar * style(ChatForm): match ChatGPT textarea effect styling * style: fix flickering of old background color on refresh --- client/src/components/Chat/Input/ChatForm.tsx | 2 +- client/src/components/SidePanel/Nav.tsx | 2 +- client/src/components/SidePanel/SidePanel.tsx | 2 +- client/src/hooks/SSE/useContentHandler.ts | 79 +- client/src/hooks/SSE/useSSE.ts | 698 +++++++++--------- client/src/style.css | 2 +- packages/data-provider/src/schemas.ts | 2 +- 7 files changed, 412 insertions(+), 375 deletions(-) diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx index bec33d7a6d..3c7ba42457 100644 --- a/client/src/components/Chat/Input/ChatForm.tsx +++ b/client/src/components/Chat/Input/ChatForm.tsx @@ -43,7 +43,7 @@ export default function ChatForm({ index = 0 }) { >
-
+
diff --git a/client/src/components/SidePanel/SidePanel.tsx b/client/src/components/SidePanel/SidePanel.tsx index a0de890147..d122ca5a42 100644 --- a/client/src/components/SidePanel/SidePanel.tsx +++ b/client/src/components/SidePanel/SidePanel.tsx @@ -172,7 +172,7 @@ export default function SidePanel({ localStorage.setItem('react-resizable-panels:collapsed', 'true'); }} className={cn( - 'sidenav border-l border-gray-200 bg-white dark:border-gray-800/50 dark:bg-gray-900', + 'sidenav hide-scrollbar border-l border-gray-200 bg-white dark:border-gray-800/50 dark:bg-gray-900', isCollapsed ? 'min-w-[50px]' : 'min-w-[340px] sm:min-w-[352px]', minSize === 0 ? 'min-w-0' : '', )} diff --git a/client/src/hooks/SSE/useContentHandler.ts b/client/src/hooks/SSE/useContentHandler.ts index a94e1db173..b0e015dab8 100644 --- a/client/src/hooks/SSE/useContentHandler.ts +++ b/client/src/hooks/SSE/useContentHandler.ts @@ -6,6 +6,7 @@ import type { ContentPart, TMessageContentParts, } from 'librechat-data-provider'; +import { useCallback, useMemo } from 'react'; type TUseContentHandler = { setMessages: (messages: TMessage[]) => void; @@ -18,49 +19,53 @@ type TContentHandler = { }; export default function useContentHandler({ setMessages, getMessages }: TUseContentHandler) { - const messageMap = new Map(); - return ({ data, submission }: TContentHandler) => { - const { type, messageId, thread_id, conversationId, index, stream } = data; + const messageMap = useMemo(() => new Map(), []); + return useCallback( + ({ data, submission }: TContentHandler) => { + const { type, messageId, thread_id, conversationId, index, stream } = data; - const _messages = getMessages(); - const messages = - _messages?.filter((m) => m.messageId !== messageId)?.map((msg) => ({ ...msg, thread_id })) ?? - []; - const userMessage = messages[messages.length - 1]; + const _messages = getMessages(); + const messages = + _messages + ?.filter((m) => m.messageId !== messageId) + ?.map((msg) => ({ ...msg, thread_id })) ?? []; + const userMessage = messages[messages.length - 1]; - const { initialResponse } = submission; + const { initialResponse } = submission; - let response = messageMap.get(messageId); - if (!response) { - response = { - ...initialResponse, - parentMessageId: userMessage?.messageId, - conversationId, - messageId, - thread_id, - }; - messageMap.set(messageId, response); - } + let response = messageMap.get(messageId); + if (!response) { + response = { + ...initialResponse, + parentMessageId: userMessage?.messageId, + conversationId, + messageId, + thread_id, + }; + messageMap.set(messageId, response); + } - // TODO: handle streaming for non-text - const part: ContentPart = - stream && data[ContentTypes.TEXT] ? { value: data[ContentTypes.TEXT] } : data[type]; + // TODO: handle streaming for non-text + const part: ContentPart = + stream && data[ContentTypes.TEXT] ? { value: data[ContentTypes.TEXT] } : data[type]; - /* spreading the content array to avoid mutation */ - response.content = [...(response.content ?? [])]; + /* spreading the content array to avoid mutation */ + response.content = [...(response.content ?? [])]; - response.content[index] = { type, [type]: part } as TMessageContentParts; + response.content[index] = { type, [type]: part } as TMessageContentParts; - if ( - type !== ContentTypes.TEXT && - initialResponse.content && - ((response.content[response.content.length - 1].type === ContentTypes.TOOL_CALL && - response.content[response.content.length - 1][ContentTypes.TOOL_CALL].progress === 1) || - response.content[response.content.length - 1].type === ContentTypes.IMAGE_FILE) - ) { - response.content.push(initialResponse.content[0]); - } + if ( + type !== ContentTypes.TEXT && + initialResponse.content && + ((response.content[response.content.length - 1].type === ContentTypes.TOOL_CALL && + response.content[response.content.length - 1][ContentTypes.TOOL_CALL].progress === 1) || + response.content[response.content.length - 1].type === ContentTypes.IMAGE_FILE) + ) { + response.content.push(initialResponse.content[0]); + } - setMessages([...messages, response]); - }; + setMessages([...messages, response]); + }, + [getMessages, messageMap, setMessages], + ); } diff --git a/client/src/hooks/SSE/useSSE.ts b/client/src/hooks/SSE/useSSE.ts index 159520439b..638e9476fc 100644 --- a/client/src/hooks/SSE/useSSE.ts +++ b/client/src/hooks/SSE/useSSE.ts @@ -1,8 +1,8 @@ import { v4 } from 'uuid'; import { useSetRecoilState } from 'recoil'; -import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { useQueryClient } from '@tanstack/react-query'; +import { useEffect, useState, useCallback } from 'react'; import { /* @ts-ignore */ SSE, @@ -83,392 +83,424 @@ export default function useSSE(submission: TSubmission | null, index = 0) { enabled: !!isAuthenticated && startupConfig?.checkBalance, }); - const messageHandler = (data: string, submission: TSubmission) => { - const { - messages, - message, - plugin, - plugins, - initialResponse, - isRegenerate = false, - } = submission; - - if (isRegenerate) { - setMessages([ - ...messages, - { - ...initialResponse, - text: data, - parentMessageId: message?.overrideParentMessageId ?? null, - messageId: message?.overrideParentMessageId + '_', - plugin: plugin ?? null, - plugins: plugins ?? [], - // unfinished: true - }, - ]); - } else { - setMessages([ - ...messages, + const messageHandler = useCallback( + (data: string, submission: TSubmission) => { + const { + messages, message, + plugin, + plugins, + initialResponse, + isRegenerate = false, + } = submission; + + if (isRegenerate) { + setMessages([ + ...messages, + { + ...initialResponse, + text: data, + parentMessageId: message?.overrideParentMessageId ?? null, + messageId: message?.overrideParentMessageId + '_', + plugin: plugin ?? null, + plugins: plugins ?? [], + // unfinished: true + }, + ]); + } else { + setMessages([ + ...messages, + message, + { + ...initialResponse, + text: data, + parentMessageId: message?.messageId, + messageId: message?.messageId + '_', + plugin: plugin ?? null, + plugins: plugins ?? [], + // unfinished: true + }, + ]); + } + }, + [setMessages], + ); + + const cancelHandler = useCallback( + (data: TResData, submission: TSubmission) => { + const { requestMessage, responseMessage, conversation } = data; + const { messages, isRegenerate = false } = submission; + + const convoUpdate = conversation ?? submission.conversation; + + // update the messages + if (isRegenerate) { + const messagesUpdate = [...messages, responseMessage].filter((msg) => msg); + setMessages(messagesUpdate); + } else { + const messagesUpdate = [...messages, requestMessage, responseMessage].filter((msg) => msg); + setMessages(messagesUpdate); + } + + const isNewConvo = conversation.conversationId !== submission.conversation.conversationId; + if (isNewConvo) { + queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { + if (!convoData) { + return convoData; + } + return deleteConversation(convoData, submission.conversation.conversationId as string); + }); + } + + // refresh title + if (isNewConvo && requestMessage?.parentMessageId === Constants.NO_PARENT) { + setTimeout(() => { + genTitle.mutate({ conversationId: convoUpdate.conversationId as string }); + }, 2500); + } + + setConversation((prevState) => { + const update = { + ...prevState, + ...convoUpdate, + }; + + setStorage(update); + return update; + }); + + setIsSubmitting(false); + }, + [setMessages, setConversation, setStorage, genTitle, queryClient, setIsSubmitting], + ); + + const syncHandler = useCallback( + (data: TSyncData, submission: TSubmission) => { + const { conversationId, thread_id, responseMessage, requestMessage } = data; + const { initialResponse, messages: _messages, message } = submission; + + const messages = _messages.filter((msg) => msg.messageId !== message.messageId); + + setMessages([ + ...messages, + requestMessage, { ...initialResponse, - text: data, - parentMessageId: message?.messageId, - messageId: message?.messageId + '_', - plugin: plugin ?? null, - plugins: plugins ?? [], - // unfinished: true + ...responseMessage, }, ]); - } - }; - const cancelHandler = (data: TResData, submission: TSubmission) => { - const { requestMessage, responseMessage, conversation } = data; - const { messages, isRegenerate = false } = submission; + let update = {} as TConversation; + setConversation((prevState) => { + update = tConvoUpdateSchema.parse({ + ...prevState, + conversationId, + thread_id, + messages: [requestMessage.messageId, responseMessage.messageId], + }) as TConversation; - const convoUpdate = conversation ?? submission.conversation; + setStorage(update); + return update; + }); - // update the messages - if (isRegenerate) { - const messagesUpdate = [...messages, responseMessage].filter((msg) => msg); - setMessages(messagesUpdate); - } else { - const messagesUpdate = [...messages, requestMessage, responseMessage].filter((msg) => msg); - setMessages(messagesUpdate); - } - - const isNewConvo = conversation.conversationId !== submission.conversation.conversationId; - if (isNewConvo) { queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { if (!convoData) { return convoData; } - return deleteConversation(convoData, submission.conversation.conversationId as string); + if (requestMessage.parentMessageId === Constants.NO_PARENT) { + return addConversation(convoData, update); + } else { + return updateConversation(convoData, update); + } }); - } - // refresh title - if (isNewConvo && requestMessage?.parentMessageId === Constants.NO_PARENT) { - setTimeout(() => { - genTitle.mutate({ conversationId: convoUpdate.conversationId as string }); - }, 2500); - } + setShowStopButton(true); - setConversation((prevState) => { - const update = { - ...prevState, - ...convoUpdate, - }; + resetLatestMessage(); + }, + [setMessages, setConversation, setStorage, queryClient, setShowStopButton, resetLatestMessage], + ); - setStorage(update); - return update; - }); + const createdHandler = useCallback( + (data: TResData, submission: TSubmission) => { + const { messages, message, initialResponse, isRegenerate = false } = submission; - setIsSubmitting(false); - }; - - const syncHandler = (data: TSyncData, submission: TSubmission) => { - const { conversationId, thread_id, responseMessage, requestMessage } = data; - const { initialResponse, messages: _messages, message } = submission; - - const messages = _messages.filter((msg) => msg.messageId !== message.messageId); - - setMessages([ - ...messages, - requestMessage, - { - ...initialResponse, - ...responseMessage, - }, - ]); - - let update = {} as TConversation; - setConversation((prevState) => { - update = tConvoUpdateSchema.parse({ - ...prevState, - conversationId, - thread_id, - messages: [requestMessage.messageId, responseMessage.messageId], - }) as TConversation; - - setStorage(update); - return update; - }); - - queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { - if (!convoData) { - return convoData; - } - if (requestMessage.parentMessageId === Constants.NO_PARENT) { - return addConversation(convoData, update); + if (isRegenerate) { + setMessages([ + ...messages, + { + ...initialResponse, + parentMessageId: message?.overrideParentMessageId ?? null, + messageId: message?.overrideParentMessageId + '_', + }, + ]); } else { - return updateConversation(convoData, update); - } - }); - - setShowStopButton(true); - - resetLatestMessage(); - }; - - const createdHandler = (data: TResData, submission: TSubmission) => { - const { messages, message, initialResponse, isRegenerate = false } = submission; - - if (isRegenerate) { - setMessages([ - ...messages, - { - ...initialResponse, - parentMessageId: message?.overrideParentMessageId ?? null, - messageId: message?.overrideParentMessageId + '_', - }, - ]); - } else { - setMessages([ - ...messages, - message, - { - ...initialResponse, - parentMessageId: message?.messageId, - messageId: message?.messageId + '_', - }, - ]); - } - - const { conversationId, parentMessageId } = message; - - let update = {} as TConversation; - setConversation((prevState) => { - let title = prevState?.title; - if (parentMessageId !== Constants.NO_PARENT && title?.toLowerCase()?.includes('new chat')) { - const convos = queryClient.getQueryData([QueryKeys.allConversations]); - const cachedConvo = getConversationById(convos, conversationId); - title = cachedConvo?.title; + setMessages([ + ...messages, + message, + { + ...initialResponse, + parentMessageId: message?.messageId, + messageId: message?.messageId + '_', + }, + ]); } - update = tConvoUpdateSchema.parse({ - ...prevState, - conversationId, - title, - }) as TConversation; + const { conversationId, parentMessageId } = message; - setStorage(update); - return update; - }); + let update = {} as TConversation; + setConversation((prevState) => { + let title = prevState?.title; + if (parentMessageId !== Constants.NO_PARENT && title?.toLowerCase()?.includes('new chat')) { + const convos = queryClient.getQueryData([QueryKeys.allConversations]); + const cachedConvo = getConversationById(convos, conversationId); + title = cachedConvo?.title; + } - queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { - if (!convoData) { - return convoData; - } - if (parentMessageId === Constants.NO_PARENT) { - return addConversation(convoData, update); - } else { - return updateConversation(convoData, update); - } - }); - resetLatestMessage(); - }; + update = tConvoUpdateSchema.parse({ + ...prevState, + conversationId, + title, + }) as TConversation; - const finalHandler = (data: TResData, submission: TSubmission) => { - const { requestMessage, responseMessage, conversation, runMessages } = data; - const { messages, conversation: submissionConvo, isRegenerate = false } = submission; + setStorage(update); + return update; + }); - setShowStopButton(false); - setCompleted((prev) => new Set(prev.add(submission?.initialResponse?.messageId))); - - // update the messages; if assistants endpoint, client doesn't receive responseMessage - if (runMessages) { - setMessages([...runMessages]); - } else if (isRegenerate && responseMessage) { - setMessages([...messages, responseMessage]); - } else if (responseMessage) { - setMessages([...messages, requestMessage, responseMessage]); - } - - const isNewConvo = conversation.conversationId !== submissionConvo.conversationId; - if (isNewConvo) { queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { if (!convoData) { return convoData; } - return deleteConversation(convoData, submissionConvo.conversationId as string); + if (parentMessageId === Constants.NO_PARENT) { + return addConversation(convoData, update); + } else { + return updateConversation(convoData, update); + } }); - } + resetLatestMessage(); + }, + [setMessages, setConversation, setStorage, queryClient, resetLatestMessage], + ); - // refresh title - if (isNewConvo && requestMessage && requestMessage.parentMessageId === Constants.NO_PARENT) { - setTimeout(() => { - genTitle.mutate({ conversationId: conversation.conversationId as string }); - }, 2500); - } + const finalHandler = useCallback( + (data: TResData, submission: TSubmission) => { + const { requestMessage, responseMessage, conversation, runMessages } = data; + const { messages, conversation: submissionConvo, isRegenerate = false } = submission; - setConversation((prevState) => { - const update = { - ...prevState, - ...conversation, - }; + setShowStopButton(false); + setCompleted((prev) => new Set(prev.add(submission?.initialResponse?.messageId))); - if (prevState?.model && prevState.model !== submissionConvo.model) { - update.model = prevState.model; + // update the messages; if assistants endpoint, client doesn't receive responseMessage + if (runMessages) { + setMessages([...runMessages]); + } else if (isRegenerate && responseMessage) { + setMessages([...messages, responseMessage]); + } else if (responseMessage) { + setMessages([...messages, requestMessage, responseMessage]); } - setStorage(update); - return update; - }); + const isNewConvo = conversation.conversationId !== submissionConvo.conversationId; + if (isNewConvo) { + queryClient.setQueryData([QueryKeys.allConversations], (convoData) => { + if (!convoData) { + return convoData; + } + return deleteConversation(convoData, submissionConvo.conversationId as string); + }); + } - setIsSubmitting(false); - }; + // refresh title + if (isNewConvo && requestMessage && requestMessage.parentMessageId === Constants.NO_PARENT) { + setTimeout(() => { + genTitle.mutate({ conversationId: conversation.conversationId as string }); + }, 2500); + } - const errorHandler = ({ data, submission }: { data?: TResData; submission: TSubmission }) => { - const { messages, message, initialResponse } = submission; + setConversation((prevState) => { + const update = { + ...prevState, + ...conversation, + }; - setCompleted((prev) => new Set(prev.add(initialResponse.messageId))); + if (prevState?.model && prevState.model !== submissionConvo.model) { + update.model = prevState.model; + } - const conversationId = message?.conversationId ?? submission?.conversationId; + setStorage(update); + return update; + }); - const parseErrorResponse = (data: TResData | Partial) => { - const metadata = data['responseMessage'] ?? data; - const errorMessage = { - ...initialResponse, - ...metadata, + setIsSubmitting(false); + }, + [ + setMessages, + setConversation, + setStorage, + genTitle, + queryClient, + setIsSubmitting, + setShowStopButton, + ], + ); + + const errorHandler = useCallback( + ({ data, submission }: { data?: TResData; submission: TSubmission }) => { + const { messages, message, initialResponse } = submission; + + setCompleted((prev) => new Set(prev.add(initialResponse.messageId))); + + const conversationId = message?.conversationId ?? submission?.conversationId; + + const parseErrorResponse = (data: TResData | Partial) => { + const metadata = data['responseMessage'] ?? data; + const errorMessage = { + ...initialResponse, + ...metadata, + error: true, + parentMessageId: message?.messageId, + }; + + if (!errorMessage.messageId) { + errorMessage.messageId = v4(); + } + + return tMessageSchema.parse(errorMessage); + }; + + if (!data) { + const convoId = conversationId ?? v4(); + const errorResponse = parseErrorResponse({ + text: 'Error connecting to server', + ...submission, + conversationId: convoId, + }); + setMessages([...messages, message, errorResponse]); + newConversation({ + template: { conversationId: convoId }, + preset: tPresetSchema.parse(submission?.conversation), + }); + setIsSubmitting(false); + return; + } + + if (!conversationId && !data.conversationId) { + const convoId = v4(); + const errorResponse = parseErrorResponse(data); + setMessages([...messages, message, errorResponse]); + newConversation({ + template: { conversationId: convoId }, + preset: tPresetSchema.parse(submission?.conversation), + }); + setIsSubmitting(false); + return; + } + + console.log('Error:', data); + const errorResponse = tMessageSchema.parse({ + ...data, error: true, parentMessageId: message?.messageId, - }; + }); - if (!errorMessage.messageId) { - errorMessage.messageId = v4(); + setMessages([...messages, message, errorResponse]); + if (data.conversationId && paramId === 'new') { + newConversation({ + template: { conversationId: data.conversationId }, + preset: tPresetSchema.parse(submission?.conversation), + }); } - return tMessageSchema.parse(errorMessage); - }; - - if (!data) { - const convoId = conversationId ?? v4(); - const errorResponse = parseErrorResponse({ - text: 'Error connecting to server', - ...submission, - conversationId: convoId, - }); - setMessages([...messages, message, errorResponse]); - newConversation({ - template: { conversationId: convoId }, - preset: tPresetSchema.parse(submission?.conversation), - }); setIsSubmitting(false); return; - } + }, + [setMessages, paramId, setIsSubmitting, newConversation], + ); - if (!conversationId && !data.conversationId) { - const convoId = v4(); - const errorResponse = parseErrorResponse(data); - setMessages([...messages, message, errorResponse]); - newConversation({ - template: { conversationId: convoId }, - preset: tPresetSchema.parse(submission?.conversation), - }); - setIsSubmitting(false); - return; - } + const abortConversation = useCallback( + async (conversationId = '', submission: TSubmission) => { + console.log(submission); + let runAbortKey = ''; + try { + const conversation = (JSON.parse(localStorage.getItem('lastConversationSetup') ?? '') ?? + {}) as TConversation; + const { conversationId, messages } = conversation; + runAbortKey = `${conversationId}:${messages?.[messages.length - 1]}`; + } catch (error) { + console.error('Error getting last conversation setup'); + console.error(error); + } + const { endpoint: _endpoint, endpointType } = submission?.conversation || {}; + const endpoint = endpointType ?? _endpoint; + try { + const response = await fetch(`${EndpointURLs[endpoint ?? '']}/abort`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + abortKey: _endpoint === EModelEndpoint.assistants ? runAbortKey : conversationId, + endpoint, + }), + }); - console.log('Error:', data); - const errorResponse = tMessageSchema.parse({ - ...data, - error: true, - parentMessageId: message?.messageId, - }); + // Check if the response is JSON + const contentType = response.headers.get('content-type'); + if (contentType && contentType.includes('application/json')) { + const data = await response.json(); + console.log('aborted', data); + if (response.status === 404) { + setIsSubmitting(false); + return; + } + if (data.final) { + finalHandler(data, submission); + } else { + cancelHandler(data, submission); + } + } else if (response.status === 204) { + const responseMessage = { + ...submission.initialResponse, + }; - setMessages([...messages, message, errorResponse]); - if (data.conversationId && paramId === 'new') { - newConversation({ - template: { conversationId: data.conversationId }, - preset: tPresetSchema.parse(submission?.conversation), - }); - } - - setIsSubmitting(false); - return; - }; - - const abortConversation = async (conversationId = '', submission: TSubmission) => { - console.log(submission); - let runAbortKey = ''; - try { - const conversation = (JSON.parse(localStorage.getItem('lastConversationSetup') ?? '') ?? - {}) as TConversation; - const { conversationId, messages } = conversation; - runAbortKey = `${conversationId}:${messages?.[messages.length - 1]}`; - } catch (error) { - console.error('Error getting last conversation setup'); - console.error(error); - } - const { endpoint: _endpoint, endpointType } = submission?.conversation || {}; - const endpoint = endpointType ?? _endpoint; - try { - const response = await fetch(`${EndpointURLs[endpoint ?? '']}/abort`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${token}`, - }, - body: JSON.stringify({ - abortKey: _endpoint === EModelEndpoint.assistants ? runAbortKey : conversationId, - endpoint, - }), - }); - - // Check if the response is JSON - const contentType = response.headers.get('content-type'); - if (contentType && contentType.includes('application/json')) { - const data = await response.json(); - console.log('aborted', data); - if (response.status === 404) { - setIsSubmitting(false); - return; - } - if (data.final) { - finalHandler(data, submission); + const data = { + requestMessage: submission.message, + responseMessage: responseMessage, + conversation: submission.conversation, + }; + console.log('aborted', data); } else { - cancelHandler(data, submission); + throw new Error( + 'Unexpected response from server; Status: ' + + response.status + + ' ' + + response.statusText, + ); } - } else if (response.status === 204) { - const responseMessage = { + } catch (error) { + console.error('Error cancelling request'); + console.error(error); + const convoId = conversationId ?? v4(); + const text = + submission.initialResponse?.text?.length > 45 ? submission.initialResponse?.text : ''; + const errorMessage = { + ...submission, ...submission.initialResponse, + text: text ?? (error as Error).message ?? 'Error cancelling request', + unfinished: !!text.length, + error: true, }; - - const data = { - requestMessage: submission.message, - responseMessage: responseMessage, - conversation: submission.conversation, - }; - console.log('aborted', data); - } else { - throw new Error( - 'Unexpected response from server; Status: ' + response.status + ' ' + response.statusText, - ); + const errorResponse = tMessageSchema.parse(errorMessage); + setMessages([...submission.messages, submission.message, errorResponse]); + newConversation({ + template: { conversationId: convoId }, + preset: tPresetSchema.parse(submission?.conversation), + }); + setIsSubmitting(false); } - } catch (error) { - console.error('Error cancelling request'); - console.error(error); - const convoId = conversationId ?? v4(); - const text = - submission.initialResponse?.text?.length > 45 ? submission.initialResponse?.text : ''; - const errorMessage = { - ...submission, - ...submission.initialResponse, - text: text ?? (error as Error).message ?? 'Error cancelling request', - unfinished: !!text.length, - error: true, - }; - const errorResponse = tMessageSchema.parse(errorMessage); - setMessages([...submission.messages, submission.message, errorResponse]); - newConversation({ - template: { conversationId: convoId }, - preset: tPresetSchema.parse(submission?.conversation), - }); - setIsSubmitting(false); - } - }; + }, + [token, setIsSubmitting, finalHandler, cancelHandler, setMessages, newConversation], + ); useEffect(() => { if (submission === null) { diff --git a/client/src/style.css b/client/src/style.css index 41d3d9ca95..23ad2f11cf 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -1410,7 +1410,7 @@ html { .dark body, .dark html { --tw-bg-opacity:1; - background-color:rgba(52,53,65,var(--tw-bg-opacity)) + background-color:rgba(33,33,33,var(--tw-bg-opacity)) } #__next, #root { diff --git a/packages/data-provider/src/schemas.ts b/packages/data-provider/src/schemas.ts index 63b7a69d88..69bb660da1 100644 --- a/packages/data-provider/src/schemas.ts +++ b/packages/data-provider/src/schemas.ts @@ -22,7 +22,7 @@ export const defaultAssistantFormValues = { name: '', description: '', instructions: '', - model: 'gpt-3.5-turbo-1106', + model: '', functions: [], code_interpreter: false, retrieval: false,