diff --git a/api/app/chatgpt-browser.js b/api/app/chatgpt-browser.js index a5bea22729..792f108e7d 100644 --- a/api/app/chatgpt-browser.js +++ b/api/app/chatgpt-browser.js @@ -10,7 +10,7 @@ const clientOptions = { proxy: process.env.PROXY || null, }; -const browserClient = async ({ text, onProgress, convo }) => { +const browserClient = async ({ text, onProgress, convo, abortController }) => { const { ChatGPTBrowserClient } = await import('@waylaidwanderer/chatgpt-api'); const store = { @@ -18,7 +18,7 @@ const browserClient = async ({ text, onProgress, convo }) => { }; const client = new ChatGPTBrowserClient(clientOptions, store); - let options = { onProgress }; + let options = { onProgress, abortController }; if (!!convo.parentMessageId && !!convo.conversationId) { options = { ...options, ...convo }; diff --git a/api/app/chatgpt-client.js b/api/app/chatgpt-client.js index 350d1210ce..04368e85bd 100644 --- a/api/app/chatgpt-client.js +++ b/api/app/chatgpt-client.js @@ -9,14 +9,14 @@ const clientOptions = { debug: false }; -const askClient = async ({ text, onProgress, convo }) => { +const askClient = async ({ text, onProgress, convo, abortController }) => { const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default; const store = { store: new KeyvFile({ filename: './data/cache.json' }) }; const client = new ChatGPTClient(process.env.OPENAI_KEY, clientOptions, store); - let options = { onProgress }; + let options = { onProgress, abortController }; if (!!convo.parentMessageId && !!convo.conversationId) { options = { ...options, ...convo }; diff --git a/api/app/chatgpt-custom.js b/api/app/chatgpt-custom.js index e7a0ee0503..a1c797e31d 100644 --- a/api/app/chatgpt-custom.js +++ b/api/app/chatgpt-custom.js @@ -9,7 +9,7 @@ const clientOptions = { debug: false }; -const customClient = async ({ text, onProgress, convo, promptPrefix, chatGptLabel }) => { +const customClient = async ({ text, onProgress, convo, promptPrefix, chatGptLabel, abortController }) => { const ChatGPTClient = (await import('@waylaidwanderer/chatgpt-api')).default; const store = { store: new KeyvFile({ filename: './data/cache.json' }) @@ -23,7 +23,7 @@ const customClient = async ({ text, onProgress, convo, promptPrefix, chatGptLabe const client = new ChatGPTClient(process.env.OPENAI_KEY, clientOptions, store); - let options = { onProgress }; + let options = { onProgress, abortController }; if (!!convo.parentMessageId && !!convo.conversationId) { options = { ...options, ...convo }; } diff --git a/api/server/routes/ask.js b/api/server/routes/ask.js index f016a49b30..3ce95ea1d6 100644 --- a/api/server/routes/ask.js +++ b/api/server/routes/ask.js @@ -12,7 +12,7 @@ router.use('/bing', askBing); router.use('/sydney', askSydney); router.post('/', async (req, res) => { - let { model, text, parentMessageId, conversationId: oldConversationId, ...convo } = req.body; + let { model, text, overrideParentMessageId=null, parentMessageId, conversationId: oldConversationId, ...convo } = req.body; if (text.length === 0) { return handleError(res, { text: 'Prompt empty or too short' }); } @@ -36,51 +36,22 @@ router.post('/', async (req, res) => { ...convo }); - await saveMessage(userMessage); - await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + if (!overrideParentMessageId) { + await saveMessage(userMessage); + await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + } return await ask({ userMessage, model, convo, preSendRequest: true, + overrideParentMessageId, req, res }); }); -router.post('/regenerate', async (req, res) => { - const { model } = req.body; - - const oldUserMessage = await getMessages({ messageId: req.body }); - - if (oldUserMessage) { - const convo = await getConvo(userMessage?.conversationId); - - const userMessageId = crypto.randomUUID(); - - let userMessage = { - ...userMessage, - messageId: userMessageId - }; - - console.log('ask log for regeneration', { - model, - ...userMessage, - ...convo - }); - - return await ask({ - userMessage, - model, - convo, - preSendRequest: false, - req, - res - }); - } else return handleError(res, { text: 'Parent message not found' }); -}); - const ask = async ({ userMessage, overrideParentMessageId = null, @@ -119,6 +90,14 @@ const ask = async ({ try { const progressCallback = createOnProgress(); + + const abortController = new AbortController(); + res.on('close', () => { + console.log('The client has disconnected.'); + // 执行其他操作 + abortController.abort(); + }) + let gptResponse = await client({ text, onProgress: progressCallback.call(null, model, { res, text }), @@ -127,7 +106,8 @@ const ask = async ({ conversationId, ...convo }, - ...convo + ...convo, + abortController }); console.log('CLIENT RESPONSE', gptResponse); @@ -136,10 +116,10 @@ const ask = async ({ gptResponse.text = gptResponse.response; // gptResponse.id = gptResponse.messageId; gptResponse.parentMessageId = overrideParentMessageId || userMessageId; - userMessage.conversationId = conversationId - ? conversationId - : gptResponse.conversationId; - await saveMessage(userMessage); + // userMessage.conversationId = conversationId + // ? conversationId + // : gptResponse.conversationId; + // await saveMessage(userMessage); delete gptResponse.response; } diff --git a/api/server/routes/askBing.js b/api/server/routes/askBing.js index 18a08c4135..ca23d8f6f5 100644 --- a/api/server/routes/askBing.js +++ b/api/server/routes/askBing.js @@ -9,6 +9,7 @@ router.post('/', async (req, res) => { const { model, text, + overrideParentMessageId=null, parentMessageId, conversationId: oldConversationId, ...convo @@ -37,8 +38,10 @@ router.post('/', async (req, res) => { ...convo }); - await saveMessage(userMessage); - await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + if (!overrideParentMessageId) { + await saveMessage(userMessage); + await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + } return await ask({ isNewConversation, @@ -46,6 +49,7 @@ router.post('/', async (req, res) => { model, convo, preSendRequest: true, + overrideParentMessageId, req, res }); @@ -80,6 +84,14 @@ const ask = async ({ try { const progressCallback = createOnProgress(); + + const abortController = new AbortController(); + res.on('close', () => { + console.log('The client has disconnected.'); + // 执行其他操作 + abortController.abort(); + }) + let response = await askBing({ text, onProgress: progressCallback.call(null, model, { @@ -91,7 +103,8 @@ const ask = async ({ ...convo, parentMessageId: userParentMessageId, conversationId - } + }, + abortController }); console.log('BING RESPONSE', response); @@ -101,7 +114,8 @@ const ask = async ({ convo.conversationSignature || response.conversationSignature; userMessage.conversationId = response.conversationId || conversationId; userMessage.invocationId = response.invocationId; - await saveMessage(userMessage); + if (!overrideParentMessageId) + await saveMessage(userMessage); // Bing API will not use our conversationId at the first time, // so change the placeholder conversationId to the real one. diff --git a/api/server/routes/askSydney.js b/api/server/routes/askSydney.js index c85bd20d52..49ebf36468 100644 --- a/api/server/routes/askSydney.js +++ b/api/server/routes/askSydney.js @@ -9,6 +9,7 @@ router.post('/', async (req, res) => { const { model, text, + overrideParentMessageId=null, parentMessageId, conversationId: oldConversationId, ...convo @@ -37,8 +38,10 @@ router.post('/', async (req, res) => { ...convo }); - await saveMessage(userMessage); - await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + if (!overrideParentMessageId) { + await saveMessage(userMessage); + await saveConvo(req?.session?.user?.username, { ...userMessage, model, ...convo }); + } return await ask({ isNewConversation, @@ -46,6 +49,7 @@ router.post('/', async (req, res) => { model, convo, preSendRequest: true, + overrideParentMessageId, req, res }); @@ -80,6 +84,14 @@ const ask = async ({ try { const progressCallback = createOnProgress(); + + const abortController = new AbortController(); + res.on('close', () => { + console.log('The client has disconnected.'); + // 执行其他操作 + abortController.abort(); + }) + let response = await askSydney({ text, onProgress: progressCallback.call(null, model, { @@ -91,7 +103,8 @@ const ask = async ({ parentMessageId: userParentMessageId, conversationId, ...convo - } + }, + abortController }); console.log('SYDNEY RESPONSE', response); @@ -102,7 +115,8 @@ const ask = async ({ userMessage.conversationId = response.conversationId || conversationId; userMessage.invocationId = response.invocationId; // Unlike gpt and bing, Sydney will never accept our given userMessage.messageId, it will generate its own one. - await saveMessage(userMessage); + if (!overrideParentMessageId) + await saveMessage(userMessage); // Save sydney response // response.id = response.messageId; @@ -125,7 +139,8 @@ const ask = async ({ // Save user message userMessage.conversationId = response.conversationId || conversationId; - await saveMessage(userMessage); + if (!overrideParentMessageId) + await saveMessage(userMessage); // Bing API will not use our conversationId at the first time, // so change the placeholder conversationId to the real one. diff --git a/client/public/index.html b/client/public/index.html index 476480f2f7..8e8c205f6c 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -2,6 +2,7 @@
+