From afe93d7fed74144c4a3b887a1be59cef9ca805e8 Mon Sep 17 00:00:00 2001 From: thzxx <1440196015@qq.com> Date: Thu, 30 Jul 2026 22:48:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20v0.16.15=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E5=AE=9A=E4=B9=89=E9=87=8D=E5=A4=8D=E3=80=81?= =?UTF-8?q?=E9=9B=86=E6=88=90=E8=87=AA=E9=80=82=E5=BA=94=E5=8E=8B=E7=BC=A9?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E3=80=81=E6=89=B9=E9=87=8F=E8=BD=A8=E8=BF=B9?= =?UTF-8?q?=E5=86=99=E5=85=A5=E3=80=81=E8=AF=AD=E4=B9=89=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +- docs/DEVELOPMENT.md | 2 +- package-lock.json | 4 +- package.json | 2 +- src/main/db/sqlite.ts | 16 ++ src/main/ipc.ts | 6 +- src/main/menu.ts | 2 +- src/main/preload.ts | 3 +- src/renderer/index.html | 4 +- src/renderer/services/agent-engine.ts | 118 ++++++--- src/renderer/services/tool-registry.ts | 330 +++---------------------- src/renderer/types.d.ts | 3 +- 12 files changed, 145 insertions(+), 355 deletions(-) diff --git a/README.md b/README.md index 903fafd..9ae5ffa 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@

- version + version electron typescript license @@ -45,7 +45,7 @@ | 🌏 | **浏览器控制** | 打开网页 · 截图 · 执行 JS · 提取内容 · 点击 · 输入 · 滚动 · 关闭 | | 🖥️ | **工作空间面板** | 终端(增量流式输出)+ 文件浏览器,命令安全检查 | | 🔢 | **上下文长度手动控制** | 设置面板下拉选择(128K / 256K / 512K / 1M),默认 128K,模型栏显示当前配置值,下拉框中显示每个模型自身的上下文长度 | -| 🗜️ | **智能上下文管理** | 滑动窗口 + Token 自动校准 + 消息重要性评分 + LLM 结构化 JSON 压缩,智能触发(120 条增量压缩 + 200 条硬上限) | +| 🗜️ | **智能上下文管理** | 滑动窗口 + Token 自动校准 + 消息重要性评分 + LLM 结构化 JSON 压缩,智能触发(120 条增量压缩 + 300 条硬上限) | | ⏱️ | **智能超时保护** | Agent Loop 看门狗(可配,默认 30min)+ 流式总超时(可配,默认 300s)+ 工具 HTTP/MCP 超时可配 | | 🪝 | **Hook 系统** | 4 阶段生命周期钩子(pre_tool / post_tool / post_iteration / pre_completion),内置安全检查、文件去重、自动计划追踪、变更审计、结果校验 | | 👥 | **子代理委派** | spawn_task 工具,独立上下文 + 超时保护 | @@ -245,7 +245,7 @@ npm start ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist ``` -产出:`release/Metona Ollama Setup v0.16.14.exe` +产出:`release/Metona Ollama Setup v0.16.15.exe` ## 🛠️ 常用命令 @@ -286,7 +286,7 @@ npm run dist # 构建 Windows 安装包 | 🌏 | **Browser Control** | Open pages · Screenshot · JS execution · Content extraction · Click · Type · Scroll · Close | | 🖥️ | **Workspace Panel** | Terminal (incremental streaming) + file browser, command security checks | | 🔢 | **Manual Context Length** | Settings dropdown (128K / 256K / 512K / 1M), default 128K. Model bar shows configured value, dropdown shows per-model context length | -| 🗜️ | **Smart Context Manager** | Sliding window + Token auto-calibration + message importance scoring + LLM structured JSON compression, smart triggers (120 msg incremental + 200 msg hard limit) | +| 🗜️ | **Smart Context Manager** | Sliding window + Token auto-calibration + message importance scoring + LLM structured JSON compression, smart triggers (120 msg incremental + 300 msg hard limit) | | ⏱️ | **Smart Timeout Protection** | Agent Loop watchdog (configurable, default 30min) + stream total timeout (configurable, default 300s) + configurable HTTP/MCP timeouts | | 🪝 | **Hook System** | 4-phase lifecycle hooks (pre_tool / post_tool / post_iteration / pre_completion), built-in security check, file dedup, auto plan tracking, change audit, result validation | | 👥 | **Sub-agent Delegation** | spawn_task tool, isolated context + timeout protection | @@ -485,7 +485,7 @@ npm start ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist ``` -Output: `release/Metona Ollama Setup v0.16.14.exe` +Output: `release/Metona Ollama Setup v0.16.15.exe` ## 🛠️ Common Commands diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 6ecab69..e7c6666 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -205,7 +205,7 @@ INIT → THINKING → PARSING → EXECUTING → OBSERVING → REFLECTING → (CO - 最大轮次:85(默认,设置面板可调) - 自动重试:2 次(MAX_RETRIES) - 看门狗超时:30 分钟(默认,可配) -- 上下文硬上限:500 条消息 +- 上下文硬上限:300 条消息 - 流式超时:可配(默认 300s,0=禁用) - HTTP 超时:可配(默认 30s) - MCP 超时:可配(默认 60s) diff --git a/package-lock.json b/package-lock.json index fc73143..1e2e71a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "metona-ollama-desktop", - "version": "0.16.14", + "version": "0.16.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "metona-ollama-desktop", - "version": "0.16.14", + "version": "0.16.15", "license": "MIT", "dependencies": { "ffmpeg-static": "^5.2.0", diff --git a/package.json b/package.json index 47652f5..f8debae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metona-ollama-desktop", - "version": "0.16.14", + "version": "0.16.15", "description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端", "main": "dist/main/main.js", "author": "thzxx", diff --git a/src/main/db/sqlite.ts b/src/main/db/sqlite.ts index 83d54e0..e8b79c9 100644 --- a/src/main/db/sqlite.ts +++ b/src/main/db/sqlite.ts @@ -365,6 +365,22 @@ export function saveTrace(trace: TraceRow): string { return trace.id; } +/** 批量保存轨迹 — 只触发一次 persist,避免逐条写盘 */ +export function saveTracesBatch(traces: TraceRow[]): number { + if (!traces.length) return 0; + const d = getDb(); + runTransaction(d, () => { + for (const trace of traces) { + runExec(d, `INSERT OR REPLACE INTO traces (id, session_id, step_index, thought, action, action_input, observation, loop_count, error_pattern, created_at) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + [trace.id, trace.session_id, trace.step_index, trace.thought, trace.action, trace.action_input, trace.observation, trace.loop_count, trace.error_pattern, trace.created_at] + ); + } + }); + persist(); // 只写盘一次 + return traces.length; +} + export function getTracesBySession(sessionId: string): TraceRow[] { return queryAll(getDb(), 'SELECT * FROM traces WHERE session_id = ? ORDER BY step_index ASC', [sessionId]) as unknown as TraceRow[]; } diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 41e6949..fa21a29 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -12,7 +12,7 @@ import { initDatabase, saveSession, getSession, getAllSessions, deleteSession, clearAllSessions, saveMessage, getMessagesBySession, saveSetting, getSetting, saveSettingsBatch, - saveTrace, getTracesBySession, + saveTrace, saveTracesBatch, getTracesBySession, exportAllSessions, importSessions, getAllSessionsTokenStats } from './db/sqlite.js'; @@ -383,6 +383,10 @@ export async function setupIPC(): Promise { try { return { success: true, id: saveTrace(trace) }; } catch (err) { return { success: false, error: (err as Error).message }; } }); + ipcMain.handle('db:saveTracesBatch', (_, traces) => { + try { return { success: true, count: saveTracesBatch(traces) }; } + catch (err) { return { success: false, error: (err as Error).message }; } + }); ipcMain.handle('db:getTraces', (_, sessionId) => { try { return getTracesBySession(sessionId); } catch { return []; } diff --git a/src/main/menu.ts b/src/main/menu.ts index 3ddbc48..83bbd1a 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -101,7 +101,7 @@ export function createMenu(): void { dialog.showMessageBox(mainWindow!, { type: 'info', title: '关于 Metona Ollama', - message: 'Metona Ollama Desktop v0.16.14', + message: 'Metona Ollama Desktop v0.16.15', detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama', icon: getIconPath() }); diff --git a/src/main/preload.ts b/src/main/preload.ts index c393d3a..915ceba 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -65,9 +65,8 @@ contextBridge.exposeInMainWorld('metonaDesktop', { getMessages: (sessionId: string) => ipcRenderer.invoke('db:getMessages', sessionId), saveSetting: (key: string, value: unknown) => ipcRenderer.invoke('db:saveSetting', key, value), getSetting: (key: string, defaultValue?: unknown) => ipcRenderer.invoke('db:getSetting', key, defaultValue), - saveToolCall: (tc: unknown) => ipcRenderer.invoke('db:saveToolCall', tc), - getToolCalls: (sessionId: string) => ipcRenderer.invoke('db:getToolCalls', sessionId), saveTrace: (trace: unknown) => ipcRenderer.invoke('db:saveTrace', trace), + saveTracesBatch: (traces: unknown[]) => ipcRenderer.invoke('db:saveTracesBatch', traces), getTraces: (sessionId: string) => ipcRenderer.invoke('db:getTraces', sessionId), exportSessions: () => ipcRenderer.invoke('db:exportSessions'), importSessions: (data: unknown) => ipcRenderer.invoke('db:importSessions', data), diff --git a/src/renderer/index.html b/src/renderer/index.html index ad0ff78..0cad355 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -28,7 +28,7 @@

Metona Ollama - v0.16.14 + v0.16.15