diff --git a/api/server/routes/ask/askBingAI.js b/api/server/routes/ask/bingAI.js similarity index 72% rename from api/server/routes/ask/askBingAI.js rename to api/server/routes/ask/bingAI.js index 7a00ea79d..9b2d92382 100644 --- a/api/server/routes/ask/askBingAI.js +++ b/api/server/routes/ask/bingAI.js @@ -108,32 +108,33 @@ const ask = async ({ if (preSendRequest) sendMessage(res, { message: userMessage, created: true }); + let lastSavedTimestamp = 0; + const { onProgress: progressCallback, getPartialText } = createOnProgress({ + onProgress: ({ text }) => { + const currentTimestamp = Date.now(); + if (currentTimestamp - lastSavedTimestamp > 500) { + lastSavedTimestamp = currentTimestamp; + saveMessage({ + messageId: responseMessageId, + sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', + conversationId, + parentMessageId: overrideParentMessageId || userMessageId, + text: text, + unfinished: true, + cancelled: false, + error: false, + }); + } + }, + }); + const abortController = new AbortController(); + let bingConversationId = null; + if (!isNewConversation) { + const convo = await getConvo(req.user.id, conversationId); + bingConversationId = convo.bingConversationId; + } + try { - let lastSavedTimestamp = 0; - const { onProgress: progressCallback } = createOnProgress({ - onProgress: ({ text }) => { - const currentTimestamp = Date.now(); - if (currentTimestamp - lastSavedTimestamp > 500) { - lastSavedTimestamp = currentTimestamp; - saveMessage({ - messageId: responseMessageId, - sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', - conversationId, - parentMessageId: overrideParentMessageId || userMessageId, - text: text, - unfinished: true, - cancelled: false, - error: false, - }); - } - }, - }); - const abortController = new AbortController(); - let bingConversationId = null; - if (!isNewConversation) { - const convo = await getConvo(req.user.id, conversationId); - bingConversationId = convo.bingConversationId; - } let response = await askBing({ text, parentMessageId: userParentMessageId, @@ -160,6 +161,13 @@ const ask = async ({ response.text = response.response || response.details.spokenText || '**Bing refused to answer.**'; + const partialText = getPartialText(); + let unfinished = false; + if (partialText?.length > response.text.length) { + response.text = partialText; + unfinished = true; + } + let responseMessage = { conversationId, bingConversationId: newConversationId, @@ -171,7 +179,7 @@ const ask = async ({ suggestions: response.details.suggestedResponses && response.details.suggestedResponses.map((s) => s.text), - unfinished: false, + unfinished, cancelled: false, error: false, }; @@ -179,7 +187,11 @@ const ask = async ({ await saveMessage(responseMessage); responseMessage.messageId = newResponseMessageId; - let conversationUpdate = { conversationId, bingConversationId: newConversationId, endpoint: 'bingAI' }; + let conversationUpdate = { + conversationId, + bingConversationId: newConversationId, + endpoint: 'bingAI', + }; if (endpointOption?.jailbreak) { conversationUpdate.jailbreak = true; @@ -224,19 +236,45 @@ const ask = async ({ }); } } catch (error) { - console.log(error); - const errorMessage = { - messageId: responseMessageId, - sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', - conversationId, - parentMessageId: overrideParentMessageId || userMessageId, - unfinished: false, - cancelled: false, - error: true, - text: error.message, - }; - await saveMessage(errorMessage); - handleError(res, errorMessage); + console.error(error); + const partialText = getPartialText(); + if (partialText?.length > 2) { + const responseMessage = { + messageId: responseMessageId, + sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', + conversationId, + parentMessageId: overrideParentMessageId || userMessageId, + text: partialText, + model: endpointOption.modelOptions.model, + unfinished: true, + cancelled: false, + error: false, + }; + + saveMessage(responseMessage); + + return { + title: await getConvoTitle(req.user.id, conversationId), + final: true, + conversation: await getConvo(req.user.id, conversationId), + requestMessage: userMessage, + responseMessage: responseMessage, + }; + } else { + console.log(error); + const errorMessage = { + messageId: responseMessageId, + sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', + conversationId, + parentMessageId: overrideParentMessageId || userMessageId, + unfinished: false, + cancelled: false, + error: true, + text: error.message, + }; + await saveMessage(errorMessage); + handleError(res, errorMessage); + } } }; diff --git a/api/server/routes/ask/index.js b/api/server/routes/ask/index.js index 696cad524..d088d97b1 100644 --- a/api/server/routes/ask/index.js +++ b/api/server/routes/ask/index.js @@ -4,7 +4,7 @@ const router = express.Router(); // const askOpenAI = require('./askOpenAI'); const openAI = require('./openAI'); const google = require('./google'); -const askBingAI = require('./askBingAI'); +const bingAI = require('./bingAI'); const gptPlugins = require('./gptPlugins'); const askChatGPTBrowser = require('./askChatGPTBrowser'); const anthropic = require('./anthropic'); @@ -12,7 +12,7 @@ const anthropic = require('./anthropic'); // router.use('/azureOpenAI', askAzureOpenAI); router.use(['/azureOpenAI', '/openAI'], openAI); router.use('/google', google); -router.use('/bingAI', askBingAI); +router.use('/bingAI', bingAI); router.use('/chatGPTBrowser', askChatGPTBrowser); router.use('/gptPlugins', gptPlugins); router.use('/anthropic', anthropic); diff --git a/client/src/components/Input/AdjustToneButton.jsx b/client/src/components/Input/AdjustToneButton.jsx index 7e918f3dd..0b9f71f55 100644 --- a/client/src/components/Input/AdjustToneButton.jsx +++ b/client/src/components/Input/AdjustToneButton.jsx @@ -1,6 +1,6 @@ import React from 'react'; import { Settings2 } from 'lucide-react'; -export default function AdjustButton({ onClick }) { +export default function AdjustToneButton({ onClick }) { const clickHandler = (e) => { e.preventDefault(); onClick(); diff --git a/client/src/components/Input/index.jsx b/client/src/components/Input/index.jsx index 716141ac3..5157820ab 100644 --- a/client/src/components/Input/index.jsx +++ b/client/src/components/Input/index.jsx @@ -11,7 +11,7 @@ import NewConversationMenu from './NewConversationMenu'; import AdjustToneButton from './AdjustToneButton'; import Footer from './Footer'; import TextareaAutosize from 'react-textarea-autosize'; -import { useMessageHandler } from '../../utils/handleSubmit'; +import { useMessageHandler } from '~/utils/handleSubmit'; import store from '~/store'; @@ -36,8 +36,20 @@ export default function TextChat({ isSearchView = false }) { // auto focus to input, when enter a conversation. useEffect(() => { - if (conversation?.conversationId !== 'search') inputRef.current?.focus(); - }, [conversation?.conversationId]); + const { conversationId } = conversation || {}; + if (!conversationId) { + return; + } + + // Prevents Settings from not showing on new conversation, also prevents showing toneStyle change without jailbreak + if (conversationId === 'new' || !conversation?.jailbreak) { + setShowBingToneSetting(false); + } + + if (conversationId !== 'search') { + inputRef.current?.focus(); + } + }, [conversation]); useEffect(() => { const timeoutId = setTimeout(() => { @@ -146,7 +158,7 @@ export default function TextChat({ isSearchView = false }) { >
- {'This is an unfinished message. The AI may still be generating a response or it was aborted. Refresh or visit later to see more updates.'} + { + 'This is an unfinished message. The AI may still be generating a response, it was aborted, or a censor was triggered. Refresh or visit later to see more updates.' + }
) : null}