mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
docs: document browser route handlers
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser agent action route registration and existing-session execution.
|
||||
*
|
||||
* Dispatches normalized actions to either Playwright-backed OpenClaw browser
|
||||
* control or Chrome MCP existing-session operations with navigation guards.
|
||||
*/
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import {
|
||||
clickChromeMcpElement,
|
||||
@@ -350,6 +356,7 @@ function getExistingSessionUnsupportedMessage(action: BrowserActRequest): string
|
||||
throw new Error("Unsupported browser act kind");
|
||||
}
|
||||
|
||||
/** Register browser action endpoints, including hook and download subroutes. */
|
||||
export function registerBrowserAgentActRoutes(
|
||||
app: BrowserRouteRegistrar,
|
||||
ctx: BrowserRouteContext,
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser debug and trace routes.
|
||||
*
|
||||
* Exposes console messages, page errors, network requests, dialog state, and
|
||||
* Playwright tracing scoped to the selected browser tab.
|
||||
*/
|
||||
import crypto from "node:crypto";
|
||||
import path from "node:path";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -44,6 +50,7 @@ async function sendPlaywrightDebugCollection(params: {
|
||||
});
|
||||
}
|
||||
|
||||
/** Register browser debug endpoints on the control server. */
|
||||
export function registerBrowserAgentDebugRoutes(
|
||||
app: BrowserRouteRegistrar,
|
||||
ctx: BrowserRouteContext,
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Shared browser route helpers.
|
||||
*
|
||||
* Centralizes body/query parsing, profile resolution, error mapping, Playwright
|
||||
* availability checks, and tab-context guards for route modules.
|
||||
*/
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { resolveBrowserNavigationProxyMode } from "../browser-proxy-mode.js";
|
||||
import { toBrowserErrorResponse } from "../errors.js";
|
||||
@@ -21,6 +27,7 @@ export const SELECTOR_UNSUPPORTED_MESSAGE = [
|
||||
"This is more reliable for modern SPAs.",
|
||||
].join("\n");
|
||||
|
||||
/** Return a safe object body for routes that accept JSON payloads. */
|
||||
export function readBody(req: BrowserRequest): Record<string, unknown> {
|
||||
const body = req.body as Record<string, unknown> | undefined;
|
||||
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
||||
@@ -29,16 +36,19 @@ export function readBody(req: BrowserRequest): Record<string, unknown> {
|
||||
return body;
|
||||
}
|
||||
|
||||
/** Read an optional targetId from a request body. */
|
||||
export function resolveTargetIdFromBody(body: Record<string, unknown>): string | undefined {
|
||||
const targetId = normalizeOptionalString(body.targetId) ?? "";
|
||||
return targetId || undefined;
|
||||
}
|
||||
|
||||
/** Read an optional targetId from a query object. */
|
||||
export function resolveTargetIdFromQuery(query: Record<string, unknown>): string | undefined {
|
||||
const targetId = normalizeOptionalString(query.targetId) ?? "";
|
||||
return targetId || undefined;
|
||||
}
|
||||
|
||||
/** Map route-level browser errors to HTTP JSON responses. */
|
||||
export function handleRouteError(ctx: BrowserRouteContext, res: BrowserResponse, err: unknown) {
|
||||
const mapped = ctx.mapTabError(err);
|
||||
if (mapped) {
|
||||
@@ -51,6 +61,7 @@ export function handleRouteError(ctx: BrowserRouteContext, res: BrowserResponse,
|
||||
jsonError(res, 500, String(err));
|
||||
}
|
||||
|
||||
/** Resolve the requested browser profile and respond with JSON on failure. */
|
||||
export function resolveProfileContext(
|
||||
req: BrowserRequest,
|
||||
res: BrowserResponse,
|
||||
@@ -64,6 +75,7 @@ export function resolveProfileContext(
|
||||
return profileCtx;
|
||||
}
|
||||
|
||||
/** Build navigation guard policy for a profile and current resolved config. */
|
||||
export function browserNavigationPolicyForProfile(
|
||||
ctx: BrowserRouteContext,
|
||||
profileCtx: ProfileContext,
|
||||
@@ -76,10 +88,12 @@ export function browserNavigationPolicyForProfile(
|
||||
});
|
||||
}
|
||||
|
||||
/** Load the optional Playwright bridge module in soft-fail mode. */
|
||||
export async function getPwAiModule(): Promise<PwAiModule | null> {
|
||||
return await getPwAiModuleBase({ mode: "soft" });
|
||||
}
|
||||
|
||||
/** Require Playwright support for a route feature, returning a 501 when absent. */
|
||||
export async function requirePwAi(
|
||||
res: BrowserResponse,
|
||||
feature: string,
|
||||
@@ -124,6 +138,7 @@ type RouteWithTabParams<T> = {
|
||||
run: (ctx: RouteTabContext) => Promise<T>;
|
||||
};
|
||||
|
||||
/** Resolve profile and tab context, optionally enforcing current URL policy. */
|
||||
export async function withRouteTabContext<T>(
|
||||
params: RouteWithTabParams<T>,
|
||||
): Promise<T | undefined> {
|
||||
@@ -198,6 +213,7 @@ type RouteWithPwParams<T> = {
|
||||
run: (ctx: RouteTabPwContext) => Promise<T>;
|
||||
};
|
||||
|
||||
/** Resolve profile, tab, and Playwright context for Playwright-only routes. */
|
||||
export async function withPlaywrightRouteContext<T>(
|
||||
params: RouteWithPwParams<T>,
|
||||
): Promise<T | undefined> {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Snapshot planning for browser route handlers.
|
||||
*
|
||||
* Resolves requested snapshot mode, format, limits, refs, labels, and driver
|
||||
* choice before the route talks to Playwright or Chrome MCP.
|
||||
*/
|
||||
import {
|
||||
parseStrictNonNegativeInteger,
|
||||
parseStrictPositiveInteger,
|
||||
@@ -34,6 +40,7 @@ type BrowserSnapshotPlan = {
|
||||
wantsRoleSnapshot: boolean;
|
||||
};
|
||||
|
||||
/** Resolve a normalized snapshot plan from query parameters and profile caps. */
|
||||
export function resolveSnapshotPlan(params: {
|
||||
profile: ResolvedBrowserProfile;
|
||||
query: Record<string, unknown>;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser snapshot, navigation, and screenshot routes.
|
||||
*
|
||||
* Handles profile-aware snapshot generation across Playwright and Chrome MCP,
|
||||
* navigation policy checks, media storage, and screenshot normalization.
|
||||
*/
|
||||
import path from "node:path";
|
||||
import { ensureMediaDir, saveMediaBuffer } from "../../media/store.js";
|
||||
import { captureScreenshot, snapshotAria, snapshotRoleViaCdp } from "../cdp.js";
|
||||
@@ -253,6 +259,7 @@ function browserStateResponseFields(state: unknown): { browserState?: unknown }
|
||||
return hasObservableBrowserState(state) ? { browserState: state } : {};
|
||||
}
|
||||
|
||||
/** Register snapshot, screenshot, and navigation endpoints. */
|
||||
export function registerBrowserAgentSnapshotRoutes(
|
||||
app: BrowserRouteRegistrar,
|
||||
ctx: BrowserRouteContext,
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser storage and context mutation routes.
|
||||
*
|
||||
* Parses and applies cookies, local/session storage, geolocation, permissions,
|
||||
* and related browser-context mutations for the selected profile/tab.
|
||||
*/
|
||||
import {
|
||||
normalizeOptionalString,
|
||||
readStringValue,
|
||||
@@ -36,6 +42,7 @@ type CookieSetOptions = {
|
||||
sameSite?: "Lax" | "None" | "Strict";
|
||||
};
|
||||
|
||||
/** Parse the supported browser storage bucket names. */
|
||||
export function parseStorageKind(raw: string): StorageKind | null {
|
||||
if (raw === "local" || raw === "session") {
|
||||
return raw;
|
||||
@@ -43,6 +50,7 @@ export function parseStorageKind(raw: string): StorageKind | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Parse an optional storage mutation request from a route body. */
|
||||
export function parseStorageMutationRequest(
|
||||
kindParam: unknown,
|
||||
body: Record<string, unknown>,
|
||||
@@ -53,6 +61,7 @@ export function parseStorageMutationRequest(
|
||||
};
|
||||
}
|
||||
|
||||
/** Parse a required storage mutation request and throw on invalid input. */
|
||||
export function parseRequiredStorageMutationRequest(
|
||||
kindParam: unknown,
|
||||
body: Record<string, unknown>,
|
||||
@@ -104,6 +113,7 @@ function assertRange(
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Parse cookie options accepted by browser storage mutation routes. */
|
||||
export function parseCookieSetOptions(cookie: Record<string, unknown>): CookieSetOptions {
|
||||
return {
|
||||
name: toStringOrEmpty(cookie.name),
|
||||
@@ -121,6 +131,7 @@ export function parseCookieSetOptions(cookie: Record<string, unknown>): CookieSe
|
||||
};
|
||||
}
|
||||
|
||||
/** Parse geolocation override options accepted by context mutation routes. */
|
||||
export function parseGeolocationOptions(body: Record<string, unknown>): GeolocationOptions {
|
||||
const clear = toBoolean(body.clear) ?? false;
|
||||
const origin = toStringOrEmpty(body.origin) || undefined;
|
||||
@@ -149,6 +160,7 @@ export function parseGeolocationOptions(body: Record<string, unknown>): Geolocat
|
||||
return { clear, latitude, longitude, accuracy, origin };
|
||||
}
|
||||
|
||||
/** Register storage and browser-context mutation endpoints. */
|
||||
export function registerBrowserAgentStorageRoutes(
|
||||
app: BrowserRouteRegistrar,
|
||||
ctx: BrowserRouteContext,
|
||||
|
||||
Reference in New Issue
Block a user