mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-17 22:07:10 +00:00
fix: 2.7 dev start
This commit is contained in:
parent
fbe8953667
commit
4a4dceec18
7 changed files with 5459 additions and 6 deletions
89
utils/openai/fetch-sse.ts
Normal file
89
utils/openai/fetch-sse.ts
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import { createParser } from 'eventsource-parser'
|
||||
|
||||
import * as types from './types'
|
||||
import { fetch as nodefetch } from 'node-fetch'
|
||||
import { streamAsyncIterable } from './stream-async-iterable'
|
||||
|
||||
export async function fetchSSE(
|
||||
url: string,
|
||||
options: Parameters<typeof fetch>[1] & {
|
||||
onMessage: (data: string) => void
|
||||
onError?: (error: any) => void
|
||||
},
|
||||
fetch: types.FetchFn = nodefetch
|
||||
) {
|
||||
const { onMessage, onError, ...fetchOptions } = options
|
||||
const res = await fetch(url, fetchOptions)
|
||||
if (!res.ok) {
|
||||
let reason: string
|
||||
|
||||
try {
|
||||
reason = await res.text()
|
||||
} catch (err) {
|
||||
reason = res.statusText
|
||||
}
|
||||
|
||||
const msg = `ChatGPT error ${res.status}: ${reason}`
|
||||
const error = new types.ChatGPTError(msg, { cause: res })
|
||||
error.statusCode = res.status
|
||||
error.statusText = res.statusText
|
||||
throw error
|
||||
}
|
||||
|
||||
const parser = createParser((event) => {
|
||||
if (event.type === 'event') {
|
||||
onMessage(event.data)
|
||||
}
|
||||
})
|
||||
|
||||
// handle special response errors
|
||||
const feed = (chunk: string) => {
|
||||
let response = null
|
||||
|
||||
try {
|
||||
response = JSON.parse(chunk)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (response?.detail?.type === 'invalid_request_error') {
|
||||
const msg = `ChatGPT error ${response.detail.message}: ${response.detail.code} (${response.detail.type})`
|
||||
const error = new types.ChatGPTError(msg, { cause: response })
|
||||
error.statusCode = response.detail.code
|
||||
error.statusText = response.detail.message
|
||||
|
||||
if (onError) {
|
||||
onError(error)
|
||||
} else {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
// don't feed to the event parser
|
||||
return
|
||||
}
|
||||
|
||||
parser.feed(chunk)
|
||||
}
|
||||
|
||||
if (!res.body.getReader) {
|
||||
// Vercel polyfills `fetch` with `node-fetch`, which doesn't conform to
|
||||
// web standards, so this is a workaround...
|
||||
const body: NodeJS.ReadableStream = res.body as any
|
||||
|
||||
if (!body.on || !body.read) {
|
||||
throw new types.ChatGPTError('unsupported "fetch" implementation')
|
||||
}
|
||||
|
||||
body.on('readable', () => {
|
||||
let chunk: string | Buffer
|
||||
while (null !== (chunk = body.read())) {
|
||||
feed(chunk.toString())
|
||||
}
|
||||
})
|
||||
} else {
|
||||
for await (const chunk of streamAsyncIterable(res.body)) {
|
||||
const str = new TextDecoder().decode(chunk)
|
||||
feed(str)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue