feat(browser): keep sessions alive during desktop, takeover and agent use (AG-4)
camofox reaps a tab after TAB_INACTIVITY_MS (5 min) without API tool calls;
desktop-mode input goes straight to Selkies and screenshots don't count, so
tabs disappeared under the user during takeover.
- BrowserKeepalive (in-process): sessions held by an open desktop WebSocket
(ref-counted), a human takeover lease, or a running/queued agent run that
used browser.* get a keepalive every BROWSER_KEEPALIVE_MS (default 120s,
0 = off). Holds are re-checked each round; release/lease expiry/agent end/
session close stop it and camofox reaps as usual.
- Keepalive call: camofox 1.17 has no keepalive/touch endpoint and /stats does
not bump toolCalls; use GET /tabs/{id}/downloads without includeData/consume
(read-only metadata). Goes through BrowserService.run so restarts or reaped
tabs self-heal via BR-3 reconnect; no lastAutomationAt, no control needed.
- Runbook browser.md §12, deploy env table, compose env; tests against the
testkit mock camofox.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
919dc02200
commit
1fcfcac885
13 files changed
+523
-12
No files matched your search
+38
-1
@@ -342,7 +342,8 @@ docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./umt-root.cr
|
||||
|
||||
- Firefox 工具栏里有 Playwright 的 "JUGGLER" 标识;用户可在画面里打开 `about:addons`、新标签页、输入任意网址——越界防护
|
||||
(`policies.json`、`context.route` 白名单、交还时核对 URL,方案 §6)未做。
|
||||
- 接管期间 camofox 看不到 API 请求,`SESSION_TIMEOUT_MS`(缺省 30 分钟)到期会回收会话窗口;接管心跳(方案 §5.5 插件)未做。
|
||||
- 接管期间 camofox 看不到 API 请求:桌面连接期间与人工接管期间由 app 定期保活(§12,AG-4),不再被空闲回收;
|
||||
浏览器里的心跳插件(方案 §5.5)不做。
|
||||
- 一个桌面承载所有站点会话:持有 A 站租约的人在画面里能看到 / 操作切到前台的其它窗口;目前同一时刻一般只有一个会话窗口。
|
||||
- 真实输入法(Windows 微软拼音、macOS 日文)、Firefox / Safari 客户端、真实 PT 站点未测;容器内 fcitx5 只验证能启动,未验证组字。
|
||||
- 画面坐标与 camofox 截图坐标不同(桌面含 56 px 工具栏,Camoufox 伪装了 `screenX` / `outerHeight`),Agent 视觉操作继续用 camofox 截图。
|
||||
@@ -605,3 +606,39 @@ Camoufox 浏览器包的层都走构建缓存,**不会重新下载 Camoufox(约
|
||||
`migration-browser-identity.test.ts`、`apps/server/src/modules/browser/__tests__/browser-identity.test.ts`(出口下发、身份存库)、
|
||||
`packages/adapters/src/browser/umt-plugin.test.ts`(插件纯函数、适配器接口);真机:本地临时容器(`--network none`,只开容器内本地
|
||||
页面)核验了 §11.1 表格与 §11.5 出口行为,未对真实站点发请求。
|
||||
|
||||
## 12. 会话保活(AG-4)
|
||||
|
||||
camofox 按 **API 调用**判断活动,有三道空闲回收(`docker-compose.yml` 的 camofox 环境变量):
|
||||
|
||||
| 回收 | 缺省 | 判据 |
|
||||
| --- | --- | --- |
|
||||
| 标签页 `TAB_INACTIVITY_MS` | 5 分钟 | 每 60 秒看一次标签页的 `toolCalls` 有没有变;没变且超过 5 分钟 → 关标签页,会话空了连会话一起关 |
|
||||
| 会话 `SESSION_TIMEOUT_MS` | 30 分钟 | 会话 `lastAccess`(大部分 `/tabs/{id}/*` 接口都会刷新) |
|
||||
| 浏览器 `BROWSER_IDLE_TIMEOUT_MS` | 5 分钟 | 一个会话都没有之后浏览器进程退出 |
|
||||
|
||||
桌面模式里人的键鼠直接进 Selkies,原站视图截图(`GET /tabs/{id}/screenshot`)只刷新 `lastAccess`、不加 `toolCalls`——
|
||||
接管 5 分钟后标签页被关掉,桌面画面里的窗口消失。app 在"正在用"的会话上定期保活,代码 `modules/browser/keepalive.ts`、
|
||||
`BrowserService.keepAlive`、适配器 `keepAlive`。
|
||||
|
||||
**保活调用**:camofox 1.17 没有 keepalive / touch 接口;`GET /tabs/{id}/stats` 只刷新 `lastAccess`,挡不住标签页回收。
|
||||
用 `GET /tabs/{id}/downloads?userId=…`(不带 `includeData` / `consume`):只列下载元数据,不读页面、不改页面、不清下载记录,
|
||||
会让 `toolCalls` 加一、刷新 `lastAccess`。只对当前标签页做,不要求控制权,不记 `lastAutomationAt`。
|
||||
|
||||
**什么时候保活**(进程内登记,各进程保活自己登记的):
|
||||
|
||||
| 使用方 | 开始 | 停止 |
|
||||
| --- | --- | --- |
|
||||
| 桌面连接 | 桌面模式 WebSocket 建立(控制或只读都算,多个连接按引用计数) | 全部连接断开 |
|
||||
| 人工接管 | `control/acquire` | 交还(`control/release`)、租约过期、会话关闭 |
|
||||
| 智能体会话 | 智能体会话里的浏览器能力调用(`browser.*`,含 `browser.navigate` 新开会话) | 智能体会话不再是排队 / 运行中(结束、等待下载或等用户),或最后一次使用后 30 分钟 |
|
||||
|
||||
每 `BROWSER_KEEPALIVE_MS`(缺省 120000 = 2 分钟,0 = 关闭;要比 `TAB_INACTIVITY_MS` 短)对登记的会话各做一次;
|
||||
每轮先复查登记是否还有效,没有使用方的会话不再保活,照常由 camofox 空闲回收。会话关闭(`DELETE`)立即撤销全部登记。
|
||||
|
||||
**保活失败**:保活走与其它动作相同的 `run()` 路径——浏览器重启过(实例标识变了)或标签页已被回收(404 / 410、适配器里没有打开的标签页)
|
||||
→ 按 §10 自愈重连(注入 Cookie、同一会话新开标签页回到原地址)后在新标签页上再保活一次;重连也失败(浏览器服务不可用)只记 warn 日志
|
||||
「浏览器会话保活失败」,会话照常标 `needsReconnect` / `reconnect.status = failed`,下一轮再试。
|
||||
|
||||
核验:`apps/server/src/modules/browser/__tests__/browser-keepalive.test.ts`(登记 / 引用计数 / 复查;对 mock camofox:接管期间保活、
|
||||
不记自动化活动、交还后停;桌面连接期间标签页被回收 → 保活时自愈重连;智能体会话结束后停、会话关闭撤销)。真机未核验。
|
||||
@@ -134,6 +134,7 @@ docker compose logs app | grep 'setup token'
|
||||
| `BROWSER_PROVIDER_URL` | `http://camofox:9377` | app 登记的浏览器服务地址(`camofox-env`);接自有实例时改 |
|
||||
| `BROWSER_ACCESS_KEY` | `CAMOFOX_ACCESS_KEY` | 该服务的访问凭据,只在进程内使用,不入库 |
|
||||
| `BROWSER_ENABLED` | `true` | `false` = 停用 `camofox-env`,界面标"浏览器不可用" |
|
||||
| `BROWSER_KEEPALIVE_MS` | `120000` | 桌面接管 / 人工接管 / 智能体正在用的浏览器会话的保活间隔,0 = 关闭;要比 camofox 标签页空闲回收(5 分钟)短(`docs/runbook/browser.md` §12) |
|
||||
| `CAMOFOX_REPLICAS` | `1` | `0` = 不起 camofox 容器 |
|
||||
| `CAMOFOX_SESSION_TIMEOUT_MS` / `CAMOFOX_BROWSER_IDLE_TIMEOUT_MS` | `1800000` / `300000` | 会话空闲回收(落盘登录状态)/ 浏览器空闲退出 |
|
||||
| `CAMOFOX_MAX_SESSIONS` / `CAMOFOX_MEM_LIMIT` | `8` / `2g` | 最多并发会话 / 容器内存上限 |
|
||||
|
||||
Reference in new issue
Block a user