2024-08-20 10:37:38 +08:00

182 lines
5.3 KiB
TypeScript
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.

import { isEmpty } from "lodash";
import { gptDefine } from "../../../define/gptDefine";
import axios from "axios";
import { RetryWithBackoff } from "../../../define/Tools/common";
/**
* 一些GPT相关的服务都在这边
*/
export class GptService {
gptUrl: string = undefined
gptModel: string = undefined
gptApiKey: string = undefined
//#region GPT 设置
/**
* 获取GPT的所有的服务商
* @param type 获取的类型就是all
* @param callback 这个是个回调函数,干嘛的不知道
* @returns
*/
private async GetGPTBusinessOption(type: string, callback: Function = null): Promise<any> {
let res = await gptDefine.getGptDataByTypeAndProperty(type, "gpt_options", []);
if (res.code == 0) {
throw new Error(res.message)
} else {
if (callback) {
callback(res.data)
}
return res.data
}
}
async RefreshGptSetting() {
let all_options = await this.GetGPTBusinessOption("all", (value) => value.gpt_url);
let index = all_options.findIndex(item => item.value == global.config.gpt_business && item.gpt_url)
if (index < 0) {
throw new Error("没有找到指定的GPT服务商的配置请检查")
}
this.gptUrl = all_options[index].gpt_url;
this.gptApiKey = global.config.gpt_key;
this.gptModel = global.config.gpt_model;
}
/**
* 初始化GPT的设置
*/
async InitGptSetting(refresh = false) {
if (refresh) {
await this.RefreshGptSetting()
} else {
// 判断是不是存在必要信息
if (isEmpty(this.gptUrl) || isEmpty(this.gptModel) || isEmpty(this.gptApiKey)) {
await this.RefreshGptSetting();
}
}
}
/**
* 适配一些请求体中的参数
* @param data
* @param gpt_url
* @returns
*/
ModifyData(data: any, gpt_url: string = null) {
let res = data;
if (!gpt_url) {
gpt_url = this.gptUrl
}
if (gpt_url.includes("dashscope.aliyuncs.com")) {
res = {
"model": data.model,
"input": {
"messages": data.messages,
},
"parameters": {
"result_format": "message"
}
}
}
return res;
}
/**
* 适配返回来的数据
* @param res 返回的数据
* @param gpt_url 请求的URL
* @returns
*/
GetResponseContent(res: any, gpt_url: string = null) {
let content = "";
if (!gpt_url) {
gpt_url = this.gptUrl
}
if (gpt_url.includes("dashscope.aliyuncs.com")) {
content = res.data.output.choices[0].message.content;
} else {
content = res.data.choices[0].message.content;
}
return content;
}
//#endregion
/**
* 发送GPT请求
* @param {*} message 请求的信息
* @param {*} gpt_url gpt的url默认在global中取
* @param {*} gpt_key gpt的key默认在global中取
* @param {*} gpt_model gpt的model默认在global中取
* @returns
*/
async FetchGpt(message: any, gpt_model: string = null, gpt_key: string = null, gpt_url: string = null): Promise<string> {
try {
await this.InitGptSetting();
let data = {
"model": gpt_model ? gpt_model : this.gptModel,
"messages": message
};
data = this.ModifyData(data, gpt_url);
let config = {
method: 'post',
maxBodyLength: Infinity,
url: gpt_url ? gpt_url : this.gptUrl,
headers: {
'Authorization': `Bearer ${gpt_key ? gpt_key : this.gptApiKey}`,
'Content-Type': 'application/json'
},
data: JSON.stringify(data)
};
let res = await axios.request(config);
let content = this.GetResponseContent(res, this.gptUrl);
return content;
} catch (error) {
throw error;
}
}
//#region 繁体中文 -> 简体中文
/**
* 将繁体中文转换为简体中文
* @param traditionalText 繁体中文文本
* @param apiKey Lai API的 Key
* @param baseUrl 请求的baseurl
* @returns
*/
async ChineseTraditionalToSimplified(traditionalText: string, apiKey: string, baseUrl: string = null): Promise<string> {
try {
let message = [
{
"role": "system",
"content": '我想让你充当中文繁体转简体专家用简体中文100%还原繁体中文,不要加其他的联想,只把原有的繁体中文转换为简体中文,请检查所有信息是否准确,并在回答时保持简活,不需要任何其他反馈。'
}, {
"role": "user",
"content": '上研究生後,發現導師竟然是曾經網戀的前男友。'
}, {
"role": "assistant",
"content": '上研究生后,发现导师竟然是曾经网恋的前男友。'
}, {
"role": "user",
"content": traditionalText
}
]
let baseSubUrl = baseUrl ? (baseUrl.endsWith('/') ? baseUrl + 'v1/chat/completions' : baseUrl + '/v1/chat/completions') : null;
let url = baseSubUrl ? baseSubUrl : "https://api.laitool.cc/v1/chat/completions"
// 开始请求这个默认是使用的是LAI API的gpt-4o-mini
let content = await RetryWithBackoff<string>(async () => {
return await this.FetchGpt(message, 'gpt-4o-mini', apiKey, url);
}, 5, 2000)
return content
} catch (error) {
throw error
}
}
//#endregion
}