晴天
3c8c315402
feat(hermes): Batch 2 §I + Batch 3 §M - 流恢复 + Kanban 看板
...
## Batch 2 §I 流恢复(chat 在切页/刷新后能接上 run)
校对稿:用 run_id 持久化到 localStorage,新页面挂载时查询 status 决定是否重连。
### 后端
- 新 Tauri 命令 hermes_run_status(run_id):
· GET /v1/runs/{run_id} 返回 { run_id, status, last_event, output?, ... }
· status: running / stopping / completed / failed / cancelled / waiting_for_approval
· 404 友好返回 status='not_found' 而不是抛错
### 前端 chat-store
- 新 STORAGE_ACTIVE_RUN 持久化 { runId, sessionId, profile, t }
- hermes-run-started 监听里 safeSet 持久化
- cleanupAfterRun 里 safeRemove 清理
- 新方法 recoverIfRunning():
· 跨 profile / 1 小时过期 → 直接清
· status=running/stopping/waiting_for_approval → attachStreamListeners + 恢复 streaming
· status=已结束 → 拉最新 messages
· 404 → 静默清
### chat.js
- 页面挂载时 store.recoverIfRunning() — 切页/刷新后无缝接上流
## Batch 3 §M Kanban 看板(Hermes 已内置)
校对稿:「Hermes 已内置 kanban 系统,直接调 /api/plugins/kanban/* 即可」。
设计稿原本是「自建本地存储」(~800 行),复用 Hermes 内置后大幅缩减。
### 新页面 /h/kanban
- 全部走 hermesDashboardApi(复用 §H 的基础设施)
- 顶部 board 切换器 + 「+ 新任务」按钮
- 渲染 board.columns(按状态分列:todo / in_progress / blocked / done / archived)
- 任务卡片:title + summary(2 行截断)+ priority badge + assignee + 评论数
- 点卡片 → showContentModal 显示详情 + 「修改状态」按钮
- 修改状态 → PATCH /api/plugins/kanban/tasks/{id} { status }
- board 切换 → POST /api/plugins/kanban/boards/{slug}/switch
### sidebar
- 「管理」section 加 Kanban 入口(inbox 图标)
- /h/kanban 路由注册
### CSS (.hm-kanban-*)
- 水平滚动 board 容器
- 280px 固定宽度列 + 内部滚动
- 卡片 hover 边框变 accent 色 + 轻阴影
- 优先级 badge(琥珀色)/ assignee(accent 色)
### i18n
- 27 个新键 × 3 语言(zh-CN/en/zh-TW)
## 累计
- Rust: 1 个新命令(hermes_run_status ~30 行)
- 前端: chat-store 流恢复(~40 行)+ kanban 新页面(~230 行)
- i18n: 27 个新键 × 3 语言
- CSS: ~100 行
- cargo check ✓ + npm build ✓
2026-05-14 05:12:37 +08:00
晴天
8eb8a7666e
feat(hermes): Batch 3 §K - 多模态图片上传(chat attach + 拖拽 + 粘贴 + base64)
...
Hermes Agent 已支持 OpenAI 多模态格式(tests/gateway/test_api_server_multimodal.py),
ClawPanel 前端补 attach UI 即可对接 Claude 3.5 / GPT-4o / Gemini 等视觉模型。
## 后端
- HermesAttachment 结构:{ kind, mime, name?, data_base64 }
- build_multimodal_input(text, attachments) 把 text 转成
[{type:"text",text}, {type:"image_url",image_url:{url:"data:..;base64,.."}}, ...]
- hermes_agent_run 加 attachments 参数(向后兼容:未传时走原 string input)
## 前端
- tauri-api.js: hermesAgentRun 加 attachments 参数
- chat-store sendMessage:
· 允许 text 空但有 attachments 也能发
· user 消息记录 attachments[].dataUrl 用于气泡内渲染
· isTauriRuntime 时 await api.hermesAgentRun(...,atts)
- chat.js 渲染层:
· renderMessage 在内容前插入 .hm-chat-msg-attachments + .hm-chat-msg-image(点击放大)
· 输入栏前面增加 .hm-chat-attach-preview 预览条(缩略图 + 文件名 + × 移除)
· 输入框左侧加 paperclip attach 按钮 + 隐藏 <input type="file" accept="image/*" multiple>
· 发送按钮 disabled 条件改为 (!text && !attachments)
- chat.js 交互:
· fileToBase64 用 FileReader 转纯 base64
· addAttachmentFromFile 校验 image/* + 10MB + 最多 5 张
· attach 按钮 click → 触发文件选择器
· 拖拽到输入区 → dragover 高亮 + drop 加附件
· 粘贴图片 → clipboardData 读 image 文件
· 移除按钮 splice
- chat-store.sendMessage 后清 pendingAttachments
## 限制
- 单图最大 10 MB(base64 后约 13 MB)
- 一次最多 5 张
- 超限 toast 友好提示
- 非图片格式拒收
## CSS
- .hm-chat-attach-btn / hover / disabled
- .hm-chat-attach-preview / chip / chip-name / chip-remove
- .hm-chat-input-wrap--dragover(拖拽虚线高亮)
- .hm-chat-msg-attachments / msg-image / msg-image--zoom(点击放大模式)
## i18n
- engine.chatAttach / chatAttachRemove / chatAttachOnlyImage
- chatAttachTooBig / chatAttachTooMany / chatAttachReadFailed
- 3 语言(zh-CN/en/zh-TW)
## 注意
- Web 模式(dev-api 走 SSE)暂不支持 attachments 透传(hermes_agent_run_stream 没改),
原因:Web 模式当前 chat 是 stream-only 路径,需要单独改 dev-api 的 hermes_agent_run_stream handler
- 桌面端 Tauri 模式开箱可用
- 累计变动:6 个文件,~120 行新代码,6 个 i18n 键
- cargo check ✓ + npm build ✓
2026-05-14 04:59:36 +08:00
晴天
efade55f61
feat(hermes): Batch 1 §C+§D+§C-bis - Approval Flow + Stop 真中断 + 3 类新事件
...
校对稿(hermes-source-verified)基于真实 Hermes 源码确认了关键事实:
- 真实 SSE 事件 9 类(设计稿推测的 6 个根本不存在)
- 真实 abort 端点:POST /v1/runs/{run_id}/stop(用 run_id 不是 session_id)
- Approval Flow 是 Hermes 重要原生特性,ClawPanel 0% 接入 → 跑代码工具就崩
本 PR 一次解决 3 个必修硬伤:
## 修复 1: Stop 假停(§D)
- 新 Tauri 命令 hermes_run_stop(run_id) → POST /v1/runs/{run_id}/stop
- chat-store: state 新增 currentRunId,来自 hermes-run-started 事件
- stopStreaming() 改为:先调 hermes_run_stop(currentRunId) 通知后端,再 abort 本地 SSE
- 之前 stopStreaming 只 abort 本地 SSE,后端继续跑完 → 是「假停」
## 修复 2: Approval Flow 接入(§C-bis 新增 — 设计稿原本没写)
- 新 Tauri 命令 hermes_run_approval(run_id, choice) → POST /v1/runs/{run_id}/approval
- choice 枚举校验:once / session / always / deny
- chat-store: state.pendingApproval 存待批准信息(tool, args, choices, run_id)
- chat.js: 新增 renderApprovalPanel() 渲染琥珀色气泡 + 4 按钮 + JSON args 预览
- store.respondApproval(choice) 暴露给 UI(乐观清状态 + 失败回滚)
- 用户跑代码工具(terminal/code_execution)时会触发,没接入就会卡死
## 修复 3: SSE 事件白名单补 3 类(§C 校对版)
- normalize_hermes_stream_event 白名单增加:
· approval.request → emit hermes-run-approval-request
· approval.responded → emit hermes-run-approval-responded
· run.cancelled → emit hermes-run-cancelled(终态,返回 Ok(true))
- chat-store 新监听 u5..u9(5 个新事件):
· hermes-run-started → 存 currentRunId
· approval-request → 设 pendingApproval
· approval-responded → 清 pendingApproval
· cancelled → 标记 (stopped) + cleanup
· reasoning → 标记 hasReasoning(设计稿推测的 reasoning.delta 不存在)
- handleStreamEvent(Web 模式)同步加 4 个新分支
## chat.js UI
- renderApprovalPanel:琥珀色边框 + 🔐 emoji + 工具名 + JSON args 预览 + 4 选项按钮
- "deny" 用 btn-secondary(灰色),其他 btn-primary(蓝色)
- 按钮点击 → store.respondApproval(choice) → 后端 POST + 等服务端 approval.responded 作权威清理
- streaming 中显示 aborting 文案当 state.aborting=true
## CSS (.hm-chat-approval*)
- 琥珀色边框 + 半透明背景(明/暗主题各自适配)
- args 单独 monospace 代码块、max-height: 180px 防过长
- 响应式:max-width: 720px,按钮 flex-wrap
## i18n
- engine.chatAborting / chatApprovalTitle / chatApprovalHint
- chatApprovalOnce / chatApprovalSession / chatApprovalAlways / chatApprovalDeny
- chatApprovalFailed
- 3 语言(zh-CN/en/zh-TW),其它语言走 fallback
## 设计稿对照(保留可信细节,砍掉推测)
- ✅ 留:approval.request / approval.responded / run.cancelled / reasoning.available(4 类真实事件)
- ❌ 砍:reasoning.delta / thinking.delta / compression.* / abort.* / usage.updated / run.queued(6 类不存在的事件,hermes-web-ui 内部合成)
- ✅ 修:abort 端点路径 /v1/runs/{run_id}/stop(用 run_id)
## 累计
- Rust: 1 个 helper(read_hermes_api_key) + 2 个新命令 + emit_hermes_stream_event 加 3 分支
- 前端: chat-store 新 4 个 state 字段 + 5 个监听器 + 4 个 handleStreamEvent 分支 + respondApproval API
- chat.js: renderApprovalPanel + 按钮绑定 + aborting 文案
- i18n: +8 个键 × 3 语言
- cargo check ✓ + npm build ✓
2026-05-14 04:48:14 +08:00
晴天
d0d6950628
fix(web-mode): consolidate Tauri event subscription helper to silence transformCallback errors ( #256 )
...
- Add shared safeTauriListen helper in tauri-api.js that returns a noop
unsubscriber when running outside Tauri, so dynamic-importing
@tauri-apps/api/event in the browser no longer throws
'Cannot read properties of undefined (reading transformCallback)'.
- Replace 4 bare 'await import(@tauri-apps/api/event)' call sites
(about.js hermes upgrade button + channels.js three install/action flows)
that previously crashed the page on web mode.
- Drop the duplicated local tauriListen helpers in hermes dashboard / chat
store and route them through the shared helper.
2026-05-14 01:31:58 +08:00
晴天
81c42dbfe2
chore: release v0.15.1
2026-05-10 21:30:36 +08:00
晴天
328624cf03
chore: release v0.15.0
...
发布 0.15.0:
- 新增内核版本兼容层、特性门控、低版本阻断和升级提示
- 新增 PATH 中 OpenClaw CLI 冲突检测、隔离与恢复
- 修复 Hermes Gateway loopback 自动拉起与 /v1/runs 诊断
- 修复 standalone 一键安装包在 About/仪表盘显示未知版本
- 同步 OpenClaw 2026.5.6 推荐版本和热更新 minAppVersion
- 补齐本地 JS/Rust 测试与发布前检查说明
验证:
- npm run build
- node --test tests/*.test.js
- node --check src/scripts JS 文件
- cargo fmt --all -- --check
- cargo check
- cargo clippy --all-targets -- -D warnings
- cargo test
2026-05-08 04:39:36 +08:00
晴天
3ed59fcb2b
feat(hermes): align dashboard APIs and add xintian engine
2026-04-25 10:31:32 +08:00