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 构建输出构建流程:
cd webui && bun run build→ 输出到webui/dist/- Hatch 构建时通过
hatch_build.py将webui/dist/包含进 wheel - 安装 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”定位,降低部署门槛。