diff --git a/app/chatgpt-client.js b/app/chatgpt-client.js index 27865b808d..3bc629b1d8 100644 --- a/app/chatgpt-client.js +++ b/app/chatgpt-client.js @@ -20,7 +20,7 @@ const davinciOptions = { const askClient = async ({ model, text, progressCallback, convo }) => { // const clientOptions = model === 'chatgpt' ? proxyOptions : davinciOptions; const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default; - const client = new ChatGPTClient(process.env.CHATGPT_TOKEN, davinciOptions, { + const client = new ChatGPTClient(process.env.OPENAI_KEY, davinciOptions, { store: new KeyvFile({ filename: 'cache.json' }) }); let options = { diff --git a/models/Conversation.js b/models/Conversation.js index f7adce638b..5a7f59e909 100644 --- a/models/Conversation.js +++ b/models/Conversation.js @@ -13,17 +13,21 @@ const convoSchema = mongoose.Schema({ }, title: { type: String, - default: 'New conversation', + default: 'New conversation' }, conversationSignature: { - type: String, + type: String }, clientId: { - type: String, + type: String }, invocationId: { - type: String, + type: String }, + model: { + type: String + }, + suggestions: [{ type: String }], messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }], created: { type: Date, @@ -35,10 +39,10 @@ const Conversation = mongoose.models.Conversation || mongoose.model('Conversation', convoSchema); module.exports = { - saveConvo: async ({ conversationId, parentMessageId, title }) => { + saveConvo: async ({ conversationId, title, ...convo }) => { try { const messages = await getMessages({ conversationId }); - const update = { parentMessageId, messages }; + const update = { ...convo, messages }; if (title) { update.title = title; } @@ -55,11 +59,9 @@ module.exports = { }, updateConvo: async ({ conversationId, ...update }) => { try { - return await Conversation.findOneAndUpdate( - { conversationId }, - update, - { new: true } - ).exec(); + return await Conversation.findOneAndUpdate({ conversationId }, update, { + new: true + }).exec(); } catch (error) { console.log(error); return { message: 'Error updating conversation' }; @@ -67,7 +69,6 @@ module.exports = { }, getConvos: async () => await Conversation.find({}).sort({ created: -1 }).exec(), deleteConvos: async (filter) => { - let deleteCount = await Conversation.deleteMany(filter).exec(); deleteCount.messages = await deleteMessages(filter); return deleteCount; diff --git a/models/Message.js b/models/Message.js index d204f22074..50492331d0 100644 --- a/models/Message.js +++ b/models/Message.js @@ -10,9 +10,19 @@ const messageSchema = mongoose.Schema({ type: String, required: true }, + conversationSignature: { + type: String, + // required: true + }, + clientId: { + type: String, + }, + invocationId: { + type: Number, + }, parentMessageId: { type: String, - required: true + // required: true }, sender: { type: String, diff --git a/server/routes/ask.js b/server/routes/ask.js index 1e078ef0ec..c64be8e0ad 100644 --- a/server/routes/ask.js +++ b/server/routes/ask.js @@ -17,7 +17,7 @@ const sendMessage = (res, message) => { }; router.post('/bing', async (req, res) => { - const { model, text, parentMessageId, conversationId } = req.body; + const { model, text, conversationSignature, conversationId } = req.body; if (!text.trim().includes(' ') && text.length < 5) { return handleError(res, 'Prompt empty or too short'); } @@ -25,7 +25,7 @@ router.post('/bing', async (req, res) => { const userMessageId = crypto.randomUUID(); let userMessage = { id: userMessageId, sender: 'User', text }; - console.log('ask log', { model, ...userMessage, parentMessageId, conversationId }); + console.log('ask log', { model, ...userMessage, conversationSignature, conversationId }); res.writeHead(200, { Connection: 'keep-alive', @@ -39,13 +39,13 @@ router.post('/bing', async (req, res) => { let i = 0; let tokens = ''; const progressCallback = async (partial) => { - tokens += partial; - sendMessage(res, { text: tokens, message: true }); + tokens += partial; + sendMessage(res, { text: tokens, message: true }); }; let response = await askBing({ text, - progressCallback, + progressCallback // convo: { // parentMessageId, // conversationId @@ -53,23 +53,13 @@ router.post('/bing', async (req, res) => { }); console.log('CLIENT RESPONSE'); - console.dir(response, {depth: null}); + console.dir(response, { depth: null }); - // if (!parentMessageId) { - // response.title = await titleConvo(text, response.text); - // } - - // if (!response.parentMessageId) { - // response.text = response.response; - // response.id = response.messageId; - // response.parentMessageId = response.messageId; - // userMessage.parentMessageId = parentMessageId ? parentMessageId : response.messageId; - // userMessage.conversationId = conversationId - // ? conversationId - // : response.conversationId; - // await saveMessage(userMessage); - // delete response.response; - // } + userMessage.conversationSignature = + conversationSignature || response.conversationSignature; + userMessage.conversationId = conversationId || response.conversationId; + userMessage.invocationId = response.invocationId; + await saveMessage(userMessage); // if ( // (response.text.includes('2023') && !response.text.trim().includes(' ')) || @@ -79,15 +69,22 @@ router.post('/bing', async (req, res) => { // return handleError(res, 'Prompt empty or too short'); // } - response.sender = 'Bing'; + if (!conversationSignature) { + response.title = await titleConvo(text, response.response); + } + + response.text = response.response; + response.id = response.details.messageId; + response.suggestions = response.details.suggestedResponses.map((s) => s.text); + response.sender = model; response.final = true; - // await saveMessage(response); - // await saveConvo(response); + await saveMessage(response); + await saveConvo(response); sendMessage(res, response); res.end(); } catch (error) { console.log(error); - // await deleteMessages({ id: userMessageId }); + await deleteMessages({ id: userMessageId }); handleError(res, error.message); } }); @@ -143,10 +140,6 @@ router.post('/', async (req, res) => { console.log('CLIENT RESPONSE', gptResponse); - if (!parentMessageId) { - gptResponse.title = await titleConvo(text, gptResponse.text); - } - if (!gptResponse.parentMessageId) { gptResponse.text = gptResponse.response; gptResponse.id = gptResponse.messageId; @@ -167,6 +160,9 @@ router.post('/', async (req, res) => { return handleError(res, 'Prompt empty or too short'); } + if (!parentMessageId) { + gptResponse.title = await titleConvo(text, gptResponse.text); + } gptResponse.sender = model; gptResponse.final = true; await saveMessage(gptResponse); diff --git a/src/store/convoSlice.js b/src/store/convoSlice.js index 89d6b666ec..601575c5cb 100644 --- a/src/store/convoSlice.js +++ b/src/store/convoSlice.js @@ -5,7 +5,9 @@ const initialState = { title: 'ChatGPT Clone', conversationId: null, parentMessageId: null, - // convos: [], + conversationSignature: null, + clientId: null, + invocationId: null, convosLoading: false, };