第9章:前端与 ACP —— 同一个运行时,多个交互表面
一、前端的职责不是重新实现 Agent
Hermes 目前同时包含 CLI/TUI、Web、Desktop、API Server、ACP 和 Gateway 平台。这些表面拥有不同的交互需求:终端需要快捷键和同步输出,Web 需要事件流和会话管理,编辑器需要协议化工具/审批,消息平台需要分块和限速。
正确的边界是:
frontend event → normalized session command
→ shared AIAgent / Gateway runtime
→ normalized stream event
→ frontend-specific renderer
如果前端自己维护一份 tool loop,UI 很快会和 CLI 的压缩、重试、凭证和安全语义分叉。
二、TUI:同步体验包住异步 Agent
ui-tui/src/app.tsx、gatewayClient.ts 和 gatewayTypes.ts 表明 TUI 使用 gateway client 与运行时通信;它的重点不是直接 import Python,而是消费统一的状态和事件。
CLI 侧则由 prompt_toolkit、rich 和 cli.py 处理多行编辑、slash command、历史、streaming display、interrupt/redirect。它需要把“新输入”转成 steering,而不是粗暴地杀掉进程;第 2 章的 Loop 才能决定是在当前 turn 边界处理 redirect。
三、Web 与 Desktop:管理面和交互面
web/ 是 Vite/React 前端;apps/desktop/ 提供桌面应用;hermes_cli/web_routers/、web_models.py 和 gateway/platforms/api_server.py 提供后端 API/模型。
这类管理面通常需要:
- provider/model 选择;
- session 浏览、搜索、重命名、导入/导出;
- memory provider 配置;
- toolset toggle;
- gateway 状态、健康和日志;
- 文件管理和工作区操作。
这些 API 不应把内部 Python 对象原样暴露。hermes_cli/web_models.py 使用 Pydantic request models,把外部输入转换成受控的领域对象,并把错误转成稳定的 HTTP 语义。
四、ACP:为编辑器提供 Agent 协议边界
acp_adapter/entry.py、session.py、events.py、permissions.py、edit_approval.py 和 server.py 构成 ACP 适配器。SessionManager 负责创建/加载 session;server 再把编辑器请求翻译成 Hermes turn。
ACP 特别强调:
- auth 与 session 隔离;
- edit approval;
- 工具事件和 provenance;
- server 重启后的 session load;
- 与 MCP 的互操作。
这说明“编辑器集成”不是另一个 UI,而是一个有独立安全模型的入口协议。
五、Gateway 与 API Server 的共同点和差异
共同点是都把外部请求映射到 Agent/session;差异在于:
| 表面 | 连接形态 | 更关心什么 |
|---|---|---|
| Messaging Gateway | 长连接/回调、弱同步 | pairing、平台限流、delivery、线程/频道 |
| API Server | HTTP 请求/流式响应 | auth、schema、状态码、上传和资源生命周期 |
| ACP | 编辑器协议、多轮 RPC | 权限、编辑审批、session 能力协商 |
| TUI | 本地交互、低延迟 | 快捷键、重绘、interrupt、终端尺寸 |
统一运行时只需要提供共同的 session/turn/stream 语义;外层处理自己的交互协议。
六、流式 UI 的一个关键细节:single writer
多来源同时写一个终端或平台消息会产生错乱:模型 token、tool progress、状态提示、错误和最终回复可能来自不同线程。Hermes 的 stream_single_writer.py、gateway stream consumer 和前端 client 共同体现 single-writer 思路:
many producers → one ordered consumer → one output surface
这不仅是 UI 问题,也影响 session display metadata 和 delivery ledger 的一致性。
七、前端扩展的正确方法
新增前端时优先复用:
- session resolve/load/store;
- Agent run/conversation loop;
- normalized stream events;
- tool approval 和 interrupt API;
- delivery/status/health contract。
只在最后一层实现平台特有的渲染、快捷键、分块、媒体和错误文案。