route-claudecode
Version:
Advanced routing and transformation system for Claude Code outputs to multiple AI providers
403 lines • 16.4 kB
JavaScript
"use strict";
/**
* CodeWhisperer 主客户端 - 重构版本
* 支持动态切换缓冲式和实时流式实现
* 项目所有者: Jason Zhang
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.CodeWhispererClient = void 0;
const logger_1 = require("@/utils/logger");
const client_factory_1 = require("./client-factory");
const streaming_config_1 = require("./config/streaming-config");
const performance_metrics_1 = require("./config/performance-metrics");
class CodeWhispererClient {
client;
configManager;
metrics;
configChangeListener = () => { }; // 默认空函数
failureCount = 0;
maxFailuresBeforeFallback = 3;
constructor(config) {
this.configManager = streaming_config_1.CodeWhispererStreamingConfigManager.getInstance();
// 如果提供了配置,更新管理器
if (config) {
this.configManager.updateConfig(config);
}
const currentConfig = this.configManager.getConfig();
this.metrics = new performance_metrics_1.CodeWhispererPerformanceMetrics(currentConfig);
this.client = client_factory_1.CodeWhispererClientFactory.createClient(currentConfig);
// 设置配置变更监听器
this.setupConfigChangeListener();
logger_1.logger.info('CodeWhisperer主客户端初始化完成', {
implementation: currentConfig.implementation,
config: {
implementation: currentConfig.implementation,
realtimeOptions: currentConfig.realtimeOptions,
performanceMetrics: currentConfig.performanceMetrics,
fallback: currentConfig.fallback,
},
clientType: this.client.getClientType(),
healthCheck: typeof this.client.healthCheck === 'function' ? 'available' : 'unavailable',
});
}
/**
* 处理流式请求 - 统一接口
*/
async handleStreamRequest(anthropicReq, writeSSE, onError) {
const requestId = `main_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
const startTime = Date.now();
try {
const config = this.configManager.getConfig();
logger_1.logger.info('CodeWhisperer主客户端开始处理流式请求', {
requestId,
implementation: config.implementation,
clientType: this.client.getClientType(),
model: anthropicReq.model,
messageCount: anthropicReq.messages.length,
hasTools: !!(anthropicReq.tools && anthropicReq.tools.length > 0),
});
// 执行请求
await this.client.handleStreamRequest(anthropicReq, writeSSE, onError);
// 重置失败计数
this.failureCount = 0;
const duration = Date.now() - startTime;
logger_1.logger.info('CodeWhisperer流式请求处理完成', {
requestId,
duration,
implementation: config.implementation,
success: true,
});
}
catch (error) {
this.failureCount++;
const duration = Date.now() - startTime;
const config = this.configManager.getConfig();
logger_1.logger.error('CodeWhisperer流式请求处理失败', {
requestId,
duration,
implementation: config.implementation,
clientType: this.client.getClientType(),
failureCount: this.failureCount,
maxFailuresBeforeFallback: this.maxFailuresBeforeFallback,
error: error instanceof Error ? error.message : String(error),
});
// 检查是否需要故障转移
if (this.shouldFallback(config)) {
await this.handleFallback(error, onError);
}
else {
// 直接调用错误处理
onError(`CodeWhisperer请求失败: ${error instanceof Error ? error.message : String(error)}`, error);
}
}
}
/**
* 处理非流式请求 - 统一接口
*/
async handleNonStreamRequest(anthropicReq) {
const requestId = `main_nonstream_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
const startTime = Date.now();
try {
const config = this.configManager.getConfig();
logger_1.logger.info('CodeWhisperer主客户端开始处理非流式请求', {
requestId,
implementation: config.implementation,
clientType: this.client.getClientType(),
model: anthropicReq.model,
messageCount: anthropicReq.messages.length,
});
// 执行请求
const result = await this.client.handleNonStreamRequest(anthropicReq);
// 重置失败计数
this.failureCount = 0;
const duration = Date.now() - startTime;
logger_1.logger.info('CodeWhisperer非流式请求处理完成', {
requestId,
duration,
implementation: config.implementation,
success: true,
});
return result;
}
catch (error) {
this.failureCount++;
const duration = Date.now() - startTime;
const config = this.configManager.getConfig();
logger_1.logger.error('CodeWhisperer非流式请求处理失败', {
requestId,
duration,
implementation: config.implementation,
clientType: this.client.getClientType(),
failureCount: this.failureCount,
maxFailuresBeforeFallback: this.maxFailuresBeforeFallback,
error: error instanceof Error ? error.message : String(error),
});
// 检查是否需要故障转移
if (this.shouldFallback(config)) {
return await this.handleNonStreamFallback(error);
}
else {
throw error;
}
}
}
/**
* 动态切换实现
*/
switchImplementation(implementation) {
const oldImplementation = this.client.getClientType();
const oldConfig = this.configManager.getConfig();
logger_1.logger.info('CodeWhisperer主客户端开始切换实现', {
from: oldImplementation,
to: implementation,
failureCount: this.failureCount,
});
try {
// 更新配置
this.configManager.switchImplementation(implementation);
const newConfig = this.configManager.getConfig();
// 创建新的客户端实例
const newClient = client_factory_1.CodeWhispererClientFactory.createClient(newConfig);
// 健康检查
newClient.healthCheck().then(healthCheck => {
logger_1.logger.info('新客户端健康检查完成', {
implementation,
healthCheck,
});
if (healthCheck.healthy) {
// 替换客户端
this.client = newClient;
// 重置失败计数
this.failureCount = 0;
logger_1.logger.info('CodeWhisperer实现切换成功', {
from: oldImplementation,
to: implementation,
newClientType: this.client.getClientType(),
});
}
else {
logger_1.logger.warn('新客户端健康检查失败,回滚到原实现', {
implementation,
healthCheck,
});
// 回滚配置
this.configManager.switchImplementation(oldImplementation);
}
}).catch(healthError => {
logger_1.logger.error('新客户端健康检查失败,回滚到原实现', {
implementation,
error: healthError instanceof Error ? healthError.message : String(healthError),
});
// 回滚配置
this.configManager.switchImplementation(oldImplementation);
});
}
catch (error) {
logger_1.logger.error('CodeWhisperer实现切换失败', {
from: oldImplementation,
to: implementation,
error: error instanceof Error ? error.message : String(error),
});
throw error;
}
}
/**
* 获取当前客户端类型
*/
getClientType() {
return this.client.getClientType();
}
/**
* 获取当前配置
*/
getCurrentConfig() {
return this.configManager.getConfig();
}
/**
* 更新配置
*/
updateConfig(newConfig) {
this.configManager.updateConfig(newConfig);
// 重新创建客户端以应用新配置
const updatedConfig = this.configManager.getConfig();
this.client = client_factory_1.CodeWhispererClientFactory.createClient(updatedConfig);
logger_1.logger.info('CodeWhisperer主客户端配置已更新', {
newConfig: updatedConfig,
clientType: this.client.getClientType(),
});
}
/**
* 健康检查
*/
async healthCheck() {
try {
const clientHealth = await this.client.healthCheck();
const config = this.configManager.getConfig();
return {
...clientHealth,
implementation: config.implementation,
config,
};
}
catch (error) {
const config = this.configManager.getConfig();
return {
healthy: false,
type: this.client.getClientType(),
implementation: config.implementation,
config,
message: error instanceof Error ? error.message : String(error),
};
}
}
/**
* 获取性能报告
*/
getPerformanceReport() {
return this.metrics.getAggregatedReport();
}
/**
* 获取实现对比报告
*/
getImplementationComparison() {
return this.metrics.compareImplementations();
}
/**
* 重置性能指标
*/
resetPerformanceMetrics() {
this.metrics.resetAggregatedMetrics();
logger_1.logger.info('CodeWhisperer性能指标已重置');
}
/**
* 判断是否需要故障转移
*/
shouldFallback(config) {
return (config.fallback.enableFallback &&
this.failureCount >= this.maxFailuresBeforeFallback &&
config.fallback.fallbackToBuffered &&
config.implementation === 'realtime');
}
/**
* 处理流式请求故障转移
*/
async handleFallback(error, onError) {
logger_1.logger.warn('CodeWhisperer实时客户端失败,尝试故障转移', {
failureCount: this.failureCount,
maxFailuresBeforeFallback: this.maxFailuresBeforeFallback,
error: error instanceof Error ? error.message : String(error),
});
try {
// 切换到缓冲式实现
this.switchImplementation('buffered');
// 重新执行请求
await this.client.handleStreamRequest(error.anthropicReq || {
model: 'claude-sonnet-4-20250514',
max_tokens: 1000,
messages: [{ role: 'user', content: 'fallback request' }],
stream: true,
}, (event, data) => { }, // writeSSE
(message, error) => { } // onError
);
logger_1.logger.info('CodeWhisperer故障转移成功');
}
catch (fallbackError) {
logger_1.logger.error('CodeWhisperer故障转移失败', {
fallbackError: fallbackError instanceof Error ? fallbackError.message : String(fallbackError),
originalError: error instanceof Error ? error.message : String(error),
});
onError(`CodeWhisperer实时客户端失败且故障转移也失败: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`, fallbackError);
}
}
/**
* 处理非流式请求故障转移
*/
async handleNonStreamFallback(error) {
logger_1.logger.warn('CodeWhisperer实时非流式客户端失败,尝试故障转移', {
failureCount: this.failureCount,
maxFailuresBeforeFallback: this.maxFailuresBeforeFallback,
error: error instanceof Error ? error.message : String(error),
});
try {
// 切换到缓冲式实现
this.switchImplementation('buffered');
// 重新执行请求
const result = await this.client.handleNonStreamRequest(error.anthropicReq || {
model: 'claude-sonnet-4-20250514',
max_tokens: 1000,
messages: [{ role: 'user', content: 'fallback request' }],
stream: false,
});
logger_1.logger.info('CodeWhisperer非流式故障转移成功');
return result;
}
catch (fallbackError) {
logger_1.logger.error('CodeWhisperer非流式故障转移失败', {
fallbackError: fallbackError instanceof Error ? fallbackError.message : String(fallbackError),
originalError: error instanceof Error ? error.message : String(error),
});
throw fallbackError;
}
}
/**
* 设置配置变更监听器
*/
setupConfigChangeListener() {
this.configChangeListener = (config) => {
logger_1.logger.info('检测到CodeWhisperer配置变更', {
newImplementation: config.implementation,
configChange: true,
});
try {
// 创建新的客户端实例
const newClient = client_factory_1.CodeWhispererClientFactory.createClient(config);
// 健康检查
newClient.healthCheck().then(healthCheck => {
if (healthCheck.healthy) {
// 替换客户端
this.client = newClient;
logger_1.logger.info('配置变更后客户端更新成功', {
implementation: config.implementation,
clientType: this.client.getClientType(),
});
}
else {
logger_1.logger.warn('配置变更后新客户端健康检查失败,保持原客户端', {
implementation: config.implementation,
healthCheck,
});
}
}).catch(healthError => {
logger_1.logger.error('配置变更后新客户端健康检查失败', {
implementation: config.implementation,
error: healthError instanceof Error ? healthError.message : String(healthError),
});
});
}
catch (clientError) {
logger_1.logger.error('配置变更后客户端创建失败', {
implementation: config.implementation,
error: clientError instanceof Error ? clientError.message : String(clientError),
});
}
};
// 添加监听器
this.configManager.addConfigChangeListener(this.configChangeListener);
}
/**
* 销毁客户端
*/
destroy() {
// 移除配置监听器
if (this.configChangeListener) {
this.configManager.removeConfigChangeListener(this.configChangeListener);
}
// 销毁性能监控器
this.metrics.destroy();
logger_1.logger.info('CodeWhisperer主客户端已销毁');
}
}
exports.CodeWhispererClient = CodeWhispererClient;
// 向后兼容的默认导出
exports.default = CodeWhispererClient;
//# sourceMappingURL=client.js.map