aisapi
Version:
A JavaScript/TypeScript API library for multiple AI providers
493 lines • 18.7 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.OpenAIProvider = void 0;
const base_1 = require("./base");
/**
* OpenAI服务接口实现
*/
class OpenAIProvider extends base_1.BaseProvider {
/**
* 创建一个新的OpenAI服务实例
*/
constructor(options = {}) {
super(options);
this.name = 'OpenAI';
this.model = options.model || 'gpt-3.5-turbo';
this.organization = options.organization;
// 设置组织信息(如果有的话)
if (this.organization) {
// 后续可能需要根据组织信息设置请求头等
}
}
/**
* 获取默认API地址
*/
getDefaultBaseUrl() {
return 'https://api.openai.com/v1';
}
/**
* 准备API请求头
*/
getHeaders() {
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
};
if (this.organization) {
headers['OpenAI-Organization'] = this.organization;
}
return headers;
}
/**
* 生成文本(旧版API,保留是为了兼容)
*/
generateText(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
// 有系统消息时,转用Chat接口
if (params.systemMessage) {
const messages = [
{ role: 'system', content: params.systemMessage },
{ role: 'user', content: params.prompt }
];
return this.chatCompletion({
model: params.model || this.model,
messages,
maxTokens: params.maxTokens,
temperature: params.temperature,
topP: params.topP,
stream: params.stream
});
}
// 没有系统消息则用传统接口
const model = params.model || this.model;
const requestBody = {
model,
prompt: params.prompt,
max_tokens: params.maxTokens || 150,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 0.7,
top_p: params.topP,
stream: params.stream || false
};
const response = yield this.sendRequest(`${this.baseUrl}/completions`, 'POST', requestBody);
return {
text: response.choices[0].text.trim(),
usage: {
promptTokens: response.usage.prompt_tokens,
completionTokens: response.usage.completion_tokens,
totalTokens: response.usage.total_tokens
},
rawResponse: response
};
});
}
/**
* 对话聊天接口(推荐使用这个)
*/
chatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const requestBody = {
model: params.model || this.model,
messages: params.messages,
max_tokens: params.maxTokens,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 0.7,
top_p: params.topP,
n: params.n,
stream: params.stream || false,
stop: params.stop,
presence_penalty: params.presencePenalty,
frequency_penalty: params.frequencyPenalty,
logit_bias: params.logitBias,
user: params.user,
response_format: params.responseFormat
};
// 清理掉没设置的选项
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: response.usage.promptTokens,
completionTokens: response.usage.completionTokens,
totalTokens: response.usage.totalTokens
},
rawResponse: response
};
});
}
/**
* 生成图片 - 调用DALL·E
*/
generateImage(params) {
return __awaiter(this, void 0, void 0, function* () {
const requestBody = {
model: params.model || 'dall-e-3',
prompt: params.prompt,
n: params.n || 1,
size: params.size || '1024x1024',
response_format: params.responseFormat || 'url',
user: params.user
};
// 清理掉没设置的选项
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
const response = yield this.sendRequest(`${this.baseUrl}/images/generations`, 'POST', requestBody);
return {
urls: response.data.map((item) => item.url),
rawResponse: response
};
});
}
/**
* 图片编辑 - 上传并修改现有图片
*/
editImage(params) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.baseUrl}/images/edits`;
const formData = new FormData();
formData.append('image', params.image);
if (params.mask)
formData.append('mask', params.mask);
formData.append('prompt', params.prompt);
if (params.n)
formData.append('n', params.n.toString());
if (params.size)
formData.append('size', params.size);
if (params.model)
formData.append('model', params.model);
if (params.user)
formData.append('user', params.user);
const headers = {
'Authorization': `Bearer ${this.apiKey}`
};
if (this.organization) {
headers['OpenAI-Organization'] = this.organization;
}
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(url, {
method: 'POST',
headers,
body: formData,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
return {
urls: data.data.map((item) => item.url),
rawResponse: data
};
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] ${e.message}`);
}
throw e;
}
});
}
/**
* 图片变体 - 基于上传图片生成相似但不同的版本
*/
createImageVariation(params) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.baseUrl}/images/variations`;
const formData = new FormData();
formData.append('image', params.image);
if (params.n)
formData.append('n', params.n.toString());
if (params.size)
formData.append('size', params.size);
if (params.model)
formData.append('model', params.model);
if (params.user)
formData.append('user', params.user);
const headers = {
'Authorization': `Bearer ${this.apiKey}`
};
if (this.organization) {
headers['OpenAI-Organization'] = this.organization;
}
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(url, {
method: 'POST',
headers,
body: formData,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
return {
urls: data.data.map((item) => item.url),
rawResponse: data
};
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] ${e.message}`);
}
throw e;
}
});
}
/**
* 语音识别 - 把录音转成文字
*/
transcribeAudio(params) {
return __awaiter(this, void 0, void 0, function* () {
const url = `${this.baseUrl}/audio/transcriptions`;
const formData = new FormData();
formData.append('file', params.file);
formData.append('model', params.model || 'whisper-1');
if (params.language)
formData.append('language', params.language);
if (params.prompt)
formData.append('prompt', params.prompt);
if (params.responseFormat)
formData.append('response_format', params.responseFormat);
if (params.temperature)
formData.append('temperature', params.temperature.toString());
const headers = {
'Authorization': `Bearer ${this.apiKey}`
};
if (this.organization) {
headers['OpenAI-Organization'] = this.organization;
}
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(url, {
method: 'POST',
headers,
body: formData,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
const data = yield response.json();
// 根据响应格式处理结果
if (params.responseFormat === 'text') {
return { text: data, rawResponse: data };
}
else {
return {
text: data.text,
rawResponse: data
};
}
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] ${e.message}`);
}
throw e;
}
});
}
/**
* 语音合成 - 把文字转成自然语音
*/
textToSpeech(params) {
return __awaiter(this, void 0, void 0, function* () {
const requestBody = {
model: params.model || 'tts-1',
input: params.input,
voice: params.voice || 'alloy',
response_format: params.responseFormat || 'mp3',
speed: params.speed || 1.0
};
const url = `${this.baseUrl}/audio/speech`;
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
};
if (this.organization) {
headers['OpenAI-Organization'] = this.organization;
}
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}`);
}
const audioData = yield response.arrayBuffer();
return {
audioData,
format: params.responseFormat || 'mp3'
};
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] ${e.message}`);
}
throw e;
}
});
}
/**
* 生成向量嵌入 - 把文本转为AI可理解的数值向量
*/
createEmbedding(params) {
return __awaiter(this, void 0, void 0, function* () {
const requestBody = {
model: params.model || 'text-embedding-3-small',
input: params.input,
user: params.user
};
const response = yield this.sendRequest(`${this.baseUrl}/embeddings`, 'POST', requestBody);
return response;
});
}
/**
* 测试API密钥是否有效
*/
validateApiKey() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield this.sendRequest(`${this.baseUrl}/models`, 'GET');
return true;
}
catch (_a) {
return false;
}
});
}
/**
* 获取可用的模型列表
*/
listModels() {
return __awaiter(this, void 0, void 0, function* () {
return yield this.sendRequest(`${this.baseUrl}/models`, 'GET');
});
}
/**
* 获取特定模型的详细信息
*/
getModel(modelId) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.sendRequest(`${this.baseUrl}/models/${modelId}`, 'GET');
});
}
/**
* 直接获取JSON格式的回复
*/
generateJSON(params) {
return __awaiter(this, void 0, void 0, function* () {
const chatParams = {
model: params.model || this.model,
messages: [
...(params.systemMessage ? [{ role: 'system', content: params.systemMessage }] : []),
{ role: 'user', content: params.prompt }
],
maxTokens: params.maxTokens,
temperature: params.temperature,
responseFormat: { type: 'json_object' }
};
const response = yield this.chatCompletion(chatParams);
try {
const jsonContent = response.text;
const jsonData = JSON.parse(jsonContent);
return {
data: jsonData,
usage: response.usage
};
}
catch (e) {
throw new Error(`[${this.name}] 解析JSON响应失败: ${e.message}`);
}
});
}
/**
* 创建流式对话 - 即时获取生成中的回复
* 返回可监听的数据流
*/
createStreamingChatCompletion(params) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (!params.stream) {
params.stream = true;
}
const requestBody = {
model: params.model || this.model,
messages: params.messages,
max_tokens: params.maxTokens,
temperature: (_a = params.temperature) !== null && _a !== void 0 ? _a : 0.7,
top_p: params.topP,
stream: true,
stop: params.stop,
presence_penalty: params.presencePenalty,
frequency_penalty: params.frequencyPenalty,
logit_bias: params.logitBias,
user: params.user
};
// 移除undefined字段
Object.keys(requestBody).forEach(key => {
if (requestBody[key] === undefined) {
delete requestBody[key];
}
});
const headers = this.getHeaders();
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = yield fetch(`${this.baseUrl}/chat/completions`, {
method: 'POST',
headers,
body: JSON.stringify(requestBody),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API请求失败: ${response.status} ${response.statusText}`);
}
if (!response.body) {
throw new Error('响应没有包含可读流');
}
return response.body;
}
catch (e) {
if (e instanceof Error) {
throw new Error(`[${this.name}] ${e.message}`);
}
throw e;
}
});
}
}
exports.OpenAIProvider = OpenAIProvider;
//# sourceMappingURL=openai.js.map