Skip to content

Commit

Permalink
added chatGPT error handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
kholmogorov27 committed Mar 13, 2023
1 parent 6a48a01 commit a7bd9fd
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 30 deletions.
94 changes: 67 additions & 27 deletions src/chatGPT/createCompletion.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,37 @@ const PARAMS = {
// frequency_penalty: 1.0,
}

function createCompletion(stateSetter, messages, temperature, key, endCallback) {
function createCompletion(stateSetter, messages, temperature, key) {
const controller = new AbortController()

fetch(API_URL, {
signal: controller.signal,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + String(key)
},
body: JSON.stringify({ ...PARAMS, messages, temperature })
}).then(result => {
fetchStream(result.body, stateSetter).then(content => endCallback({ content, role: 'assistant' }))
return ({
controller,
promise: new Promise((resolve, reject) => {
fetch(API_URL, {
signal: controller.signal,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + String(key)
},
body: JSON.stringify({ ...PARAMS, messages, temperature })
})
.then(result => {
fetchStream(
result.body,
result.ok ? dataParser(stateSetter) : errorParser)
.then(content => {
result.ok
? resolve({ content, role: 'assistant' })
: reject(content)
})
})
})
})

return controller
}

function fetchStream(stream, stateSetter) {
let content = ''
function fetchStream(stream, parser) {
let content = null
const reader = stream.getReader()

// read() returns a promise that resolves
Expand All @@ -39,23 +50,52 @@ function fetchStream(stream, stateSetter) {
if (done)
return content

for (const entry of new TextDecoder('utf-8').decode(value).split('\n'))
if (entry) {
const text = entry.slice(entry.indexOf(':') + 2)
let response
try {
response = JSON.parse(text)
} catch (error) { /* pass */ }

if (response && response.choices[0].delta.content)
content += response.choices[0].delta.content
stateSetter(content)
}
const decoded = new TextDecoder('utf-8').decode(value)
console.log(decoded)

content = parser(decoded, content)

return reader.read().then(processText)
}
)
}

function dataParser(stateSetter) {
return (data, acc) => {
for (const entry of data.split('\n'))
if (entry) {
const text = entry.slice(entry.indexOf(':') + 2)
let response
try {
response = JSON.parse(text)
} catch (error) { /* pass */ }

if (response && typeof response.choices[0].delta.content === 'string') {
if (typeof acc === 'string')
acc += response.choices[0].delta.content
else
acc = response.choices[0].delta.content

stateSetter(acc)
}
}

return acc
}
}

function errorParser(data, acc) {
const parsed = JSON.parse(data)
if (!acc)
acc = {}

acc.code = parsed.error.code
if (typeof acc.message === 'string')
acc.message += parsed.error.message
else
acc.message = parsed.error.message

return acc
}

export default createCompletion
10 changes: 7 additions & 3 deletions src/components/AIcompletion/AIcompletion.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ function AIcompletion({ query, className }) {
const currentQuery = { content: query, role: 'user' }
const messages = [getAiConfigMessage(language), ...chatLogRef.current, currentQuery ]

controller = createCompletion(
const completionRequest = createCompletion(
setCompletion,
messages,
temperature,
apiKey,
result => chatLogRef.current.push(currentQuery, result)
apiKey
)
completionRequest.promise
.then(result => chatLogRef.current.push(currentQuery, result))
.catch(error => setCompletion(`## ⚠️ ${error.code || 'error'} \n \`\`\`${error.message || 'No description available ☹️'}\`\`\``))

controller = completionRequest.controller
}
else
setCompletion('')
Expand Down

0 comments on commit a7bd9fd

Please sign in to comment.