perf: bill
This commit is contained in:
@@ -1,13 +1,8 @@
|
||||
import { ChatItemType } from '@/types/chat';
|
||||
import { modelToolMap } from '@/utils/plugin';
|
||||
import type { ChatModelType } from '@/constants/model';
|
||||
import { ChatRoleEnum, sseResponseEventEnum } from '@/constants/chat';
|
||||
import { sseResponse } from '../tools';
|
||||
import { ChatRoleEnum } from '@/constants/chat';
|
||||
import { OpenAiChatEnum } from '@/constants/model';
|
||||
import { chatResponse, openAiStreamResponse } from './openai';
|
||||
import type { NextApiResponse } from 'next';
|
||||
import { textAdaptGptResponse } from '@/utils/adapt';
|
||||
import { parseStreamChunk } from '@/utils/adapt';
|
||||
|
||||
export type ChatCompletionType = {
|
||||
apiKey: string;
|
||||
@@ -36,11 +31,6 @@ export type StreamResponseReturnType = {
|
||||
finishMessages: ChatItemType[];
|
||||
};
|
||||
|
||||
export const modelServiceToolMap = {
|
||||
chatCompletion: chatResponse,
|
||||
streamResponse: openAiStreamResponse
|
||||
};
|
||||
|
||||
/* delete invalid symbol */
|
||||
const simplifyStr = (str = '') =>
|
||||
str
|
||||
@@ -54,7 +44,7 @@ export const ChatContextFilter = ({
|
||||
prompts,
|
||||
maxTokens
|
||||
}: {
|
||||
model: ChatModelType;
|
||||
model: string;
|
||||
prompts: ChatItemType[];
|
||||
maxTokens: number;
|
||||
}) => {
|
||||
@@ -111,126 +101,3 @@ export const ChatContextFilter = ({
|
||||
|
||||
return [...systemPrompts, ...chats];
|
||||
};
|
||||
|
||||
/* stream response */
|
||||
export const resStreamResponse = async ({
|
||||
model,
|
||||
res,
|
||||
chatResponse,
|
||||
prompts
|
||||
}: StreamResponseType & {
|
||||
model: ChatModelType;
|
||||
}) => {
|
||||
// 创建响应流
|
||||
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.setHeader('X-Accel-Buffering', 'no');
|
||||
res.setHeader('Cache-Control', 'no-cache, no-transform');
|
||||
|
||||
const { responseContent, totalTokens, finishMessages } = await modelServiceToolMap.streamResponse(
|
||||
{
|
||||
chatResponse,
|
||||
prompts,
|
||||
res,
|
||||
model
|
||||
}
|
||||
);
|
||||
|
||||
return { responseContent, totalTokens, finishMessages };
|
||||
};
|
||||
|
||||
/* stream response */
|
||||
export const V2_StreamResponse = async ({
|
||||
model,
|
||||
res,
|
||||
chatResponse,
|
||||
prompts
|
||||
}: StreamResponseType & {
|
||||
model: ChatModelType;
|
||||
}) => {
|
||||
let responseContent = '';
|
||||
let error: any = null;
|
||||
let truncateData = '';
|
||||
const clientRes = async (data: string) => {
|
||||
//部分代理会导致流式传输时的数据被截断,不为json格式,这里做一个兼容
|
||||
const { content = '' } = (() => {
|
||||
try {
|
||||
if (truncateData) {
|
||||
try {
|
||||
//判断是否为json,如果是的话直接跳过后续拼装操作,注意极端情况下可能出现截断成3截以上情况也可以兼容
|
||||
JSON.parse(data);
|
||||
} catch (e) {
|
||||
data = truncateData + data;
|
||||
}
|
||||
truncateData = '';
|
||||
}
|
||||
const json = JSON.parse(data);
|
||||
const content: string = json?.choices?.[0].delta.content || '';
|
||||
error = json.error;
|
||||
responseContent += content;
|
||||
return { content };
|
||||
} catch (error) {
|
||||
truncateData = data;
|
||||
return {};
|
||||
}
|
||||
})();
|
||||
|
||||
if (res.closed || error) return;
|
||||
|
||||
if (data === '[DONE]') {
|
||||
sseResponse({
|
||||
res,
|
||||
event: sseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
text: null,
|
||||
finish_reason: 'stop'
|
||||
})
|
||||
});
|
||||
sseResponse({
|
||||
res,
|
||||
event: sseResponseEventEnum.answer,
|
||||
data: '[DONE]'
|
||||
});
|
||||
} else {
|
||||
sseResponse({
|
||||
res,
|
||||
event: sseResponseEventEnum.answer,
|
||||
data: textAdaptGptResponse({
|
||||
text: content
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
for await (const chunk of chatResponse.data as any) {
|
||||
if (res.closed) break;
|
||||
const parse = parseStreamChunk(chunk);
|
||||
parse.forEach((item) => clientRes(item.data));
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('pipe error', error);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.log(error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// count tokens
|
||||
const finishMessages = prompts.concat({
|
||||
obj: ChatRoleEnum.AI,
|
||||
value: responseContent
|
||||
});
|
||||
|
||||
const totalTokens = modelToolMap.countTokens({
|
||||
model,
|
||||
messages: finishMessages
|
||||
});
|
||||
|
||||
return {
|
||||
responseContent,
|
||||
totalTokens,
|
||||
finishMessages
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user