99AI/dist/modules/chatgpt/openai.js
2024-02-04 21:06:59 +08:00

180 lines
8.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTokenCount = exports.sendMessageFromOpenAi = void 0;
const axios_1 = require("axios");
const tiktoken_1 = require("@dqbd/tiktoken");
const common_1 = require("@nestjs/common");
const uuid = require("uuid");
const tokenizer = (0, tiktoken_1.get_encoding)('cl100k_base');
function getFullUrl(proxyUrl) {
const processedUrl = proxyUrl.endsWith('/') ? proxyUrl.slice(0, -1) : proxyUrl;
const baseUrl = processedUrl || 'https://api.openai.com';
return `${baseUrl}/v1/chat/completions`;
}
async function sendMessageFromOpenAi(messagesHistory, inputs, uploadService) {
var _a, _b, _c, _d;
const { onProgress, maxToken, apiKey, model, temperature = 0.8, proxyUrl, prompt } = inputs;
if (model.includes('dall')) {
let result = { text: '', fileInfo: '' };
try {
const options = {
method: 'POST',
url: `${proxyUrl}/v1/images/generations`,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${apiKey}`,
},
data: {
prompt: prompt,
model: model,
response_format: 'b64_json'
},
};
const response = await (0, axios_1.default)(options);
const { b64_json, revised_prompt } = response.data.data[0];
const buffer = Buffer.from(b64_json, 'base64');
let imgUrl = '';
try {
const filename = uuid.v4().slice(0, 10) + '.png';
common_1.Logger.debug(`------> 开始上传图片!!!`, 'MidjourneyService');
const buffer = Buffer.from(b64_json, 'base64');
imgUrl = await uploadService.uploadFile({ filename, buffer });
common_1.Logger.debug(`图片上传成功URL: ${imgUrl}`, 'MidjourneyService');
}
catch (error) {
common_1.Logger.error(`上传图片过程中出现错误: ${error}`, 'MidjourneyService');
}
result.fileInfo = imgUrl;
result.text = revised_prompt;
onProgress && onProgress({ text: result.text });
return result;
}
catch (error) {
const status = ((_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status) || 500;
console.log('openai-draw error: ', JSON.stringify(error), status);
const message = (_d = (_c = (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error) === null || _d === void 0 ? void 0 : _d.message;
if (status === 429) {
result.text = '当前请求已过载、请稍等会儿再试试吧!';
return result;
}
if (status === 400 && message.includes('This request has been blocked by our content filters')) {
result.text = '您的请求已被系统拒绝。您的提示可能存在一些非法的文本。';
return result;
}
if (status === 400 && message.includes('Billing hard limit has been reached')) {
result.text = '当前模型key已被封禁、已冻结当前调用Key、尝试重新对话试试吧';
return result;
}
if (status === 500) {
result.text = '绘制图片失败,请检查你的提示词是否有非法描述!';
return result;
}
if (status === 401) {
result.text = '绘制图片失败,此次绘画被拒绝了!';
return result;
}
result.text = '绘制图片失败,请稍后试试吧!';
return result;
}
}
else {
let result = { text: '' };
const options = {
method: 'POST',
url: getFullUrl(proxyUrl),
responseType: 'stream',
headers: {
'Content-Type': 'application/json',
Accept: "application/json",
Authorization: `Bearer ${apiKey}`,
},
data: {
stream: true,
temperature,
model,
messages: messagesHistory,
},
};
if (model === 'gpt-4-vision-preview') {
options.data.max_tokens = 2048;
}
return new Promise(async (resolve, reject) => {
try {
const response = await (0, axios_1.default)(options);
const stream = response.data;
stream.on('data', (chunk) => {
var _a;
const splitArr = chunk.toString().split('\n\n').filter((line) => line.trim() !== '');
for (const line of splitArr) {
const data = line.replace('data:', '');
let ISEND = false;
try {
ISEND = JSON.parse(data).choices[0].finish_reason === 'stop';
}
catch (error) {
ISEND = false;
}
if (ISEND) {
result.text = result.text.trim();
return result;
}
try {
if (data !== " [DONE]" && data !== "[DONE]" && data != "[DONE] ") {
const parsedData = JSON.parse(data);
if (parsedData.id) {
result.id = parsedData.id;
}
if ((_a = parsedData.choices) === null || _a === void 0 ? void 0 : _a.length) {
const delta = parsedData.choices[0].delta;
result.delta = delta.content;
if (delta === null || delta === void 0 ? void 0 : delta.content)
result.text += delta.content;
if (delta.role) {
result.role = delta.role;
}
result.detail = parsedData;
}
onProgress && onProgress({ text: result.text });
}
}
catch (error) {
console.log('parse Error', data);
}
}
});
let totalText = '';
messagesHistory.forEach(message => {
totalText += message.content + ' ';
});
stream.on('end', () => {
if (result.detail && result.text) {
const promptTokens = getTokenCount(totalText);
const completionTokens = getTokenCount(result.text);
result.detail.usage = {
prompt_tokens: promptTokens,
completion_tokens: completionTokens,
total_tokens: promptTokens + completionTokens,
estimated: true
};
}
return resolve(result);
});
}
catch (error) {
reject(error);
}
});
}
}
exports.sendMessageFromOpenAi = sendMessageFromOpenAi;
function getTokenCount(text) {
if (!text)
return 0;
if (typeof text !== 'string') {
text = String(text);
}
text = text.replace(/<\|endoftext\|>/g, '');
return tokenizer.encode(text).length;
}
exports.getTokenCount = getTokenCount;