openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
126 lines (125 loc) • 7.18 kB
JavaScript
import { F as resolveTimerTimeoutMs, S as parseStrictInteger, a as addTimerTimeoutGraceMs, n as MAX_TIMER_TIMEOUT_MS, p as clampPositiveTimerTimeoutMs } from "./number-coercion-CLj0HTDM.js";
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import "./number-runtime-Cy4drVnh.js";
import "./string-coerce-runtime-GQa0ehRA.js";
import { i as DEFAULT_BROWSER_ACTION_TIMEOUT_MS } from "./constants-DKjTvIBP.js";
//#region extensions/browser/src/browser/act-policy.ts
/**
* Browser action limits and timeout normalization.
*
* Shared by the tool schema and runtime action handlers so model-facing limits
* and browser-control enforcement stay aligned.
*/
/** Maximum click delay accepted from model/tool input. */
const ACT_MAX_CLICK_DELAY_MS = 5e3;
/** Maximum explicit wait duration accepted from model/tool input. */
const ACT_MAX_WAIT_TIME_MS = 3e4;
/** Maximum viewport side length accepted by resize actions. */
const ACT_MAX_VIEWPORT_DIMENSION = 8192;
const ACT_MIN_TIMEOUT_MS = 500;
const ACT_MAX_INTERACTION_TIMEOUT_MS = 6e4;
const ACT_MAX_WAIT_TIMEOUT_MS = 12e4;
const ACT_DEFAULT_INTERACTION_TIMEOUT_MS = 8e3;
const ACT_DEFAULT_WAIT_TIMEOUT_MS = 2e4;
/** Grace between the runtime's action budget and an outer transport watchdog. */
const BROWSER_ACTION_TRANSPORT_SLACK_MS = 5e3;
/** Keep navigation timeouts consistent across transports and browser backends. */
function resolveBrowserNavigationTimeoutMs(timeoutMs) {
return Math.min(12e4, resolveTimerTimeoutMs(timeoutMs, 2e4, 1e3));
}
function normalizeActBoundedNonNegativeMs(value, fieldName, maxMs) {
if (value === void 0) return;
if (!Number.isFinite(value) || value < 0) throw new Error(`${fieldName} must be >= 0`);
const normalized = Math.floor(value);
if (normalized > maxMs) throw new Error(`${fieldName} exceeds maximum of ${maxMs}ms`);
return normalized;
}
/** Clamp interaction actions to the supported browser-control timeout window. */
function resolveActInteractionTimeoutMs(timeoutMs) {
return Math.max(ACT_MIN_TIMEOUT_MS, Math.min(ACT_MAX_INTERACTION_TIMEOUT_MS, typeof timeoutMs === "number" && Number.isFinite(timeoutMs) ? Math.floor(timeoutMs) : ACT_DEFAULT_INTERACTION_TIMEOUT_MS));
}
/** Clamp wait actions to their wider supported browser-control timeout window. */
function resolveActWaitTimeoutMs(timeoutMs) {
return Math.max(ACT_MIN_TIMEOUT_MS, Math.min(ACT_MAX_WAIT_TIMEOUT_MS, typeof timeoutMs === "number" && Number.isFinite(timeoutMs) ? Math.floor(timeoutMs) : ACT_DEFAULT_WAIT_TIMEOUT_MS));
}
function parseTimerInteger(value) {
return typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : parseStrictInteger(value);
}
function resolveNonNegativeTimerMs(value) {
const parsed = parseTimerInteger(value);
return parsed !== void 0 && parsed >= 0 ? resolveTimerTimeoutMs(parsed, 0, 0) : 0;
}
function addExecutionBudgetMs(totalMs, nextMs) {
return Math.min(MAX_TIMER_TIMEOUT_MS, totalMs + nextMs);
}
function multiplyExecutionBudgetMs(durationMs, count) {
return Math.min(MAX_TIMER_TIMEOUT_MS, durationMs * count);
}
function resolveInteractionTimeoutMs(request) {
return resolveActInteractionTimeoutMs(parseTimerInteger("timeoutMs" in request ? request.timeoutMs : void 0));
}
function addNavigationGraceMs(durationMs, count = 1) {
return addExecutionBudgetMs(durationMs, multiplyExecutionBudgetMs(250, count));
}
function isActionObject(value) {
return isRecord(value);
}
function resolveLeafExecutionBudgetMs(request) {
switch (request.kind) {
case "click": {
const timeoutMs = resolveInteractionTimeoutMs(request);
const delayMs = Math.min(ACT_MAX_CLICK_DELAY_MS, resolveNonNegativeTimerMs(request.delayMs));
return addNavigationGraceMs(delayMs > 0 ? addExecutionBudgetMs(timeoutMs * 2, delayMs) : timeoutMs);
}
case "clickCoords": {
const delayMs = Math.min(ACT_MAX_CLICK_DELAY_MS, resolveNonNegativeTimerMs(request.delayMs));
return addNavigationGraceMs(addExecutionBudgetMs(clampPositiveTimerTimeoutMs(parseTimerInteger(request.timeoutMs)) ?? 0, multiplyExecutionBudgetMs(delayMs, request.doubleClick ? 3 : 1)));
}
case "type": {
const phaseCount = (request.slowly ? 2 : 1) + (request.submit ? 1 : 0);
return addNavigationGraceMs(multiplyExecutionBudgetMs(resolveInteractionTimeoutMs(request), phaseCount));
}
case "press": return addNavigationGraceMs(resolveNonNegativeTimerMs(request.delayMs));
case "fill": {
const fieldCount = (Array.isArray(request.fields) ? request.fields : []).filter((field) => Boolean(field) && typeof field === "object" && typeof field.ref === "string" && Boolean(field.ref.trim())).length;
return addNavigationGraceMs(multiplyExecutionBudgetMs(resolveInteractionTimeoutMs(request), fieldCount), fieldCount);
}
case "evaluate": return addNavigationGraceMs(resolveActWaitTimeoutMs(parseTimerInteger(request.timeoutMs)));
case "scrollIntoView": return addNavigationGraceMs(resolveActWaitTimeoutMs(parseTimerInteger(request.timeoutMs)));
case "hover":
case "drag":
case "select": return addNavigationGraceMs(resolveInteractionTimeoutMs(request));
case "resize":
case "close": return 0;
}
return 0;
}
function resolveExecutionBudgetMs(request) {
if (request.kind === "batch") return (Array.isArray(request.actions) ? request.actions.filter(isActionObject) : []).reduce((totalMs, action) => addExecutionBudgetMs(totalMs, resolveExecutionBudgetMs(action)), 0);
if (request.kind !== "wait") return resolveLeafExecutionBudgetMs(request);
const conditionCount = [
Boolean(request.text),
Boolean(request.textGone),
typeof request.selector === "string" && Boolean(request.selector.trim()),
typeof request.url === "string" && Boolean(request.url.trim()),
Boolean(request.loadState),
typeof request.fn === "string" && Boolean(request.fn.trim())
].filter(Boolean).length;
const timeoutMs = resolveActWaitTimeoutMs(parseTimerInteger(request.timeoutMs));
return addExecutionBudgetMs(resolveNonNegativeTimerMs(request.timeMs), multiplyExecutionBudgetMs(timeoutMs, conditionCount));
}
/**
* Resolve the runtime budget before an outer transport watchdog is armed.
* Wait phases and batch children execute serially, so maxima would abort valid work midway.
*/
function resolveBrowserActExecutionBudgetMs(request) {
const executionBudgetMs = resolveExecutionBudgetMs(request);
if (request.kind === "wait") return executionBudgetMs;
return (request.kind === "batch" ? void 0 : clampPositiveTimerTimeoutMs(parseTimerInteger("timeoutMs" in request ? request.timeoutMs : void 0))) === void 0 ? Math.max(DEFAULT_BROWSER_ACTION_TIMEOUT_MS, executionBudgetMs) : executionBudgetMs;
}
/** Add action transport slack once after the full sequential runtime budget is known. */
function resolveBrowserActRequestTimeoutMs(request) {
return addTimerTimeoutGraceMs(resolveBrowserActExecutionBudgetMs(request), 5e3) ?? 1;
}
//#endregion
export { normalizeActBoundedNonNegativeMs as a, resolveBrowserActRequestTimeoutMs as c, BROWSER_ACTION_TRANSPORT_SLACK_MS as i, resolveBrowserNavigationTimeoutMs as l, ACT_MAX_VIEWPORT_DIMENSION as n, resolveActInteractionTimeoutMs as o, ACT_MAX_WAIT_TIME_MS as r, resolveActWaitTimeoutMs as s, ACT_MAX_CLICK_DELAY_MS as t };