route-claudecode
Version:
Advanced routing and transformation system for Claude Code outputs to multiple AI providers
216 lines • 8.56 kB
JavaScript
;
/**
* 通用高效流式解析器框架
* 适用于所有Provider的响应优化
* Owner: Jason Zhang
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UniversalParserFactory = exports.UniversalStreamingParser = exports.DirectStreamingStrategy = exports.BufferedProcessingStrategy = exports.BatchStreamingStrategy = exports.OpenAIAnalyzer = exports.CodeWhispererAnalyzer = void 0;
const logger_1 = require("@/utils/logger");
/**
* CodeWhisperer数据分析器
*/
class CodeWhispererAnalyzer {
analyzeResponseStructure(buffer) {
const size = Buffer.isBuffer(buffer) ? buffer.length : Buffer.byteLength(buffer);
const content = Buffer.isBuffer(buffer) ? buffer.toString('utf8', 0, Math.min(2048, size)) : buffer.slice(0, 2048);
// 基于实际CodeWhisperer数据模式
const hasToolCalls = this.detectToolCalls(content);
const estimatedEventCount = this.estimateEventCount(content);
return {
totalSize: size,
estimatedEventCount,
hasToolCalls,
recommendedStrategy: hasToolCalls ? 'buffered' :
(estimatedEventCount > 500 ? 'batch-streaming' : 'direct-streaming'),
eventSize: estimatedEventCount > 500 ? 'small' : 'medium',
confidence: 0.9
};
}
detectToolCalls(data) {
const toolSignatures = [
'tool_use', 'function_call', 'Tool call:',
'"type": "tool_use"', '"name":', '"input":'
];
return toolSignatures.some(sig => data.includes(sig));
}
estimateEventCount(data) {
// 基于实际观察:114KB = 856个事件
const avgEventSize = 133; // 字节
const totalSize = Buffer.byteLength(data);
return Math.ceil(totalSize / avgEventSize);
}
}
exports.CodeWhispererAnalyzer = CodeWhispererAnalyzer;
/**
* OpenAI数据分析器
*/
class OpenAIAnalyzer {
analyzeResponseStructure(buffer) {
const size = Buffer.isBuffer(buffer) ? buffer.length : Buffer.byteLength(buffer);
const content = Buffer.isBuffer(buffer) ? buffer.toString('utf8') : buffer;
const hasToolCalls = this.detectToolCalls(content);
const estimatedEventCount = this.estimateEventCount(content);
return {
totalSize: size,
estimatedEventCount,
hasToolCalls,
recommendedStrategy: hasToolCalls ? 'buffered' : 'direct-streaming',
eventSize: 'medium',
confidence: 0.8
};
}
detectToolCalls(data) {
const toolSignatures = [
'"tool_calls":', '"function":', '"tool_call_id":',
'function_call', 'tool_call'
];
return toolSignatures.some(sig => data.includes(sig));
}
estimateEventCount(data) {
// OpenAI事件通常比CodeWhisperer大
const lines = data.split('\n').filter(line => line.startsWith('data: '));
return lines.length;
}
}
exports.OpenAIAnalyzer = OpenAIAnalyzer;
/**
* 批量流式优化策略
*/
class BatchStreamingStrategy {
name = 'batch-streaming';
shouldUse(analysis) {
return analysis.recommendedStrategy === 'batch-streaming' &&
analysis.eventSize === 'small' &&
analysis.estimatedEventCount > 100;
}
async process(data, requestId, metadata) {
logger_1.logger.info(`🚀 Using batch streaming optimization`, {
dataSize: Buffer.isBuffer(data) ? data.length : data.length,
strategy: this.name
}, requestId, 'universal-parser');
// 这里应该调用具体provider的批量处理逻辑
// 由子类实现具体的解析逻辑
throw new Error('BatchStreamingStrategy.process must be implemented by provider-specific class');
}
}
exports.BatchStreamingStrategy = BatchStreamingStrategy;
/**
* 完全缓冲优化策略
*/
class BufferedProcessingStrategy {
name = 'buffered';
shouldUse(analysis) {
return analysis.recommendedStrategy === 'buffered' || analysis.hasToolCalls;
}
async process(data, requestId, metadata) {
logger_1.logger.info(`🔧 Using buffered processing (tool calls detected)`, {
dataSize: Buffer.isBuffer(data) ? data.length : data.length,
strategy: this.name
}, requestId, 'universal-parser');
// 由子类实现具体的缓冲处理逻辑
throw new Error('BufferedProcessingStrategy.process must be implemented by provider-specific class');
}
}
exports.BufferedProcessingStrategy = BufferedProcessingStrategy;
/**
* 直接流式策略
*/
class DirectStreamingStrategy {
name = 'direct-streaming';
shouldUse(analysis) {
return analysis.recommendedStrategy === 'direct-streaming' &&
!analysis.hasToolCalls &&
analysis.estimatedEventCount < 100;
}
async process(data, requestId, metadata) {
logger_1.logger.info(`⚡ Using direct streaming (small response)`, {
dataSize: Buffer.isBuffer(data) ? data.length : data.length,
strategy: this.name
}, requestId, 'universal-parser');
// 由子类实现具体的直接处理逻辑
throw new Error('DirectStreamingStrategy.process must be implemented by provider-specific class');
}
}
exports.DirectStreamingStrategy = DirectStreamingStrategy;
/**
* 通用流式解析器
*/
class UniversalStreamingParser {
analyzer;
strategies;
constructor(analyzer, strategies) {
this.analyzer = analyzer;
this.strategies = strategies;
}
async processResponse(data, requestId, metadata) {
const startTime = Date.now();
// 分析数据特征
const analysis = this.analyzer.analyzeResponseStructure(data);
logger_1.logger.info('📊 Stream response analysis completed', {
totalSize: analysis.totalSize,
estimatedEvents: analysis.estimatedEventCount,
hasToolCalls: analysis.hasToolCalls,
recommendedStrategy: analysis.recommendedStrategy,
eventSize: analysis.eventSize,
confidence: analysis.confidence,
analysisTime: Date.now() - startTime
}, requestId, 'universal-parser');
// 选择最佳策略
const selectedStrategy = this.strategies.find(strategy => strategy.shouldUse(analysis));
if (!selectedStrategy) {
throw new Error(`No suitable streaming strategy found for analysis: ${JSON.stringify(analysis)}`);
}
logger_1.logger.info(`🎯 Selected optimization strategy: ${selectedStrategy.name}`, {
strategy: selectedStrategy.name,
reason: analysis.recommendedStrategy
}, requestId, 'universal-parser');
// 执行选择的策略
return selectedStrategy.process(data, requestId, { analysis, ...metadata });
}
}
exports.UniversalStreamingParser = UniversalStreamingParser;
/**
* Provider工厂方法
*/
class UniversalParserFactory {
static createCodeWhispererParser() {
const analyzer = new CodeWhispererAnalyzer();
const strategies = [
new BufferedProcessingStrategy(),
new BatchStreamingStrategy(),
new DirectStreamingStrategy()
];
return new UniversalStreamingParser(analyzer, strategies);
}
static createOpenAIParser() {
const analyzer = new OpenAIAnalyzer();
const strategies = [
new BufferedProcessingStrategy(),
new DirectStreamingStrategy()
];
return new UniversalStreamingParser(analyzer, strategies);
}
static createGeminiParser() {
// Note: GeminiAnalyzer will be imported from gemini provider
// This method will be implemented after circular dependency resolution
throw new Error('Gemini parser should be created via gemini provider factory method');
}
/**
* 通用工厂方法 - 根据provider类型创建对应解析器
*/
static createParser(providerType) {
switch (providerType) {
case 'codewhisperer':
return this.createCodeWhispererParser();
case 'openai':
return this.createOpenAIParser();
case 'gemini':
return this.createGeminiParser();
default:
throw new Error(`Unsupported provider type: ${providerType}`);
}
}
}
exports.UniversalParserFactory = UniversalParserFactory;
//# sourceMappingURL=universal-streaming-parser.js.map