mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-18 06:17:06 +00:00
feat: API3支持event stream
This commit is contained in:
parent
cc785261eb
commit
a4d8488a55
2 changed files with 112 additions and 30 deletions
|
|
@ -21,6 +21,7 @@
|
||||||
"puppeteer-extra": "^3.3.6",
|
"puppeteer-extra": "^3.3.6",
|
||||||
"puppeteer-extra-plugin-recaptcha": "^3.6.8",
|
"puppeteer-extra-plugin-recaptcha": "^3.6.8",
|
||||||
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
"puppeteer-extra-plugin-stealth": "^2.11.2",
|
||||||
"sharp": "^0.31.3"
|
"sharp": "^0.31.3",
|
||||||
|
"eventsource-parser": "^1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,16 @@
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import {Config, defaultChatGPTAPI, officialChatGPTAPI} from '../utils/config.js'
|
import { Config, officialChatGPTAPI } from './config.js'
|
||||||
import _ from 'lodash'
|
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
|
import delay from 'delay'
|
||||||
|
import _ from 'lodash'
|
||||||
|
// import { createParser } from 'eventsource-parser'
|
||||||
|
let createParser
|
||||||
|
try {
|
||||||
|
createParser = (await import('eventsource-parser')).createParser
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('未安装eventsource-parser,请在插件目录下执行pnpm i')
|
||||||
|
}
|
||||||
|
|
||||||
let proxy
|
let proxy
|
||||||
if (Config.proxy) {
|
if (Config.proxy) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -87,6 +96,7 @@ export class OfficialChatGPTClient {
|
||||||
}
|
}
|
||||||
const res = await this._fetch(url, option)
|
const res = await this._fetch(url, option)
|
||||||
if (res.status === 403) {
|
if (res.status === 403) {
|
||||||
|
await delay(500)
|
||||||
return await this.sendMessage(prompt, opts)
|
return await this.sendMessage(prompt, opts)
|
||||||
}
|
}
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
|
|
@ -97,7 +107,77 @@ export class OfficialChatGPTClient {
|
||||||
throw new Error(body)
|
throw new Error(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// todo accept as stream
|
if (createParser) {
|
||||||
|
let conversationResponse
|
||||||
|
const responseP = new Promise(
|
||||||
|
// eslint-disable-next-line no-async-promise-executor
|
||||||
|
async (resolve, reject) => {
|
||||||
|
let response
|
||||||
|
function onMessage (data) {
|
||||||
|
if (data === '[DONE]') {
|
||||||
|
return resolve({
|
||||||
|
error: null,
|
||||||
|
response,
|
||||||
|
conversationId,
|
||||||
|
messageId,
|
||||||
|
conversationResponse
|
||||||
|
})
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const _checkJson = JSON.parse(data)
|
||||||
|
} catch (error) {
|
||||||
|
// console.log('warning: parse error.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const convoResponseEvent = JSON.parse(data)
|
||||||
|
conversationResponse = convoResponseEvent
|
||||||
|
if (convoResponseEvent.conversation_id) {
|
||||||
|
conversationId = convoResponseEvent.conversation_id
|
||||||
|
}
|
||||||
|
|
||||||
|
if (convoResponseEvent.message?.id) {
|
||||||
|
messageId = convoResponseEvent.message.id
|
||||||
|
}
|
||||||
|
|
||||||
|
const partialResponse =
|
||||||
|
convoResponseEvent.message?.content?.parts?.[0]
|
||||||
|
if (partialResponse) {
|
||||||
|
if (Config.debug) {
|
||||||
|
logger.info(JSON.stringify(convoResponseEvent))
|
||||||
|
}
|
||||||
|
response = partialResponse
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('fetchSSE onMessage unexpected error', err)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parser = createParser((event) => {
|
||||||
|
if (event.type === 'event') {
|
||||||
|
onMessage(event.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
res.body.on('readable', async () => {
|
||||||
|
logger.mark('成功连接到chat.openai.com,准备读取数据流')
|
||||||
|
let chunk
|
||||||
|
while ((chunk = res.body.read()) !== null) {
|
||||||
|
let str = chunk.toString()
|
||||||
|
parser.feed(str)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
let response = await responseP
|
||||||
|
return {
|
||||||
|
text: response.response,
|
||||||
|
conversationId: response.conversationId,
|
||||||
|
id: response.messageId,
|
||||||
|
parentMessageId
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn('未安装eventsource-parser,强烈建议安装以提高API3响应性能,在插件目录下执行pnpm i或pnpm add -w eventsource-parser')
|
||||||
const decoder = new TextDecoder('utf-8')
|
const decoder = new TextDecoder('utf-8')
|
||||||
const bodyBytes = await res.arrayBuffer()
|
const bodyBytes = await res.arrayBuffer()
|
||||||
const bodyText = decoder.decode(bodyBytes)
|
const bodyText = decoder.decode(bodyBytes)
|
||||||
|
|
@ -112,11 +192,11 @@ export class OfficialChatGPTClient {
|
||||||
fullResponse = tmp
|
fullResponse = tmp
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(event)
|
// console.log(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Config.debug) {
|
if (Config.debug) {
|
||||||
logger.mark(fullResponse)
|
logger.mark(JSON.stringify(fullResponse))
|
||||||
}
|
}
|
||||||
if (!fullResponse?.message) {
|
if (!fullResponse?.message) {
|
||||||
throw new Error(bodyText || 'unkown error, please check log')
|
throw new Error(bodyText || 'unkown error, please check log')
|
||||||
|
|
@ -128,4 +208,5 @@ export class OfficialChatGPTClient {
|
||||||
parentMessageId
|
parentMessageId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue