UNPKG

doomiaichat

Version:

Doomisoft OpenAI

97 lines (95 loc) 4.16 kB
import { ApiResult, OpenAIApiParameters, ProxyPatameters } from './declare'; import OpenAIGpt from './openai'; import axios from 'axios'; const ERROR_RESPONSE: string[] = ['[AUTHORIZATION NEEDED]', '[AUTHORIZATION ERROR]', '[BODY ERROR]','[REQUEST ERROR]'] export default class OpenAIProxy extends OpenAIGpt { protected readonly proxySetting: ProxyPatameters; constructor(apiKey: string, proxyOption: ProxyPatameters, apiOption: OpenAIApiParameters = {}) { super(apiKey, apiOption); this.proxySetting = proxyOption; } /** * 重写chatRequest方法 * @param chatText * @param callChatOption * @param axiosOption */ override async chatRequest(chatText: string | any[], _paramOption: any, axiosOption?: any): Promise<ApiResult> { const opts: any = { headers: { 'Content-Type': 'application/json', 'authorization': `Bearer ${this.apiKey}` }, method: 'post', url: this.proxySetting.serviceurl, data: { chatText, option: _paramOption }, ...axiosOption } const requestResult = await axios(opts); return requestResult.data as ApiResult; } /** * 重写chatRequestInStream方法 * @param chatText * @param callChatOption * @param attach * @param axiosOption */ override async chatRequestInStream(chatText:Array<any>, callChatOption: OpenAIApiParameters, attach?: any, axiosOption?: any): Promise<any> { // const decoder = new TextDecoder(); //overContent, let streamText,requestid = Math.ceil(Math.random() * (new Date().getTime() * Math.random()) / 1000); const opts:any = { headers: { 'Content-Type': 'application/json', 'authorization': `Bearer ${this.apiKey}` }, method: 'post', url: this.proxySetting.serviceurl +'/stream', data: { messages:chatText, option: callChatOption, axiosOption }, responseType: 'stream', } let unCompleteSegment:string = ''; axios(opts) .then(res => { res.data.on('data', (chunk:any) => { streamText = chunk.toString(); //decoder.decode(chunk); if (streamText){ ///请求的响应发生了错误 if (ERROR_RESPONSE.includes(streamText)) { return this.emit('requesterror', { successed: false, requestid, error: 'Request Remote OpenAI Error : ' + streamText }); } const fullData = (unCompleteSegment +streamText).split('*&$') unCompleteSegment = ''; // console.log('fullData', fullData.length); for (const segment of fullData){ if (!segment) continue; try { ////判断接收到的不是一个完整的JSON段了,则该段作为下一次的数据段 if (!segment.endsWith('}')) { unCompleteSegment = segment; break; } const objData = Object.assign(JSON.parse(segment), attach); this.emit(objData.finish_reason?'chatdone':'chattext', objData); } catch (errParse) { break; //this.emit('chaterror', { successed: false, requestid, error: 'JSON parse stream message' + errParse }); } } } return; }); //res.data.on('end', () => { this.emit('chatdone', Object.assign(streamText, attach)); }); }).catch(err=>{ this.emit('requesterror', { successed: false, requestid, error: 'Axios Error : ' + err }); }) } }