diff --git a/src/background/apis/chatgpt-web.mjs b/src/background/apis/chatgpt-web.mjs index 0d4de34..ffaee9a 100644 --- a/src/background/apis/chatgpt-web.mjs +++ b/src/background/apis/chatgpt-web.mjs @@ -53,13 +53,24 @@ export async function generateAnswersWithChatgptWebApi(port, question, session, } const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() deleteConversation() }) - const models = await getModels(accessToken).catch(() => {}) + const models = await getModels(accessToken).catch(() => { + port.onMessage.removeListener(stopListener) + }) const config = await getUserConfig() let answer = '' @@ -112,8 +123,12 @@ export async function generateAnswersWithChatgptWebApi(port, question, session, async onStart() { // sendModerations(accessToken, question, session.conversationId, session.messageId) }, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } diff --git a/src/background/apis/openai-api.mjs b/src/background/apis/openai-api.mjs index 1aa5fdc..409cb52 100644 --- a/src/background/apis/openai-api.mjs +++ b/src/background/apis/openai-api.mjs @@ -35,6 +35,15 @@ export async function generateAnswersWithGptCompletionApi( modelName, ) { const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() @@ -79,8 +88,12 @@ export async function generateAnswersWithGptCompletionApi( port.postMessage({ answer: answer, done: false, session: null }) }, async onStart() {}, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } @@ -99,6 +112,15 @@ export async function generateAnswersWithGptCompletionApi( */ export async function generateAnswersWithChatgptApi(port, question, session, apiKey, modelName) { const controller = new AbortController() + const stopListener = (msg) => { + if (msg.stop) { + console.debug('stop generating') + port.postMessage({ done: true }) + controller.abort() + port.onMessage.removeListener(stopListener) + } + } + port.onMessage.addListener(stopListener) port.onDisconnect.addListener(() => { console.debug('port disconnected') controller.abort() @@ -142,8 +164,12 @@ export async function generateAnswersWithChatgptApi(port, question, session, api port.postMessage({ answer: answer, done: false, session: null }) }, async onStart() {}, - async onEnd() {}, + async onEnd() { + port.onMessage.removeListener(stopListener) + }, async onError(resp) { + if (resp instanceof Error) throw resp + port.onMessage.removeListener(stopListener) if (resp.status === 403) { throw new Error('CLOUDFLARE') } diff --git a/src/background/index.mjs b/src/background/index.mjs index 8574be8..bcc8c9d 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -51,8 +51,9 @@ Browser.runtime.onConnect.addListener((port) => { console.debug('connected') port.onMessage.addListener(async (msg) => { console.debug('received msg', msg) - const config = await getUserConfig() const session = msg.session + if (!session) return + const config = await getUserConfig() if (session.useApiKey == null) { session.useApiKey = isUsingApiKey(config) } @@ -84,8 +85,10 @@ Browser.runtime.onConnect.addListener((port) => { } } catch (err) { console.error(err) - port.postMessage({ error: err.message }) - cache.delete(KEY_ACCESS_TOKEN) + if (!err.message.includes('aborted')) { + port.postMessage({ error: err.message }) + cache.delete(KEY_ACCESS_TOKEN) + } } }) }) diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index 7adf2fc..ab31c11 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -223,6 +223,7 @@ function ConversationCard(props) { type={data.type} session={data.session} done={data.done} + port={port} /> ))} diff --git a/src/components/ConversationItem/index.jsx b/src/components/ConversationItem/index.jsx index 0682d14..5896bd4 100644 --- a/src/components/ConversationItem/index.jsx +++ b/src/components/ConversationItem/index.jsx @@ -5,7 +5,7 @@ import CopyButton from '../CopyButton' import PropTypes from 'prop-types' import MarkdownRender from '../MarkdownRender/markdown.jsx' -export function ConversationItem({ type, content, session, done }) { +export function ConversationItem({ type, content, session, done, port }) { const [collapsed, setCollapsed] = useState(false) switch (type) { @@ -36,6 +36,17 @@ export function ConversationItem({ type, content, session, done }) {

{session ? 'ChatGPT:' : 'Loading...'}

+ {!done && ( + + )} {done && session && session.conversationId && ( { + await onError(err) + }) + if (!resp) return if (!resp.ok) { await onError(resp) + return } const parser = createParser((event) => { if (event.type === 'event') {