From 7d796f2c3ed34297bc6b5f3e97301f868b720e03 Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Mon, 20 Mar 2023 17:02:37 -0400 Subject: [PATCH] bing hotfix, latest api, uses sydney --- api/app/clients/bingai.js | 2 +- api/app/clients/sydney.js | 2 +- api/models/Message.js | 17 +++++++++++++++ api/models/index.js | 3 ++- api/server/routes/askBing.js | 26 ++++++++++++---------- api/server/routes/askSydney.js | 29 +++++++++++++------------ client/src/components/Main/TextChat.jsx | 4 ++-- client/src/store/convoSlice.js | 8 ++++++- 8 files changed, 59 insertions(+), 32 deletions(-) diff --git a/api/app/clients/bingai.js b/api/app/clients/bingai.js index dcf150d1cf..2e7f80e0b0 100644 --- a/api/app/clients/bingai.js +++ b/api/app/clients/bingai.js @@ -2,7 +2,7 @@ require('dotenv').config(); const { KeyvFile } = require('keyv-file'); const askBing = async ({ text, onProgress, convo }) => { - const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api')); + const { BingAIClient } = (await import('chatgpt-latest')); const bingAIClient = new BingAIClient({ // "_U" cookie from bing.com diff --git a/api/app/clients/sydney.js b/api/app/clients/sydney.js index 3466f71c17..2ecc064378 100644 --- a/api/app/clients/sydney.js +++ b/api/app/clients/sydney.js @@ -2,7 +2,7 @@ require('dotenv').config(); const { KeyvFile } = require('keyv-file'); const askSydney = async ({ text, onProgress, convo }) => { - const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api')); + const { BingAIClient } = (await import('chatgpt-latest')); const sydneyClient = new BingAIClient({ // "_U" cookie from bing.com diff --git a/api/models/Message.js b/api/models/Message.js index 288a03ee7e..cb6c531291 100644 --- a/api/models/Message.js +++ b/api/models/Message.js @@ -83,6 +83,23 @@ module.exports = { return { message: 'Error saving message' }; } }, + saveBingMessage: async ({ messageId, oldMessageId = messageId, conversationId, parentMessageId, sender, text, isCreatedByUser=false, error }) => { + try { + await Message.findOneAndUpdate({ messageId: oldMessageId }, { + messageId, + conversationId, + parentMessageId, + sender, + text, + isCreatedByUser, + error + }, { upsert: true, new: true }); + return { messageId, conversationId, parentMessageId, sender, text, isCreatedByUser }; + } catch (error) { + console.error(error); + return { message: 'Error saving message' }; + } + }, deleteMessagesSince: async ({ messageId, conversationId }) => { try { const message = await Message.findOne({ messageId }).exec() diff --git a/api/models/index.js b/api/models/index.js index d9c5dc8e9d..f0672134a9 100644 --- a/api/models/index.js +++ b/api/models/index.js @@ -1,10 +1,11 @@ -const { getMessages, saveMessage, deleteMessagesSince, deleteMessages } = require('./Message'); +const { getMessages, saveMessage, saveBingMessage, deleteMessagesSince, deleteMessages } = require('./Message'); const { getCustomGpts, updateCustomGpt, updateByLabel, deleteCustomGpts } = require('./CustomGpt'); const { getConvoTitle, getConvo, saveConvo } = require('./Conversation'); module.exports = { getMessages, saveMessage, + saveBingMessage, deleteMessagesSince, deleteMessages, getConvoTitle, diff --git a/api/server/routes/askBing.js b/api/server/routes/askBing.js index ca23d8f6f5..56a8570456 100644 --- a/api/server/routes/askBing.js +++ b/api/server/routes/askBing.js @@ -2,7 +2,7 @@ const express = require('express'); const crypto = require('crypto'); const router = express.Router(); const { titleConvo, askBing } = require('../../app/'); -const { saveMessage, getConvoTitle, saveConvo } = require('../../models'); +const { saveBingMessage, getConvoTitle, saveConvo } = require('../../models'); const { handleError, sendMessage, createOnProgress, handleText } = require('./handlers'); router.post('/', async (req, res) => { @@ -21,7 +21,7 @@ router.post('/', async (req, res) => { const conversationId = oldConversationId || crypto.randomUUID(); const isNewConversation = !oldConversationId; - const userMessageId = crypto.randomUUID(); + const userMessageId = convo.messageId; const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000'; let userMessage = { messageId: userMessageId, @@ -34,13 +34,13 @@ router.post('/', async (req, res) => { console.log('ask log', { model, - ...userMessage, - ...convo + ...convo, + ...userMessage }); if (!overrideParentMessageId) { - await saveMessage(userMessage); - await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + await saveBingMessage(userMessage); + await saveConvo(req?.session?.user?.username, { model, ...convo, ...userMessage }); } return await ask({ @@ -114,8 +114,9 @@ const ask = async ({ convo.conversationSignature || response.conversationSignature; userMessage.conversationId = response.conversationId || conversationId; userMessage.invocationId = response.invocationId; + userMessage.messageId = response.details.requestId || userMessageId; if (!overrideParentMessageId) - await saveMessage(userMessage); + await saveBingMessage({ oldMessageId: userMessageId, ...userMessage }); // Bing API will not use our conversationId at the first time, // so change the placeholder conversationId to the real one. @@ -140,13 +141,14 @@ const ask = async ({ response.sender = model; // response.final = true; + response.messageId = response.details.messageId; // override the parentMessageId, for the regeneration. response.parentMessageId = - overrideParentMessageId || response.parentMessageId || userMessageId; + overrideParentMessageId || response.details.requestId || userMessageId; response.text = await handleText(response, true); - await saveMessage(response); - await saveConvo(req?.session?.user?.username, { ...response, model, chatGptLabel: null, promptPrefix: null, ...convo }); + await saveBingMessage(response); + await saveConvo(req?.session?.user?.username, { model, chatGptLabel: null, promptPrefix: null, ...convo, ...response }); sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), @@ -178,9 +180,9 @@ const ask = async ({ error: true, text: error.message }; - await saveMessage(errorMessage); + await saveBingMessage(errorMessage); handleError(res, errorMessage); } }; -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/api/server/routes/askSydney.js b/api/server/routes/askSydney.js index 49ebf36468..7d117cd748 100644 --- a/api/server/routes/askSydney.js +++ b/api/server/routes/askSydney.js @@ -2,7 +2,7 @@ const express = require('express'); const crypto = require('crypto'); const router = express.Router(); const { titleConvo, askSydney } = require('../../app/'); -const { saveMessage, saveConvo, getConvoTitle } = require('../../models'); +const { saveBingMessage, saveConvo, getConvoTitle } = require('../../models'); const { handleError, sendMessage, createOnProgress, handleText } = require('./handlers'); router.post('/', async (req, res) => { @@ -21,7 +21,7 @@ router.post('/', async (req, res) => { const conversationId = oldConversationId || crypto.randomUUID(); const isNewConversation = !oldConversationId; - const userMessageId = crypto.randomUUID(); + const userMessageId = convo.messageId; const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000'; let userMessage = { messageId: userMessageId, @@ -34,13 +34,13 @@ router.post('/', async (req, res) => { console.log('ask log', { model, - ...userMessage, - ...convo + ...convo, + ...userMessage }); if (!overrideParentMessageId) { - await saveMessage(userMessage); - await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + await saveBingMessage(userMessage); + await saveConvo(req?.session?.user?.username, { model, ...convo, ...userMessage }); } return await ask({ @@ -100,9 +100,9 @@ const ask = async ({ parentMessageId: overrideParentMessageId || userMessageId }), convo: { + ...convo, parentMessageId: userParentMessageId, - conversationId, - ...convo + conversationId }, abortController }); @@ -114,9 +114,10 @@ const ask = async ({ convo.conversationSignature || response.conversationSignature; userMessage.conversationId = response.conversationId || conversationId; userMessage.invocationId = response.invocationId; + userMessage.messageId = response.parentMessageId || userMessageId; // Unlike gpt and bing, Sydney will never accept our given userMessage.messageId, it will generate its own one. if (!overrideParentMessageId) - await saveMessage(userMessage); + await saveBingMessage({ oldMessageId: userMessageId, ...userMessage }); // Save sydney response // response.id = response.messageId; @@ -140,7 +141,7 @@ const ask = async ({ // Save user message userMessage.conversationId = response.conversationId || conversationId; if (!overrideParentMessageId) - await saveMessage(userMessage); + await saveBingMessage(userMessage); // Bing API will not use our conversationId at the first time, // so change the placeholder conversationId to the real one. @@ -158,8 +159,8 @@ const ask = async ({ response.text = await handleText(response, true); // Save sydney response & convo, then send - await saveMessage(response); - await saveConvo(req?.session?.user?.username, { ...response, model, chatGptLabel: null, promptPrefix: null, ...convo }); + await saveBingMessage(response); + await saveConvo(req?.session?.user?.username, { model, chatGptLabel: null, promptPrefix: null, ...convo, ...response }); sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), @@ -191,9 +192,9 @@ const ask = async ({ error: true, text: error.message }; - await saveMessage(errorMessage); + await saveBingMessage(errorMessage); handleError(res, errorMessage); } }; -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index d4f7392266..bd6fb3458a 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -160,12 +160,12 @@ export default function TextChat({ messages }) { } else if (model === 'bingai') { console.log('Bing data:', data); const { title } = data; - const { conversationSignature, clientId, conversationId, invocationId } = + const { conversationSignature, clientId, conversationId, invocationId, parentMessageId } = responseMessage; dispatch( setConversation({ title, - parentMessageId: null, + parentMessageId, conversationSignature, clientId, conversationId, diff --git a/client/src/store/convoSlice.js b/client/src/store/convoSlice.js index 2d84e05b38..f0c5de2042 100644 --- a/client/src/store/convoSlice.js +++ b/client/src/store/convoSlice.js @@ -28,7 +28,13 @@ const currentSlice = createSlice({ state.refreshConvoHint = state.refreshConvoHint + 1; }, setConversation: (state, action) => { - return { ...state, ...action.payload }; + // return { ...state, ...action.payload }; + + for (const key in action.payload) { + if (Object.hasOwnProperty.call(action.payload, key)) { + state[key] = action.payload[key]; + } + } }, setError: (state, action) => { state.error = action.payload;