diff --git a/README.md b/README.md index bbaf9ed..3d9dab9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 全离线运行 · 数据本地存储 · 零外部依赖 -[](https://gitee.com/thzxx/metona-ollama-desktop/releases) +[](https://gitee.com/thzxx/metona-ollama-desktop/releases) [](https://gitee.com/thzxx/metona-ollama-desktop/releases) [](https://www.typescriptlang.org/) [](https://www.electronjs.org/) @@ -294,7 +294,7 @@ src/ | 文件 | 类型 | |------|------| -| `Metona Ollama Setup 5.0.0.exe` | NSIS 安装包(可选目录、创建快捷方式) | +| `Metona Ollama Setup 5.0.1.exe` | NSIS 安装包(可选目录、创建快捷方式) | > ⚠️ 未签名版本,首次运行 Windows 可能弹出安全警告,点击「仍要运行」即可。 diff --git a/docs/BUILD.md b/docs/BUILD.md index db724d9..87ff19b 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -14,7 +14,7 @@ # 1. 克隆并安装依赖 git clone https://gitee.com/thzxx/metona-ollama-desktop.git cd metona-ollama-desktop -git checkout metona-ollama-desktop-v5.0.0 +git checkout metona-ollama-desktop-v5.0.1 npm config set registry https://registry.npmmirror.com npm install @@ -176,6 +176,15 @@ electron-builder 会自动处理所有依赖下载(Electron、NSIS、winCodeSi ## 构建日志 +### v5.0.1(2026-04-18) — metona-ollama-desktop 仓库 + +- 🔧 修复 DuckDuckGo 搜索超时过长(15s → 8s),添加 Google 作为第三搜索引擎兜底 +- 🔧 修复 web_fetch User-Agent(MetonaOllama/1.0 → Chrome UA),增加超时至 30 秒 +- 🔧 修复 Agent Loop 跨轮去重误杀失败工具的重试(仅对成功的调用去重,失败的允许重试) +- 🔧 优化 TOOL_USAGE_GUIDE:新增搜索 fallback 规则(fetch 失败时直接用搜索结果回答)、禁止抓取 SPA 页面、搜索查询进化指导 +- 🔧 更新 AGENT_SYSTEM_PROMPT:工具数 25 → 34,新增 fetch 失败 fallback 规则 +- 📝 版本号更新至 5.0.1(package.json / package-lock.json / index.html / README.md / CHANGELOG.md / BUILD.md / DEVELOPMENT.md) + ### v5.0.0(2026-04-18) — metona-ollama-desktop 仓库 - ✨ 新增 8 个浏览器控制工具(browser_open/screenshot/evaluate/extract/click/type/scroll/close) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 98dc990..e4c791f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -3,7 +3,7 @@ ## 分支结构 **桌面版主线**(`master`): -- `metona-ollama-desktop-v1.1` → `metona-ollama-desktop-v2` → `metona-ollama-desktop-v3.0.0` → `metona-ollama-desktop-v3.1.0` → `metona-ollama-desktop-v3.1.1` → `metona-ollama-desktop-v3.2.0` → `metona-ollama-desktop-v3.2.1` → `metona-ollama-desktop-v3.2.2` → `metona-ollama-desktop-v3.2.3` → `metona-ollama-desktop-v3.2.4` → `metona-ollama-desktop-v3.2.5` → `metona-ollama-desktop-v3.2.6` → `metona-ollama-desktop-v3.3.0` → `metona-ollama-desktop-v3.3.1` → `metona-ollama-desktop-v3.3.2` → `metona-ollama-desktop-v3.3.3` → `metona-ollama-desktop-v3.3.4` → `metona-ollama-desktop-v4.0.0` → `metona-ollama-desktop-v5.0.0`(当前发布分支) +- `metona-ollama-desktop-v3.2.6` → `metona-ollama-desktop-v3.3.4` → `metona-ollama-desktop-v4.0.0` → `metona-ollama-desktop-v5.0.0` → `metona-ollama-desktop-v5.0.1`(当前发布分支) **Web 版历史**已独立为 [metona-ollama-web](https://gitee.com/thzxx/metona-ollama-web) 仓库(v1.1.0 ~ v4.0.3)。 @@ -11,6 +11,33 @@ ## 桌面版(Desktop) +### Desktop v5.0.1 — 搜索引擎优化 & Agent 去重修复 + +- 🔧 **修复 DuckDuckGo 搜索超时过长** + - 超时从 15 秒降至 8 秒(国内环境 DuckDuckGo 通常不可达,减少等待) + - 添加 Google 作为第三搜索引擎兜底(DuckDuckGo → Bing → Google) + - 新增 `parseGoogleResults()` 解析函数 + - 搜索 User-Agent 统一更新为 Chrome 131 +- 🔧 **修复 web_fetch 无法抓取部分网站** + - User-Agent 从 `MetonaOllama/1.0` 改为 Chrome 131 UA(部分网站屏蔽非浏览器 UA) + - 超时从 15 秒增加至 30 秒(大页面加载更慢) + - 新增 `Accept` 和 `Accept-Language` 请求头 +- 🔧 **修复 Agent Loop 跨轮去重误杀失败工具的重试** + - 原逻辑:连续两轮工具调用(工具名+参数)完全相同即终止 + - 问题:上一轮 `web_fetch` 超时失败,下一轮同样调用是合理重试,却被当作重复终止 + - 修复:仅对成功的工具调用做去重,失败的允许重试 + - 新增 `prevLoopSuccessKeys` 替代 `prevLoopToolKeys` +- 🔧 **优化 TOOL_USAGE_GUIDE(新增 3 条规则)** + - 新增规则 2:web_fetch 失败时直接用 web_search 摘要回答,不要反复重试同一 URL + - 新增规则 3:禁止抓取 SPA 页面(GitHub releases、npm 等),直接从搜索结果提取信息 + - 新增规则 4:搜索查询要进化,不要重复相同的查询 +- 🔧 **更新 AGENT_SYSTEM_PROMPT** + - 工具数量描述从 25 → 34 + - 核心规则新增:web_search 结果中的 snippet 已包含关键信息,不要忽视 + - 核心规则细化:同一 URL 连续失败 2 次后不要再尝试 + - 多工具协同示例新增:web_fetch 失败时直接用搜索结果回答 +- 📝 **版本号更新至 5.0.1**(7 个文件同步更新) + ### Desktop v5.0.0 — 浏览器控制 & MCP & 技能系统 & 全面重构 - ✨ **MCP (Model Context Protocol) 完整实现** diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 6cb844d..d4dc86c 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -1,6 +1,6 @@ # Metona Ollama Desktop — 开发规范 -> 版本: 5.0.0 | 更新: 2026-04-18 | 维护: 项目团队 +> 版本: 5.0.1 | 更新: 2026-04-18 | 维护: 项目团队 --- diff --git a/package-lock.json b/package-lock.json index 395245e..a985471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "metona-ollama-desktop", - "version": "5.0.0", + "version": "5.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "metona-ollama-desktop", - "version": "5.0.0", + "version": "5.0.1", "license": "MIT", "dependencies": { "sql.js": "^1.11.0" @@ -4398,7 +4398,7 @@ } }, "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { - "version": "5.0.0", + "version": "5.0.1", "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "dev": true, @@ -5791,7 +5791,7 @@ } }, "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", + "version": "5.0.1", "resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, diff --git a/package.json b/package.json index 7498b7a..f12f5a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metona-ollama-desktop", - "version": "5.0.0", + "version": "5.0.1", "description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端", "main": "dist/main/main.js", "author": "thzxx", diff --git a/src/main/tool-handlers.ts b/src/main/tool-handlers.ts index 6097129..e6103c4 100644 --- a/src/main/tool-handlers.ts +++ b/src/main/tool-handlers.ts @@ -437,8 +437,12 @@ export async function handleWebFetch(params: { url: string; max_chars?: number; sendLog('info', `🌐 web_fetch`, `${url} (${maxChars > 0 ? maxChars + ' chars' : '完整内容'})`); const resp = await fetch(url, { - headers: { 'User-Agent': 'MetonaOllama/1.0' }, - signal: AbortSignal.timeout(15000) + headers: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' + }, + signal: AbortSignal.timeout(30000) }); if (!resp.ok) { @@ -499,18 +503,20 @@ export async function handleWebSearch(params: { query: string; max_results?: num sendLog('info', `🔍 web_search`, `"${query}" (${maxResults} 条)`); - // 1. 尝试 DuckDuckGo HTML 搜索 + const searchHeaders = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + 'Accept': 'text/html', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' + }; + + // 1. 尝试 DuckDuckGo HTML 搜索(8 秒超时,国内环境通常不可用) let results: Array<{ title: string; url: string; snippet: string }> = []; try { const ddgUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`; const resp = await fetch(ddgUrl, { - headers: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Accept': 'text/html', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' - }, - signal: AbortSignal.timeout(15000) + headers: searchHeaders, + signal: AbortSignal.timeout(8000) }); if (resp.ok) { @@ -518,19 +524,15 @@ export async function handleWebSearch(params: { query: string; max_results?: num results = parseDDGResults(html, maxResults); } } catch (e) { - sendLog('warn', `🔍 DuckDuckGo 搜索失败`, (e as Error).message); + sendLog('warn', `🔍 DuckDuckGo 搜索失败(8s 超时)`, (e as Error).message); } - // 2. 如果 DuckDuckGo 无结果,尝试备用方案 + // 2. DuckDuckGo 无结果,尝试 Bing if (results.length === 0) { try { const bingUrl = `https://www.bing.com/search?q=${encodeURIComponent(query)}&count=${maxResults}`; const resp = await fetch(bingUrl, { - headers: { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - 'Accept': 'text/html', - 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' - }, + headers: searchHeaders, signal: AbortSignal.timeout(15000) }); @@ -543,6 +545,24 @@ export async function handleWebSearch(params: { query: string; max_results?: num } } + // 3. Bing 也失败,尝试 Google(通过 google.com/search) + if (results.length === 0) { + try { + const googleUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}&num=${maxResults}`; + const resp = await fetch(googleUrl, { + headers: searchHeaders, + signal: AbortSignal.timeout(15000) + }); + + if (resp.ok) { + const html = await resp.text(); + results = parseGoogleResults(html, maxResults); + } + } catch (e) { + sendLog('warn', `🔍 Google 搜索失败`, (e as Error).message); + } + } + if (results.length === 0) { return { success: false, error: '未找到搜索结果,请尝试其他关键词' }; } @@ -621,6 +641,38 @@ function parseBingResults(html: string, maxResults: number): Array<{ title: stri return results; } +/** 解析 Google HTML 搜索结果 */ +function parseGoogleResults(html: string, maxResults: number): Array<{ title: string; url: string; snippet: string }> { + const results: Array<{ title: string; url: string; snippet: string }> = []; + + // Google 结果块: