Skip to content

v2.2.0 — 多 agent 并行,窗口可以不出现

Choose a tag to compare

@Glittering Glittering released this 27 Oct 17:53
· 44 commits to main since this release

v2.2.0 — 多 agent 并行,窗口可以不出现

这一版解决两件事,它们其实是同一个问题的两面:agent 该在哪一页上干活,以及
浏览器必须长什么样。

1. 几个 agent 同时用,各干各的

以前默认目标是全局 activeTab,也就是"人眼看的那一页"。单 agent 时它恰好等于
"agent 正在干的活",看不出问题。多个 agent 同时用时立刻崩:

  • A 开一个标签页 → 所有人的默认目标都变成它;
  • B 只说"点一下提交",点在了 A 的页面上;
  • 人切一下标签页看热闹 → 把所有 agent 的目标一起切走。

共同点:动作落在哪个页面,取决于别人做了什么。回执 success、页面真的变了,
但不是该变的那个 —— 比直接失败难查得多。

现在每条连接(每个 MCP 进程)有自己的工作标签页,判据只有一处
(shared/tab_route.cjs):

点名的 tab > 你自己的 tab > 人正在看的 > 第一个
  • browse_tabs {"op":"new"} 不顶掉用户正在看的那一页(show:true 才显示)。
    唯一例外:人眼前还是没被动过的启动页 —— 否则用户会盯着百度首页看 agent 干活。
  • browse_tabs {"op":"list"} 在你自己那条上标 mine: true。
  • 你的页被别人关掉 → 下一次调用明确报 -32001,绝不静默落到别人的页面上。
    自己关自己的页 → 照浏览器惯例落回可见页。
  • 点链接弹出新页:只把目标挪过去;只有打开者本身是可见页时才挪视野。
    (agent 流程里登录/预览/下载弹窗极多,每弹一个抢一次视野等于人没法用电脑。)

2. 窗口不显示,活照样干完

用户的原话:"必须可以不在前台显示的情况下,agent 可以完成所有操作 … 跟无头浏览器
一样无感知运行,并且随时可以点开,使用它,还不影响 agent 进行任何任务。"

这以前做不到,三处硬伤:

  1. 隐藏不是稳定状态:任何动作都会把隐藏/最小化的窗口 showInactive 回来 ——
    agent 每操作一次,窗口就自己爬出来一次。
  2. 没挂进窗口的标签页没有合成表面:读树/点击/输入/导航都正常,但 screenshot
    返回 0 字节、paint_check 直接 no-frame。截图正是 agent 判断"这一页画出什么"
    的唯一手段 —— 后台标签页变成一个看不见也拍不到的黑盒。
  3. 窗口不可见时仍在做白屏判定:取帧要么空要么陈旧,而阶梯会据此 reload ——
    后台无人值守时等于自己制造一场重载风暴。

现在的行为:

AI_BROWSER_START_HIDDEN=1 ...        # 进程起来但不出窗口
browse_tabs {"op":"window","visible":false}   # 中途退到后台
browse_tabs {"op":"window","visible":true}    # 要人登录/扫码时打开
  • 可见性只由人(Dock 图标 → activate)和显式调用决定;AI_BROWSER_FOCUS=auto
    不再碰窗口任何状态。
  • 所有标签页都挂进窗口、用 z 序决定谁在上面(setTopBrowserView),因此后台标签页有
    真实表面
    :能截图、能自检、能录 canvas。每个标签页从出生起 backgroundThrottling=false。
  • 窗口不可见时跳过白屏判定;人把窗口点开时补一次自检(兜住"agent 在后台把页面搞白了,
    人一打开正好看到白屏")。
  • 隐藏期间全部能力可用:读树 / 点击 / 输入 / 滚动 / 上传 / 下载 / 应答对话框 / 抓包 /
    截图 / 导航。npm run background 用 37 条断言钉住,其中启动就是 START_HIDDEN=1
    ——窗口从头到尾没出现过。

已知边界

  • 两个 agent 往同一个输入框里同时打字不做协调,值校验会如实报 input not verified;
    不同标签页之间完全并行。
  • 每个标签页都占一份合成资源(和 Chrome 多标签一个量级),不是"免费"。

验证

  • 单元:npm test — 71 文件 / 1001 条。
  • 端到端:npm run e2e:all — 22 套件 / 696 断言,新增两个:
    • npm run multiagent(32 断言):两条连接对同一个浏览器,各自的目标、并行动作不串台、
      被关掉要报错、switch 只换目标不换视野。
    • npm run background(37 断言):启动即隐藏,跑完整能力切片,再显示回去验证可见页没变。
  • e2e/run_all.cjs 顺带补了一条:套件没有摘要时打印它最后几行输出。
    以前只写"无摘要(未知)",等于把唯一的线索扔了。