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 c8313efd68..3ce95ea1d6 100644 --- a/api/server/routes/ask.js +++ b/api/server/routes/ask.js @@ -90,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 }), @@ -98,7 +106,8 @@ const ask = async ({ conversationId, ...convo }, - ...convo + ...convo, + abortController }); console.log('CLIENT RESPONSE', gptResponse); diff --git a/api/server/routes/askBing.js b/api/server/routes/askBing.js index 007aba779b..bff342ca3e 100644 --- a/api/server/routes/askBing.js +++ b/api/server/routes/askBing.js @@ -84,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, { @@ -95,7 +103,8 @@ const ask = async ({ ...convo, parentMessageId: userParentMessageId, conversationId - } + }, + abortController }); console.log('BING RESPONSE', response); diff --git a/api/server/routes/askSydney.js b/api/server/routes/askSydney.js index 77f95371a0..81a3b2fa20 100644 --- a/api/server/routes/askSydney.js +++ b/api/server/routes/askSydney.js @@ -84,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, { @@ -95,7 +103,8 @@ const ask = async ({ parentMessageId: userParentMessageId, conversationId, ...convo - } + }, + abortController }); console.log('SYDNEY RESPONSE', response); diff --git a/client/src/components/Main/SubmitButton.jsx b/client/src/components/Main/SubmitButton.jsx index 1aa437e26e..79b1634c54 100644 --- a/client/src/components/Main/SubmitButton.jsx +++ b/client/src/components/Main/SubmitButton.jsx @@ -1,8 +1,10 @@ import React from 'react'; import { useSelector } from 'react-redux'; -export default function SubmitButton({ submitMessage }) { - const { isSubmitting, disabled } = useSelector((state) => state.submit); +export default function SubmitButton({ submitMessage, disabled }) { + const { isSubmitting } = useSelector((state) => state.submit); + const { error, latestMessage } = useSelector((state) => state.convo); + const clickHandler = (e) => { e.preventDefault(); submitMessage(); diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index e6bd79c8f0..59b81e7182 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -28,7 +28,9 @@ export default function TextChat({ messages }) { useSelector((state) => state.submit); const { text } = useSelector((state) => state.text); const { error, latestMessage } = convo; - const { ask, regenerate } = useMessageHandler(); + const { ask, regenerate, stopGenerating } = useMessageHandler(); + + const isNotAppendable = (!isSubmitting && latestMessage?.submitting) || latestMessage?.error; // auto focus to input, when enter a conversation. useEffect(() => { @@ -231,6 +233,10 @@ export default function TextChat({ messages }) { regenerate(latestMessage) } + const handleStopGenerating = () => { + stopGenerating() + } + const handleKeyDown = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); @@ -273,31 +279,23 @@ export default function TextChat({ messages }) { e.preventDefault(); dispatch(setError(false)); }; - + isNotAppendable return (
- {error ? ( - - ) : ( - <> - - {(latestMessage&&!latestMessage?.isCreatedByUser)? - isSubmitting? - : + + {isSubmitting? + + :(latestMessage&&!latestMessage?.isCreatedByUser)?