v0.16.7: 引擎修复 + 工具面板统一 + AGENT.md 改为仅工作空间加载

核心引擎修复:
- 状态转换表补全 THINKING/PARSING/EXECUTING -> COMPRESSING,修复紧急压缩成为死代码的 P1 问题
- 新增跨轮次死循环检测器(软性提示 + 硬性熔断),防止模型陷入重复工具调用死循环
- handleCompressing 空响应回到 THINKING 而非 REFLECTING,避免错误终止
- executeHooks 添加 .catch() 防止未处理的 Promise 拒绝
- ALWAYS_PARALLEL 移除 git 和 browser_evaluate(有副作用的工具不应并行)
- thinking fallback:content 为空但有 thinking 时,用 [推理过程] 作为 content 保留上下文
- 8个写类工具添加专用格式化器(含 success + message 字段)
- 清理死代码:3个未使用函数 + 3个未使用 import

工具面板统一:
- 10个工具独立下拉框统一为1个全局执行模式选择器
- FIFO 队列防止并行 showToolConfirm 导致静默取消
- delete_file 支持 paths 数组参数批量删除

工具定义与实现一致性修复:
- run_command 移除未使用的 timeout 参数,描述改为"超时可配置"
- list_directory 添加 2000 条截断逻辑 + filter_extension 参数
- calculator 正则移除 ^ 字符(parser 用 ** 替代)
- search_files/tree/web_search/fetch_top 描述与实现对齐

消息传递修复:
- trimByTokenLimit 改为原子组选择(assistant+tool_calls 与后续 tool 消息作为一组)
- 历史工具结果复用 formatToolResultForModel,与当前格式一致

AGENT.md 加载策略变更:
- 删除内置 AGENT.md 文件
- 仅从工作空间加载:有则注入,无则跳过

其他修复:
- 修复初始化失败 "Cannot convert undefined or null to object"(saveSetting null 导致 JSON.parse 陷阱)
- 修复工作空间命令行标签页 idle 状态残留导致样式错乱

版本号: 0.16.5 -> 0.16.7
This commit is contained in:
紫影233
2026-07-14 16:26:43 +08:00
parent 4326fcce42
commit bd3a06bfaf
31 changed files with 909 additions and 986 deletions
+13 -8
View File
@@ -15,9 +15,10 @@ import { showToast } from './toast.js';
import { addToolCard, startToolCard, updateToolCard, clearToolCardsExternal, clearTerminalExternal, getWorkspaceDirPath, hasActiveCards, showWorkingHint, clearWorkingHint } from './workspace-panel.js';
import { ChatDB } from '../db/chat-db.js';
import { OllamaAPI } from '../api/ollama.js';
import { runAgentLoop } from '../services/agent-engine.js';
import { runAgentLoop, formatToolResultForModel } from '../services/agent-engine.js';
import { estimateTokens } from '../services/context-manager.js';
import { showToolConfirm } from './tool-confirm-modal.js';
import { showConfirm } from './prompt-modal.js';
import { logInfo, logStream, logError, logSuccess, logWarn, resetVideoProgress, updateVideoProgress } from '../services/log-service.js';
import type { ChatSession, ChatMessage, OllamaStreamChunk, OllamaMessage, FileContent, ChatFile, ToolCallRecord, AgentMode } from '../types.js';
@@ -95,9 +96,9 @@ export function initInputArea(): void {
// Ctrl+K: 清空聊天(需要确认)
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
e.preventDefault();
if (confirm('确定要清空当前对话吗?')) {
clearMessages();
}
showConfirm('确定要清空当前对话吗?', '清空对话').then(ok => {
if (ok) clearMessages();
});
}
// Escape: 停止生成(当正在流式输出时)
if (e.key === 'Escape' && state.get<boolean>(KEYS.IS_STREAMING)) {
@@ -1023,17 +1024,21 @@ function buildHistoryMessages(msgs: ChatMessage[], maxCount = 20): OllamaMessage
result.push(assistantMsg);
// ── 注入 tool 结果消息(role: 'tool')──
// 复用 formatToolResultForModel 保持与当前 Loop 格式一致
if (msg.toolCalls?.length) {
for (const tc of msg.toolCalls) {
if (!tc.result) continue;
if (result.length >= maxCount) break;
const resultContent = tc.status === 'success'
? JSON.stringify(tc.result)
: JSON.stringify({ success: false, error: tc.result.error || '工具执行失败' });
const formattedResult = formatToolResultForModel(tc.name, tc.result);
// R92: 工具结果格式标准化 — 添加统一头信息 + 数据边界标记
const resultDuration = Date.now() - tc.timestamp;
const resultSize = formattedResult.length;
const sizeCategory = resultSize > 10000 ? 'large' : resultSize > 2000 ? 'medium' : 'small';
const r92Header = `[工具:${tc.name} 状态:${tc.status} 耗时:${resultDuration}ms 大小:${sizeCategory}(${resultSize}字符)]`;
result.push({
role: 'tool',
tool_name: tc.name,
content: resultContent,
content: `<<<TOOL_RESULT_START name="${tc.name}">>>\n${r92Header}\n${formattedResult}\n<<<TOOL_RESULT_END>>>`,
});
}
}