@anvia/browser 1.0.7 → 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MIGRATION.md +68 -0
- package/README.md +202 -26
- package/dist/automation-worker.d.ts +2 -0
- package/dist/automation-worker.js +298 -0
- package/dist/automation-worker.js.map +1 -0
- package/dist/index.d.ts +71 -21
- package/dist/index.js +2006 -572
- package/dist/index.js.map +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/automation-worker.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { Browser, Locator, Page, Route } from \"playwright-core\";\nimport { chromium } from \"playwright-core\";\nimport type {\n AutomationCancel,\n AutomationCommand,\n AutomationRequest,\n AutomationResponse,\n BrowserTarget,\n SerializedError,\n} from \"./automation-protocol\";\nimport type { BrowserNavigationPolicy, BrowserTab } from \"./types\";\n\ntype ActiveOperation = {\n cancelled: boolean;\n page?: Page;\n completed: Promise<void>;\n complete: () => void;\n};\n\nlet browser: Browser | undefined;\nlet selected: Page | undefined;\nconst tabIds = new WeakMap<Page, string>();\nconst pagesById = new Map<string, Page>();\nconst operations = new Map<number, ActiveOperation>();\nlet navigationPolicyKey: string | undefined;\n\nprocess.once(\"disconnect\", () => {\n void closeAfterParentExit();\n});\n\nprocess.on(\"message\", (message: AutomationRequest | AutomationCancel) => {\n if (message.kind === \"cancel\") {\n void cancelOperation(message);\n return;\n }\n void runRequest(message);\n});\n\nasync function runRequest(request: AutomationRequest): Promise<void> {\n let complete: (() => void) | undefined;\n const operation: ActiveOperation = {\n cancelled: false,\n completed: new Promise<void>((resolve) => {\n complete = resolve;\n }),\n complete: () => complete?.(),\n };\n operations.set(request.id, operation);\n try {\n const value = await execute(request, operation);\n send({ kind: \"response\", id: request.id, ok: true, value });\n } catch (error) {\n send({ kind: \"response\", id: request.id, ok: false, error: serializeError(error) });\n } finally {\n operation.complete();\n operations.delete(request.id);\n }\n}\n\nasync function cancelOperation(request: AutomationCancel): Promise<void> {\n const operation = operations.get(request.id);\n if (operation !== undefined) {\n operation.cancelled = true;\n await operation.page?.close().catch(() => undefined);\n await operation.completed;\n }\n send({ kind: \"cancelled\", id: request.id });\n}\n\nasync function execute(request: AutomationRequest, operation: ActiveOperation): Promise<unknown> {\n const command: AutomationCommand = request;\n switch (command.method) {\n case \"connect\": {\n if (browser !== undefined) throw new Error(\"Automation worker is already connected.\");\n const connected = await chromium.connectOverCDP(command.params.endpointUrl, {\n timeout: command.params.timeoutMs,\n });\n try {\n if (operation.cancelled) throw new Error(\"Connection attempt was cancelled.\");\n const context = connected.contexts()[0];\n if (context === undefined) {\n throw new Error(\"CDP connection did not expose a browser context.\");\n }\n const session = await connected.newBrowserCDPSession();\n try {\n await session.send(\"Browser.getVersion\");\n } finally {\n await session.detach().catch(() => undefined);\n }\n if (operation.cancelled) throw new Error(\"Connection attempt was cancelled.\");\n } catch (error) {\n await connected.close().catch(() => undefined);\n throw error;\n }\n browser = connected;\n selected = pages()[0];\n for (const page of pages()) idFor(page);\n connected.once(\"disconnected\", () => {\n browser = undefined;\n send({ kind: \"event\", event: \"disconnected\" });\n });\n return undefined;\n }\n case \"disconnect\": {\n const connected = browser;\n browser = undefined;\n selected = undefined;\n if (connected !== undefined) await connected.close();\n return undefined;\n }\n case \"listTabs\":\n return tabSummaries();\n case \"setNavigationPolicy\":\n await setNavigationPolicy(command.params.policy);\n return undefined;\n case \"openTab\": {\n const context = assertBrowser().contexts()[0];\n if (context === undefined) throw new Error(\"Browser has no CDP context.\");\n const page = await context.newPage();\n operation.page = page;\n if (operation.cancelled) {\n await page.close().catch(() => undefined);\n throw new Error(\"Open-tab operation was cancelled.\");\n }\n selected = page;\n return tabResult(page);\n }\n case \"selectTab\": {\n const page = pageFor(command.params.tabId);\n selected = page;\n return tabResult(page);\n }\n case \"closeTab\": {\n const page = pageFor(command.params.tabId);\n operation.page = page;\n await page.close();\n if (page === selected) selected = pages()[0];\n return { closedTabId: command.params.tabId, tabs: await tabSummaries() };\n }\n case \"navigate\": {\n const page = targetPage(command.params.tabId, operation);\n await page.goto(command.params.url, {\n timeout: command.params.timeoutMs,\n waitUntil: command.params.waitUntil,\n });\n return tabResult(page);\n }\n case \"snapshot\": {\n const page = targetPage(command.params.tabId, operation);\n const snapshot = await page.locator(\"body\").ariaSnapshot({\n timeout: command.params.timeoutMs,\n });\n const truncated = snapshot.length > command.params.maxChars;\n return {\n ...(await tabResult(page)),\n snapshot: truncated ? snapshot.slice(0, command.params.maxChars) : snapshot,\n truncated,\n };\n }\n case \"click\": {\n const page = targetPage(command.params.tabId, operation);\n await locatorFor(page, command.params.target).click({ timeout: command.params.timeoutMs });\n return tabResult(page);\n }\n case \"type\": {\n const page = targetPage(command.params.tabId, operation);\n await locatorFor(page, command.params.target).fill(command.params.text, {\n timeout: command.params.timeoutMs,\n });\n return tabResult(page);\n }\n case \"pressKey\": {\n const page = targetPage(command.params.tabId, operation);\n await page.keyboard.press(command.params.key);\n return tabResult(page);\n }\n case \"screenshot\": {\n const page = targetPage(command.params.tabId, operation);\n const png = await page.screenshot({\n type: \"png\",\n fullPage: false,\n timeout: command.params.timeoutMs,\n });\n return { metadata: await tabResult(page), pngBase64: png.toString(\"base64\") };\n }\n }\n}\n\nfunction assertBrowser(): Browser {\n if (browser === undefined || !browser.isConnected())\n throw new Error(\"Browser connection is closed.\");\n return browser;\n}\n\nfunction pages(): Page[] {\n return browser?.contexts().flatMap((context) => context.pages()) ?? [];\n}\n\nfunction idFor(page: Page): string {\n const existing = tabIds.get(page);\n if (existing !== undefined) return existing;\n const id = randomUUID();\n tabIds.set(page, id);\n pagesById.set(id, page);\n page.once(\"close\", () => pagesById.delete(id));\n return id;\n}\n\nfunction pageFor(id: string): Page {\n assertBrowser();\n const page = pagesById.get(id);\n if (page === undefined || page.isClosed() || !pages().includes(page)) {\n throw new Error(`Browser tab does not exist: ${id}`);\n }\n return page;\n}\n\nfunction targetPage(id: string, operation: ActiveOperation): Page {\n const page = pageFor(id);\n operation.page = page;\n return page;\n}\n\nasync function tabSummaries(): Promise<readonly BrowserTab[]> {\n assertBrowser();\n if (selected?.isClosed()) selected = pages()[0];\n return Promise.all(\n pages().map(async (page) => ({\n id: idFor(page),\n title: await page.title(),\n url: page.url(),\n selected: page === selected,\n })),\n );\n}\n\nasync function tabResult(page: Page) {\n return { tabId: idFor(page), title: await page.title(), url: page.url() };\n}\n\nasync function setNavigationPolicy(policy: BrowserNavigationPolicy): Promise<void> {\n const key = JSON.stringify(policy);\n if (navigationPolicyKey !== undefined) {\n if (navigationPolicyKey !== key) {\n throw new TypeError(\"Browser connection already has a different navigation policy.\");\n }\n return;\n }\n navigationPolicyKey = key;\n await Promise.all(\n assertBrowser()\n .contexts()\n .map((context) => context.route(\"**/*\", (route) => enforceNavigationPolicy(route, policy))),\n );\n}\n\nasync function enforceNavigationPolicy(\n route: Route,\n policy: BrowserNavigationPolicy,\n): Promise<void> {\n const request = route.request();\n const frame = request.frame();\n if (\n request.isNavigationRequest() &&\n frame === frame.page().mainFrame() &&\n !isNavigationAllowed(request.url(), policy)\n ) {\n await route.abort(\"blockedbyclient\");\n return;\n }\n await route.continue();\n}\n\nfunction isNavigationAllowed(value: string, policy: BrowserNavigationPolicy): boolean {\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return false;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") return false;\n if (url.username.length > 0 || url.password.length > 0) return false;\n return policy.mode === \"allow-all-http\" || policy.origins.includes(url.origin);\n}\n\nfunction locatorFor(page: Page, target: BrowserTarget): Locator {\n switch (target.by) {\n case \"role\": {\n const options: { name?: string; exact?: boolean } = {};\n if (target.name !== undefined) options.name = target.name;\n if (target.exact !== undefined) options.exact = target.exact;\n return page.getByRole(target.role as never, options);\n }\n case \"text\": {\n const options: { exact?: boolean } = {};\n if (target.exact !== undefined) options.exact = target.exact;\n return page.getByText(target.text, options);\n }\n case \"label\": {\n const options: { exact?: boolean } = {};\n if (target.exact !== undefined) options.exact = target.exact;\n return page.getByLabel(target.label, options);\n }\n case \"placeholder\": {\n const options: { exact?: boolean } = {};\n if (target.exact !== undefined) options.exact = target.exact;\n return page.getByPlaceholder(target.placeholder, options);\n }\n case \"test-id\":\n return page.getByTestId(target.testId);\n case \"css\":\n return page.locator(target.selector);\n }\n}\n\nfunction serializeError(error: unknown): SerializedError {\n if (error instanceof Error) {\n const value: { name: string; message: string; stack?: string; code?: string } = {\n name: error.name,\n message: error.message,\n };\n if (error.stack !== undefined) value.stack = error.stack;\n if (\"code\" in error && typeof error.code === \"string\") value.code = error.code;\n return value;\n }\n return { name: \"Error\", message: String(error) };\n}\n\nfunction send(message: AutomationResponse): void {\n if (!process.connected || process.send === undefined) return;\n process.send(message, () => undefined);\n}\n\nasync function closeAfterParentExit(): Promise<void> {\n const forceExit = setTimeout(() => process.exit(1), 2_000);\n const connected = browser;\n browser = undefined;\n await connected?.close().catch(() => undefined);\n clearTimeout(forceExit);\n process.exit(0);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
1
|
import { DockerSandboxWorkspace, DockerSandboxResources, DockerSandboxRuntimeLimits, DockerSandboxState, DockerSandbox, DockerSandboxInspectionOptions, DockerSandboxInspector, DockerSandboxClient } from '@anvia/sandbox';
|
|
2
2
|
import { AnyTool } from '@anvia/core/tool';
|
|
3
3
|
|
|
4
|
+
type BrowserErrorCode = "action_timeout" | "agent_action_busy" | "cancelled" | "connection_closed" | "connection_timeout" | "human_control_conflict" | "human_controlled" | "invalid_state" | "lifecycle_timeout" | "navigation_blocked" | "not_ready" | "readiness_timeout" | "runtime_destroyed" | "startup_failed" | "tool_failed" | "transport_failure";
|
|
5
|
+
type BrowserErrorRecovery = "none" | "retry" | "reconnect" | "restart" | "recreate";
|
|
6
|
+
type BrowserErrorOptions = ErrorOptions & Readonly<{
|
|
7
|
+
retryable?: boolean;
|
|
8
|
+
recovery?: BrowserErrorRecovery;
|
|
9
|
+
capability?: BrowserCapability;
|
|
10
|
+
phase?: string;
|
|
11
|
+
}>;
|
|
12
|
+
declare class BrowserError extends Error {
|
|
13
|
+
readonly code: BrowserErrorCode;
|
|
14
|
+
readonly retryable: boolean;
|
|
15
|
+
readonly recovery: BrowserErrorRecovery;
|
|
16
|
+
readonly capability: BrowserCapability | undefined;
|
|
17
|
+
readonly phase: string | undefined;
|
|
18
|
+
constructor(message: string, code: BrowserErrorCode, options?: BrowserErrorOptions);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type BrowserLifecycleOptions = Readonly<{
|
|
22
|
+
timeoutMs?: number | undefined;
|
|
23
|
+
abortSignal?: AbortSignal | undefined;
|
|
24
|
+
}>;
|
|
4
25
|
type DockerBrowserClientOptions = Readonly<{
|
|
5
26
|
sandboxClient: DockerSandboxClient;
|
|
6
27
|
image: string;
|
|
7
28
|
}>;
|
|
8
|
-
type PullDockerBrowserImageOptions =
|
|
9
|
-
abortSignal?: AbortSignal;
|
|
10
|
-
}>;
|
|
29
|
+
type PullDockerBrowserImageOptions = BrowserLifecycleOptions;
|
|
11
30
|
type BrowserViewport = Readonly<{
|
|
12
31
|
width: number;
|
|
13
32
|
height: number;
|
|
@@ -26,28 +45,59 @@ type CreateDockerBrowserOptions = Readonly<{
|
|
|
26
45
|
desktop: BrowserDesktopOptions;
|
|
27
46
|
resources?: DockerSandboxResources;
|
|
28
47
|
runtime?: DockerSandboxRuntimeLimits;
|
|
29
|
-
|
|
48
|
+
timeoutMs?: number | undefined;
|
|
49
|
+
abortSignal?: AbortSignal | undefined;
|
|
30
50
|
}>;
|
|
31
51
|
type ResumeDockerBrowserOptions = Readonly<{
|
|
32
52
|
id: string;
|
|
33
|
-
|
|
53
|
+
timeoutMs?: number | undefined;
|
|
54
|
+
abortSignal?: AbortSignal | undefined;
|
|
55
|
+
}>;
|
|
56
|
+
type BrowserCapability = "runtime" | "browser" | "automation" | "desktop";
|
|
57
|
+
type BrowserCapabilityState = "unknown" | "checking" | "ready" | "failed" | "stopped" | "destroyed";
|
|
58
|
+
type BrowserCapabilitySnapshot = Readonly<{
|
|
59
|
+
capability: BrowserCapability;
|
|
60
|
+
state: BrowserCapabilityState;
|
|
61
|
+
checkedAt?: string;
|
|
62
|
+
error?: BrowserError;
|
|
63
|
+
}>;
|
|
64
|
+
type BrowserReadinessSnapshot = Readonly<{
|
|
65
|
+
state: "unknown" | "checking" | "partial" | "ready" | "degraded" | "failed" | "stopped" | "destroyed";
|
|
66
|
+
capabilities: Readonly<Record<BrowserCapability, BrowserCapabilitySnapshot>>;
|
|
34
67
|
}>;
|
|
35
68
|
type BrowserWaitUntilReadyOptions = Readonly<{
|
|
36
69
|
timeoutMs: number;
|
|
37
|
-
abortSignal?: AbortSignal;
|
|
70
|
+
abortSignal?: AbortSignal | undefined;
|
|
71
|
+
capabilities?: readonly [BrowserCapability, ...BrowserCapability[]] | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
type BrowserSchedulingOptions = Readonly<{
|
|
74
|
+
mode: "serial";
|
|
75
|
+
maxQueuedActions?: number;
|
|
76
|
+
}> | Readonly<{
|
|
77
|
+
mode: "per-tab";
|
|
78
|
+
maxConcurrentTabs?: number;
|
|
79
|
+
maxQueuedActions?: number;
|
|
38
80
|
}>;
|
|
39
81
|
type BrowserConnectOptions = Readonly<{
|
|
40
|
-
|
|
82
|
+
timeoutMs?: number | undefined;
|
|
83
|
+
abortSignal?: AbortSignal | undefined;
|
|
84
|
+
scheduling?: BrowserSchedulingOptions | undefined;
|
|
41
85
|
}>;
|
|
86
|
+
type BrowserControlAvailability = "available" | "degraded" | "disconnected" | "destroyed";
|
|
42
87
|
type BrowserControlSnapshot = Readonly<{
|
|
43
88
|
mode: "agent" | "human";
|
|
89
|
+
state: "agent" | "agent-active" | "human-pending" | "human";
|
|
90
|
+
availability: BrowserControlAvailability;
|
|
91
|
+
activeAgentActions: number;
|
|
92
|
+
humanPending: boolean;
|
|
44
93
|
ownerId?: string;
|
|
45
94
|
expiresAt?: string;
|
|
46
95
|
}>;
|
|
47
96
|
type AcquireBrowserHumanControlOptions = Readonly<{
|
|
48
97
|
ownerId: string;
|
|
49
98
|
leaseTimeoutMs: number;
|
|
50
|
-
|
|
99
|
+
timeoutMs?: number | undefined;
|
|
100
|
+
abortSignal?: AbortSignal | undefined;
|
|
51
101
|
}>;
|
|
52
102
|
type RenewBrowserHumanControlOptions = Readonly<{
|
|
53
103
|
leaseTimeoutMs: number;
|
|
@@ -70,16 +120,21 @@ type BrowserDesktopEndpoint = Readonly<{
|
|
|
70
120
|
}>;
|
|
71
121
|
interface DockerBrowser extends AsyncDisposable {
|
|
72
122
|
readonly id: string;
|
|
123
|
+
/** Includes browser-handle lifecycle transitions such as `stopping` and `destroying`. */
|
|
73
124
|
readonly state: DockerSandboxState;
|
|
74
125
|
readonly desktop: BrowserDesktopEndpoint;
|
|
75
126
|
readonly sandbox: DockerSandbox;
|
|
76
127
|
inspector(options: DockerSandboxInspectionOptions): DockerSandboxInspector;
|
|
128
|
+
readiness(): BrowserReadinessSnapshot;
|
|
129
|
+
waitForCapabilities(options: BrowserWaitUntilReadyOptions): Promise<BrowserReadinessSnapshot>;
|
|
77
130
|
waitUntilReady(options: BrowserWaitUntilReadyOptions): Promise<void>;
|
|
78
131
|
connect(options?: BrowserConnectOptions): Promise<PlaywrightBrowserConnection>;
|
|
79
|
-
stop(options?:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
132
|
+
stop(options?: BrowserLifecycleOptions): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Starts an irreversible terminal transition. A timeout or cancellation bounds this caller's
|
|
135
|
+
* wait; uncancellable sandbox cleanup remains owned and visible as `destroying` to later callers.
|
|
136
|
+
*/
|
|
137
|
+
destroy(options?: BrowserLifecycleOptions): Promise<void>;
|
|
83
138
|
}
|
|
84
139
|
type BrowserTab = Readonly<{
|
|
85
140
|
id: string;
|
|
@@ -87,10 +142,11 @@ type BrowserTab = Readonly<{
|
|
|
87
142
|
url: string;
|
|
88
143
|
selected: boolean;
|
|
89
144
|
}>;
|
|
145
|
+
type BrowserActionOptions = BrowserLifecycleOptions;
|
|
90
146
|
interface PlaywrightBrowserConnection extends AsyncDisposable {
|
|
91
147
|
readonly closed: boolean;
|
|
92
|
-
listTabs(): Promise<readonly BrowserTab[]>;
|
|
93
|
-
disconnect(): Promise<void>;
|
|
148
|
+
listTabs(options?: BrowserActionOptions): Promise<readonly BrowserTab[]>;
|
|
149
|
+
disconnect(options?: BrowserLifecycleOptions): Promise<void>;
|
|
94
150
|
}
|
|
95
151
|
type BrowserToolName = "browser_list_tabs" | "browser_open_tab" | "browser_select_tab" | "browser_close_tab" | "browser_navigate" | "browser_snapshot" | "browser_click" | "browser_type" | "browser_press_key" | "browser_screenshot";
|
|
96
152
|
type BrowserNavigationPolicy = Readonly<{
|
|
@@ -120,12 +176,6 @@ declare class DockerBrowserClient {
|
|
|
120
176
|
resumeBrowser(options: ResumeDockerBrowserOptions): Promise<DockerBrowser>;
|
|
121
177
|
}
|
|
122
178
|
|
|
123
|
-
type BrowserErrorCode = "connection_closed" | "human_controlled" | "invalid_state" | "navigation_blocked" | "not_ready" | "startup_failed";
|
|
124
|
-
declare class BrowserError extends Error {
|
|
125
|
-
readonly code: BrowserErrorCode;
|
|
126
|
-
constructor(message: string, code: BrowserErrorCode, options?: ErrorOptions);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
179
|
declare function createBrowserTools(options: CreateBrowserToolsOptions): readonly AnyTool[];
|
|
130
180
|
|
|
131
|
-
export { type AcquireBrowserHumanControlOptions, type BrowserConnectOptions, type BrowserControl, type BrowserControlSnapshot, type BrowserDesktopEndpoint, type BrowserDesktopOptions, BrowserError, type BrowserErrorCode, type BrowserHumanControlLease, type BrowserNavigationPolicy, type BrowserTab, type BrowserToolLimits, type BrowserToolName, type BrowserViewport, type BrowserWaitUntilReadyOptions, type CreateBrowserToolsOptions, type CreateDockerBrowserOptions, type DockerBrowser, DockerBrowserClient, type DockerBrowserClientOptions, type PlaywrightBrowserConnection, type PullDockerBrowserImageOptions, type RenewBrowserHumanControlOptions, type ResumeDockerBrowserOptions, createBrowserTools };
|
|
181
|
+
export { type AcquireBrowserHumanControlOptions, type BrowserActionOptions, type BrowserCapability, type BrowserCapabilitySnapshot, type BrowserCapabilityState, type BrowserConnectOptions, type BrowserControl, type BrowserControlAvailability, type BrowserControlSnapshot, type BrowserDesktopEndpoint, type BrowserDesktopOptions, BrowserError, type BrowserErrorCode, type BrowserErrorOptions, type BrowserErrorRecovery, type BrowserHumanControlLease, type BrowserLifecycleOptions, type BrowserNavigationPolicy, type BrowserReadinessSnapshot, type BrowserSchedulingOptions, type BrowserTab, type BrowserToolLimits, type BrowserToolName, type BrowserViewport, type BrowserWaitUntilReadyOptions, type CreateBrowserToolsOptions, type CreateDockerBrowserOptions, type DockerBrowser, DockerBrowserClient, type DockerBrowserClientOptions, type PlaywrightBrowserConnection, type PullDockerBrowserImageOptions, type RenewBrowserHumanControlOptions, type ResumeDockerBrowserOptions, createBrowserTools };
|