跳转到内容

WebSocket 多路复用与 WebUI

WebSocket 多路复用与 WebUI

学习目标

理解 Nanobot 的 WebUI 架构:Vite + React 前端通过 WebSocket 多路复用协议与 Gateway 通信,构建产物嵌入 Python wheel。

项目实践

WebUI 构建与嵌入

WebUI 是一个独立的 Vite + React 项目,位于 webui/ 目录:

webui/
├── package.json
├── vite.config.ts
├── src/
│ ├── App.tsx
│ └── ...
└── dist/ # Vite 构建输出

构建流程

  1. cd webui && bun run build → 输出到 webui/dist/
  2. Hatch 构建时通过 hatch_build.pywebui/dist/ 包含进 wheel
  3. 安装 wheel 后,WebUI 文件位于 nanobot/web/dist/

开发模式

  • Vite dev server 代理 /api, /webui, /auth 和 WebSocket 到 Gateway(127.0.0.1:8765
  • HMR 支持实时预览

WebSocket 多路复用协议

单个 WebSocket 连接支持多个”聊天会话”:

每个消息包含会话标识,Gateway 根据标识将消息路由到正确的 AgentLoop

WebUI Turn 协调器

WebuiTurnCoordinator 管理 WebUI 的 Turn 生命周期:

  • Turn 开始:发布 running 状态,前端显示 spinner
  • Turn 结束:发布 idle 状态,包含延迟时间
  • 进度回调:通过消息总线推送工具调用进度到前端
await self._webui_turns.publish_run_status(msg, "running")
# ... agent execution ...
await self._webui_turns.publish_run_status(msg, "idle")

分段流式输出

WebUI 使用流式分段(stream segment)来区分工具调用和最终回复:

{
"_stream_id": "unified:default:1234567890:0",
"_stream_delta": true,
"_stream_end": true,
"_resuming": false
}
  • _stream_delta: 内容增量
  • _stream_end: 当前段结束
  • _resuming: true 表示工具调用继续(spinner 重启),false 表示最终回复

设计取舍

为什么将 WebUI 打包进 wheel

优势

  • 用户只需 pip install nanobot-ai,不需要额外的构建步骤
  • 版本号与 Python 包同步,确保兼容性
  • 部署简单:wheel 安装即包含所有文件

代价

  • wheel 文件增大(包含 React 构建产物)
  • 前端更新需要发布新版本

替代方案:WebUI 作为独立项目/服务部署。Nanobot 选择嵌入的原因是”个人 Agent”定位,降低部署门槛。

参考来源