UNPKG

route-claudecode

Version:

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

194 lines 7.44 kB
"use strict"; /** * 统一的 Finish Reason 日志系统 * 项目所有者: Jason Zhang * * 消除重复日志记录,提供端到端的finish_reason跟踪 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.unifiedFinishReasonLogger = void 0; exports.logInputFinishReason = logInputFinishReason; exports.logTransformationFinishReason = logTransformationFinishReason; exports.logOutputFinishReason = logOutputFinishReason; exports.logStreamingFinishReason = logStreamingFinishReason; const logger_1 = require("@/utils/logger"); class UnifiedFinishReasonLogger { logEntries = new Map(); /** * 记录finish reason转换的完整过程 */ logFinishReasonTransformation(entry) { const requestEntries = this.logEntries.get(entry.requestId) || []; requestEntries.push(entry); this.logEntries.set(entry.requestId, requestEntries); // 根据情况决定日志级别 if (entry.errorInfo) { logger_1.logger.error(`🚨 [FINISH-REASON-ERROR] ${entry.errorInfo.type}: ${entry.errorInfo.message}`, { stage: entry.stage, originalReason: entry.originalReason, mappedReason: entry.mappedReason, provider: entry.provider, model: entry.model, context: entry.context, shouldRetry: entry.errorInfo.shouldRetry, metadata: entry.metadata }, entry.requestId, 'finish-reason-stage'); } else if (!entry.mappedReason && entry.originalReason) { logger_1.logger.warn(`⚠️ [FINISH-REASON-UNMAPPED] Original reason preserved without mapping`, { stage: entry.stage, originalReason: entry.originalReason, provider: entry.provider, model: entry.model, context: entry.context, metadata: entry.metadata }, entry.requestId, 'finish-reason-stage'); } else { logger_1.logger.info(`✅ [FINISH-REASON-SUCCESS] ${entry.originalReason}${entry.mappedReason}`, { stage: entry.stage, sourceFormat: entry.sourceFormat, targetFormat: entry.targetFormat, provider: entry.provider, model: entry.model, context: entry.context, metadata: entry.metadata }, entry.requestId, 'finish-reason-stage'); } } /** * 生成请求的完整finish reason跟踪报告 */ generateEndToEndReport(requestId) { const entries = this.logEntries.get(requestId) || []; if (entries.length === 0) { return `No finish reason tracking data found for request ${requestId}`; } const report = [`🔍 [FINISH-REASON-TRACE] End-to-End tracking for ${requestId}:`]; entries.forEach((entry, index) => { const errorMark = entry.errorInfo ? '❌' : '✅'; const mapping = entry.mappedReason ? `${entry.originalReason}${entry.mappedReason}` : entry.originalReason || 'undefined'; report.push(` ${index + 1}. ${errorMark} [${entry.stage}] ${mapping} (${entry.context})`); if (entry.errorInfo) { report.push(` Error: ${entry.errorInfo.message}`); } }); // 清理已完成请求的记录,防止内存泄漏 setTimeout(() => { this.logEntries.delete(requestId); }, 60000); // 1分钟后清理 return report.join('\n'); } /** * 检查是否存在静默失败 */ detectSilentFailures(requestId) { const entries = this.logEntries.get(requestId) || []; const issues = []; // 检查是否有映射失败但没有错误报告 entries.forEach(entry => { if (entry.originalReason && !entry.mappedReason && !entry.errorInfo) { issues.push(`Stage ${entry.stage}: ${entry.originalReason} was not mapped and no error was reported`); } }); // 检查是否有不完整的转换链 const stages = entries.map(e => e.stage); const expectedStages = ['input', 'transformation', 'output']; const missingStages = expectedStages.filter(stage => !stages.includes(stage)); if (missingStages.length > 0) { issues.push(`Missing stages in finish reason chain: ${missingStages.join(', ')}`); } return { hasSilentFailure: issues.length > 0, issues }; } /** * 在请求完成时生成最终报告并检查问题 */ finalizeRequest(requestId) { const report = this.generateEndToEndReport(requestId); const silentFailureCheck = this.detectSilentFailures(requestId); logger_1.logger.info(report, {}, requestId, 'finish-reason-final'); if (silentFailureCheck.hasSilentFailure) { logger_1.logger.error(`🚨 [SILENT-FAILURE-DETECTED] Request ${requestId} has potential silent failures:`, { issues: silentFailureCheck.issues }, requestId, 'finish-reason-silent-failure'); } } } // 单例实例 exports.unifiedFinishReasonLogger = new UnifiedFinishReasonLogger(); /** * 便捷方法:记录输入阶段的finish reason */ function logInputFinishReason(requestId, originalReason, provider, model, context, metadata) { exports.unifiedFinishReasonLogger.logFinishReasonTransformation({ requestId, stage: 'input', sourceFormat: provider, originalReason, provider, model, timestamp: new Date().toISOString(), context, metadata }); } /** * 便捷方法:记录转换阶段的finish reason */ function logTransformationFinishReason(requestId, originalReason, mappedReason, sourceFormat, targetFormat, provider, model, context, metadata, errorInfo) { exports.unifiedFinishReasonLogger.logFinishReasonTransformation({ requestId, stage: 'transformation', sourceFormat, targetFormat, originalReason, mappedReason, provider, model, timestamp: new Date().toISOString(), context, metadata, errorInfo }); } /** * 便捷方法:记录输出阶段的finish reason */ function logOutputFinishReason(requestId, finalReason, provider, model, context, metadata) { exports.unifiedFinishReasonLogger.logFinishReasonTransformation({ requestId, stage: 'output', sourceFormat: provider, originalReason: finalReason, provider, model, timestamp: new Date().toISOString(), context, metadata }); } /** * 便捷方法:记录流式处理阶段的finish reason */ function logStreamingFinishReason(requestId, originalReason, mappedReason, sourceFormat, targetFormat, provider, model, context, metadata, errorInfo) { exports.unifiedFinishReasonLogger.logFinishReasonTransformation({ requestId, stage: 'streaming', sourceFormat, targetFormat, originalReason, mappedReason, provider, model, timestamp: new Date().toISOString(), context, metadata, errorInfo }); } //# sourceMappingURL=unified-finish-reason-logger.js.map