fix: chatgptBrowser handling and ask.js refactor

This commit is contained in:
Daniel Avila 2023-03-28 22:28:43 -04:00
parent 005d8fb178
commit 0d7300be9b
4 changed files with 39 additions and 92 deletions

View file

@ -31,6 +31,8 @@ const browserClient = async ({ text, onProgress, convo, abortController }) => {
options = { ...options, ...convo }; options = { ...options, ...convo };
} }
console.log('gptBrowser options', options, clientOptions);
/* will error if given a convoId at the start */ /* will error if given a convoId at the start */
if (convo.parentMessageId.startsWith('0000')) { if (convo.parentMessageId.startsWith('0000')) {
delete options.conversationId; delete options.conversationId;

View file

@ -23,7 +23,7 @@ const titleConvo = async ({ model, text, response }) => {
role: 'system', role: 'system',
content: content:
// `You are a title-generator with one job: giving a conversation, detect the language and titling the conversation provided by a user, using the same language. The requirement are: 1. If possible, generate in 5 words or less, 2. Using title case, 3. must give the title using the language as the user said. 4. Don't refer to the participants of the conversation. 5. Do not include punctuation or quotation marks. 6. Your response should be in title case, exclusively containing the title. 7. don't say anything except the title. // `You are a title-generator with one job: giving a conversation, detect the language and titling the conversation provided by a user, using the same language. The requirement are: 1. If possible, generate in 5 words or less, 2. Using title case, 3. must give the title using the language as the user said. 4. Don't refer to the participants of the conversation. 5. Do not include punctuation or quotation marks. 6. Your response should be in title case, exclusively containing the title. 7. don't say anything except the title.
`Detect user language and write in the same language an extremely concise title for this conversation, which you must accurately detect. Write in the detected language. Title in 5 Words or Less. No Punctuation/Quotation. All words should be capitalized and complete only the title in User Language only. `Detect user language and write in the same language an extremely concise title for this conversation, which you must accurately detect. Write in the detected language. Title in 5 Words or Less. No Punctuation/Quotation. All first letters of every word should be capitalized and complete only the title in User Language only.
||>User: ||>User:
"${text}" "${text}"
@ -38,7 +38,7 @@ const titleConvo = async ({ model, text, response }) => {
// } // }
]; ];
console.log('MESSAGES', messages[0]); // console.log('Title Prompt', messages[0]);
const request = { const request = {
model: 'gpt-3.5-turbo', model: 'gpt-3.5-turbo',

View file

@ -43,9 +43,15 @@ module.exports = {
return { message: 'Error saving conversation' }; return { message: 'Error saving conversation' };
} }
}, },
updateConvo: async (user, { conversationId, ...update }) => { updateConvo: async (user, { conversationId, oldConvoId, ...update }) => {
try { try {
return await Conversation.findOneAndUpdate({ conversationId: conversationId, user }, update, { let convoId = conversationId;
if (oldConvoId) {
convoId = oldConvoId;
update.conversationId = conversationId;
}
return await Conversation.findOneAndUpdate({ conversationId: convoId, user }, update, {
new: true new: true
}).exec(); }).exec();
} catch (error) { } catch (error) {

View file

@ -4,26 +4,27 @@ const router = express.Router();
const askBing = require('./askBing'); const askBing = require('./askBing');
const askSydney = require('./askSydney'); const askSydney = require('./askSydney');
const { titleConvo, askClient, browserClient, customClient } = require('../../app/'); const { titleConvo, askClient, browserClient, customClient } = require('../../app/');
const { getConvo, saveMessage, getConvoTitle, saveConvo, updateConvo } = require('../../models'); const { saveMessage, getConvoTitle, saveConvo, updateConvo } = require('../../models');
const { handleError, sendMessage, createOnProgress, handleText } = require('./handlers'); const { handleError, sendMessage, createOnProgress, handleText } = require('./handlers');
const { getMessages } = require('../../models/Message');
router.use('/bing', askBing); router.use('/bing', askBing);
router.use('/sydney', askSydney); router.use('/sydney', askSydney);
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
let { model, text, overrideParentMessageId=null, parentMessageId, conversationId: oldConversationId, ...convo } = req.body; const {
if (text.length === 0) { model,
return handleError(res, { text: 'Prompt empty or too short' }); text,
} overrideParentMessageId = null,
parentMessageId,
conversationId: oldConversationId,
...convo
} = req.body;
if (text.length === 0) return handleError(res, { text: 'Prompt empty or too short' });
console.log('model:', model, 'oldConvoId:', oldConversationId);
const conversationId = oldConversationId || crypto.randomUUID(); const conversationId = oldConversationId || crypto.randomUUID();
console.log('conversationId after old:', conversationId);
const userMessageId = crypto.randomUUID(); const userMessageId = crypto.randomUUID();
const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000'; const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000';
let userMessage = { const userMessage = {
messageId: userMessageId, messageId: userMessageId,
sender: 'User', sender: 'User',
text, text,
@ -31,32 +32,18 @@ router.post('/', async (req, res) => {
conversationId, conversationId,
isCreatedByUser: true isCreatedByUser: true
}; };
console.log('ask log', { console.log('ask log', {
model, model,
...userMessage, ...userMessage,
...convo ...convo
}); });
// Chore: This creates a loose a stranded initial message for chatgptBrowser
if (!overrideParentMessageId) { if (!overrideParentMessageId) {
await saveMessage(userMessage); await saveMessage(userMessage);
}
if (!overrideParentMessageId && model !== 'chatgptBrowser') {
await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo });
} }
return await ask({ return await ask({ userMessage, model, convo, preSendRequest: true, overrideParentMessageId, req, res });
userMessage,
model,
convo,
preSendRequest: true,
overrideParentMessageId,
req,
res
});
}); });
const ask = async ({ const ask = async ({
@ -68,22 +55,14 @@ const ask = async ({
req, req,
res res
}) => { }) => {
let { const {
text, text,
parentMessageId: userParentMessageId, parentMessageId: userParentMessageId,
conversationId, conversationId,
messageId: userMessageId messageId: userMessageId
} = userMessage; } = userMessage;
let client; const client = model === 'chatgpt' ? askClient : model === 'chatgptCustom' ? customClient : browserClient;
if (model === 'chatgpt') {
client = askClient;
} else if (model === 'chatgptCustom') {
client = customClient;
} else {
client = browserClient;
}
res.writeHead(200, { res.writeHead(200, {
Connection: 'keep-alive', Connection: 'keep-alive',
@ -97,61 +76,27 @@ const ask = async ({
try { try {
const progressCallback = createOnProgress(); const progressCallback = createOnProgress();
const abortController = new AbortController(); const abortController = new AbortController();
res.on('close', () => { res.on('close', () => abortController.abort());
console.log('The client has disconnected.');
// 执行其他操作
abortController.abort();
})
let gptResponse = await client({ let gptResponse = await client({
text, text,
onProgress: progressCallback.call(null, model, { res, text }), onProgress: progressCallback.call(null, model, { res, text }),
convo: { convo: { parentMessageId: userParentMessageId, conversationId, ...convo },
parentMessageId: userParentMessageId,
conversationId,
...convo
},
...convo, ...convo,
abortController abortController
}); });
console.log('CLIENT RESPONSE', gptResponse);
gptResponse.text = gptResponse.response; gptResponse.text = gptResponse.response;
console.log('CLIENT RESPONSE', gptResponse);
if (!gptResponse.parentMessageId) { if (!gptResponse.parentMessageId) {
// gptResponse.id = gptResponse.messageId;
gptResponse.parentMessageId = overrideParentMessageId || userMessageId; gptResponse.parentMessageId = overrideParentMessageId || userMessageId;
// userMessage.conversationId = conversationId
// ? conversationId
// : gptResponse.conversationId;
// await saveMessage(userMessage);
delete gptResponse.response; delete gptResponse.response;
} }
if (
(gptResponse.text.includes('2023') && !gptResponse.text.trim().includes(' ')) ||
gptResponse.text.toLowerCase().includes('no response') ||
gptResponse.text.toLowerCase().includes('no answer')
) {
await saveMessage({
messageId: crypto.randomUUID(),
sender: model,
conversationId,
parentMessageId: overrideParentMessageId || userMessageId,
error: true,
text: 'Prompt empty or too short'
});
return handleError(res, { text: 'Prompt empty or too short' });
}
gptResponse.sender = model === 'chatgptCustom' ? convo.chatGptLabel : model; gptResponse.sender = model === 'chatgptCustom' ? convo.chatGptLabel : model;
gptResponse.model = model; gptResponse.model = model;
// gptResponse.final = true;
gptResponse.text = await handleText(gptResponse); gptResponse.text = await handleText(gptResponse);
if (convo.chatGptLabel?.length > 0 && model === 'chatgptCustom') { if (convo.chatGptLabel?.length > 0 && model === 'chatgptCustom') {
gptResponse.chatGptLabel = convo.chatGptLabel; gptResponse.chatGptLabel = convo.chatGptLabel;
} }
@ -160,16 +105,17 @@ const ask = async ({
gptResponse.promptPrefix = convo.promptPrefix; gptResponse.promptPrefix = convo.promptPrefix;
} }
// override the parentMessageId, for the regeneration.
gptResponse.parentMessageId = overrideParentMessageId || userMessageId; gptResponse.parentMessageId = overrideParentMessageId || userMessageId;
/* this is a hacky solution to get the browserClient working right, will refactor later */
if (model === 'chatgptBrowser' && userParentMessageId.startsWith('000')) { if (model === 'chatgptBrowser' && userParentMessageId.startsWith('000')) {
await saveMessage({ ...userMessage, conversationId: gptResponse.conversationId }); await saveMessage({ ...userMessage, conversationId: gptResponse.conversationId });
} }
await saveMessage(gptResponse); await saveMessage(gptResponse);
await updateConvo(req?.session?.user?.username, gptResponse); await updateConvo(req?.session?.user?.username, {
...gptResponse,
oldConvoId: model === 'chatgptBrowser' && conversationId
});
sendMessage(res, { sendMessage(res, {
title: await getConvoTitle(req?.session?.user?.username, conversationId), title: await getConvoTitle(req?.session?.user?.username, conversationId),
final: true, final: true,
@ -180,19 +126,12 @@ const ask = async ({
if (userParentMessageId == '00000000-0000-0000-0000-000000000000') { if (userParentMessageId == '00000000-0000-0000-0000-000000000000') {
const title = await titleConvo({ model, text, response: gptResponse }); const title = await titleConvo({ model, text, response: gptResponse });
await updateConvo(req?.session?.user?.username, {
await updateConvo(
req?.session?.user?.username,
{
/* again, for sake of browser client, will soon refactor */
conversationId: model === 'chatgptBrowser' ? gptResponse.conversationId : conversationId, conversationId: model === 'chatgptBrowser' ? gptResponse.conversationId : conversationId,
title title
} });
);
} }
} catch (error) { } catch (error) {
console.log(error);
// await deleteMessages({ messageId: userMessageId });
const errorMessage = { const errorMessage = {
messageId: crypto.randomUUID(), messageId: crypto.randomUUID(),
sender: model, sender: model,