diff --git a/api/server/routes/ask/askBingAI.js b/api/server/routes/ask/askBingAI.js index c8d1fd0755..6a1fe8d770 100644 --- a/api/server/routes/ask/askBingAI.js +++ b/api/server/routes/ask/askBingAI.js @@ -35,21 +35,21 @@ router.post('/', async (req, res) => { let endpointOption = {}; if (req.body?.jailbreak) endpointOption = { - jailbreak: req.body?.jailbreak || false, - jailbreakConversationId: req.body?.jailbreakConversationId || null, - systemMessage: req.body?.systemMessage || null, - context: req.body?.context || null, - toneStyle: req.body?.toneStyle || 'fast' + jailbreak: req.body?.jailbreak ?? false, + jailbreakConversationId: req.body?.jailbreakConversationId ?? null, + systemMessage: req.body?.systemMessage ?? null, + context: req.body?.context ?? null, + toneStyle: req.body?.toneStyle ?? 'fast' }; else endpointOption = { - jailbreak: req.body?.jailbreak || false, - systemMessage: req.body?.systemMessage || null, - context: req.body?.context || null, - conversationSignature: req.body?.conversationSignature || null, - clientId: req.body?.clientId || null, - invocationId: req.body?.invocationId || null, - toneStyle: req.body?.toneStyle || 'fast' + jailbreak: req.body?.jailbreak ?? false, + systemMessage: req.body?.systemMessage ?? null, + context: req.body?.context ?? null, + conversationSignature: req.body?.conversationSignature ?? null, + clientId: req.body?.clientId ?? null, + invocationId: req.body?.invocationId ?? null, + toneStyle: req.body?.toneStyle ?? 'fast' }; console.log('ask log', { @@ -122,31 +122,23 @@ const ask = async ({ console.log('BING RESPONSE', response); + const newConversationId = endpointOption?.jailbreak + ? response.jailbreakConversationId + : response.conversationId || conversationId; + const newUserMassageId = response.parentMessageId || userMessageId; + const newResponseMessageId = response.parentMessageId || response.details.requestId || userMessageId; + // STEP1 generate response message response.text = response.response || response.details.spokenText || '**Bing refused to answer.**'; let responseMessage = { + conversationId: newConversationId, + messageId: newResponseMessageId, + parentMessageId: overrideParentMessageId || newUserMassageId, + sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', text: await handleText(response, true), - suggestions: - response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text), - jailbreak: endpointOption?.jailbreak + suggestions: response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text) }; - // // response.text = await handleText(response, true); - // response.suggestions = - // response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text); - - if (endpointOption?.jailbreak) { - responseMessage.conversationId = response.jailbreakConversationId; - responseMessage.messageId = response.messageId || response.details.messageId; - responseMessage.parentMessageId = overrideParentMessageId || response.parentMessageId || userMessageId; - responseMessage.sender = 'Sydney'; - } else { - responseMessage.conversationId = response.conversationId; - responseMessage.messageId = response.messageId || response.details.messageId; - responseMessage.parentMessageId = - overrideParentMessageId || response.parentMessageId || response.details.requestId || userMessageId; - responseMessage.sender = 'BingAI'; - } await saveMessage(responseMessage); @@ -159,14 +151,22 @@ const ask = async ({ // Attition: the api will also create new conversationId while using invalid userMessage.parentMessageId, // but in this situation, don't change the conversationId, but create new convo. - let conversationUpdate = { conversationId, endpoint: 'bingAI' }; - if (conversationId != responseMessage.conversationId && isNewConversation) - conversationUpdate = { - ...conversationUpdate, - conversationId: conversationId, - newConversationId: responseMessage.conversationId || conversationId - }; - conversationId = responseMessage.conversationId || conversationId; + let conversationUpdate = { conversationId: newConversationId, endpoint: 'bingAI' }; + if (conversationId != newConversationId) + if (isNewConversation) { + // change the conversationId to new one + conversationUpdate = { + ...conversationUpdate, + conversationId: conversationId, + newConversationId: newConversationId + }; + } else { + // create new conversation + conversationUpdate = { + ...conversationUpdate, + ...endpointOption + }; + } if (endpointOption?.jailbreak) { conversationUpdate.jailbreak = true; @@ -179,17 +179,16 @@ const ask = async ({ } await saveConvo(req?.session?.user?.username, conversationUpdate); + conversationId = newConversationId; // STEP3 update the user message - userMessage.conversationId = conversationId; - userMessage.messageId = responseMessage.parentMessageId; + userMessage.conversationId = newConversationId; + userMessage.messageId = newUserMassageId; // If response has parentMessageId, the fake userMessage.messageId should be updated to the real one. - if (!overrideParentMessageId) { - const oldUserMessageId = userMessageId; - await saveMessage({ ...userMessage, messageId: oldUserMessageId, newMessageId: userMessage.messageId }); - } - userMessageId = userMessage.messageId; + if (!overrideParentMessageId) + await saveMessage({ ...userMessage, messageId: userMessageId, newMessageId: newUserMassageId }); + userMessageId = newUserMassageId; sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), diff --git a/api/server/routes/ask/askChatGPTBrowser.js b/api/server/routes/ask/askChatGPTBrowser.js index d9d2909de9..84e2e75a07 100644 --- a/api/server/routes/ask/askChatGPTBrowser.js +++ b/api/server/routes/ask/askChatGPTBrowser.js @@ -33,7 +33,7 @@ router.post('/', async (req, res) => { // build endpoint option const endpointOption = { - model: req.body?.model || 'text-davinci-002-render-sha' + model: req.body?.model ?? 'text-davinci-002-render-sha' }; const availableModels = getChatGPTBrowserModels(); @@ -106,13 +106,17 @@ const ask = async ({ console.log('CLIENT RESPONSE', response); + const newConversationId = response.conversationId || conversationId; + const newUserMassageId = response.parentMessageId || userMessageId; + const newResponseMessageId = response.messageId; + // STEP1 generate response message response.text = response.response || '**ChatGPT refused to answer.**'; let responseMessage = { - conversationId: response.conversationId, - messageId: response.messageId, - parentMessageId: overrideParentMessageId || response.parentMessageId || userMessageId, + conversationId: newConversationId, + messageId: newResponseMessageId, + parentMessageId: overrideParentMessageId || newUserMassageId, text: await handleText(response), sender: endpointOption?.chatGptLabel || 'ChatGPT' }; @@ -122,27 +126,34 @@ const ask = async ({ // STEP2 update the conversation // First update conversationId if needed - let conversationUpdate = { conversationId, endpoint: 'chatGPTBrowser' }; - if (conversationId != responseMessage.conversationId && isNewConversation) - conversationUpdate = { - ...conversationUpdate, - conversationId: conversationId, - newConversationId: responseMessage.conversationId || conversationId - }; - conversationId = responseMessage.conversationId || conversationId; + let conversationUpdate = { conversationId: newConversationId, endpoint: 'chatGPTBrowser' }; + if (conversationId != newConversationId) + if (isNewConversation) { + // change the conversationId to new one + conversationUpdate = { + ...conversationUpdate, + conversationId: conversationId, + newConversationId: newConversationId + }; + } else { + // create new conversation + conversationUpdate = { + ...conversationUpdate, + ...endpointOption + }; + } await saveConvo(req?.session?.user?.username, conversationUpdate); + conversationId = newConversationId; // STEP3 update the user message - userMessage.conversationId = conversationId; - userMessage.messageId = responseMessage.parentMessageId; + userMessage.conversationId = newConversationId; + userMessage.messageId = newUserMassageId; // If response has parentMessageId, the fake userMessage.messageId should be updated to the real one. - if (!overrideParentMessageId) { - const oldUserMessageId = userMessageId; - await saveMessage({ ...userMessage, messageId: oldUserMessageId, newMessageId: userMessage.messageId }); - } - userMessageId = userMessage.messageId; + if (!overrideParentMessageId) + await saveMessage({ ...userMessage, messageId: userMessageId, newMessageId: newUserMassageId }); + userMessageId = newUserMassageId; sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), diff --git a/api/server/routes/ask/askOpenAI.js b/api/server/routes/ask/askOpenAI.js index e44a059090..9c5d121639 100644 --- a/api/server/routes/ask/askOpenAI.js +++ b/api/server/routes/ask/askOpenAI.js @@ -19,6 +19,7 @@ router.post('/', async (req, res) => { // build user message const conversationId = oldConversationId || crypto.randomUUID(); + const isNewConversation = !oldConversationId; const userMessageId = crypto.randomUUID(); const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000'; const userMessage = { @@ -32,13 +33,13 @@ router.post('/', async (req, res) => { // build endpoint option const endpointOption = { - model: req.body?.model || 'gpt-3.5-turbo', - chatGptLabel: req.body?.chatGptLabel || null, - promptPrefix: req.body?.promptPrefix || null, - temperature: req.body?.temperature || 1, - top_p: req.body?.top_p || 1, - presence_penalty: req.body?.presence_penalty || 0, - frequency_penalty: req.body?.frequency_penalty || 0 + model: req.body?.model ?? 'gpt-3.5-turbo', + chatGptLabel: req.body?.chatGptLabel ?? null, + promptPrefix: req.body?.promptPrefix ?? null, + temperature: req.body?.temperature ?? 1, + top_p: req.body?.top_p ?? 1, + presence_penalty: req.body?.presence_penalty ?? 0, + frequency_penalty: req.body?.frequency_penalty ?? 0 }; const availableModels = getOpenAIModels(); @@ -63,6 +64,7 @@ router.post('/', async (req, res) => { // eslint-disable-next-line no-use-before-define return await ask({ + isNewConversation, userMessage, endpointOption, conversationId, @@ -74,6 +76,7 @@ router.post('/', async (req, res) => { }); const ask = async ({ + isNewConversation, userMessage, endpointOption, conversationId, @@ -84,8 +87,6 @@ const ask = async ({ }) => { let { text, parentMessageId: userParentMessageId, messageId: userMessageId } = userMessage; - const client = askClient; - res.writeHead(200, { Connection: 'keep-alive', 'Content-Type': 'text/event-stream', @@ -100,7 +101,7 @@ const ask = async ({ const progressCallback = createOnProgress(); const abortController = new AbortController(); res.on('close', () => abortController.abort()); - let response = await client({ + let response = await askClient({ text, parentMessageId: userParentMessageId, conversationId, @@ -115,13 +116,17 @@ const ask = async ({ console.log('CLIENT RESPONSE', response); + const newConversationId = response.conversationId || conversationId; + const newUserMassageId = response.parentMessageId || userMessageId; + const newResponseMessageId = response.messageId; + // STEP1 generate response message response.text = response.response || '**ChatGPT refused to answer.**'; let responseMessage = { - conversationId: response.conversationId, - messageId: response.messageId, - parentMessageId: overrideParentMessageId || userMessageId, + conversationId: newConversationId, + messageId: newResponseMessageId, + parentMessageId: overrideParentMessageId || newUserMassageId, text: await handleText(response), sender: endpointOption?.chatGptLabel || 'ChatGPT' }; @@ -129,21 +134,34 @@ const ask = async ({ await saveMessage(responseMessage); // STEP2 update the conversation - conversationId = responseMessage.conversationId || conversationId; - // it seems openAI will not change the conversationId. - // let conversationUpdate = { conversationId, endpoint: 'openAI' }; - // await saveConvo(req?.session?.user?.username, conversationUpdate); + let conversationUpdate = { conversationId: newConversationId, endpoint: 'openAI' }; + if (conversationId != newConversationId) + if (isNewConversation) { + // change the conversationId to new one + conversationUpdate = { + ...conversationUpdate, + conversationId: conversationId, + newConversationId: newConversationId + }; + } else { + // create new conversation + conversationUpdate = { + ...conversationUpdate, + ...endpointOption + }; + } + + await saveConvo(req?.session?.user?.username, conversationUpdate); + conversationId = newConversationId; // STEP3 update the user message - userMessage.conversationId = conversationId; - userMessage.messageId = responseMessage.parentMessageId; + userMessage.conversationId = newConversationId; + userMessage.messageId = newUserMassageId; // If response has parentMessageId, the fake userMessage.messageId should be updated to the real one. - if (!overrideParentMessageId) { - const oldUserMessageId = userMessageId; - await saveMessage({ ...userMessage, messageId: oldUserMessageId, newMessageId: userMessage.messageId }); - } - userMessageId = userMessage.messageId; + if (!overrideParentMessageId) + await saveMessage({ ...userMessage, messageId: userMessageId, newMessageId: newUserMassageId }); + userMessageId = newUserMassageId; sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), diff --git a/client/src/store/conversation.js b/client/src/store/conversation.js index 06520b2751..79433f7d5a 100644 --- a/client/src/store/conversation.js +++ b/client/src/store/conversation.js @@ -2,6 +2,7 @@ import endpoints from './endpoints'; import { atom, selector, useSetRecoilState, useResetRecoilState, useRecoilCallback } from 'recoil'; import buildTree from '~/utils/buildTree'; import getDefaultConversation from '~/utils/getDefaultConversation'; +import submission from './submission.js'; // current conversation, can be null (need to be fetched from server) // sample structure @@ -59,6 +60,7 @@ const latestMessage = atom({ const useConversation = () => { const setConversation = useSetRecoilState(conversation); const setMessages = useSetRecoilState(messages); + const setSubmission = useSetRecoilState(submission.submission); const resetLatestMessage = useResetRecoilState(latestMessage); const switchToConversation = useRecoilCallback( @@ -93,6 +95,7 @@ const useConversation = () => { setConversation(conversation); setMessages(messages); + setSubmission({}); resetLatestMessage(); };