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]>
36 lines
1.5 KiB
TypeScript
36 lines
1.5 KiB
TypeScript
import { browserServiceFor } from "../browser/index.ts";
|
|
import type { ServerContext, ServerModule } from "../types.ts";
|
|
import { dbSessionChecks, desktopUpstream, registerDesktopRoutes } from "./desktop.ts";
|
|
|
|
/**
|
|
* WT-1 原站视图桌面模式:/api/v1/browser/desktop/{sessionId}/* 反代浏览器桌面容器(Selkies)的 HTTP 与 WebSocket,
|
|
* 按人工租约注入控制 / 只读口令。只用会话 / 租约表(只读),不改浏览器模块。
|
|
* 桌面地址:BROWSER_DESKTOP_URL,缺省由 BROWSER_PROVIDER_URL 推出(端口换 3000)。
|
|
*/
|
|
export function createDesktopModule(): ServerModule {
|
|
let closeAll: (() => void) | null = null;
|
|
return {
|
|
name: "desktop",
|
|
registerRoutes(app, ctx: ServerContext) {
|
|
const r = registerDesktopRoutes(app, {
|
|
upstream: desktopUpstream({
|
|
providerUrl: ctx.config?.BROWSER_PROVIDER_URL,
|
|
desktopUrl: Deno.env.get("BROWSER_DESKTOP_URL") || undefined,
|
|
}),
|
|
accessKey: ctx.config?.BROWSER_ACCESS_KEY ?? null,
|
|
...dbSessionChecks(ctx.db),
|
|
// 桌面连接期间保活浏览器会话(AG-4):人在桌面里的操作不经 camofox API,不保活会被空闲 5 分钟回收
|
|
onConnect: (sessionId) => browserServiceFor(ctx)?.keepalive.hold(sessionId, "desktop", "desktop") ?? (() => {}),
|
|
log: (msg, extra) => ctx.logger.warn({ component: "desktop", ...extra }, msg),
|
|
});
|
|
closeAll = r.closeAll;
|
|
},
|
|
registerTasks() {},
|
|
stop() {
|
|
closeAll?.();
|
|
},
|
|
};
|
|
}
|
|
|
|
export const desktopModule = createDesktopModule();
|