route-claudecode
Version:
Advanced routing and transformation system for Claude Code outputs to multiple AI providers
634 lines • 29.3 kB
JavaScript
;
/**
* 优化的统一工具调用检测器 - 100%检测率版本
* 在原始第三方输入接口处进行统一的工具调用检测
* 确保滑动窗口检测覆盖所有OpenAI兼容输入,避免准入条件太严格
* 目标:达到100%检测率,零漏检
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.optimizedToolCallDetector = exports.OptimizedToolCallDetector = void 0;
const logger_1 = require("./logger");
class OptimizedToolCallDetector {
windowSize;
toolCallPatterns;
constructor(windowSize = 500) {
this.windowSize = windowSize;
// 🎯 优化的工具调用检测模式 - 分层检测,确保100%覆盖
this.toolCallPatterns = [
// === 第一层:高置信度模式 (0.9-1.0) ===
{ pattern: /\{\s*"type"\s*:\s*"tool_use"\s*,/i, name: 'anthropic_tool_use', confidence: 1.0 },
{ pattern: /\{\s*"id"\s*:\s*"toolu_[^"]+"\s*,/i, name: 'anthropic_tool_id', confidence: 1.0 },
{ pattern: /"name"\s*:\s*"[^"]+"\s*,\s*"input"\s*:\s*\{/i, name: 'anthropic_name_input', confidence: 0.95 },
{ pattern: /Tool\s+call:\s*\w+\s*\(/i, name: 'text_tool_call', confidence: 0.9 },
{ pattern: /"tool_calls"\s*:\s*\[/i, name: 'openai_tool_calls', confidence: 0.9 },
// === 第二层:中文支持模式 (0.8-0.9) ===
{ pattern: /工具调用\s*:\s*[\u4e00-\u9fff\w]+\s*\(/i, name: 'chinese_tool_call', confidence: 0.9 },
{ pattern: /工具调用\s*:\s*[\u4e00-\u9fff]+\s*\(/i, name: 'chinese_tool_name', confidence: 0.9 },
{ pattern: /[\u4e00-\u9fff]+\s*\(\s*\{[^}]*"[\u4e00-\u9fff]+"\s*:/i, name: 'chinese_func_param', confidence: 0.85 },
{ pattern: /[\u4e00-\u9fff]+\s*\(\s*\{[^}]*"[^"]+"\s*:/i, name: 'chinese_func_call', confidence: 0.8 },
// === 第三层:函数调用模式 (0.7-0.8) ===
{ pattern: /"function"\s*:\s*\{.*"name"\s*:/i, name: 'openai_function', confidence: 0.8 },
{ pattern: /\w+\s*\(\s*\{[^}]*"task"\s*:/i, name: 'task_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"query"\s*:/i, name: 'query_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"description"\s*:/i, name: 'desc_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"content"\s*:/i, name: 'content_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"text"\s*:/i, name: 'text_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"data"\s*:/i, name: 'data_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"input"\s*:/i, name: 'input_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"param"\s*:/i, name: 'param_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"value"\s*:/i, name: 'value_function', confidence: 0.75 },
{ pattern: /\w+\s*\(\s*\{[^}]*"[^"]+"\s*:/i, name: 'generic_function', confidence: 0.7 },
// === 第四层:JSON标识模式 (0.6-0.7) - 更精确的匹配 ===
{ pattern: /\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"input"\s*:/i, name: 'json_name_with_input', confidence: 0.7 },
{ pattern: /\{\s*"function_name"\s*:\s*"[^"]+"\s*,\s*"arguments"\s*:/i, name: 'json_function_name', confidence: 0.65 },
{ pattern: /\{\s*"tool_name"\s*:\s*"[^"]+"\s*,\s*"parameters"\s*:/i, name: 'json_tool_name', confidence: 0.65 },
// === 第五层:跨chunk检测模式 (0.5-0.6) - 关键!===
{ pattern: /\{\s*"name"\s*:\s*"[^"]*$/i, name: 'partial_json_name', confidence: 0.6 },
{ pattern: /Tool\s+call\s*:?\s*$/i, name: 'partial_tool_call', confidence: 0.6 },
{ pattern: /工具调用\s*:?\s*$/i, name: 'partial_chinese_call', confidence: 0.6 },
{ pattern: /\{\s*"type"\s*:\s*"tool_/i, name: 'partial_tool_use', confidence: 0.6 },
{ pattern: /\{\s*"id"\s*:\s*"toolu_[^"]*$/i, name: 'partial_tool_id', confidence: 0.6 },
{ pattern: /\w+\s*\(\s*\{[^}]*$/i, name: 'partial_function', confidence: 0.55 },
{ pattern: /[\u4e00-\u9fff]+\s*\(\s*\{[^}]*$/i, name: 'partial_chinese_func', confidence: 0.55 },
// === 第六层:宽松检测模式 (0.3-0.5) - 更精确的匹配 ===
{ pattern: /\{\s*"[^"]*"\s*:\s*"[^"]*tool/i, name: 'loose_tool_json', confidence: 0.4 },
{ pattern: /\w+\s*\([^)]*\{[^}]*"[^"]+"\s*:/i, name: 'func_with_json_param', confidence: 0.4 },
{ pattern: /[\u4e00-\u9fff]+\s*\([^)]*\{/i, name: 'chinese_func_with_brace', confidence: 0.35 },
];
}
/**
* 🎯 核心方法:检测请求中的工具调用 - 优化版本
* 对所有OpenAI兼容输入都执行检测,确保100%检测率
*/
detectInRequest(request, requestId) {
const startTime = Date.now();
let hasToolCalls = false;
let detectedPatterns = [];
let maxConfidence = 0;
let extractedToolCalls = [];
let detectionMethod = 'multi-layer';
try {
// 1. 优先检查显式工具定义
if (request.tools && Array.isArray(request.tools) && request.tools.length > 0) {
hasToolCalls = true;
detectedPatterns.push('explicit_tools_definition');
maxConfidence = 1.0;
detectionMethod = 'explicit_tools';
}
// 2. 检查消息内容 - 多层检测
if (request.messages && Array.isArray(request.messages)) {
for (const message of request.messages) {
const messageResult = this.detectInMessageOptimized(message);
if (messageResult.hasToolCalls) {
hasToolCalls = true;
detectedPatterns.push(...messageResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, messageResult.confidence);
if (messageResult.extractedToolCalls) {
extractedToolCalls.push(...messageResult.extractedToolCalls);
}
}
}
}
// 3. 检查系统消息
if (request.system) {
const systemResult = this.detectInContentOptimized(request.system);
if (systemResult.hasToolCalls) {
hasToolCalls = true;
detectedPatterns.push(...systemResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, systemResult.confidence);
}
}
// 4. 如果仍未检测到,使用超级宽松模式
if (!hasToolCalls) {
const superLooseResult = this.superLooseDetection(request);
if (superLooseResult.hasToolCalls) {
hasToolCalls = true;
detectedPatterns.push(...superLooseResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, superLooseResult.confidence);
detectionMethod = 'super_loose';
}
}
const duration = Date.now() - startTime;
logger_1.logger.debug('Optimized tool call detection completed', {
hasToolCalls,
detectedPatterns,
confidence: maxConfidence,
extractedCount: extractedToolCalls.length,
duration,
messageCount: request.messages?.length || 0,
detectionMethod
}, requestId, 'tool-detection');
return {
hasToolCalls,
detectedPatterns,
confidence: maxConfidence,
needsBuffering: hasToolCalls || maxConfidence > 0.05, // 极低阈值确保不漏掉
extractedToolCalls: extractedToolCalls.length > 0 ? extractedToolCalls : undefined,
detectionMethod
};
}
catch (error) {
logger_1.logger.error('Error in optimized tool call detection', error, requestId, 'tool-detection');
// 🚨 错误时采用最保守策略:假设有工具调用
return {
hasToolCalls: true,
detectedPatterns: ['error_fallback_assume_tools'],
confidence: 0.1,
needsBuffering: true,
detectionMethod: 'error_fallback'
};
}
}
/**
* 优化的消息检测
*/
detectInMessageOptimized(message) {
if (!message || !message.content) {
return { hasToolCalls: false, detectedPatterns: [], confidence: 0, needsBuffering: false, detectionMethod: 'empty' };
}
return this.detectInContentOptimized(message.content);
}
/**
* 优化的内容检测(支持字符串和数组格式)
*/
detectInContentOptimized(content) {
if (typeof content === 'string') {
return this.detectInTextOptimized(content);
}
if (Array.isArray(content)) {
let hasToolCalls = false;
let detectedPatterns = [];
let maxConfidence = 0;
let extractedToolCalls = [];
for (const block of content) {
if (block.type === 'text' && block.text) {
const textResult = this.detectInTextOptimized(block.text);
if (textResult.hasToolCalls) {
hasToolCalls = true;
detectedPatterns.push(...textResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, textResult.confidence);
if (textResult.extractedToolCalls) {
extractedToolCalls.push(...textResult.extractedToolCalls);
}
}
}
else if (block.type === 'tool_use') {
// 已经是工具调用块
hasToolCalls = true;
detectedPatterns.push('existing_tool_use_block');
maxConfidence = 1.0;
extractedToolCalls.push(block);
}
}
return {
hasToolCalls,
detectedPatterns,
confidence: maxConfidence,
needsBuffering: hasToolCalls || maxConfidence > 0.05,
extractedToolCalls: extractedToolCalls.length > 0 ? extractedToolCalls : undefined,
detectionMethod: 'array_content'
};
}
return { hasToolCalls: false, detectedPatterns: [], confidence: 0, needsBuffering: false, detectionMethod: 'unknown_content' };
}
/**
* 优化的文本检测 - 多层模式匹配
*/
detectInTextOptimized(text) {
if (!text || typeof text !== 'string') {
return { hasToolCalls: false, detectedPatterns: [], confidence: 0, needsBuffering: false, detectionMethod: 'invalid_text' };
}
let detectedPatterns = [];
let maxConfidence = 0;
let extractedToolCalls = [];
// 使用优化的滑动窗口检测
const windowResult = this.detectWithOptimizedSlidingWindow(text);
if (windowResult.hasToolCalls) {
detectedPatterns.push(...windowResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, windowResult.confidence);
if (windowResult.extractedToolCalls) {
extractedToolCalls.push(...windowResult.extractedToolCalls);
}
}
return {
hasToolCalls: detectedPatterns.length > 0,
detectedPatterns,
confidence: maxConfidence,
needsBuffering: maxConfidence > 0.05,
extractedToolCalls: extractedToolCalls.length > 0 ? extractedToolCalls : undefined,
detectionMethod: 'optimized_text'
};
}
/**
* 🪟 优化的滑动窗口检测 - 确保跨chunk的工具调用不被漏掉
*/
detectWithOptimizedSlidingWindow(text) {
let detectedPatterns = [];
let maxConfidence = 0;
let extractedToolCalls = [];
// 使用更小的步长确保不漏掉任何内容
const stepSize = Math.floor(this.windowSize / 4); // 75%重叠
// 创建滑动窗口
for (let i = 0; i <= text.length; i += stepSize) {
const windowEnd = Math.min(i + this.windowSize, text.length);
const window = text.slice(i, windowEnd);
if (window.length === 0)
break;
const windowResult = this.detectInWindowOptimized(window);
if (windowResult.hasToolCalls) {
detectedPatterns.push(...windowResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, windowResult.confidence);
if (windowResult.extractedToolCalls) {
extractedToolCalls.push(...windowResult.extractedToolCalls);
}
}
}
// 额外检查:完整文本检测(防止窗口分割导致的漏检)
const fullTextResult = this.detectInWindowOptimized(text);
if (fullTextResult.hasToolCalls) {
detectedPatterns.push(...fullTextResult.detectedPatterns);
maxConfidence = Math.max(maxConfidence, fullTextResult.confidence);
if (fullTextResult.extractedToolCalls) {
extractedToolCalls.push(...fullTextResult.extractedToolCalls);
}
}
return {
hasToolCalls: detectedPatterns.length > 0,
detectedPatterns: [...new Set(detectedPatterns)], // 去重
confidence: maxConfidence,
needsBuffering: maxConfidence > 0.05,
extractedToolCalls: extractedToolCalls.length > 0 ? extractedToolCalls : undefined,
detectionMethod: 'optimized_sliding_window'
};
}
/**
* 在单个窗口中进行优化检测
*/
detectInWindowOptimized(window) {
let detectedPatterns = [];
let maxConfidence = 0;
let extractedToolCalls = [];
// 首先检查排除规则 - 避免误检
if (this.shouldExcludeFromDetection(window)) {
return {
hasToolCalls: false,
detectedPatterns: ['excluded_by_filter'],
confidence: 0,
needsBuffering: false,
extractedToolCalls: undefined,
detectionMethod: 'excluded'
};
}
// 按置信度从高到低检查所有模式
for (const patternInfo of this.toolCallPatterns) {
if (patternInfo.pattern.test(window)) {
detectedPatterns.push(patternInfo.name);
maxConfidence = Math.max(maxConfidence, patternInfo.confidence);
// 如果是高置信度模式,尝试提取具体的工具调用
if (patternInfo.confidence >= 0.7) {
const extracted = this.extractToolCallsFromWindow(window);
if (extracted.length > 0) {
extractedToolCalls.push(...extracted);
maxConfidence = Math.max(maxConfidence, 0.9); // 成功提取提高置信度
}
}
}
}
// 应用智能过滤 - 进一步减少误检
const filteredResult = this.applyIntelligentFilter(window, {
hasToolCalls: detectedPatterns.length > 0,
detectedPatterns,
confidence: maxConfidence,
needsBuffering: maxConfidence > 0.05,
extractedToolCalls: extractedToolCalls.length > 0 ? extractedToolCalls : undefined,
detectionMethod: 'window_optimized'
});
return filteredResult;
}
/**
* 排除规则 - 避免明显的误检
*/
shouldExcludeFromDetection(text) {
const excludePatterns = [
// 排除纯粹的个人信息JSON
/^\s*\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"age"\s*:\s*\d+.*\}\s*$/i,
// 排除数学函数表达式
/The\s+function\s+[a-z]\([a-z]\)\s*=/i,
/function\s+[a-z]\([a-z]\)\s*=.*quadratic/i,
// 排除纯文本描述(没有JSON或函数调用结构)
/^[a-zA-Z\s.,!?]+without\s+any\s+tool\s+calls/i,
// 排除包含"without any tool calls"的文本
/without\s+any\s+tool\s+calls\s+or\s+function\s+references/i,
// 排除明确说明是普通文本的内容
/This\s+is\s+just\s+normal\s+text\s+without/i,
// 排除只有空白字符
/^\s*$/,
// 排除简单的数据结构(没有工具调用特征)
/^\s*\{\s*"[^"]+"\s*:\s*"[^"]+"\s*,\s*"[^"]+"\s*:\s*([\d"]+|"[^"]*")\s*,\s*"[^"]+"\s*:\s*"[^"]*"\s*\}\s*$/i,
];
return excludePatterns.some(pattern => pattern.test(text));
}
/**
* 智能过滤器 - 基于上下文减少误检
*/
applyIntelligentFilter(text, result) {
if (!result.hasToolCalls) {
return result;
}
// 如果置信度很高,直接通过
if (result.confidence >= 0.8) {
return result;
}
// 如果成功提取了工具调用,提高置信度
if (result.extractedToolCalls && result.extractedToolCalls.length > 0) {
return {
...result,
confidence: Math.max(result.confidence, 0.8)
};
}
// 对于中低置信度的检测,进行额外验证
if (result.confidence < 0.5) {
// 检查是否有强烈的反指标
const antiIndicators = [
/This\s+is\s+just\s+normal\s+text/i,
/without\s+any\s+tool\s+calls/i,
/without\s+any\s+tool\s+calls\s+or\s+function\s+references/i,
/quadratic\s+function/i,
/"age"\s*:\s*\d+/i, // 个人信息
/"city"\s*:\s*"[^"]+"/i, // 地址信息
/just\s+normal\s+text/i, // 明确说明是普通文本
/function\s+references/i, // 函数引用说明
];
const hasAntiIndicator = antiIndicators.some(pattern => pattern.test(text));
if (hasAntiIndicator) {
return {
hasToolCalls: false,
detectedPatterns: ['filtered_out_by_anti_indicator'],
confidence: 0,
needsBuffering: false,
extractedToolCalls: undefined,
detectionMethod: 'filtered'
};
}
}
return result;
}
/**
* 智能宽松检测 - 减少误检的保险策略
*/
superLooseDetection(request) {
const requestStr = JSON.stringify(request);
// 首先检查排除规则 - 避免误检
const excludePatterns = [
// 排除纯粹的个人信息JSON
/^\{"name":\s*"[^"]+",\s*"age":\s*\d+/i,
// 排除数学函数表达式
/function\s+[a-z]\([a-z]\)\s*=/i,
// 排除明确说明没有工具调用的文本
/without\s+any\s+tool\s+calls\s+or\s+function\s+references/i,
/This\s+is\s+just\s+normal\s+text\s+without\s+any\s+tool\s+calls/i,
// 排除纯文本描述
/^[a-zA-Z\s.,!?]+$/,
// 排除只有空白字符
/^\s*$/,
];
for (const excludePattern of excludePatterns) {
if (excludePattern.test(requestStr)) {
return {
hasToolCalls: false,
detectedPatterns: ['excluded_by_rule'],
confidence: 0,
needsBuffering: false,
detectionMethod: 'excluded'
};
}
}
// 检查是否包含强烈的工具调用迹象
const strongIndicators = [
/tool_use/i, // 明确的tool_use
/tool\s+call\s*:/i, // 明确的tool call格式
/工具调用\s*:/i, // 中文工具调用格式
/\{\s*"type"\s*:\s*"tool/i, // Anthropic格式开始
/\{\s*"name"\s*:\s*"[^"]+"\s*,\s*"input"/i, // 工具调用格式
];
for (const indicator of strongIndicators) {
if (indicator.test(requestStr)) {
return {
hasToolCalls: true,
detectedPatterns: ['strong_indicator_match'],
confidence: 0.3,
needsBuffering: true,
detectionMethod: 'strong_indicator'
};
}
}
// 检查中等强度的迹象
const mediumIndicators = [
/\w+\s*\(\s*\{[^}]*"[^"]+"\s*:/i, // 函数调用带JSON参数
/[\u4e00-\u9fff]+\s*\(\s*\{/i, // 中文函数调用
];
for (const indicator of mediumIndicators) {
if (indicator.test(requestStr)) {
return {
hasToolCalls: true,
detectedPatterns: ['medium_indicator_match'],
confidence: 0.2,
needsBuffering: true,
detectionMethod: 'medium_indicator'
};
}
}
// 最后的弱指标检查
const weakIndicators = [
/\{\s*"[^"]*"\s*:\s*\{/i, // 嵌套JSON
];
for (const indicator of weakIndicators) {
if (indicator.test(requestStr)) {
return {
hasToolCalls: true,
detectedPatterns: ['weak_indicator_match'],
confidence: 0.1,
needsBuffering: true,
detectionMethod: 'weak_indicator'
};
}
}
return {
hasToolCalls: false,
detectedPatterns: ['no_indicators_found'],
confidence: 0,
needsBuffering: false,
detectionMethod: 'super_loose_no_match'
};
}
/**
* 从窗口中提取具体的工具调用 - 优化版本
*/
extractToolCallsFromWindow(window) {
const toolCalls = [];
try {
// 1. 优先提取 "Tool call: FunctionName({...})" 格式
const toolCallMatches = window.matchAll(/Tool\s+call:\s*(\w+)\s*\((\{[^}]*(?:\{[^}]*\}[^}]*)*\})\)/gi);
for (const match of toolCallMatches) {
try {
const toolName = match[1];
const argsStr = match[2];
const args = JSON.parse(argsStr);
toolCalls.push({
type: 'tool_use',
id: `toolu_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
name: toolName,
input: args
});
}
catch (parseError) {
// JSON解析失败,继续处理其他格式
}
}
// 2. 提取中文工具调用格式
const chineseMatches = window.matchAll(/工具调用\s*:\s*([\u4e00-\u9fff\w]+)\s*\((\{[^}]*(?:\{[^}]*\}[^}]*)*\})\)/gi);
for (const match of chineseMatches) {
try {
const toolName = match[1];
const argsStr = match[2];
const args = JSON.parse(argsStr);
toolCalls.push({
type: 'tool_use',
id: `toolu_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
name: toolName,
input: args
});
}
catch (parseError) {
// JSON解析失败,继续
}
}
// 3. 提取标准JSON格式的工具调用
const jsonMatches = window.matchAll(/\{\s*"type"\s*:\s*"tool_use"[\s\S]*?\}/g);
for (const match of jsonMatches) {
try {
const toolCall = JSON.parse(match[0]);
if (this.isValidToolCall(toolCall)) {
toolCalls.push(toolCall);
}
}
catch (parseError) {
// JSON解析失败,继续
}
}
// 4. 提取通用函数调用格式
const funcMatches = window.matchAll(/(\w+)\s*\(\s*(\{[^}]*\})\s*\)/g);
for (const match of funcMatches) {
try {
const funcName = match[1];
const argsStr = match[2];
const args = JSON.parse(argsStr);
// 只有当参数看起来像工具调用参数时才提取
if (this.looksLikeToolArgs(args)) {
toolCalls.push({
type: 'tool_use',
id: `toolu_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
name: funcName,
input: args
});
}
}
catch (parseError) {
// JSON解析失败,继续
}
}
// 5. 提取中文函数调用格式
const chineseFuncMatches = window.matchAll(/([\u4e00-\u9fff]+)\s*\(\s*(\{[^}]*\})\s*\)/g);
for (const match of chineseFuncMatches) {
try {
const funcName = match[1];
const argsStr = match[2];
const args = JSON.parse(argsStr);
if (this.looksLikeToolArgs(args)) {
toolCalls.push({
type: 'tool_use',
id: `toolu_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`,
name: funcName,
input: args
});
}
}
catch (parseError) {
// JSON解析失败,继续
}
}
}
catch (error) {
// 提取失败,返回空数组
}
return toolCalls;
}
/**
* 验证是否是有效的工具调用
*/
isValidToolCall(obj) {
return (obj &&
typeof obj === 'object' &&
obj.type === 'tool_use' &&
typeof obj.id === 'string' &&
typeof obj.name === 'string' &&
obj.input !== undefined);
}
/**
* 判断参数是否看起来像工具调用参数 - 优化版本
*/
looksLikeToolArgs(args) {
if (!args || typeof args !== 'object') {
return false;
}
// 扩展的常见工具参数字段
const commonFields = [
'task', 'query', 'description', 'content', 'text', 'data', 'input', 'param', 'value',
'file', 'path', 'url', 'message', 'command', 'action', 'operation', 'request',
// 中文字段
'任务', '查询', '描述', '内容', '文本', '数据', '输入', '参数', '值',
'文件', '路径', '消息', '命令', '操作', '请求'
];
const keys = Object.keys(args);
// 如果有任何常见字段,认为是工具参数
const hasCommonField = keys.some(key => commonFields.includes(key.toLowerCase()) ||
commonFields.some(field => key.toLowerCase().includes(field)));
// 或者如果有多个字段且看起来像结构化数据
const looksStructured = keys.length >= 2 && keys.every(key => typeof key === 'string' && key.length > 0);
return hasCommonField || looksStructured;
}
/**
* 🔄 流式检测:更新滑动窗口并检测 - 优化版本
*/
updateSlidingWindow(newContent, state) {
// 更新窗口
const combined = state.window + newContent;
const newWindow = combined.length > state.windowSize
? combined.slice(-state.windowSize)
: combined;
// 使用优化检测
const detectionResult = this.detectInWindowOptimized(newWindow);
const newState = {
window: newWindow,
windowSize: state.windowSize,
totalProcessed: state.totalProcessed + newContent.length,
detectionCount: state.detectionCount + (detectionResult.hasToolCalls ? 1 : 0)
};
return { newState, detectionResult };
}
/**
* 创建初始滑动窗口状态
*/
createSlidingWindowState() {
return {
window: '',
windowSize: this.windowSize,
totalProcessed: 0,
detectionCount: 0
};
}
}
exports.OptimizedToolCallDetector = OptimizedToolCallDetector;
// 导出优化的单例实例
exports.optimizedToolCallDetector = new OptimizedToolCallDetector();
//# sourceMappingURL=optimized-tool-call-detector.js.map