UNPKG

aisapi

Version:

A JavaScript/TypeScript API library for multiple AI providers

493 lines 18.7 kB
"use strict"; 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