feat(server): browser module with DB-backed sessions, takeover lease and browser.* capabilities

/browser/providers, /browser/sessions (open/close/list), navigate/snapshot/screenshot/
click/type/scroll/select/extract/download and control acquire/release. Human input
needs an active lease; expiry or captcha moves the session to waiting with a decision;
release forces a fresh snapshot. Downloads are staged under DATA_DIR/tmp, verified by
infohash and submitted through POST /acquisition-plans. Capability count 21 -> 25.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 20:17:46 +08:00
1 parent c17d4b90bd
commit adffe36846
12 files changed
+2133 -5

No files matched your search

@@ -42,8 +42,8 @@ describe.skipIf(!hasPg)("E2 Agent 委托闭环(fake 模型 + 真实能力/授权
return r.body.data.id as string;
};
it("启动断言:21 个能力全部注册,并在能力目录里可见", async () => {
expect(e.booted.ctx.capabilities.list()).toHaveLength(21);
it("启动断言:25 个能力全部注册,并在能力目录里可见", async () => {
expect(e.booted.ctx.capabilities.list()).toHaveLength(25);
const r = await e.api("GET", "/capabilities");
expect(r.body.data.items.map((c: { id: string }) => c.id).sort()).toEqual(
e.booted.ctx.capabilities
+3
View File
@@ -5,6 +5,7 @@ import { makeTorrent } from "@umt/testkit";
import { createAcquisitionOrganizeModule } from "../../../src/modules/acquisition-organize/index.ts";
import { createAgentModule } from "../../../src/modules/agent/index.ts";
import { authSettingsModule } from "../../../src/modules/auth-settings/index.ts";
import { createBrowserModule } from "../../../src/modules/browser/index.ts";
import { createSchedulesModule } from "../../../src/modules/schedules/index.ts";
import { createSourcesIdentityModule } from "../../../src/modules/sources-identity/index.ts";
import type { ServerModule } from "../../../src/modules/types.ts";
@@ -65,6 +66,8 @@ export function buildModules(o: E2EModuleOptions): ServerModule[] {
...(o.fakeScripts ? { fakeScripts: o.fakeScripts } : {}),
goalPollSec: 1,
}),
// 浏览器能力(browser.*)随首批能力一起注册;e2e 不配置浏览器服务
createBrowserModule(),
// 定时任务调度器(驱动上面模块登记的周期任务;须在末尾)
createSchedulesModule({ builtinChecks: false, scheduler: { tickMs: 100, lockRetryMs: 200 } }),
];