mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-08 11:02:26 +00:00
docs: document browser tool runtime
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Shared in-process browser control runtime state.
|
||||
*
|
||||
* The HTTP server path and background control service both reuse this singleton
|
||||
* so local tools can attach to the same browser runtime without racing owners.
|
||||
*/
|
||||
import type { Server } from "node:http";
|
||||
import { createBrowserRuntimeState, stopBrowserRuntime } from "./browser/runtime-lifecycle.js";
|
||||
import { type BrowserServerState, createBrowserRouteContext } from "./browser/server-context.js";
|
||||
@@ -11,6 +17,7 @@ export function getBrowserControlState(): BrowserServerState | null {
|
||||
return state;
|
||||
}
|
||||
|
||||
/** Create a route context bound to the current shared browser runtime. */
|
||||
export function createBrowserControlContext() {
|
||||
return createBrowserRouteContext({
|
||||
getState: () => state,
|
||||
@@ -18,6 +25,7 @@ export function createBrowserControlContext() {
|
||||
});
|
||||
}
|
||||
|
||||
/** Start or attach the shared browser runtime for either the server or service owner. */
|
||||
export async function ensureBrowserControlRuntime(params: {
|
||||
server?: Server | null;
|
||||
port: number;
|
||||
@@ -27,6 +35,8 @@ export async function ensureBrowserControlRuntime(params: {
|
||||
}): Promise<BrowserServerState> {
|
||||
if (state) {
|
||||
if (params.server) {
|
||||
// A foreground server takes ownership of the already-started service
|
||||
// runtime so shutdown and port reporting follow the visible server.
|
||||
state.server = params.server;
|
||||
state.port = params.port;
|
||||
state.resolved = { ...params.resolved, controlPort: params.port };
|
||||
@@ -45,6 +55,7 @@ export async function ensureBrowserControlRuntime(params: {
|
||||
return state;
|
||||
}
|
||||
|
||||
/** Stop the shared browser runtime when the requesting owner is allowed to do so. */
|
||||
export async function stopBrowserControlRuntime(params: {
|
||||
requestedBy: BrowserControlOwner;
|
||||
closeServer?: boolean;
|
||||
@@ -55,6 +66,8 @@ export async function stopBrowserControlRuntime(params: {
|
||||
return;
|
||||
}
|
||||
if (params.requestedBy === "service" && current.server && owner === "server") {
|
||||
// The background service must not close a runtime currently claimed by the
|
||||
// visible HTTP server; otherwise CLI/browser calls lose their control port.
|
||||
return;
|
||||
}
|
||||
await stopBrowserRuntime({
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* Gateway method and scope constants for browser proxy requests.
|
||||
*
|
||||
* Node-hosted browser control uses these values on both sides of the gateway
|
||||
* contract, so keep them as literal exports instead of duplicated strings.
|
||||
*/
|
||||
export const BROWSER_REQUEST_GATEWAY_METHOD = "browser.request" as const;
|
||||
/** Admin scope required to proxy browser-control requests through Gateway. */
|
||||
export const BROWSER_REQUEST_GATEWAY_SCOPE = "operator.admin" as const;
|
||||
/** Scope tuple shape consumed by Gateway tool registration. */
|
||||
export const BROWSER_REQUEST_GATEWAY_SCOPES = [BROWSER_REQUEST_GATEWAY_SCOPE] as const;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Public browser runtime barrel.
|
||||
*
|
||||
* Exposes the browser control server, client helpers, config resolution, and
|
||||
* route/runtime primitives used by the plugin entrypoints and local CLI.
|
||||
*/
|
||||
export { startBrowserBridgeServer, stopBrowserBridgeServer } from "./browser/bridge-server.js";
|
||||
export type { BrowserBridge } from "./browser/bridge-server.js";
|
||||
export {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser agent tool action executors.
|
||||
*
|
||||
* Converts model-facing parameters into browser control client calls and wraps
|
||||
* browser-originated text as untrusted content before returning it to agents.
|
||||
*/
|
||||
import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core";
|
||||
import {
|
||||
readNonNegativeIntegerParam,
|
||||
@@ -102,6 +108,8 @@ function withConfiguredActTimeout(
|
||||
return request;
|
||||
}
|
||||
if (existingSessionRejectsActTimeout(request) && usesExistingSessionProfile(profileName)) {
|
||||
// Chrome MCP existing-session actions reject per-call timeouts for these
|
||||
// operations, so default timeout injection must stay disabled there.
|
||||
return request;
|
||||
}
|
||||
|
||||
@@ -197,6 +205,8 @@ function wrapBrowserExternalJson(params: {
|
||||
includeWarning?: boolean;
|
||||
}): { wrappedText: string; safeDetails: Record<string, unknown> } {
|
||||
const extractedText = JSON.stringify(params.payload, null, 2);
|
||||
// Browser tabs, snapshots, and console output are page-controlled data. Keep
|
||||
// text wrapped even when details carry the structured fields for callers.
|
||||
const wrappedText = wrapExternalContent(extractedText, {
|
||||
source: "browser",
|
||||
includeWarning: params.includeWarning ?? true,
|
||||
@@ -332,6 +342,7 @@ export async function executeTabsAction(params: {
|
||||
return formatTabsToolResult(tabs);
|
||||
}
|
||||
|
||||
/** Execute and format browser snapshots for agent consumption. */
|
||||
export async function executeSnapshotAction(params: {
|
||||
input: Record<string, unknown>;
|
||||
baseUrl?: string;
|
||||
@@ -380,6 +391,8 @@ export async function executeSnapshotAction(params: {
|
||||
: hasMaxChars
|
||||
? maxChars
|
||||
: undefined;
|
||||
// AI snapshots have a compact default cap; ARIA snapshots keep full structure
|
||||
// unless maxChars is explicit, because agents often need complete node refs.
|
||||
const snapshotTimeoutMs =
|
||||
readPositiveIntegerParam(input, "timeoutMs", {
|
||||
message: "timeoutMs must be a positive integer.",
|
||||
@@ -520,6 +533,7 @@ export async function executeSnapshotAction(params: {
|
||||
}
|
||||
}
|
||||
|
||||
/** Execute browser console retrieval and wrap page-controlled messages. */
|
||||
export async function executeConsoleAction(params: {
|
||||
input: Record<string, unknown>;
|
||||
baseUrl?: string;
|
||||
@@ -549,6 +563,7 @@ export async function executeConsoleAction(params: {
|
||||
return formatConsoleToolResult(result);
|
||||
}
|
||||
|
||||
/** Execute browser actions with profile-aware timeout defaults and stale-tab recovery. */
|
||||
export async function executeActAction(params: {
|
||||
request: BrowserActRequest;
|
||||
baseUrl?: string;
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
/**
|
||||
* Runtime dependency barrel for the Browser agent tool.
|
||||
*
|
||||
* Kept separate from browser-tool.ts so tests can mock the tool boundary while
|
||||
* production still imports SDK helpers and browser client actions lazily.
|
||||
*/
|
||||
import { getRuntimeConfig } from "./sdk-config.js";
|
||||
|
||||
export { getRuntimeConfig };
|
||||
/** Resolve global image downscaling for screenshots returned to agent tools. */
|
||||
export function resolveRuntimeImageSanitization(): { maxDimensionPx: number } | undefined {
|
||||
const configured = getRuntimeConfig().agents?.defaults?.imageMaxDimensionPx;
|
||||
if (typeof configured !== "number" || !Number.isFinite(configured)) {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* JSON schema for the Browser agent tool.
|
||||
*
|
||||
* The schema stays intentionally flat because provider function-tool validators
|
||||
* reject several nested union shapes that TypeBox can otherwise emit.
|
||||
*/
|
||||
import {
|
||||
optionalFiniteNumberSchema,
|
||||
optionalNonNegativeIntegerSchema,
|
||||
@@ -99,6 +105,7 @@ const BrowserActSchema = Type.Object({
|
||||
// IMPORTANT: OpenAI function tool schemas must have a top-level `type: "object"`.
|
||||
// A root-level `Type.Union([...])` compiles to `{ anyOf: [...] }` (no `type`),
|
||||
// which OpenAI rejects ("Invalid schema ... type: None"). Keep this schema an object.
|
||||
/** Provider-compatible Browser tool argument schema. */
|
||||
export const BrowserToolSchema = Type.Object({
|
||||
action: stringEnum(BROWSER_TOOL_ACTIONS),
|
||||
target: optionalStringEnum(BROWSER_TARGETS),
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* Browser agent tool registration.
|
||||
*
|
||||
* Builds the model-facing browser tool, chooses sandbox/host/node routing, and
|
||||
* maps high-level actions onto browser control client calls.
|
||||
*/
|
||||
import crypto from "node:crypto";
|
||||
import {
|
||||
executeActAction,
|
||||
@@ -441,6 +447,7 @@ function readToolTimeoutMs(params: Record<string, unknown>) {
|
||||
});
|
||||
}
|
||||
|
||||
/** Create the Browser tool exposed to agents. */
|
||||
export function createBrowserTool(opts?: {
|
||||
sandboxBridgeUrl?: string;
|
||||
allowHostControl?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user