AIClient-2-API/src/adapter.js
hex2077 35ced87e99 feat: 添加lodash依赖并优化Claude策略处理逻辑
重构Kiro服务从openai迁移至claude模块,更新相关文档和测试
修复Claude策略中内容提取逻辑,支持input_json_delta类型
优化系统提示词处理,当无系统消息时使用首个用户消息
更新README文档,添加健康检查端点和最新模型支持说明
2025-07-29 22:01:09 +08:00

183 lines
6.6 KiB
JavaScript

import { GeminiApiService } from './gemini/gemini-core.js'; // 导入geminiApiService
import { OpenAIApiService } from './openai/openai-core.js'; // 导入OpenAIApiService
import { ClaudeApiService } from './claude/claude-core.js'; // 导入ClaudeApiService
import { KiroApiService } from './claude/claude-kiro.js'; // 导入KiroApiService
import { MODEL_PROVIDER } from './common.js'; // 导入 MODEL_PROVIDER
// 定义AI服务适配器接口
// 所有的服务适配器都应该实现这些方法
export class ApiServiceAdapter {
constructor() {
if (new.target === ApiServiceAdapter) {
throw new TypeError("Cannot construct ApiServiceAdapter instances directly");
}
}
/**
* 生成内容
* @param {string} model - 模型名称
* @param {object} requestBody - 请求体
* @returns {Promise<object>} - API响应
*/
async generateContent(model, requestBody) {
throw new Error("Method 'generateContent()' must be implemented.");
}
/**
* 流式生成内容
* @param {string} model - 模型名称
* @param {object} requestBody - 请求体
* @returns {AsyncIterable<object>} - API响应流
*/
async *generateContentStream(model, requestBody) {
throw new Error("Method 'generateContentStream()' must be implemented.");
}
/**
* 列出可用模型
* @returns {Promise<object>} - 模型列表
*/
async listModels() {
throw new Error("Method 'listModels()' must be implemented.");
}
}
// Gemini API 服务适配器
export class GeminiApiServiceAdapter extends ApiServiceAdapter {
constructor(config) {
super();
this.geminiApiService = new GeminiApiService(config);
this.geminiApiService.initialize().catch(error => {
console.error("Failed to initialize geminiApiService:", error);
});
}
async generateContent(model, requestBody) {
if (!this.geminiApiService.isInitialized) {
console.warn("geminiApiService not initialized, attempting to re-initialize...");
await this.geminiApiService.initialize();
}
return this.geminiApiService.generateContent(model, requestBody);
}
async *generateContentStream(model, requestBody) {
if (!this.geminiApiService.isInitialized) {
console.warn("geminiApiService not initialized, attempting to re-initialize...");
await this.geminiApiService.initialize();
}
yield* this.geminiApiService.generateContentStream(model, requestBody);
}
async listModels() {
if (!this.geminiApiService.isInitialized) {
console.warn("geminiApiService not initialized, attempting to re-initialize...");
await this.geminiApiService.initialize();
}
// Gemini Core API 的 listModels 已经返回符合 Gemini 格式的数据,所以不需要额外转换
return this.geminiApiService.listModels();
}
}
// OpenAI API 服务适配器
export class OpenAIApiServiceAdapter extends ApiServiceAdapter {
constructor(config) {
super();
this.openAIApiService = new OpenAIApiService(config);
}
async generateContent(model, requestBody) {
// The adapter now expects the requestBody to be in the native OpenAI format.
// The conversion logic is handled upstream in the server.
return this.openAIApiService.generateContent(model, requestBody);
}
async *generateContentStream(model, requestBody) {
// The adapter now expects the requestBody to be in the native OpenAI format.
const stream = this.openAIApiService.generateContentStream(model, requestBody);
// The stream is yielded directly without conversion.
yield* stream;
}
async listModels() {
// The adapter now returns the native model list from the underlying service.
return this.openAIApiService.listModels();
}
}
// Claude API 服务适配器
export class ClaudeApiServiceAdapter extends ApiServiceAdapter {
constructor(config) {
super();
this.claudeApiService = new ClaudeApiService(config);
}
async generateContent(model, requestBody) {
// The adapter now expects the requestBody to be in the native Claude format.
return this.claudeApiService.generateContent(model, requestBody);
}
async *generateContentStream(model, requestBody) {
// The adapter now expects the requestBody to be in the native Claude format.
const stream = this.claudeApiService.generateContentStream(model, requestBody);
yield* stream;
}
async listModels() {
// The adapter now returns the native model list from the underlying service.
return this.claudeApiService.listModels();
}
}
// Kiro API 服务适配器
export class KiroApiServiceAdapter extends ApiServiceAdapter {
constructor(config) {
super();
this.kiroApiService = new KiroApiService(config);
this.kiroApiService.initialize().catch(error => {
console.error("Failed to initialize kiroApiService:", error);
});
}
async generateContent(model, requestBody) {
// The adapter expects the requestBody to be in OpenAI format for Kiro API
return this.kiroApiService.generateContent(model, requestBody);
}
async *generateContentStream(model, requestBody) {
// The adapter expects the requestBody to be in OpenAI format for Kiro API
const stream = this.kiroApiService.generateContentStream(model, requestBody);
yield* stream;
}
async listModels() {
// Returns the native model list from the Kiro service
return this.kiroApiService.listModels();
}
}
// 用于存储服务适配器单例的映射
const serviceInstances = {};
// 服务适配器工厂
export function getServiceAdapter(config) {
const provider = config.MODEL_PROVIDER;
if (!serviceInstances[provider]) {
switch (provider) {
case MODEL_PROVIDER.OPENAI_CUSTOM:
serviceInstances[provider] = new OpenAIApiServiceAdapter(config);
break;
case MODEL_PROVIDER.GEMINI_CLI:
serviceInstances[provider] = new GeminiApiServiceAdapter(config);
break;
case MODEL_PROVIDER.CLAUDE_CUSTOM:
serviceInstances[provider] = new ClaudeApiServiceAdapter(config);
break;
case MODEL_PROVIDER.KIRO_API:
serviceInstances[provider] = new KiroApiServiceAdapter(config);
break;
default:
throw new Error(`Unsupported model provider: ${provider}`);
}
}
return serviceInstances[provider];
}