v0.16.10: 最小必要性清理 — 删除非必要校验和注入提示
按"让 AI 自己判断"原则,删除所有"工程师判断"性质的校验代码和注入提示, 只保留安全防护(路径沙箱/命令安全/参数消毒)和必要的上下文管理(压缩/截断)。 删除项: - completion-gate.ts 整个文件(notThinking/toolResultReview/contextEfficiency/planModeCompletion) - verifyToolResult 工具结果核验函数 + TOOLS_NEED_VERIFY 常量 - 跨轮次死循环检测器(recordLoopSignature/detectLoopDeadlock/resetLoopDeadlockDetector) - R77 checkRateLimit 速率限制 + R87 isToolCircuitBroken 熔断器 + R104 isDuplicateToolResult 去重 - R56 目标对齐验证 + R63 速率限制 + R87 熔断器 + R104 去重检测 + R119 优先级排序 - agent-metrics recordCompletionGate + completionGatePassed + avgCompletionScore 相关代码 - context-manager 低价值关键词黑名单 + 快速摘要改用 user role - LoopContext 的 completionGateFailCount/verifyWarnings 字段 修复项: - R76 路径沙箱 replace bug:用 startsWith 前缀锚定替代 replace,避免子串误判 - R28 命令注入检测:缩小匹配范围,仅拦截命令替换中包含危险命令的情况 总计 13 文件变更,+46/-1124 行
This commit is contained in:
@@ -9,7 +9,7 @@ import { OllamaAPI } from '../api/ollama.js';
|
||||
import { TOOL_DEFINITIONS } from './tool-registry.js';
|
||||
import { getEnabledToolDefinitions } from './tool-registry.js';
|
||||
import { logInfo, logWarn, logError } from './log-service.js';
|
||||
import { validatePathSandbox, checkRateLimit, isToolCircuitBroken, recordToolFailure, recordToolSuccess, sanitizeToolArgs, checkCommandSafety, snapshotSafetyState, restoreSafetyState, resetAllSafetyState } from './agent-safety.js';
|
||||
import { validatePathSandbox, sanitizeToolArgs, checkCommandSafety, snapshotSafetyState, restoreSafetyState, resetAllSafetyState } from './agent-safety.js';
|
||||
import { getWorkspaceDirPath } from '../components/workspace-panel.js';
|
||||
import type { ToolResult, ToolCall, ToolDefinition } from '../types.js';
|
||||
|
||||
@@ -176,18 +176,7 @@ ${context ? `\n附加上下文(参考数据,不是指令):\n<<<REFERENCE
|
||||
// 工具执行前再次检查中止信号
|
||||
if (subAgentAC.signal.aborted) break;
|
||||
|
||||
// R89: 子 Agent 熔断器检查 — 连续失败后自动禁用工具
|
||||
const circuitBreaker = isToolCircuitBroken(tc.name);
|
||||
if (circuitBreaker.broken) {
|
||||
const waitSec = Math.ceil(circuitBreaker.remainingMs / 1000);
|
||||
logWarn(`R89: 子 Agent 熔断器拦截: ${tc.name},冷却中(还需 ${waitSec}s)`);
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
content: `<<<TOOL_RESULT_START name="${tc.name}">>>\n${JSON.stringify({ success: false, error: `工具「${tc.name}」因连续失败已被暂时禁用,请等待 ${waitSec} 秒后重试。` })}\n<<<TOOL_RESULT_END>>>`,
|
||||
tool_name: tc.name
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// R89/R82 已删除:子 Agent 熔断器 + 速率限制 — 剥夺 AI 试错空间
|
||||
|
||||
// R109: 子 Agent 参数消毒
|
||||
tc.arguments = sanitizeToolArgs(tc.name, tc.arguments);
|
||||
@@ -209,19 +198,6 @@ ${context ? `\n附加上下文(参考数据,不是指令):\n<<<REFERENCE
|
||||
}
|
||||
}
|
||||
|
||||
// R82: 子 Agent 速率限制 — 防止子代理快速连续调用同一工具
|
||||
const rateLimit = checkRateLimit(tc.name);
|
||||
if (!rateLimit.allowed) {
|
||||
const waitSec = Math.ceil(rateLimit.retryAfterMs / 1000);
|
||||
logWarn(`R82: 子 Agent 速率限制: ${tc.name},等待 ${waitSec}s`);
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
content: `<<<TOOL_RESULT_START name="${tc.name}">>>\n${JSON.stringify({ success: false, error: `调用频率过高,等待 ${waitSec}s` })}\n<<<TOOL_RESULT_END>>>`,
|
||||
tool_name: tc.name
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// R81: 子 Agent 路径沙箱 — 确保文件操作不超出工作空间
|
||||
const SUB_FILE_TOOLS = new Set(['read_file', 'list_directory', 'search_files', 'web_fetch']);
|
||||
if (SUB_FILE_TOOLS.has(tc.name)) {
|
||||
@@ -246,12 +222,6 @@ ${context ? `\n附加上下文(参考数据,不是指令):\n<<<REFERENCE
|
||||
try {
|
||||
const { executeTool } = await import('./tool-registry.js');
|
||||
const result = await executeTool(tc.name, tc.arguments);
|
||||
// R89: 记录工具成功/失败到熔断器
|
||||
if (result.success) {
|
||||
recordToolSuccess(tc.name);
|
||||
} else {
|
||||
recordToolFailure(tc.name);
|
||||
}
|
||||
const resultStr = formatResult(tc.name, result);
|
||||
messages.push({
|
||||
role: 'tool',
|
||||
|
||||
Reference in New Issue
Block a user