aisapi
Version:
A JavaScript/TypeScript API library for multiple AI providers
278 lines • 11.4 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErnieProvider = exports.ErnieModel = void 0;
const base_1 = require("./base");
/**
* 文心一言可用的模型列表
*/
var ErnieModel;
(function (ErnieModel) {
// 基础系列
ErnieModel["ERNIE_BOT"] = "ernie-bot";
ErnieModel["ERNIE_BOT_TURBO"] = "ernie-bot-turbo";
ErnieModel["ERNIE_BOT_4"] = "ernie-bot-4";
// 速度优化系列
ErnieModel["ERNIE_SPEED_8K"] = "ernie-speed-8k";
ErnieModel["ERNIE_SPEED_128K"] = "ernie-speed-128k";
// 高性能系列
ErnieModel["ERNIE_4_0_8K"] = "ernie-4.0-8k";
ErnieModel["ERNIE_4_0_8K_PREVIEW"] = "ernie-4.0-8k-preview";
ErnieModel["ERNIE_3_5_8K"] = "ernie-3.5-8k";
ErnieModel["ERNIE_3_5_8K_PREVIEW"] = "ernie-3.5-8k-preview";
// 轻量系列
ErnieModel["ERNIE_LITE_8K"] = "ernie-lite-8k";
ErnieModel["ERNIE_TINY_8K"] = "ernie-tiny-8k";
// 特色模型
ErnieModel["ERNIE_CHARACTER_8K"] = "ernie-character-8k";
ErnieModel["ERNIE_SPEED_APP_BUILDER"] = "ernie-speed-appbuilder"; // 应用开发专用模型
})(ErnieModel || (exports.ErnieModel = ErnieModel = {}));
/**
* 文心一言接口实现
*/
class ErnieProvider extends base_1.BaseProvider {
/**
* 创建文心一言服务实例
*/
constructor(options = {}) {
super(options);
this.name = 'Ernie';
this.tokenExpireTime = 0;
this.model = options.model || ErnieModel.ERNIE_BOT;
this.secretKey = options.secretKey;
if (!this.secretKey) {
console.warn(`[${this.name}] 提示: 缺少安全密钥(Secret Key),部分功能可能无法使用`);
}
}
/**
* 获取默认API地址
*/
getDefaultBaseUrl() {
return 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop';
}
/**
* 获取授权Token
* 百度API需要先获取访问凭证才能调用
*/
getAccessToken() {
return __awaiter(this, void 0, void 0, function* () {
// 已有有效token就直接用
const now = Date.now();
if (this.accessToken && now < this.tokenExpireTime) {
return this.accessToken;
}
if (!this.apiKey || !this.secretKey) {
throw new Error('使用文心一言需要提供API Key和Secret Key');
}
try {
const tokenUrl = `https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=${this.apiKey}&client_secret=${this.secretKey}`;
const response = yield fetch(tokenUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
if (!response.ok) {
throw new Error(`授权失败: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
if (!data.access_token) {
throw new Error('获取授权失败: 响应中没有access_token');
}
this.accessToken = data.access_token;
// token有效期通常是30天,我们保守设为29天
const expireSeconds = data.expires_in || (30 * 24 * 60 * 60);
this.tokenExpireTime = now + (expireSeconds - 86400) * 1000;
return this.accessToken;
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] 获取授权失败: ${e.message}`);
}
throw e;
}
});
}
/**
* 生成文本内容
*/
generateText(params) {
return __awaiter(this, void 0, void 0, function* () {
const model = params.model || this.model;
// 准备对话消息
const messages = [
{ role: 'user', content: params.prompt }
];
// 添加系统指令
if (params.systemMessage) {
messages.unshift({ role: 'system', content: params.systemMessage });
}
// 使用对话接口处理
return this.chatCompletion({
model,
messages,
maxTokens: params.maxTokens,
temperature: params.temperature,
topP: params.topP,
stream: params.stream
});
});
}
/**
* 聊天对话功能
*/
chatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
const model = params.model || this.model;
const accessToken = yield this.getAccessToken();
// 准备请求数据
const requestBody = {
messages: this.convertMessagesToErnieFormat(params.messages),
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 0.7,
top_p: (_b = params.topP) !== null && _b !== void 0 ? _b : 0.9
};
// 根据模型不同添加特定参数
if (params.maxTokens) {
requestBody.max_output_tokens = params.maxTokens;
}
// 清理未设置的选项
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
// 组装完整API地址
const apiUrl = `${this.baseUrl}/chat/${this.getErnieModelPath(model)}?access_token=${accessToken}`;
// 发送请求并处理结果
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
// 检查API错误
if (data.error_code) {
throw new Error(`文心一言API错误: ${data.error_msg} (代码: ${data.error_code})`);
}
// 返回统一格式的响应
return {
text: data.result || '',
usage: {
promptTokens: ((_c = data.usage) === null || _c === void 0 ? void 0 : _c.prompt_tokens) || 0,
completionTokens: ((_d = data.usage) === null || _d === void 0 ? void 0 : _d.completion_tokens) || 0,
totalTokens: ((_e = data.usage) === null || _e === void 0 ? void 0 : _e.total_tokens) || 0
},
rawResponse: data
};
}
catch (error) {
if (error instanceof Error) {
throw new Error(`[${this.name}] ${error.message}`);
}
throw error;
}
});
}
/**
* 转换消息格式为文心一言API格式
*/
convertMessagesToErnieFormat(messages) {
return messages.map(msg => {
// 文心一言API使用与OpenAI兼容的角色名称
return {
role: msg.role,
content: msg.content
};
});
}
/**
* 获取文心一言API的模型路径
*/
getErnieModelPath(modelName) {
switch (modelName) {
case ErnieModel.ERNIE_BOT:
return 'completions';
case ErnieModel.ERNIE_BOT_TURBO:
return 'ernie-bot-turbo';
case ErnieModel.ERNIE_BOT_4:
return 'ernie-bot-4';
case ErnieModel.ERNIE_SPEED_8K:
return 'ernie-speed-8k';
case ErnieModel.ERNIE_SPEED_128K:
return 'ernie-speed-128k';
case ErnieModel.ERNIE_4_0_8K:
return 'ernie-4.0-8k';
case ErnieModel.ERNIE_4_0_8K_PREVIEW:
return 'ernie-4.0-8k-preview';
case ErnieModel.ERNIE_3_5_8K:
return 'ernie-3.5-8k';
case ErnieModel.ERNIE_3_5_8K_PREVIEW:
return 'ernie-3.5-8k-preview';
case ErnieModel.ERNIE_LITE_8K:
return 'ernie-lite-8k';
case ErnieModel.ERNIE_TINY_8K:
return 'ernie-tiny-8k';
case ErnieModel.ERNIE_CHARACTER_8K:
return 'ernie-character-8k';
case ErnieModel.ERNIE_SPEED_APP_BUILDER:
return 'ernie-speed-appbuilder';
default:
return 'completions'; // 默认使用ERNIE-Bot
}
}
/**
* 生成JSON格式输出
*/
generateJSON(params) {
return __awaiter(this, void 0, void 0, function* () {
const model = params.model || this.model;
// 构建系统消息,指示返回JSON格式
const systemMessage = params.systemMessage
? `${params.systemMessage}\n请以有效的JSON格式返回回复。`
: '请以有效的JSON格式返回回复。';
const messages = [
{ role: 'system', content: systemMessage },
{ role: 'user', content: params.prompt }
];
const response = yield this.chatCompletion({
model,
messages,
maxTokens: params.maxTokens,
temperature: params.temperature || 0.1, // 降低温度以获得更确定的响应
topP: params.topP,
stream: false
});
try {
// 尝试解析响应文本为JSON
return JSON.parse(response.text);
}
catch (error) {
// 如果解析失败,返回原始文本
console.warn(`[${this.name}] 无法解析响应为JSON: ${error instanceof Error ? error.message : '未知错误'}`);
return { text: response.text, error: '解析JSON失败' };
}
});
}
}
exports.ErnieProvider = ErnieProvider;
//# sourceMappingURL=ernie.js.map