UNPKG

route-claudecode

Version:

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

356 lines 14.3 kB
"use strict"; /** * Demo3流水线数据匹配器 - 完整流程一致性保证 * 确保从输入到输出的每个环节都与Demo3 AIClient-2-API保持一致 * 项目所有者: Jason Zhang */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Demo3PipelineMatcher = void 0; exports.createDemo3PipelineMatcher = createDemo3PipelineMatcher; const logger_1 = require("@/utils/logger"); const demo3_data_matcher_1 = require("./demo3-data-matcher"); class Demo3PipelineMatcher { config; constructor(config) { this.config = { endpoint: '/v1/messages', authHeaderName: 'x-api-key', authHeaderValue: 'demo3-api-key', enableProfileArn: true, profileArnTruncateLength: 50, conversationIdPrefix: 'demo3_conv_', messageIdPrefix: 'msg_demo3_', ...config }; logger_1.logger.info('Demo3 Pipeline Matcher initialized', { endpoint: this.config.endpoint, authHeader: this.config.authHeaderName, enableProfileArn: this.config.enableProfileArn }); } /** * 🎯 Step 1: 输入预处理 - 完全匹配Demo3的输入处理逻辑 */ preprocessInput(request) { const requestId = this.generateRequestId(); const context = { requestId, sessionId: request.metadata?.sessionId, conversationId: request.metadata?.conversationId || this.generateConversationId(), originalRequest: { ...request }, demo3Request: {}, // Will be filled in next step metadata: { startTime: Date.now(), stage: 'preprocessing' } }; // 🎯 Demo3特殊处理:ProfileArn处理(与demo3保持一致) if (this.config.enableProfileArn && request.metadata) { const profileArn = request.metadata.profileArn; if (profileArn && typeof profileArn === 'string') { context.metadata.profileArn = profileArn.length > this.config.profileArnTruncateLength ? profileArn.substring(0, this.config.profileArnTruncateLength) + '...' : profileArn; } else { context.metadata.profileArn = 'N/A (authMethod!=social)'; } } logger_1.logger.debug('Demo3 input preprocessing completed', { requestId: context.requestId, conversationId: context.conversationId, hasProfileArn: !!context.metadata.profileArn, originalModel: request.model }); return context; } /** * 🎯 Step 2: 请求转换 - 精确转换为Demo3格式 */ transformRequest(context) { context.metadata.stage = 'request_transformation'; try { // 使用Demo3数据匹配器进行精确转换 context.demo3Request = demo3_data_matcher_1.demo3DataMatcher.transformToDemo3Format(context.originalRequest); // 🎯 Demo3特殊字段处理 context.demo3Request.max_tokens = context.originalRequest.max_tokens || 131072; // 验证转换结果 demo3_data_matcher_1.demo3DataMatcher.validateDemo3Request(context.demo3Request); logger_1.logger.debug('Demo3 request transformation completed', { requestId: context.requestId, demo3Model: context.demo3Request.model, messageCount: context.demo3Request.messages.length, hasTools: !!(context.demo3Request.tools && context.demo3Request.tools.length > 0) }); return context; } catch (error) { logger_1.logger.error('Demo3 request transformation failed', { requestId: context.requestId, error: error instanceof Error ? error.message : String(error), originalRequest: context.originalRequest }); throw error; } } /** * 🎯 Step 3: API调用准备 - 生成Demo3兼容的API调用参数 */ prepareApiCall(context) { context.metadata.stage = 'api_preparation'; const headers = { 'Content-Type': 'application/json', 'User-Agent': 'claude-code-router/2.8.0 (demo3-compatible)' }; // 🎯 Demo3认证头处理 headers[this.config.authHeaderName] = this.config.authHeaderValue; // 🎯 Demo3特殊头部 (如果需要) if (context.metadata.profileArn) { headers['X-Profile-Arn'] = context.metadata.profileArn; } const apiCall = { url: this.config.endpoint, method: 'POST', headers, body: context.demo3Request }; logger_1.logger.debug('Demo3 API call prepared', { requestId: context.requestId, endpoint: apiCall.url, authMethod: this.config.authHeaderName, bodySize: JSON.stringify(apiCall.body).length }); return apiCall; } /** * 🎯 Step 4: 响应处理 - 处理Demo3返回的响应 */ processResponse(context, apiResponse) { context.metadata.stage = 'response_processing'; context.metadata.endTime = Date.now(); context.metadata.duration = context.metadata.endTime - context.metadata.startTime; try { // 🎯 确保响应符合Demo3格式 const demo3Response = this.validateAndNormalizeDemo3Response(apiResponse); context.demo3Response = demo3Response; // 验证响应完整性 demo3_data_matcher_1.demo3DataMatcher.validateDemo3Response(demo3Response); logger_1.logger.debug('Demo3 response processing completed', { requestId: context.requestId, responseId: demo3Response.id, contentBlocks: demo3Response.content.length, stopReason: demo3Response.stop_reason, duration: context.metadata.duration }); return context; } catch (error) { logger_1.logger.error('Demo3 response processing failed', { requestId: context.requestId, error: error instanceof Error ? error.message : String(error), apiResponse: typeof apiResponse === 'object' ? JSON.stringify(apiResponse).substring(0, 500) : apiResponse }); throw error; } } /** * 🎯 Step 5: 输出转换 - 转换为标准格式但保持Demo3特征 */ transformOutput(context) { context.metadata.stage = 'output_transformation'; if (!context.demo3Response) { throw new Error('No Demo3 response available for transformation'); } try { // 使用Demo3数据匹配器转换响应 const transformedResponse = demo3_data_matcher_1.demo3DataMatcher.transformFromDemo3Format(context.demo3Response); // 🎯 保持Demo3特殊字段 context.transformedResponse = { ...transformedResponse, // 保留原始请求ID映射 id: context.demo3Response.id, // 保留Demo3模型名 model: context.demo3Response.model, // 添加Demo3特有的元数据 metadata: { demo3Compatible: true, originalRequestId: context.requestId, conversationId: context.conversationId, processingDuration: context.metadata.duration } }; logger_1.logger.debug('Demo3 output transformation completed', { requestId: context.requestId, outputId: context.transformedResponse?.id, contentBlocks: context.transformedResponse?.content?.length, demo3Compatible: true }); return context; } catch (error) { logger_1.logger.error('Demo3 output transformation failed', { requestId: context.requestId, error: error instanceof Error ? error.message : String(error) }); throw error; } } /** * 🎯 完整流水线处理 - 一站式Demo3兼容处理 */ async processFullPipeline(request, apiCallFunction) { let context; try { // Step 1: 输入预处理 context = this.preprocessInput(request); // Step 2: 请求转换 context = this.transformRequest(context); // Step 3: API调用准备 const apiCall = this.prepareApiCall(context); // Step 4: 执行API调用 logger_1.logger.debug('Executing Demo3-compatible API call', { requestId: context.requestId, endpoint: apiCall.url }); const apiResponse = await apiCallFunction(apiCall); // Step 5: 响应处理 context = this.processResponse(context, apiResponse); // Step 6: 输出转换 context = this.transformOutput(context); if (!context.transformedResponse) { throw new Error('Pipeline completed but no transformed response available'); } logger_1.logger.info('Demo3 pipeline processing completed successfully', { requestId: context.requestId, totalDuration: context.metadata.duration, stage: context.metadata.stage }); return context.transformedResponse; } catch (error) { logger_1.logger.error('Demo3 pipeline processing failed', { requestId: context?.requestId || 'unknown', stage: context?.metadata.stage || 'unknown', error: error instanceof Error ? error.message : String(error) }); throw error; } } /** * 🎯 流式处理支持 - Demo3兼容的流式响应处理 */ async *processStreamPipeline(request, streamApiCallFunction) { let context; try { // 准备阶段 context = this.preprocessInput(request); context = this.transformRequest(context); const apiCall = this.prepareApiCall(context); // 流式处理 logger_1.logger.debug('Starting Demo3-compatible stream processing', { requestId: context.requestId }); let chunkCount = 0; for await (const chunk of streamApiCallFunction(apiCall)) { chunkCount++; // 🎯 Demo3流式响应格式化 const formattedChunk = this.formatStreamChunk(chunk, context, chunkCount); logger_1.logger.trace(context.requestId, 'demo3', 'Demo3 stream chunk processed', { requestId: context.requestId, chunkIndex: chunkCount, chunkType: formattedChunk.event }); yield formattedChunk; } logger_1.logger.debug('Demo3 stream processing completed', { requestId: context.requestId, totalChunks: chunkCount }); } catch (error) { logger_1.logger.error('Demo3 stream pipeline failed', { requestId: context?.requestId || 'unknown', error: error instanceof Error ? error.message : String(error) }); throw error; } } /** * Demo3响应格式验证和标准化 */ validateAndNormalizeDemo3Response(apiResponse) { if (!apiResponse || typeof apiResponse !== 'object') { throw new Error('Invalid API response: not an object'); } // 🎯 确保具有Demo3响应的必需字段 const normalized = { id: apiResponse.id || this.generateMessageId(), type: 'message', role: 'assistant', content: Array.isArray(apiResponse.content) ? apiResponse.content : [], model: apiResponse.model || 'CLAUDE_SONNET_4_20250514_V1_0', stop_reason: apiResponse.stop_reason || 'end_turn', stop_sequence: apiResponse.stop_sequence || null, usage: apiResponse.usage || { input_tokens: 0, output_tokens: 0 } }; return normalized; } /** * 流式chunk格式化 */ formatStreamChunk(chunk, context, chunkIndex) { return { event: chunk.event || 'data', data: chunk.data || chunk, metadata: { requestId: context.requestId, chunkIndex, demo3Compatible: true } }; } /** * 生成Demo3兼容的请求ID */ generateRequestId() { return `demo3_req_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`; } /** * 生成Demo3兼容的对话ID */ generateConversationId() { return `${this.config.conversationIdPrefix}${Date.now()}_${Math.random().toString(36).substring(2, 8)}`; } /** * 生成Demo3兼容的消息ID */ generateMessageId() { return `${this.config.messageIdPrefix}${Date.now()}_${Math.random().toString(36).substring(2, 8)}`; } /** * 🎯 获取处理统计信息 */ getProcessingStats(context) { return { requestId: context.requestId, conversationId: context.conversationId, stage: context.metadata.stage, duration: context.metadata.duration, hasProfileArn: !!context.metadata.profileArn, demo3Model: context.demo3Request?.model, contentBlocks: context.transformedResponse?.content?.length || 0, demo3Compatible: true }; } } exports.Demo3PipelineMatcher = Demo3PipelineMatcher; /** * 创建Demo3流水线匹配器实例 */ function createDemo3PipelineMatcher(config) { return new Demo3PipelineMatcher(config); } //# sourceMappingURL=demo3-pipeline-matcher.js.map