Agent Buddy Bridge:将 M5StickC 物理按钮连接到 Hermes Agent 的完整方案

April 26, 2026

Agent Buddy Bridge:将 M5StickC 物理按钮连接到 Hermes Agent


目标


实现用 M5StickC Plus 设备的物理按钮(A/B)对 Hermes Agent 的 Dangerous Command 进行审批:



M5StickC Plus (BLE Peripheral, Claude Desktop Buddy firmware)
       ↕ BLE NUS
BLECentral (ble_central.py)
       ↓ JSON over BLE
HTTPServer (:8765) ← POST /buddy/state + X-Session-Key
       ↑ Hermes BuddyPlatformAdapter.send_exec_approval()
       (via platform_class: "agent_buddy_bridge.platform.BuddyPlatformAdapter")
       
M5StickC 按钮 → BLE → BLECentral._handle_notification
       ↓
HTTPServer.handle_internal_approve() → Hermes /internal/approve
       ↓ (PR #11812 合并后) 或 Approval Relay (fallback)
resolve_gateway_approval(session_key, choice)

架构组件


1. M5StickC Plus 设备端


状态:已有完整开源固件,直接复用。


- 源码:https://github.com/anthropics/claude-desktop-buddy

- BLE NUS Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e

- RX Char (写): 6e400002-b5a3-f393-e0a9-e50e24dcca9e

- TX Char (通知): 6e400003-b5a3-f393-e0a9-e50e24dcca9e

- 设备名称格式:Claude-XXXX


2. BLE NUS JSON 协议


Desktop → Device(心跳,每 10s):


{
  "total": 3,
  "running": 1,
  "waiting": 1,
  "msg": "approve: Bash",
  "entries": ["10:42 git push", "10:41 yarn test"],
  "tokens": 184502,
  "tokens_today": 31200,
  "prompt": {
    "id": "req_abc123",
    "tool": "Bash",
    "hint": "rm -rf /tmp/foo"
  }
}

Device → Desktop(按钮决策):


{"cmd": "permission", "id": "req_abc123", "decision": "once"}
{"cmd": "permission", "id": "req_abc123", "decision": "deny"}

3. Hermes BuddyPlatformAdapter(进程内)


位置agent_buddy_bridge/platform.py


- 通过 platform_class 配置注入 Hermes Gateway

- 实现 send_exec_approval() 推送状态到 BuddyBridge HTTP Server

- 注册 approval_callback 给 AIAgent(PR #11812 特性)

- 关键类:BuddyPlatformAdapter, BuddyApprovalCallback



# ~/.hermes/config.yaml
platforms:
  buddy:
    enabled: true
    platform_class: "agent_buddy_bridge.platform.BuddyPlatformAdapter"
    bridge_url: "http://localhost:8765"
    hermes_approve_url: "http://localhost:8642"

4. BuddyBridge(独立进程,Mac)


位置hermes_buddy_bridge/


文件职责
`http_server.py`HTTP Server (:8765),接收 Hermes POST /buddy/state,暴露 /internal/approve 端点
`json_codec.py`NUS JSON 编解码
`main.py`入口,整合所有组件,管理 prompt_id → session_key 映射

5. Hermes Plugin(pre_tool_call hook)


位置hermes_plugin/


- 注册 pre_tool_call hook

- 可选:插件侧 allowlist 直接 approve 某些工具



# ~/.hermes/config.yaml
plugins:
  enabled:
    - buddy-bridge

HTTP 接口


进程PortMethodPathDirectionBody
BuddyBridge8765GET`/buddy/status`Hermes → Bridge
BuddyBridge8765POST`/internal/approve`Bridge → Hermes`{"session_key","choice"}`
Approval Relay8766POST`/approve`Bridge → Hermes`{"session_key","choice"}` (fallback)

启动命令



# Terminal 1: BuddyBridge(推荐方式,PR #11812 合并后)
python -m hermes_buddy_bridge.main \
    --http-port 8765 \
    --hermes-approve-url http://localhost:8642 \
    --relay-url http://localhost:8766

# PR #11812 合并前,需启动 Approval Relay 作为 fallback
python -m hermes_buddy_bridge.approval_relay \
    --hermes-home ~/.hermes \
    --port 8766

Hermes 配置(PR #11812 合并后)



# ~/.hermes/config.yaml

# 1. 启用 BuddyBridge Platform Adapter(via platform_class)
platforms:
  buddy:
    enabled: true
    platform_class: "agent_buddy_bridge.platform.BuddyPlatformAdapter"
    bridge_url: "http://localhost:8765"
    hermes_approve_url: "http://localhost:8642"

# 2. 启用 BuddyBridge Plugin(pre_tool_call hook)
plugins:
  enabled:
    - buddy-bridge

# 3. 确保 approvals 配置(默认 telegram 或你的主平台)
approvals:
  mode: "telegram"  # 或 "buddy"(PR #11812 后支持)

安装 agent-buddy-bridge



# 编辑模式安装,Hermes 可自动发现
cd ~/code/agent-buddy-bridge
pip install -e .

# 或者手动符号链接插件
ln -s ~/code/agent-buddy-bridge/hermes_plugin ~/.hermes/plugins/buddy-bridge

关键文件清单



~/code/agent-buddy-bridge/
├── README.md
├── LICENSE
├── requirements.txt          # bleak, aiohttp
├── .gitignore
├── hermes_plugin/             # Hermes 插件(pre_tool_call hook)
│   ├── __init__.py            # register() + _on_pre_tool_call()
│   └── plugin.yaml
└── hermes_buddy_bridge/       # BuddyBridge 主程序
    ├── __init__.py
    ├── platform.py             # BuddyPlatformAdapter + BuddyApprovalCallback (PR #11812)
    ├── ble_central.py          # BLE Central(bleak + CoreBluetooth)
    ├── json_codec.py           # NUS JSON 编解码
    ├── http_server.py          # HTTP Server (:8765,接收 Hermes 状态 + /internal/approve)
    ├── approval_relay.py       # Approval Relay Server (:8766,fallback 方案)
    └── main.py                 # Bridge 入口

PR #11812 关键改动(待合并)


改动文件意义
`pre_tool_call` → `{"action": "approve"}``tools/terminal_tool.py`插件可绕过 dangerous command 审批
`"plugin"` approval mode`tools/approval.py`新的审批模式,插件处理审批
`approval_callback` param`run_agent.py`AIAgent 接收审批回调参数

参考资料

参考资料

- Claude Desktop Buddy 源码:https://github.com/anthropics/claude-desktop-buddy

- BLE NUS 协议:src/ble_bridge.cpp, src/data.h, REFERENCE.md

- PR #11812:https://github.com/NousResearch/hermes-agent/pull/11812

- PR #11816(实现):https://github.com/NousResearch/hermes-agent/pull/11816

- Hermes Plugin 系统:AGENTS.md → Plugin 部分

- bleak 文档:https://bleak.readthedocs.io/


开发日志


日期阶段内容产出
2026-04-26项目初始化创建 GitHub 仓库 `harryfan1985/agent-buddy-bridge`,编写代码骨架`ble_central.py`, `http_server.py`, `http_client.py`, `json_codec.py`, `main.py`, `approval_relay.py`
2026-04-26Hermes 调研分析 Hermes 扩展机制(Plugin、Webhook、Platform Adapter),确认 Hermes 没有内置 HTTP 审批回调端点结论:需要 PR #11812
2026-04-26PR #11812 研究详细查看 Issue 和 PR #11816 代码,理解 `platform_class`、`pre_tool_call approve`、`approval_callback` 三大改动明确基于 PR #11812 的新架构
2026-04-26集成开发基于 PR #11812 设计实现 BuddyPlatformAdapter + Hermes Plugin + 双路径 fallback`platform.py`, `hermes_plugin/`, `http_server.py` 更新,`main.py` 重构

后续任务计划


Phase 1: BuddyBridge 独立测试(不依赖 Hermes)


- [ ] BLE Central 扫描测试

- 测试 bleak 能否在 Mac 上扫描到 M5StickC 设备(设备名 Claude-XXXX

- 验证 CoreBluetooth 权限


- [ ] BLE 连接测试

- 建立 BLE 连接,启用 NUS TX notify

- 测试 JSON 心跳收发


- [ ] NUS 协议验证

- 对比 Claude Desktop Buddy 固件的 NUS 协议与 json_codec.py 实现是否完全匹配

- 必要时调整编解码格式


Phase 2: Hermes 侧桩代码(不等 PR 合并)


- [ ] 手动注册 BuddyAdapter 到 Platform 枚举

- 修改 gateway/config.pyPlatform 枚举添加 BUDDY

- 在 gateway/platforms/ 创建 buddy.py

- 绕过 platform_class,直接走 Hermes 内置加载机制

- ⚠️ 违反"不修改 Hermes 核心代码"约束,仅用于原型验证


- [ ] 添加 Hermes /internal/approve 端点

- 在 gateway/platforms/api_server.py 添加 /internal/approve POST 端点

- 调用 resolve_gateway_approval(session_key, choice)

- ⚠️ 同样需要修改 Hermes


Phase 3: 端到端集成(需硬件 + Hermes 改动)


- [ ] 完整审批流程测试

- Hermes 检测 dangerous command → send_exec_approval() → POST /buddy/state

- BuddyBridge 接收 → BLE → M5StickC 显示

- M5StickC 按钮 A/B → BLE 回传 → POST /internal/approve

- Hermes resolve_gateway_approval() → Agent 线程解锁


- [ ] 超时和错误处理

- M5StickC 无响应超时(60s Hermes 默认超时)

- BLE 断线重连

- Hermes 端点不可用 fallback 到 Approval Relay


Phase 4: 硬件与固件


- [ ] M5StickC 固件适配

- 确认 Claude Desktop Buddy 固件是否需要修改

- 验证 NUS 心跳间隔、permission 消息格式兼容性


- [ ] 设备配对流程

- macOS BLE 配对对话框处理

- 首次配对后的自动重连


Phase 5: PR #11812 合并后


- [ ] 移除桩代码

- 删除 Phase 2 的 Hermes 临时修改

- 切换到正式的 platform_class 配置方式


- [ ] 正式部署

- pip install -e . 安装 agent-buddy-bridge

- 配置 ~/.hermes/config.yamlplatforms.buddyplugins.buddy-bridge

- 验证 Hermes 自动加载 BuddyPlatformAdapter


阻塞项


阻塞依赖解决方案
`platform_class` 不存在PR #11812 未合并Phase 2 桩代码 或 等待 PR 合并
无法真机测试 BLE需要 M5StickC Plus 硬件Phase 1 扫描测试验证 bleak 是否正常工作
NUS 协议兼容性未知需要抓包或查看 Claude Buddy 固件源码Phase 1 协议验证