UNPKG

route-claudecode

Version:

Advanced routing and transformation system for Claude Code outputs to multiple AI providers

338 lines 11.4 kB
"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