浏览器实时预览
当前浏览器实时画面的鉴权、绑定节点代理、标签页与历史回放链路。
实时预览已实现,采用 Frontend → Backend → 绑定 Executor Manager → Executor → Chrome CDP 的 WebSocket 代理。JPEG 二进制帧沿原路返回,Backend 和 Manager 都转发帧,用户浏览器无需直接访问执行节点随机端口。
当前链路
用户态入口为 POST /api/v1/sessions/{session_id}/computer/browser-stream,返回 stream_url 与 expires_at。Backend 代理路径为 /api/v1/sessions/browser-stream/ws,Executor 路径为 /v1/browser/stream。生产环境正确配置 Backend 公共地址及 WebSocket 反向代理。
标签页与订阅
可查询浏览器标签并通过 target_id 预览指定标签;未指定时使用默认目标选择。预览只订阅画面,不发送键鼠输入或页面导航,不应抢占 Agent 操作。
同一默认目标或同一 target_id 的订阅者共享 producer,不是整个 session 永远只有一个 producer。不同目标可拥有独立 producer。慢客户端只保留最新帧,取消最后一个订阅后停止对应 producer;当前没有可作为产品保证的每会话观看人数上限。
画面使用 JPEG,质量 60,最大宽 1280、高 720。实际刷新速度受 Chrome、页面内容、编码和多级代理网络影响,不能把建议帧率当作固定保证。
鉴权与路由
Backend 校验用户权限并签发会话代理令牌,Manager 根据会话绑定查找容器,Executor 校验流令牌与会话身份。当前代理和流令牌有效期为 5 分钟,用于握手;断线后重新申请地址,不保留过期地址作为长期链接。
会话首次执行后绑定 worker,预览返回该节点。节点地址需可被 Backend 访问,Executor 发布主机和随机端口需可被 Manager 访问。多个执行节点不能只配置一个固定默认 Manager 代替绑定路由。
实时与回放
实时帧用于当前观看,不作为完整录像落盘。历史回放继续使用工具执行时采集的关键截图,以 tool_use_id 关联,并从对象存储读取。实时连接失败时,可查看已生成的关键截图;已有截图不代表实时浏览器仍运行。
上线核对包括 WebSocket 握手、目标标签选择、关闭后的订阅释放、慢客户端行为、绑定节点网络和关键截图回放。
源码入口
- 用户态申请:
backend/app/api/v1/sessions.py。 - Backend 代理:
backend/app/api/v1/session_browser_stream.py。 - Manager 服务发现与代理:
executor_manager/app/api/v1/computer.py。 - Executor WebSocket:
executor/app/api/v1/browser_stream.py。 - CDP 与共享订阅:
executor/app/core/browser_stream.py。 - 前端画面:
frontend/features/chat/components/execution/computer-panel/。