aisapi
Version:
A JavaScript/TypeScript API library for multiple AI providers
286 lines • 12 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.QwenProvider = exports.QwenApiMode = exports.QwenModel = void 0;
const base_1 = require("./base");
/**
* 千问API可用模型
*/
var QwenModel;
(function (QwenModel) {
QwenModel["TURBO"] = "qwen-turbo";
QwenModel["PLUS"] = "qwen-plus";
QwenModel["MAX"] = "qwen-max-2025-01-25"; // 顶级性能模型 (如 Qwen2.5-Max)
})(QwenModel || (exports.QwenModel = QwenModel = {}));
/**
* 千问API调用模式
*/
var QwenApiMode;
(function (QwenApiMode) {
QwenApiMode["DASH_SCOPE"] = "dashscope";
QwenApiMode["OPENAI_COMPATIBLE"] = "openai"; // OpenAI兼容模式
})(QwenApiMode || (exports.QwenApiMode = QwenApiMode = {}));
/**
* 阿里巴巴千问(Qwen)API实现
*/
class QwenProvider extends base_1.BaseProvider {
/**
* 创建千问API提供商实例
*/
constructor(options = {}) {
super(options);
this.name = 'Qwen';
this.model = options.model || QwenModel.TURBO;
this.apiMode = QwenApiMode.OPENAI_COMPATIBLE; // 默认使用OpenAI兼容模式,更易集成
}
/**
* @inheritdoc
*/
getDefaultBaseUrl() {
return this.apiMode === QwenApiMode.OPENAI_COMPATIBLE
? 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1'
: 'https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
}
/**
* 获取请求头
*/
getHeaders() {
const headers = {
'Content-Type': 'application/json'
};
if (this.apiKey) {
headers['Authorization'] = `Bearer ${this.apiKey}`;
}
return headers;
}
/**
* @inheritdoc
*/
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 });
}
// 使用聊天完成API
return this.chatCompletion({
model,
messages,
maxTokens: params.maxTokens,
temperature: params.temperature,
topP: params.topP,
stream: params.stream
});
});
}
/**
* 聊天完成API
*/
chatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
if (this.apiMode === QwenApiMode.OPENAI_COMPATIBLE) {
return this.openaiCompatibleChatCompletion(params);
}
else {
return this.dashscopeChatCompletion(params);
}
});
}
/**
* 使用OpenAI兼容接口调用聊天完成
*/
openaiCompatibleChatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const requestBody = {
model: params.model || this.model,
messages: params.messages,
max_tokens: params.maxTokens,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 1.0,
top_p: params.topP,
stream: params.stream || false
};
// 移除undefined字段
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
const response = yield this.sendRequest(`${this.baseUrl}/chat/completions`, 'POST', requestBody);
// 转换响应为统一格式
return {
text: response.choices[0].message.content || '',
usage: {
promptTokens: ((_b = response.usage) === null || _b === void 0 ? void 0 : _b.prompt_tokens) || 0,
completionTokens: ((_c = response.usage) === null || _c === void 0 ? void 0 : _c.completion_tokens) || 0,
totalTokens: ((_d = response.usage) === null || _d === void 0 ? void 0 : _d.total_tokens) || 0
},
rawResponse: response
};
});
}
/**
* 使用DashScope原生API调用聊天完成
*/
dashscopeChatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
const requestBody = {
model: params.model || this.model,
messages: params.messages,
parameters: {
max_tokens: params.maxTokens,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 1.0,
top_p: params.topP
},
result_format: 'message'
};
// 移除undefined字段
["max_tokens", "temperature", "top_p"].forEach(key => {
if (requestBody.parameters[key] === undefined) {
delete requestBody.parameters[key];
}
});
const response = yield this.sendRequest(this.baseUrl, 'POST', requestBody);
// 转换DashScope响应为统一格式
return {
text: response.output.choices[0].message.content || '',
usage: {
promptTokens: ((_b = response.usage) === null || _b === void 0 ? void 0 : _b.input_tokens) || 0,
completionTokens: ((_c = response.usage) === null || _c === void 0 ? void 0 : _c.output_tokens) || 0,
totalTokens: (((_d = response.usage) === null || _d === void 0 ? void 0 : _d.input_tokens) || 0) + (((_e = response.usage) === null || _e === void 0 ? void 0 : _e.output_tokens) || 0)
},
rawResponse: response
};
});
}
/**
* 设置API调用模式
*/
setApiMode(mode) {
this.apiMode = mode;
// 更新基础URL
this.baseUrl = this.getDefaultBaseUrl();
}
/**
* 流式聊天完成
*/
createStreamingChatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (this.apiMode !== QwenApiMode.OPENAI_COMPATIBLE) {
throw new Error(`[${this.name}] 流式响应仅支持OpenAI兼容模式`);
}
const requestBody = {
model: params.model || this.model,
messages: params.messages,
max_tokens: params.maxTokens,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 1.0,
top_p: params.topP,
stream: true
};
// 移除undefined字段
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
const headers = this.getHeaders();
const url = `${this.baseUrl}/chat/completions`;
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(requestBody),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
return response.body;
}
catch (error) {
if (error instanceof Error) {
throw new Error(`[${this.name}] ${error.message}`);
}
throw error;
}
});
}
/**
* 生成JSON格式输出
*/
generateJSON(params) {
return __awaiter(this, void 0, void 0, function* () {
const model = params.model || this.model;
if (this.apiMode === QwenApiMode.OPENAI_COMPATIBLE) {
// 在OpenAI兼容模式下使用responseFormat参数
const systemMessage = params.systemMessage
? `${params.systemMessage}\n请以有效的JSON格式返回回复。`
: '请以有效的JSON格式返回回复。';
const messages = [
{ role: 'system', content: systemMessage },
{ role: 'user', content: params.prompt }
];
const requestBody = {
model,
messages,
max_tokens: params.maxTokens,
temperature: params.temperature || 0.1, // 降低温度以获得更确定的响应
top_p: params.topP,
response_format: { type: "json_object" }
};
// 移除undefined字段
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
const response = yield this.sendRequest(`${this.baseUrl}/chat/completions`, 'POST', requestBody);
try {
const content = response.choices[0].message.content || '';
return JSON.parse(content);
}
catch (error) {
console.warn(`[${this.name}] 无法解析响应为JSON: ${error instanceof Error ? error.message : '未知错误'}`);
return { text: response.choices[0].message.content, error: '解析JSON失败' };
}
}
else {
// DashScope原生API模式下不支持responseFormat,使用手动提示
const systemMessage = params.systemMessage
? `${params.systemMessage}\n请以有效的JSON格式返回回复。仅返回JSON,不要有其他解释性文字。`
: '请以有效的JSON格式返回回复。仅返回JSON,不要有其他解释性文字。';
const response = yield this.generateText(Object.assign(Object.assign({}, params), { systemMessage, temperature: params.temperature || 0.1 // 降低温度以获得更确定的响应
}));
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.QwenProvider = QwenProvider;
//# sourceMappingURL=qwen.js.map