route-claudecode
Version:
Advanced routing and transformation system for Claude Code outputs to multiple AI providers
338 lines • 11.4 kB
JavaScript
"use strict";
/**
* 统一预处理器 - 重构版本
* 作为所有格式的统一入口,使用模块化解析器
* 遵循零硬编码、零Fallback、零沉默失败原则
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnifiedPreprocessor = void 0;
exports.getUnifiedPreprocessor = getUnifiedPreprocessor;
exports.resetUnifiedPreprocessor = resetUnifiedPreprocessor;
const parser_manager_1 = require("./parsers/parser-manager");
const logging_1 = require("../logging");
class UnifiedPreprocessor {
parserManager;
logger;
config;
performanceMetrics = {
totalProcessed: 0,
totalDuration: 0,
toolDetections: 0,
finishReasonFixes: 0,
errors: 0
};
constructor(port, config) {
this.config = {
enabled: process.env.RCC_UNIFIED_PREPROCESSING !== 'false',
debugMode: process.env.RCC_PREPROCESSING_DEBUG === 'true',
strictMode: true, // 强制严格模式
performanceTracking: true,
forceToolDetection: true, // 强制启用,不可配置关闭
forceFinishReasonFix: true, // 强制启用,不可配置关闭
...config
};
// 🚨 强制关键配置,防止被覆盖
this.config.strictMode = true;
this.config.forceToolDetection = true;
this.config.forceFinishReasonFix = true;
this.logger = (0, logging_1.getLogger)(port);
this.parserManager = (0, parser_manager_1.getParserManager)({
strictMode: this.config.strictMode,
debugMode: this.config.debugMode
});
if (this.config.debugMode) {
console.log('🎯 [UNIFIED-PREPROCESSOR] Initialized with config:', this.config);
}
}
/**
* 预处理请求数据
*/
async preprocessRequest(data, provider, requestId) {
const startTime = Date.now();
if (!this.config.enabled) {
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: 0
};
}
const context = {
provider,
requestId,
stage: 'request',
format: this.detectFormat(data)
};
try {
// 请求阶段主要是验证和清理,不做工具检测
const result = {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: Date.now() - startTime
};
this.updateMetrics(result);
return result;
}
catch (error) {
this.performanceMetrics.errors++;
console.error('🚨 [UNIFIED-PREPROCESSOR] Request preprocessing failed:', {
error: error instanceof Error ? error.message : String(error),
provider,
requestId
});
// 严格模式下抛出错误
if (this.config.strictMode) {
throw error;
}
// 返回原始数据
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: Date.now() - startTime
};
}
}
/**
* 预处理响应数据
*/
async preprocessResponse(data, provider, requestId) {
const startTime = Date.now();
if (!this.config.enabled) {
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: 0
};
}
const context = {
provider,
requestId,
stage: 'response',
format: this.detectFormat(data)
};
try {
let modifiedData = data;
let modified = false;
// 🎯 强制工具调用检测
const parseResult = this.parserManager.parseToolCalls(modifiedData, context);
if (this.config.debugMode) {
console.log('🔍 [UNIFIED-PREPROCESSOR] Tool detection result:', {
hasTools: parseResult.hasTools,
toolCount: parseResult.toolCount,
confidence: parseResult.confidence,
provider,
requestId
});
}
// 🔧 强制finish reason修复(如果检测到工具调用)
if (parseResult.hasTools && this.config.forceFinishReasonFix) {
try {
modifiedData = this.parserManager.fixFinishReason(modifiedData, 'tool_calls', context);
modified = true;
this.performanceMetrics.finishReasonFixes++;
console.log('🔧 [UNIFIED-PREPROCESSOR] Forced finish_reason fix for tool calls:', {
toolCount: parseResult.toolCount,
provider,
requestId
});
}
catch (error) {
console.error('🚨 [UNIFIED-PREPROCESSOR] Finish reason fix failed:', {
error: error instanceof Error ? error.message : String(error),
provider,
requestId
});
if (this.config.strictMode) {
throw error;
}
}
}
const result = {
data: modifiedData,
hasTools: parseResult.hasTools,
toolCount: parseResult.toolCount,
finishReason: parseResult.finishReason,
modified,
processingTime: Date.now() - startTime
};
this.updateMetrics(result);
return result;
}
catch (error) {
this.performanceMetrics.errors++;
console.error('🚨 [UNIFIED-PREPROCESSOR] Response preprocessing failed:', {
error: error instanceof Error ? error.message : String(error),
provider,
requestId
});
// 严格模式下抛出错误
if (this.config.strictMode) {
throw error;
}
// 返回原始数据
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: Date.now() - startTime
};
}
}
/**
* 预处理流式数据
*/
async preprocessStreaming(data, provider, requestId) {
const startTime = Date.now();
if (!this.config.enabled) {
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: 0
};
}
const context = {
provider,
requestId,
stage: 'response', // 流式数据按响应处理
format: this.detectFormat(data)
};
try {
// 流式数据的工具检测(轻量级)
const parseResult = this.parserManager.parseToolCalls(data, context);
const result = {
data,
hasTools: parseResult.hasTools,
toolCount: parseResult.toolCount,
finishReason: parseResult.finishReason,
modified: false, // 流式数据通常不修改
processingTime: Date.now() - startTime
};
this.updateMetrics(result);
return result;
}
catch (error) {
this.performanceMetrics.errors++;
console.error('🚨 [UNIFIED-PREPROCESSOR] Streaming preprocessing failed:', {
error: error instanceof Error ? error.message : String(error),
provider,
requestId
});
// 流式处理失败不应该中断流
return {
data,
hasTools: false,
toolCount: 0,
modified: false,
processingTime: Date.now() - startTime
};
}
}
/**
* 检测数据格式
*/
detectFormat(data) {
if (!data || typeof data !== 'object') {
return 'anthropic'; // 默认格式
}
// 简单的格式检测
if (data.choices && Array.isArray(data.choices)) {
return 'openai';
}
if (data.candidates && Array.isArray(data.candidates)) {
return 'gemini';
}
if (data.content && Array.isArray(data.content)) {
return 'anthropic';
}
// 默认返回anthropic格式
return 'anthropic';
}
/**
* 更新性能指标
*/
updateMetrics(result) {
if (!this.config.performanceTracking) {
return;
}
this.performanceMetrics.totalProcessed++;
this.performanceMetrics.totalDuration += result.processingTime;
if (result.hasTools) {
this.performanceMetrics.toolDetections++;
}
}
/**
* 获取性能统计
*/
getPerformanceMetrics() {
const avgDuration = this.performanceMetrics.totalProcessed > 0
? this.performanceMetrics.totalDuration / this.performanceMetrics.totalProcessed
: 0;
return {
...this.performanceMetrics,
averageDuration: Math.round(avgDuration * 100) / 100,
parserStats: this.parserManager.getStats(),
config: this.config
};
}
/**
* 重置性能指标
*/
resetMetrics() {
this.performanceMetrics = {
totalProcessed: 0,
totalDuration: 0,
toolDetections: 0,
finishReasonFixes: 0,
errors: 0
};
console.log('🔄 [UNIFIED-PREPROCESSOR] Metrics reset');
}
/**
* 更新配置
*/
updateConfig(newConfig) {
// 保护关键配置不被覆盖
const protectedConfig = {
...this.config,
...newConfig,
strictMode: true, // 强制严格模式
forceToolDetection: true, // 强制工具检测
forceFinishReasonFix: true // 强制finish reason修复
};
this.config = protectedConfig;
console.log('🔧 [UNIFIED-PREPROCESSOR] Config updated:', protectedConfig);
}
}
exports.UnifiedPreprocessor = UnifiedPreprocessor;
// 单例模式:全局预处理器实例
const preprocessorInstances = new Map();
/**
* 获取或创建统一预处理器实例
*/
function getUnifiedPreprocessor(port, config) {
const key = port || 'default';
if (!preprocessorInstances.has(key)) {
preprocessorInstances.set(key, new UnifiedPreprocessor(port, config));
}
return preprocessorInstances.get(key);
}
/**
* 重置统一预处理器实例
*/
function resetUnifiedPreprocessor(port) {
const key = port || 'default';
if (preprocessorInstances.has(key)) {
preprocessorInstances.delete(key);
}
}
//# sourceMappingURL=unified-preprocessor.js.map