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:
+25
-93
@@ -28,7 +28,7 @@
|
||||
<div class="header-left">
|
||||
<img class="logo" src="./assets/icons/llama.png" alt="logo" />
|
||||
<span class="app-title">Metona Ollama</span>
|
||||
<span class="app-version">v0.16.2</span>
|
||||
<span class="app-version">v0.16.7</span>
|
||||
<button class="icon-btn help-btn" id="btnHelp" title="使用帮助">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/>
|
||||
@@ -445,7 +445,7 @@
|
||||
<div class="help-section"><h4>🤖 Agent Loop 增强</h4><ul><li><strong>🎬 视频上传</strong>:支持上传 .mp4/.avi/.mov/.mkv/.webm 等视频(≤10MB),自动 1fps 提取帧序列(带时间戳),多模态模型原生理解视频时序关系</li><li><strong>8 状态机</strong>:INIT→THINKING→PARSING→EXECUTING→OBSERVING→REFLECTING→COMPRESSING→TERMINATED,每个状态独立的中止检查和处理</li><li><strong>智能上下文压缩</strong>:滑动窗口 + LLM结构化JSON摘要,120条触发增量压缩 + 200条硬上限强制压缩</li><li><strong>流式总超时</strong>:可配置(默认300s),Ollama 假死不再永久阻塞</li><li><strong>HTTP/MCP 超时可配</strong>:设置面板可分别调整 HTTP(默认30s)和 MCP(默认60s)超时</li><li><strong>智能工具调度</strong>:路径依赖检测自动串行化(write→read/create→write),只读工具并行执行</li><li><strong>工具缓存 TTL</strong>:搜索5分钟/网页10分钟/文件30分钟/git 30秒,默认60秒过期,不再永久缓存</li><li><strong>Plan Mode 断点续传</strong>:中止后可恢复未完成的计划,进度自动保存</li><li><strong>Token 感知迭代预算</strong>:上下文使用率>80%时自动缩减剩余轮次到3轮</li><li><strong>跨会话工具上下文</strong>:新对话自动注入上一轮已执行的工具调用及结果(role:tool 消息),AI 不会重复执行已完成的操作</li><li><strong>旧工具结果智能截断</strong>:超过10轮后自动截断到2000字符,优先在JSON边界处截断</li></ul></div>
|
||||
<div class="help-section"><h4>🔌 MCP(Model Context Protocol)</h4><ul><li>支持连接外部 MCP Server,动态扩展工具能力</li><li>设置面板可添加/启用/禁用/删除 MCP 服务器</li><li>MCP 工具以 <code>mcp_{server}__{tool}</code> 前缀注册,与内置工具统一调度</li><li>启动时自动连接已启用的 MCP 服务器</li></ul></div>
|
||||
<div class="help-section"><h4>🔍 SearXNG 元搜索引擎</h4><ul><li>点击顶部 🔍 按钮打开配置面板,可接入自部署的 SearXNG 实例</li><li><strong>JSON 模式</strong>:调用 SearXNG JSON API,聚合 70+ 引擎结果,结构化解析</li><li><strong>HTML 模式</strong>:获取原始搜索结果页面,交由 AI 自行分析提取信息</li><li>支持认证 Key(HTTP Header Authorization),保护私有实例</li><li>启用后替代内置四引擎方案;关闭即回退,无缝切换</li><li>所有参数(引擎、语言、安全搜索、时间范围等)均可独立配置</li></ul></div>
|
||||
<div class="help-section"><h4>📋 自定义文件(SOUL.md / AGENT.md / USER.md)</h4><ul><li>在工作空间目录创建以下文件即可自定义 AI 行为,修改后下一轮对话立即生效</li><li><strong>SOUL.md</strong> — AI 身份、性格、行为准则(<strong>永远不可被压缩</strong>,注入为最高优先级系统提示词)</li><li><strong>AGENT.md</strong> — 工具调用规则、链式调用模式、核心约束(内置精简默认版,可通过工作空间覆盖)</li><li><strong>USER.md</strong> — 用户画像:技术栈、偏好、习惯等个人信息,AI 在对话中自动参考(仅工作空间,无内置默认)</li><li>可在 AI 回复顶部的 📋 系统提示词卡片中查看实际注入的完整上下文</li><li>SOUL.md / AGENT.md 删除工作空间中文件可恢复为内置默认版本;USER.md 无内置版,不存在则不注入</li></ul></div>
|
||||
<div class="help-section"><h4>📋 自定义文件(SOUL.md / AGENT.md / USER.md)</h4><ul><li>在工作空间目录创建以下文件即可自定义 AI 行为,修改后下一轮对话立即生效</li><li><strong>SOUL.md</strong> — AI 身份、性格、行为准则(<strong>永远不可被压缩</strong>,注入为最高优先级系统提示词)</li><li><strong>AGENT.md</strong> — 工具调用规则、链式调用模式、核心约束(仅从工作空间加载,有则注入,无则不注入)</li><li><strong>USER.md</strong> — 用户画像:技术栈、偏好、习惯等个人信息,AI 在对话中自动参考(仅工作空间,无内置默认)</li><li>可在 AI 回复顶部的 📋 系统提示词卡片中查看实际注入的完整上下文</li><li>SOUL.md 删除工作空间文件可恢复内置默认版本;AGENT.md / USER.md 无内置版,工作空间不存在则不注入</li></ul></div>
|
||||
<div class="help-section"><h4>📊 Token 实时监控</h4><ul><li>点击顶部 📊 按钮打开 Token 监控仪表盘</li><li><strong>全局统计</strong> — 跨会话累计 Token 消耗,柱状图按会话展示趋势</li><li><strong>当前会话</strong> — 实时显示本轮对话的 Token 消耗,按轮次展示明细</li><li>每 2 秒自动刷新数据,支持输入/输出分色显示</li></ul></div>
|
||||
<div class="help-section"><h4>🖥️ 布局说明</h4><ul><li><strong>左侧面板</strong> — 执行日志,实时显示应用运行日志(连接、模型加载、工具调用等)</li><li><strong>中间区域</strong> — 聊天消息,顶部 Header + 模型栏,底部输入框</li><li><strong>右侧面板</strong> — 工作空间(常驻显示),包含 3 个页签:<ul><li><strong>💻 命令行 Tab</strong> — 终端界面,实时流式输出,支持长时间运行(无超时),单一终端进程</li><li><strong>🔧 工具 Tab</strong> — 展示本轮对话的工具调用卡片,含状态统计(总数 ✅ 成功 ❌ 失败),AI 执行命令时自动切到此页签</li><li><strong>📁 文件 Tab</strong> — 浏览工作空间目录,点击文件预览内容(带行号),支持上级目录导航</li></ul></li><li>工作空间目录可在设置中修改</li></ul></div>
|
||||
<div class="help-section"><h4>🕐 历史记录</h4><ul><li>所有会话自动保存到本地 SQLite</li><li>点击顶部 🕐 按钮查看、搜索、恢复历史会话</li><li>支持导出 JSON / <code>.metona</code> 加密备份</li></ul></div>
|
||||
@@ -467,22 +467,26 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="text-muted" style="font-size:12px;margin-bottom:12px;">AI 始终可在对话中自主调用以下工具(Tool Calling 永久开启)。高风险操作需用户确认。</p>
|
||||
<div style="margin-bottom:16px;padding:12px;background:var(--bg-card);border:1px solid var(--border-default);border-radius:8px;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;gap:12px;">
|
||||
<div>
|
||||
<div style="font-weight:600;font-size:14px;">⚙️ 全局工具执行模式</div>
|
||||
<div style="font-size:11px;color:var(--text-secondary);margin-top:2px;">统一管理所有工具的执行模式,不区分工具</div>
|
||||
</div>
|
||||
<select id="select_global_tool_mode" style="font-size:13px;padding:6px 12px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:6px;min-width:140px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tools-grid">
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📄</span><span class="tool-card-name">read_file</span><span class="tool-card-badge auto">自动</span></div>
|
||||
<div class="tool-card-desc">读取文件(文本/binary/base64),2000行默认,截断自动提示续读</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">✏️</span><span class="tool-card-name">write_file</span><span class="tool-card-badge confirm" id="badge_write_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">✏️</span><span class="tool-card-name">write_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">写入/追加文件,支持base64二进制,最大10MB</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="write_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📁</span><span class="tool-card-name">list_directory</span><span class="tool-card-badge auto">自动</span></div>
|
||||
@@ -493,80 +497,32 @@
|
||||
<div class="tool-card-desc">按文件名或内容搜索,支持正则表达式</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📂</span><span class="tool-card-name">create_directory</span><span class="tool-card-badge confirm" id="badge_create_directory">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📂</span><span class="tool-card-name">create_directory</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">创建目录,自动创建父级</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="create_directory" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🗑️</span><span class="tool-card-name">delete_file</span><span class="tool-card-badge confirm" id="badge_delete_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🗑️</span><span class="tool-card-name">delete_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">删除文件或目录,返回被删文件数和总大小</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="delete_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📦</span><span class="tool-card-name">move_file</span><span class="tool-card-badge confirm" id="badge_move_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📦</span><span class="tool-card-name">move_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">移动或重命名文件/目录</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="move_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📋</span><span class="tool-card-name">copy_file</span><span class="tool-card-badge confirm" id="badge_copy_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📋</span><span class="tool-card-name">copy_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">复制文件或目录到新位置</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="copy_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🌐</span><span class="tool-card-name">web_fetch</span><span class="tool-card-badge auto">自动</span></div>
|
||||
<div class="tool-card-desc">抓取网页内容,反爬headers+UA切换+自动回退浏览器渲染</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">✂️</span><span class="tool-card-name">edit_file</span><span class="tool-card-badge confirm" id="badge_edit_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">✂️</span><span class="tool-card-name">edit_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">查找替换(支持正则use_regex),全部或单次替换</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="edit_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">💻</span><span class="tool-card-name">run_command</span><span class="tool-card-badge confirm" id="badge_run_command">需确认</span></div>
|
||||
<div class="tool-card-desc">执行 shell 命令,无超时限制</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="run_command" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">💻</span><span class="tool-card-name">run_command</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">执行 shell 命令,支持超时配置</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">ℹ️</span><span class="tool-card-name">get_file_info</span><span class="tool-card-badge auto">自动</span></div>
|
||||
@@ -577,32 +533,16 @@
|
||||
<div class="tool-card-desc">以树形结构展示目录内容</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">⬇️</span><span class="tool-card-name">download_file</span><span class="tool-card-badge confirm" id="badge_download_file">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">⬇️</span><span class="tool-card-name">download_file</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">从 URL 下载文件到本地</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="download_file" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🔀</span><span class="tool-card-name">diff_files</span><span class="tool-card-badge auto">自动</span></div>
|
||||
<div class="tool-card-desc">对比两个文件,显示差异</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🔄</span><span class="tool-card-name">replace_in_files</span><span class="tool-card-badge confirm" id="badge_replace_in_files">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🔄</span><span class="tool-card-name">replace_in_files</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">按 glob 模式批量查找替换多个文件</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="replace_in_files" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">📚</span><span class="tool-card-name">read_multiple_files</span><span class="tool-card-badge auto">自动</span></div>
|
||||
@@ -613,16 +553,8 @@
|
||||
<div class="tool-card-desc">Git 全操作(17个子命令:status/log/diff/add/commit/push等)</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🗜️</span><span class="tool-card-name">compress</span><span class="tool-card-badge confirm" id="badge_compress">需确认</span></div>
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🗜️</span><span class="tool-card-name">compress</span><span class="tool-card-badge confirm">需确认</span></div>
|
||||
<div class="tool-card-desc">创建或解压 zip/tar.gz 归档</div>
|
||||
<div style="margin-top:6px;display:flex;align-items:center;gap:8px;">
|
||||
<label style="margin:0;font-size:11px;color:var(--text-secondary);">执行模式:</label>
|
||||
<select class="tool-mode-select" data-tool="compress" style="font-size:11px;padding:2px 6px;background:var(--bg-card);color:var(--text-primary);border:1px solid var(--border-default);border-radius:4px;">
|
||||
<option value="confirm">需确认</option>
|
||||
<option value="auto">自动执行</option>
|
||||
<option value="disabled">禁用</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-card-header"><span class="tool-card-icon">🔍</span><span class="tool-card-name">web_search</span><span class="tool-card-badge auto">自动</span></div>
|
||||
|
||||
Reference in New Issue
Block a user