diff --git a/README.md b/README.md
index f7ebb27..ecbb10b 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
Metona Ollama Desktop
- 🤖 本地 AI 桌面客户端 · Local AI Desktop Client
+ 🤖 本地 AI 桌面客户?· Local AI Desktop Client
@@ -14,7 +14,7 @@
-
+
@@ -22,65 +22,65 @@
- 所有 AI 推理在本地完成,数据不离开本机。
- All AI inference runs locally — data never leaves your machine.
+ 所?AI 推理在本地完成,数据不离开本机?/em>
+ All AI inference runs locally ?data never leaves your machine.
---
# 🇨🇳 中文
-## ✨ 特性
+## ?特?
| | 功能 | 说明 |
|:---:|:---|:---|
-| 🤖 | **ReAct Agent Loop** | 始终开启的唯一对话模式。8 状态机(INIT→THINKING→PARSING→EXECUTING→OBSERVING→REFLECTING→COMPRESSING→TERMINATED),最大 85 轮(可配置),智能重试(永久错误立即返回、瞬态错误指数退避),工具去重,智能路径依赖串行化,看门狗超时保护 |
-| 🛡️ | **提示词加固** | 参考数据标记(<<>>)+ 工具结果仅为数据非指令的安全规则注入 |
-| 📋 | **Plan Mode** | 开关切换,AI 首先生成执行计划(Markdown 渲染确认弹窗),批准后按步骤追踪执行,plan_track 工具标记完成状态,**支持断点续传**(中止后可恢复未完成计划) |
-| 🔧 | **32 个内置工具** | 文件系统(13个) · 命令执行 · 联网搜索 · 浏览器控制(9个) · Git · 记忆 · 会话 · 子代理 · 系统工具 · Plan Mode 追踪 |
-| 🧠 | **智能记忆系统** | 三类记忆(fact / preference / rule),存储于工作空间 MEMORY.md 文件,受路径保护仅 memory 工具可访问,写入前安全扫描,容量 500 条,对话结束自动提取,严格格式校验 |
-| 📋 | **自定义文件** | SOUL.md(人格,不可压缩)+ AGENT.md(行为准则,内置 fallback)+ USER.md(用户画像,仅工作空间读取,不存在则不注入) |
+| 🤖 | **ReAct Agent Loop** | 始终开启的唯一对话模式? 状态机(INIT→THINKING→PARSING→EXECUTING→OBSERVING→REFLECTING→COMPRESSING→TERMINATED),最?85 轮(可配置),智能重试(永久错误立即返回、瞬态错误指数退避),工具去重,智能路径依赖串行化,看门狗超时保?|
+| 🛡?| **提示词加?* | 参考数据标记(<<>>? 工具结果仅为数据非指令的安全规则注入 |
+| 📋 | **Plan Mode** | 开关切换,AI 首先生成执行计划(Markdown 渲染确认弹窗),批准后按步骤追踪执行,plan_track 工具标记完成状态,**支持断点续传**(中止后可恢复未完成计划?|
+| 🔧 | **32 个内置工?* | 文件系统?3个) · 命令执行 · 联网搜索 · 浏览器控制(9个) · Git · 记忆 · 会话 · 子代?· 系统工具 · Plan Mode 追踪 |
+| 🧠 | **智能记忆系统** | 三类记忆(fact / preference / rule),存储于工作空?MEMORY.md 文件,受路径保护?memory 工具可访问,写入前安全扫描,容量 500 条,对话结束自动提取,严格格式校?|
+| 📋 | **自定义文?* | SOUL.md(人格,不可压缩? AGENT.md(行为准则,内置 fallback? USER.md(用户画像,仅工作空间读取,不存在则不注入) |
| 🌐 | **MCP 协议扩展** | JSON-RPC 2.0 over stdio,动态工具发现,Shadowing 防护 |
-| 🔍 | **联网搜索(双模式)** | SearXNG 元搜索引擎 JSON API(70+引擎聚合)/ 四引擎 HTML 解析(Bing+百度+搜狗+360),双模式可切换;web_fetch 支持反爬+UA切换+浏览器回退 |
-| 🌏 | **浏览器控制** | 打开网页 · 截图 · 执行 JS · 提取内容 · 点击 · 输入 · 滚动 · 关闭 |
-| 🖥️ | **工作空间面板** | 终端(增量流式输出)+ 文件浏览器,命令安全检查 |
-| 🔢 | **上下文长度手动控制** | 设置面板下拉选择(128K / 256K / 512K / 1M),默认 128K,模型栏显示当前配置值,下拉框中显示每个模型自身的上下文长度 |
-| 🗜️ | **智能上下文管理** | 滑动窗口 + Token 自动校准 + 消息重要性评分 + LLM 结构化 JSON 压缩,智能触发(120 条增量压缩 + 300 条硬上限) |
-| ⏱️ | **智能超时保护** | Agent Loop 看门狗(可配,默认 30min)+ 流式总超时(可配,默认 300s)+ 工具 HTTP/MCP 超时可配 |
-| 🪝 | **Hook 系统** | 4 阶段生命周期钩子(pre_tool / post_tool / post_iteration / pre_completion),内置安全检查、文件去重、自动计划追踪、变更审计、结果校验 |
-| 👥 | **子代理委派** | spawn_task 工具,独立上下文 + 超时保护 |
-| 📈 | **Token 仪表盘** | 全局 + 会话统计,消耗趋势柱状图,2 秒刷新,输入/输出分色 |
-| 📋 | **系统提示词卡片** | 每条 AI 回复顶部折叠卡片,点击查看实际发送给模型的完整上下文 |
-| 🎨 | **暖色调 UI** | 奶白 `#FAF7F2` + 珊瑚橙 `#E8734A`,长时间使用不疲劳,流式渲染优化 |
+| 🔍 | **联网搜索(双模式?* | SearXNG 元搜索引?JSON API?0+引擎聚合? 四引?HTML 解析(Bing+百度+搜狗+360),双模式可切换;web_fetch 支持反爬+UA切换+浏览器回退 |
+| 🌏 | **浏览器控?* | 打开网页 · 截图 · 执行 JS · 提取内容 · 点击 · 输入 · 滚动 · 关闭 |
+| 🖥?| **工作空间面板** | 终端(增量流式输出)+ 文件浏览器,命令安全检?|
+| 🔢 | **上下文长度手动控?* | 设置面板下拉选择?28K / 256K / 512K / 1M),默认 128K,模型栏显示当前配置值,下拉框中显示每个模型自身的上下文长度 |
+| 🗜?| **智能上下文管?* | 滑动窗口 + Token 自动校准 + 消息重要性评?+ LLM 结构?JSON 压缩,智能触发(120 条增量压?+ 300 条硬上限?|
+| ⏱️ | **智能超时保护** | Agent Loop 看门狗(可配,默?30min? 流式总超时(可配,默?300s? 工具 HTTP/MCP 超时可配 |
+| 🪝 | **Hook 系统** | 4 阶段生命周期钩子(pre_tool / post_tool / post_iteration / pre_completion),内置安全检查、文件去重、自动计划追踪、变更审计、结果校?|
+| 👥 | **子代理委?* | spawn_task 工具,独立上下文 + 超时保护 |
+| 📈 | **Token 仪表?* | 全局 + 会话统计,消耗趋势柱状图? 秒刷新,输入/输出分色 |
+| 📋 | **系统提示词卡?* | 每条 AI 回复顶部折叠卡片,点击查看实际发送给模型的完整上下文 |
+| 🎨 | **暖色?UI** | 奶白 `#FAF7F2` + 珊瑚?`#E8734A`,长时间使用不疲劳,流式渲染优化 |
| 🔔 | **系统托盘** | 原生托盘集成 |
| 🔐 | **AES-256-GCM** | 数据加密支持 |
-| 🧪 | **可观测性** | 执行轨迹缓冲批量写入 SQLite + Agent Metrics JSON/Prometheus 双格式导出 |
+| 🧪 | **可观测?* | 执行轨迹缓冲批量写入 SQLite + Agent Metrics JSON/Prometheus 双格式导?|
## 🔧 工具清单
-📁 文件系统(13 个)
+📁 文件系统?3 个)
| 工具 | 功能 |
|------|------|
-| `read_file` | 读取文件(文本/binary,2000行默认) |
+| `read_file` | 读取文件(文?binary?000行默认) |
| `write_file` | 写入/追加文件(支持base64二进制) |
| `list_directory` | 列出目录内容 |
-| `search_files` | 搜索文件(正则/通配符) |
+| `search_files` | 搜索文件(正?通配符) |
| `create_directory` | 创建目录 |
| `delete_file` | 删除文件/目录(返回大小) |
-| `move_file` | 移动/重命名文件 |
+| `move_file` | 移动/重命名文?|
| `copy_file` | 复制文件 |
| `edit_file` | 编辑文件(支持正则替换) |
| `tree` | 目录树结构(默认5层深度) |
| `download_file` | 下载文件 |
-| `read_multiple_files` | 批量读取(50文件/10KB) |
+| `read_multiple_files` | 批量读取?0文件/10KB?|
| `compress` | 压缩文件/目录 |
-⚡ 命令执行(1 个)
+?命令执行? 个)
| 工具 | 功能 |
|------|------|
@@ -89,11 +89,11 @@
-🔍 联网搜索(2 个)
+🔍 联网搜索? 个)
| 工具 | 功能 |
|------|------|
-| `web_search` | SearXNG JSON API / 四引擎并行,默认 30 条结果 |
+| `web_search` | SearXNG JSON API / 四引擎并行,默认 30 条结?|
| `web_fetch` | 网页内容抓取,自动重试(指数退避),移动端UA切换,SPA页面自动升级到浏览器渲染 |
@@ -111,27 +111,27 @@
| `browser_type` | 输入文本 |
| `browser_scroll` | 页面滚动 |
| `browser_wait` | 等待元素/延时 |
-| `browser_close` | 关闭浏览器 |
+| `browser_close` | 关闭浏览?|
-📦 Git(1 个,17 个子命令)
+📦 Git? 个,17 个子命令?/strong>
-| 子命令 | 功能 |
+| 子命?| 功能 |
|--------|------|
| `init` `clone` `add` `commit` `push` `pull` | 基础操作 |
-| `diff` `log` `status` `branch` `checkout` | 查看与切换 |
+| `diff` `log` `status` `branch` `checkout` | 查看与切?|
| `merge` `stash` `reset` `tag` `remote` | 高级操作 |
-🧠 记忆管理(1 个)
+🧠 记忆管理? 个)
| 工具 | 功能 |
|------|------|
-| `memory` | 统一记忆管理(5 个 action:search 搜索 / add 添加 / replace 替换 / remove 删除 / read_all 读取全部)。工作空间 MEMORY.md 受路径保护,仅此工具可访问 |
+| `memory` | 统一记忆管理? ?action:search 搜索 / add 添加 / replace 替换 / remove 删除 / read_all 读取全部)。工作空?MEMORY.md 受路径保护,仅此工具可访?|
@@ -142,21 +142,21 @@
|------|------|
| `session_list` | 列出历史会话 |
| `session_read` | 读取会话内容 |
-| `spawn_task` | 委派子代理(独立上下文 + 超时保护) |
+| `spawn_task` | 委派子代理(独立上下?+ 超时保护?|
-🕐 系统工具(1 个)
+🕐 系统工具? 个)
| 工具 | 功能 |
|------|------|
-| `calculator` | 安全数学计算(+ - * / ** % (),递归下降解析器) |
+| `calculator` | 安全数学计算? - * / ** % (),递归下降解析器) |
-📋 Plan Mode(1 个,仅 Plan 模式激活)
+📋 Plan Mode? 个,?Plan 模式激活)
| 工具 | 功能 |
|------|------|
@@ -164,51 +164,51 @@
-## 🏗️ 架构
+## 🏗?架构
```
-用户消息 → 扫描工作空间 SOUL.md(不可压缩层)→ AGENT.md → USER.md(工作空间,不存在则跳过)
- ↓
- 记忆检索 (MEMORY.md 关键词搜索) → 上下文注入
- ↓
- Agent Engine (8 状态机 ReAct Loop, ≤85 轮, 智能重试, 路径依赖串行化, 看门狗+分级超时)
- ↓
- 提示词加固(参考数据标记 + 工具结果安全规则)
- ↓
+用户消息 ?扫描工作空间 SOUL.md(不可压缩层)→ AGENT.md ?USER.md(工作空间,不存在则跳过?
+ ?
+ 记忆检?(MEMORY.md 关键词搜? ?上下文注?
+ ?
+ Agent Engine (8 状态机 ReAct Loop, ?5 ? 智能重试, 路径依赖串行? 看门?分级超时)
+ ?
+ 提示词加固(参考数据标?+ 工具结果安全规则?
+ ?
Ollama API (流式响应,num_ctx 用户可配 128K/256K/512K/1M)
- ↓
- Tool Registry (32 内置 + MCP 动态 + Plan Mode plan_track)
- ↓
- Hook 系统 (pre/post tool/iteration/completion) → 观察结果 → 反思 → 循环 / 最终回答
+ ?
+ Tool Registry (32 内置 + MCP 动?+ Plan Mode plan_track)
+ ?
+ Hook 系统 (pre/post tool/iteration/completion) ?观察结果 ?反??循环 / 最终回?
```
-### 🧩 UI 组件(原生 DOM)
+### 🧩 UI 组件(原?DOM?
```
main.ts (入口)
- ├── header.ts # 顶部导航栏
- ├── model-bar.ts # 模型选择栏
+ ├── header.ts # 顶部导航?
+ ├── model-bar.ts # 模型选择?
├── chat-area.ts # 聊天消息区域
- ├── input-area.ts # 输入框 + 文件上传 + Plan Mode 开关
- ├── workspace-panel.ts # 终端 + 文件浏览器 + 工具卡片
+ ├── input-area.ts # 输入?+ 文件上传 + Plan Mode 开?
+ ├── workspace-panel.ts # 终端 + 文件浏览?+ 工具卡片
├── settings-modal.ts # 设置面板(含看门狗超时配置)
├── history-modal.ts # 会话历史
├── memory-modal.ts # 记忆管理
├── tools-modal.ts # 工具列表
├── token-dashboard.ts # Token 消耗仪表盘
├── tool-confirm-modal.ts # 工具执行确认
- ├── prompt-modal.ts # 系统提示词查看 + Plan 确认弹窗
+ ├── prompt-modal.ts # 系统提示词查?+ Plan 确认弹窗
├── toast.ts # Toast 通知
└── lightbox.ts # 图片灯箱
```
-### 🗄️ 数据库
+### 🗄?数据?
-SQLite (sql.js WASM),5 张表,WAL 模式:
+SQLite (sql.js WASM)? 张表,WAL 模式?
-| 表 | 用途 |
+| ?| 用?|
|---|---|
-| `sessions` | 会话(parent_id 父子关系) |
+| `sessions` | 会话(parent_id 父子关系?|
| `messages` | 消息(外键级联删除) |
| `tool_calls` | 工具调用记录 |
| `settings` | 设置(JSON 序列化) |
@@ -218,17 +218,17 @@ SQLite (sql.js WASM),5 张表,WAL 模式:
| 层级 | 措施 |
|------|------|
-| 📁 文件系统 | `checkPathAllowed()` — 路径黑名单(33 个系统/敏感目录,含 Linux + Windows) |
-| ⚡ 命令执行 | `checkCommandAllowed()` — 命令黑名单(30 条危险命令,含 POSIX + Windows)+ 三种模式 |
-| 🖥️ 前端渲染 | HTML 净化器(白名单标签 + URI 协议检查) |
-| 🔒 Electron | `contextIsolation: true` + IPC 白名单 + IPC fs 路径验证 |
+| 📁 文件系统 | `checkPathAllowed()` ?路径黑名单(33 个系?敏感目录,含 Linux + Windows?|
+| ?命令执行 | `checkCommandAllowed()` ?命令黑名单(30 条危险命令,?POSIX + Windows? 三种模式 |
+| 🖥?前端渲染 | HTML 净化器(白名单标签 + URI 协议检查) |
+| 🔒 Electron | `contextIsolation: true` + IPC 白名?+ IPC fs 路径验证 |
| 🔐 数据加密 | AES-256-GCM |
-| 🧠 记忆安全 | 写入前 Prompt Injection / 敏感信息检测,多层级去重过滤 |
-| 🌐 MCP 安全 | Shadowing 防护 + 双下划线分隔防歧义 |
-| 🌐 网络安全 | `web_fetch` 流式体积限制(10MB)+ 无 content-length 时防 OOM |
-| ⚡ 进程安全 | Windows `taskkill` 强制终止 + 工作空间路径大小写不敏感校验 |
+| 🧠 记忆安全 | 写入?Prompt Injection / 敏感信息检测,多层级去重过?|
+| 🌐 MCP 安全 | Shadowing 防护 + 双下划线分隔防歧?|
+| 🌐 网络安全 | `web_fetch` 流式体积限制?0MB? ?content-length 时防 OOM |
+| ?进程安全 | Windows `taskkill` 强制终止 + 工作空间路径大小写不敏感校验 |
-## 🚀 快速开始
+## 🚀 快速开?
```bash
git clone https://gitee.com/thzxx/metona-ollama-desktop.git
@@ -238,32 +238,32 @@ npm install
npm start
```
-## 📦 构建 Windows 安装包
+## 📦 构建 Windows 安装?
```bash
# 环境:Ubuntu 24.04 + Node.js v22 + Wine 9.0+
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
```
-产出:`release/Metona Ollama Setup v0.16.17.exe`
+产出:`release/Metona Ollama Setup v0.16.18.exe`
-## 🛠️ 常用命令
+## 🛠?常用命令
```bash
-npm start # 构建并运行
+npm start # 构建并运?
npm run dev:renderer # Vite watch(渲染进程)
-npm run dev:main # tsc watch(主进程)
+npm run dev:main # tsc watch(主进程?
npm run build # 完整构建
-npm run dist # 构建 Windows 安装包
+npm run dist # 构建 Windows 安装?
```
## 💻 系统要求
-- 🖥️ Windows 10/11(64 位)
-- 🤖 Ollama 本地运行中(默认 `http://localhost:11434`)
+- 🖥?Windows 10/11?4 位)
+- 🤖 Ollama 本地运行中(默认 `http://localhost:11434`?
- 💾 建议 8GB+ 内存
-## 📄 许可证
+## 📄 许可?
[MIT](LICENSE)
@@ -271,27 +271,27 @@ npm run dist # 构建 Windows 安装包
# 🇬🇧 English
-## ✨ Features
+## ?Features
| | Feature | Description |
|:---:|:---|:---|
| 🤖 | **ReAct Agent Loop** | Always-on, only chat mode. 8-state machine, up to 85 iterations (configurable), smart retry (permanent errors return immediately, transient errors use exponential backoff), tool dedup, path-aware dependency serialization, watchdog + tiered timeout protection |
-| 🛡️ | **Prompt Hardening** | Reference data markers (<<>>) + tool results are data-not-instructions safety rules |
+| 🛡?| **Prompt Hardening** | Reference data markers (<<>>) + tool results are data-not-instructions safety rules |
| 📋 | **Plan Mode** | Toggle switch. AI first generates an execution plan (Markdown-rendered confirmation dialog), then tracks step-by-step execution, **supports resume** (interrupted plans restore on next session) |
| 🔧 | **32 Built-in Tools** | File system · Command · Web search · Browser · Git · Memory · Sessions · Sub-agent · System · Plan Mode tracking |
-| 🧠 | **Smart Memory System** | Three types (fact / preference / rule), stored in workspace MEMORY.md file, path-protected — only the memory tool can access it, pre-write security scan, 500 capacity, auto-extract on conversation end, strict format validation |
+| 🧠 | **Smart Memory System** | Three types (fact / preference / rule), stored in workspace MEMORY.md file, path-protected ?only the memory tool can access it, pre-write security scan, 500 capacity, auto-extract on conversation end, strict format validation |
| 📋 | **Custom Files** | SOUL.md (persona, never compressed) + AGENT.md (behavior rules, built-in fallback) + USER.md (user profile, workspace only, skipped if absent) |
| 🌐 | **MCP Protocol Extension** | JSON-RPC 2.0 over stdio, dynamic tool discovery, Shadowing protection |
| 🔍 | **Web Search (dual-mode)** | SearXNG meta-search JSON API (70+ engines) / quad-engine HTML parsing (Bing+Baidu+Sogou+360), switchable; web_fetch with auto-retry+mobile UA+SPA browser fallback |
| 🌏 | **Browser Control** | Open pages · Screenshot · JS execution · Content extraction · Click · Type · Scroll · Close |
-| 🖥️ | **Workspace Panel** | Terminal (incremental streaming) + file browser, command security checks |
+| 🖥?| **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 + 300 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 |
| 📈 | **Token Dashboard** | Global + session stats, consumption trend bar chart, 2s refresh, input/output color-coded |
-| 📋 | **System Prompt Card** | Collapsible card atop each AI reply — click to inspect the full context sent to the model |
+| 📋 | **System Prompt Card** | Collapsible card atop each AI reply ?click to inspect the full context sent to the model |
| 🎨 | **Warm-tone UI** | Cream `#FAF7F2` + coral `#E8734A`, fatigue-free for extended use, streaming render optimized |
| 🔔 | **System Tray** | Native tray integration |
| 🔐 | **AES-256-GCM** | Data encryption support |
@@ -321,7 +321,7 @@ npm run dist # 构建 Windows 安装包
-⚡ Command Execution (1)
+?Command Execution (1)
| Tool | Function |
|------|------|
@@ -404,22 +404,22 @@ npm run dist # 构建 Windows 安装包
-## 🏗️ Architecture
+## 🏗?Architecture
```
-User message → workspace SOUL.md (never compressed) → AGENT.md → USER.md (workspace, skipped if absent)
- ↓
- Memory Retrieval (MEMORY.md keyword search) → Context Injection
- ↓
- Agent Engine (8-state ReAct Loop, ≤85 iter, smart retry, path-aware serialization, watchdog+tiered timeout)
- ↓
+User message ?workspace SOUL.md (never compressed) ?AGENT.md ?USER.md (workspace, skipped if absent)
+ ?
+ Memory Retrieval (MEMORY.md keyword search) ?Context Injection
+ ?
+ Agent Engine (8-state ReAct Loop, ?5 iter, smart retry, path-aware serialization, watchdog+tiered timeout)
+ ?
Prompt Hardening (reference data markers + tool result safety rules)
- ↓
+ ?
Ollama API (Streaming Response, num_ctx user-configurable 128K/256K/512K/1M)
- ↓
+ ?
Tool Registry (32 Built-in + MCP Dynamic + Plan Mode plan_track)
- ↓
- Hook System (pre/post tool/iteration/completion) → Observation → Reflection → Loop / Final Answer
+ ?
+ Hook System (pre/post tool/iteration/completion) ?Observation ?Reflection ?Loop / Final Answer
```
### 🧩 UI Components (Native DOM)
@@ -442,7 +442,7 @@ main.ts (Entry)
└── lightbox.ts # Image lightbox
```
-### 🗄️ Database
+### 🗄?Database
SQLite (sql.js WASM), 5 tables, WAL mode:
@@ -458,15 +458,15 @@ SQLite (sql.js WASM), 5 tables, WAL mode:
| Layer | Measure |
|------|------|
-| 📁 File System | `checkPathAllowed()` — path blacklist (33 system/sensitive dirs, Linux + Windows) |
-| ⚡ Command Execution | `checkCommandAllowed()` — command blacklist (30 dangerous commands, POSIX + Windows) + three modes |
-| 🖥️ Frontend Rendering | HTML sanitizer (whitelist tags + URI protocol check) |
+| 📁 File System | `checkPathAllowed()` ?path blacklist (33 system/sensitive dirs, Linux + Windows) |
+| ?Command Execution | `checkCommandAllowed()` ?command blacklist (30 dangerous commands, POSIX + Windows) + three modes |
+| 🖥?Frontend Rendering | HTML sanitizer (whitelist tags + URI protocol check) |
| 🔒 Electron | `contextIsolation: true` + IPC whitelist + IPC fs path validation |
| 🔐 Data Encryption | AES-256-GCM |
| 🧠 Memory Security | Pre-write prompt injection / sensitive info detection, multi-layer dedup filtering |
| 🌐 MCP Security | Shadowing protection + double-underscore delimiter disambiguation |
| 🌐 Network Security | `web_fetch` streaming size limit (10MB) + OOM prevention without content-length |
-| ⚡ Process Security | Windows `taskkill` forced termination + case-insensitive workspace path validation |
+| ?Process Security | Windows `taskkill` forced termination + case-insensitive workspace path validation |
## 🚀 Quick Start
@@ -485,9 +485,9 @@ npm start
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm run dist
```
-Output: `release/Metona Ollama Setup v0.16.17.exe`
+Output: `release/Metona Ollama Setup v0.16.18.exe`
-## 🛠️ Common Commands
+## 🛠?Common Commands
```bash
npm start # Build and run
@@ -499,7 +499,7 @@ npm run dist # Build Windows installer
## 💻 System Requirements
-- 🖥️ Windows 10/11 (64-bit)
+- 🖥?Windows 10/11 (64-bit)
- 🤖 Ollama running locally (default `http://localhost:11434`)
- 💾 8GB+ RAM recommended
diff --git a/package-lock.json b/package-lock.json
index 089b8d3..70ecebd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "metona-ollama-desktop",
- "version": "0.16.17",
+ "version": "0.16.18",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "metona-ollama-desktop",
- "version": "0.16.17",
+ "version": "0.16.18",
"license": "MIT",
"dependencies": {
"ffmpeg-static": "^5.2.0",
diff --git a/package.json b/package.json
index 42554c5..3fc0fad 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "metona-ollama-desktop",
- "version": "0.16.17",
+ "version": "0.16.18",
"description": "Metona Ollama - TypeScript + Electron 桌面 AI 聊天客户端",
"main": "dist/main/main.js",
"author": "thzxx",
diff --git a/src/main/menu.ts b/src/main/menu.ts
index 8f43a78..c0395ee 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.17',
+ message: 'Metona Ollama Desktop v0.16.18',
detail: 'TypeScript + Electron Ollama AI 聊天客户端\n\nhttps://gitee.com/thzxx/metona-ollama',
icon: getIconPath()
});
diff --git a/src/main/tool-handlers-system.ts b/src/main/tool-handlers-system.ts
index 0505edb..748ab7a 100644
--- a/src/main/tool-handlers-system.ts
+++ b/src/main/tool-handlers-system.ts
@@ -124,8 +124,8 @@ export function killToolProcess(): boolean {
-/** HTTP 请求超时(毫秒),默认 30s,可通过 IPC 设置 */
-let HTTP_TIMEOUT = 30_000;
+/** HTTP 请求超时(毫秒),默认 900s,可通过 IPC 设置 */
+let HTTP_TIMEOUT = 900_000;
/** 设置 HTTP 请求超时(毫秒),0=禁用超时 */
export function setHTTPTimeout(ms: number): void {
@@ -576,7 +576,7 @@ export async function handleWebFetch(params: { url: string; max_chars?: number;
} catch (err) {
const errMsg = (err as Error).message;
if (errMsg.includes('abort') && attempt < maxAttempts - 1) {
- lastError = `请求超时 (${HTTP_TIMEOUT > 0 ? HTTP_TIMEOUT / 1000 : '∞'}s)(将重试)`;
+ lastError = `请求超时 (${HTTP_TIMEOUT > 0 ? HTTP_TIMEOUT / 1000 : '∞'}s)(将重试)`; // 900s 默认,大页面/慢服务器需要更长时间
continue;
}
if (errMsg.includes('abort')) {
diff --git a/src/renderer/components/metrics-dashboard.ts b/src/renderer/components/metrics-dashboard.ts
index b0e3e1c..e1d01a1 100644
--- a/src/renderer/components/metrics-dashboard.ts
+++ b/src/renderer/components/metrics-dashboard.ts
@@ -129,7 +129,7 @@ function renderMetricsDashboard(): void {
suggestionsEl.innerHTML = suggestions.map(s => `
${s.severity}
- ${s.message}
+ ${s.suggestion}
`).join('');
}
diff --git a/src/renderer/components/settings-modal.ts b/src/renderer/components/settings-modal.ts
index 2d6ee21..ff56f52 100644
--- a/src/renderer/components/settings-modal.ts
+++ b/src/renderer/components/settings-modal.ts
@@ -106,22 +106,22 @@ export function initSettingsModal(): void {
const saveHttpTimeout = debounce(async () => {
const db = state.get(KEYS.DB);
const sec = parseSec(inputHttpTimeout.value.trim());
- const ms = sec >= 0 ? sec * 1000 : 30_000;
+ const ms = sec >= 0 ? sec * 1000 : 900_000;
if (db) await db.saveSetting('httpTimeout', sec);
const bridge = window.metonaDesktop;
if (bridge?.tool?.setTimeouts) {
await bridge.tool.setTimeouts({ http: ms });
}
- logSetting('HTTP 超时', sec >= 0 ? (sec === 0 ? '已禁用' : `${sec}s`) : '默认(30s)');
+ logSetting('HTTP 超时', sec >= 0 ? (sec === 0 ? '已禁用' : `${sec}s`) : '默认(900s)');
}, 500);
const saveStreamTimeout = debounce(async () => {
const db = state.get(KEYS.DB);
const sec = parseSec(inputStreamTimeout.value.trim());
- const ms = sec >= 0 ? sec * 1000 : 300_000;
+ const ms = sec >= 0 ? sec * 1000 : -1;
state.set('streamTimeout', ms);
if (db) await db.saveSetting('streamTimeout', sec);
- logSetting('流式超时', sec >= 0 ? (sec === 0 ? '已禁用' : `${sec}s`) : '默认(300s)');
+ logSetting('流式超时', sec >= 0 ? (sec === 0 ? '已禁用' : `${sec}s`) : '默认(动态)');
}, 500);
const saveMCPTimeout = debounce(async () => {
diff --git a/src/renderer/index.html b/src/renderer/index.html
index 4a6cd9e..309b23b 100644
--- a/src/renderer/index.html
+++ b/src/renderer/index.html
@@ -28,7 +28,7 @@