From ce56fc176a6fa4ab4494fa530276e5b1ca82a3f3 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 4 Jun 2026 07:27:43 -0400 Subject: [PATCH] docs: document browser act routes --- .../browser/src/browser/routes/agent.act.download.ts | 7 +++++++ .../browser/src/browser/routes/agent.act.errors.ts | 9 +++++++++ extensions/browser/src/browser/routes/agent.act.hooks.ts | 9 +++++++++ .../browser/src/browser/routes/agent.act.normalize.ts | 8 ++++++++ .../browser/src/browser/routes/agent.act.shared.ts | 9 +++++++++ 5 files changed, 42 insertions(+) diff --git a/extensions/browser/src/browser/routes/agent.act.download.ts b/extensions/browser/src/browser/routes/agent.act.download.ts index b10f2c5ad583..cd852246a7fb 100644 --- a/extensions/browser/src/browser/routes/agent.act.download.ts +++ b/extensions/browser/src/browser/routes/agent.act.download.ts @@ -1,3 +1,9 @@ +/** + * Browser agent action routes for download handling. + * + * Registers endpoints that wait for a pending download or trigger a referenced + * page download while keeping files scoped to the configured downloads root. + */ import { formatErrorMessage } from "../../infra/errors.js"; import { getBrowserProfileCapabilities } from "../profile-capabilities.js"; import type { BrowserRouteContext } from "../server-context.js"; @@ -22,6 +28,7 @@ function buildDownloadRequestBase(cdpUrl: string, targetId: string, timeoutMs: n }; } +/** Register download action endpoints on the browser control server. */ export function registerBrowserAgentActDownloadRoutes( app: BrowserRouteRegistrar, ctx: BrowserRouteContext, diff --git a/extensions/browser/src/browser/routes/agent.act.errors.ts b/extensions/browser/src/browser/routes/agent.act.errors.ts index d04b22d087c2..bd0871ae3fc4 100644 --- a/extensions/browser/src/browser/routes/agent.act.errors.ts +++ b/extensions/browser/src/browser/routes/agent.act.errors.ts @@ -1,5 +1,12 @@ +/** + * Shared browser action error codes and messages. + * + * Keeps route responses stable for browser-tool callers that branch on `code` + * rather than parsing human-readable errors. + */ import type { BrowserResponse } from "./types.js"; +/** Stable machine-readable codes returned by browser action routes. */ export const ACT_ERROR_CODES = { kindRequired: "ACT_KIND_REQUIRED", invalidRequest: "ACT_INVALID_REQUEST", @@ -11,6 +18,7 @@ export const ACT_ERROR_CODES = { type ActErrorCode = (typeof ACT_ERROR_CODES)[keyof typeof ACT_ERROR_CODES]; +/** Send a browser action JSON error with a stable action error code. */ export function jsonActError( res: BrowserResponse, status: number, @@ -20,6 +28,7 @@ export function jsonActError( res.status(status).json({ error: message, code }); } +/** Build the config-disabled message for JavaScript evaluation actions. */ export function browserEvaluateDisabledMessage(action: "wait" | "evaluate"): string { return [ action === "wait" diff --git a/extensions/browser/src/browser/routes/agent.act.hooks.ts b/extensions/browser/src/browser/routes/agent.act.hooks.ts index 91b0a6153a05..376b6bde3fcf 100644 --- a/extensions/browser/src/browser/routes/agent.act.hooks.ts +++ b/extensions/browser/src/browser/routes/agent.act.hooks.ts @@ -1,3 +1,9 @@ +/** + * Browser agent action hook routes. + * + * Handles file chooser and dialog interception for both Playwright-backed + * OpenClaw profiles and Chrome MCP existing-session profiles. + */ import { formatErrorMessage } from "../../infra/errors.js"; import { evaluateChromeMcpScript, uploadChromeMcpFile } from "../chrome-mcp.js"; import { resolveExistingUploadPaths } from "../paths.js"; @@ -20,6 +26,7 @@ import { toStringOrEmpty, } from "./utils.js"; +/** Register file chooser and dialog hook endpoints on the browser control server. */ export function registerBrowserAgentActHookRoutes( app: BrowserRouteRegistrar, ctx: BrowserRouteContext, @@ -150,6 +157,8 @@ export function registerBrowserAgentActHookRoutes( profileName: profileCtx.profile.name, profile: profileCtx.profile, targetId: tab.targetId, + // Existing-session Chrome MCP has no dialog hook primitive. Patch + // one-shot window dialog functions in-page, then restore them. fn: `() => { const state = (window.__openclawDialogHook ??= {}); if (!state.originals) { diff --git a/extensions/browser/src/browser/routes/agent.act.normalize.ts b/extensions/browser/src/browser/routes/agent.act.normalize.ts index 7245c527c66e..b5fe36f04a6d 100644 --- a/extensions/browser/src/browser/routes/agent.act.normalize.ts +++ b/extensions/browser/src/browser/routes/agent.act.normalize.ts @@ -1,3 +1,9 @@ +/** + * Browser action request normalization. + * + * Converts loosely typed route bodies into the closed BrowserActRequest union + * used by Playwright and Chrome MCP action executors. + */ import { ACT_MAX_BATCH_ACTIONS, ACT_MAX_CLICK_DELAY_MS, @@ -39,6 +45,7 @@ function countBatchActions(actions: BrowserActRequest[]): number { return count; } +/** Validate that nested batch actions cannot drift to a different target tab. */ export function validateBatchTargetIds( actions: BrowserActRequest[], targetId: string, @@ -110,6 +117,7 @@ function readResizeDimension(body: Record, key: "width" | "heig return value; } +/** Normalize one model/client action payload into a BrowserActRequest. */ export function normalizeActRequest( body: Record, options?: { source?: "request" | "batch" }, diff --git a/extensions/browser/src/browser/routes/agent.act.shared.ts b/extensions/browser/src/browser/routes/agent.act.shared.ts index 1e92e32d0e15..7ea9c88e2ce3 100644 --- a/extensions/browser/src/browser/routes/agent.act.shared.ts +++ b/extensions/browser/src/browser/routes/agent.act.shared.ts @@ -1,3 +1,9 @@ +/** + * Shared browser action enums and parsers. + * + * Keeps route normalization, schema tests, and action dispatch using the same + * action names, mouse buttons, and keyboard modifier vocabulary. + */ const ACT_KINDS = [ "batch", "click", @@ -17,6 +23,7 @@ const ACT_KINDS = [ export type ActKind = (typeof ACT_KINDS)[number]; +/** Return true when a raw value names a supported browser action kind. */ export function isActKind(value: unknown): value is ActKind { if (typeof value !== "string") { return false; @@ -35,6 +42,7 @@ const ALLOWED_CLICK_MODIFIERS = new Set([ "Shift", ]); +/** Parse a model/client mouse button string into the supported click button set. */ export function parseClickButton(raw: string): ClickButton | undefined { if (raw === "left" || raw === "right" || raw === "middle") { return raw; @@ -42,6 +50,7 @@ export function parseClickButton(raw: string): ClickButton | undefined { return undefined; } +/** Parse and validate click modifier names accepted by Playwright actions. */ export function parseClickModifiers(raw: string[]): { modifiers?: ClickModifier[]; error?: string;