doomiaichat
Version:
Doomisoft OpenAI
97 lines (95 loc) • 4.16 kB
text/typescript
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 });
})
}
}