Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.

Commit d19c139

Browse files
committed
Fix JSON parsing error
1 parent b8b65c6 commit d19c139

File tree

6 files changed

+93
-42
lines changed

6 files changed

+93
-42
lines changed

src/background/chatgpt.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import { v4 as uuidv4 } from 'uuid'
2+
import { Event } from './event'
3+
import { fetchSSE } from './fetch-sse'
4+
15
async function request(token: string, method: string, path: string, data: unknown) {
26
return fetch(`https://chat.openai.com/backend-api${path}`, {
37
method,
@@ -20,3 +24,59 @@ export async function setConversationProperty(
2024
) {
2125
await request(token, 'PATCH', `/conversation/${conversationId}`, propertyObject)
2226
}
27+
28+
export async function sendMessage(params: {
29+
token: string
30+
prompt: string
31+
onEvent: (event: Event) => void
32+
signal?: AbortSignal
33+
}) {
34+
await fetchSSE('https://chat.openai.com/backend-api/conversation', {
35+
method: 'POST',
36+
signal: params.signal,
37+
headers: {
38+
'Content-Type': 'application/json',
39+
Authorization: `Bearer ${params.token}`,
40+
},
41+
body: JSON.stringify({
42+
action: 'next',
43+
messages: [
44+
{
45+
id: uuidv4(),
46+
role: 'user',
47+
content: {
48+
content_type: 'text',
49+
parts: [params.prompt],
50+
},
51+
},
52+
],
53+
model: 'text-davinci-002-render',
54+
parent_message_id: uuidv4(),
55+
}),
56+
onMessage(message: string) {
57+
console.debug('sse message', message)
58+
if (message === '[DONE]') {
59+
params.onEvent({ type: 'done' })
60+
return
61+
}
62+
let data
63+
try {
64+
data = JSON.parse(message)
65+
} catch (err) {
66+
console.error(err)
67+
return
68+
}
69+
const text = data.message?.content?.parts?.[0]
70+
if (text) {
71+
params.onEvent({
72+
type: 'answer',
73+
data: {
74+
text,
75+
messageId: data.message.id,
76+
conversationId: data.conversation_id,
77+
},
78+
})
79+
}
80+
},
81+
})
82+
}

src/background/event.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Answer } from '../messaging'
2+
3+
export type Event =
4+
| {
5+
type: 'answer'
6+
data: Answer
7+
}
8+
| {
9+
type: 'done'
10+
}

src/background/fetch-sse.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createParser } from 'eventsource-parser'
2+
import { isEmpty } from 'lodash-es'
23
import { streamAsyncIterable } from './stream-async-iterable.js'
34

45
export async function fetchSSE(
@@ -8,8 +9,8 @@ export async function fetchSSE(
89
const { onMessage, ...fetchOptions } = options
910
const resp = await fetch(resource, fetchOptions)
1011
if (!resp.ok) {
11-
const detail = (await resp.json().catch(() => ({}))).detail
12-
throw new Error(detail || `${resp.status} ${resp.statusText}`)
12+
const error = await resp.json().catch(() => ({}))
13+
throw new Error(!isEmpty(error) ? JSON.stringify(error) : `${resp.status} ${resp.statusText}`)
1314
}
1415
const parser = createParser((event) => {
1516
if (event.type === 'event') {

src/background/index.ts

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import ExpiryMap from 'expiry-map'
2-
import { v4 as uuidv4 } from 'uuid'
32
import Browser from 'webextension-polyfill'
4-
import { Answer } from '../messaging.js'
5-
import { sendMessageFeedback, setConversationProperty } from './chatgpt.js'
6-
import { fetchSSE } from './fetch-sse.js'
3+
import { sendMessage, sendMessageFeedback, setConversationProperty } from './chatgpt.js'
74

85
const KEY_ACCESS_TOKEN = 'accessToken'
96

@@ -41,45 +38,18 @@ async function generateAnswers(port: Browser.Runtime.Port, question: string) {
4138
deleteConversation()
4239
})
4340

44-
await fetchSSE('https://chat.openai.com/backend-api/conversation', {
45-
method: 'POST',
41+
await sendMessage({
42+
token: accessToken,
43+
prompt: question,
4644
signal: controller.signal,
47-
headers: {
48-
'Content-Type': 'application/json',
49-
Authorization: `Bearer ${accessToken}`,
50-
},
51-
body: JSON.stringify({
52-
action: 'next',
53-
messages: [
54-
{
55-
id: uuidv4(),
56-
role: 'user',
57-
content: {
58-
content_type: 'text',
59-
parts: [question],
60-
},
61-
},
62-
],
63-
model: 'text-davinci-002-render',
64-
parent_message_id: uuidv4(),
65-
}),
66-
onMessage(message: string) {
67-
console.debug('sse message', message)
68-
if (message === '[DONE]') {
45+
onEvent(event) {
46+
if (event.type === 'done') {
6947
port.postMessage({ event: 'DONE' })
7048
deleteConversation()
7149
return
7250
}
73-
const data = JSON.parse(message)
74-
const text = data.message?.content?.parts?.[0]
75-
conversationId = data.conversation_id
76-
if (text) {
77-
port.postMessage({
78-
text,
79-
messageId: data.message.id,
80-
conversationId: data.conversation_id,
81-
} as Answer)
82-
}
51+
conversationId = event.data.conversationId
52+
port.postMessage(event.data)
8353
},
8454
})
8555
}
@@ -101,5 +71,15 @@ Browser.runtime.onMessage.addListener(async (message) => {
10171
if (message.type === 'FEEDBACK') {
10272
const token = await getAccessToken()
10373
await sendMessageFeedback(token, message.data)
74+
} else if (message.type === 'OPEN_OPTIONS_PAGE') {
75+
Browser.runtime.openOptionsPage()
76+
} else if (message.type === 'GET_ACCESS_TOKEN') {
77+
return getAccessToken()
78+
}
79+
})
80+
81+
Browser.runtime.onInstalled.addListener((details) => {
82+
if (details.reason === 'install') {
83+
Browser.runtime.openOptionsPage()
10484
}
10585
})

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ChatGPT - Jupyter - AI Assistant",
33
"description": "ChatGPT-powered AI assistant for Jupyter Notebooks",
4-
"version": "0.2.3",
4+
"version": "0.3.0",
55
"manifest_version": 3,
66
"icons": {
77
"16": "logo.png",

src/manifest.v2.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ChatGPT - Jupyter - AI Assistant",
33
"description": "ChatGPT-powered AI assistant for Jupyter Notebooks",
4-
"version": "0.2.3",
4+
"version": "0.3.0",
55
"manifest_version": 2,
66
"icons": {
77
"16": "logo.png",

0 commit comments

Comments
 (0)