Skip to content

Commit b8aa749

Browse files
committed
Auto-merge upstream openclaw/openclaw
2 parents 0a28959 + 5613913 commit b8aa749

46 files changed

Lines changed: 3211 additions & 2521 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ Docs: https://docs.openclaw.ai
6363
- ACP/stream relay: pass parent delivery context to ACP stream relay system events so `streamTo="parent"` updates route to the correct thread or topic instead of falling back to the main DM. (#57056) Thanks @pingren.
6464
- Agents/sessions: preserve announce `threadId` when `sessions.list` fallback rehydrates agent-to-agent announce targets so final announce messages stay in the originating thread/topic. (#63506) Thanks @SnowSky1.
6565
- Browser/plugin SDK: route browser auth, profile, host-inspection, and doctor readiness helpers through browser plugin public facades so core compatibility helpers stop carrying duplicate runtime implementations. (#63957) Thanks @joshavant.
66+
- Browser/act: centralize `/act` request normalization and execution dispatch while adding stable machine-readable route-level error codes for invalid requests, selector misuse, evaluate-disabled gating, target mismatch, and existing-session unsupported actions. (#63977) Thanks @joshavant.
6667

6768
## 2026.4.9
6869

docs/tools/browser.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,27 @@ Notes:
576576
- If `gateway.auth.mode` is `none` or `trusted-proxy`, these loopback browser
577577
routes do not inherit those identity-bearing modes; keep them loopback-only.
578578

579+
### `/act` error contract
580+
581+
`POST /act` uses a structured error response for route-level validation and
582+
policy failures:
583+
584+
```json
585+
{ "error": "<message>", "code": "ACT_*" }
586+
```
587+
588+
Current `code` values:
589+
590+
- `ACT_KIND_REQUIRED` (HTTP 400): `kind` is missing or unrecognized.
591+
- `ACT_INVALID_REQUEST` (HTTP 400): action payload failed normalization or validation.
592+
- `ACT_SELECTOR_UNSUPPORTED` (HTTP 400): `selector` was used with an unsupported action kind.
593+
- `ACT_EVALUATE_DISABLED` (HTTP 403): `evaluate` (or `wait --fn`) is disabled by config.
594+
- `ACT_TARGET_ID_MISMATCH` (HTTP 403): top-level or batched `targetId` conflicts with request target.
595+
- `ACT_EXISTING_SESSION_UNSUPPORTED` (HTTP 501): action is not supported for existing-session profiles.
596+
597+
Other runtime failures may still return `{ "error": "<message>" }` without a
598+
`code` field.
599+
579600
### Playwright requirement
580601

581602
Some features (navigate/act/AI snapshot/role snapshot, element screenshots,
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export const ACT_MAX_BATCH_ACTIONS = 100;
2+
export const ACT_MAX_BATCH_DEPTH = 5;
3+
export const ACT_MAX_CLICK_DELAY_MS = 5_000;
4+
export const ACT_MAX_WAIT_TIME_MS = 30_000;
5+
6+
const ACT_MIN_TIMEOUT_MS = 500;
7+
const ACT_MAX_INTERACTION_TIMEOUT_MS = 60_000;
8+
const ACT_MAX_WAIT_TIMEOUT_MS = 120_000;
9+
const ACT_DEFAULT_INTERACTION_TIMEOUT_MS = 8_000;
10+
const ACT_DEFAULT_WAIT_TIMEOUT_MS = 20_000;
11+
12+
export function normalizeActBoundedNonNegativeMs(
13+
value: number | undefined,
14+
fieldName: string,
15+
maxMs: number,
16+
): number | undefined {
17+
if (value === undefined) {
18+
return undefined;
19+
}
20+
if (!Number.isFinite(value) || value < 0) {
21+
throw new Error(`${fieldName} must be >= 0`);
22+
}
23+
const normalized = Math.floor(value);
24+
if (normalized > maxMs) {
25+
throw new Error(`${fieldName} exceeds maximum of ${maxMs}ms`);
26+
}
27+
return normalized;
28+
}
29+
30+
export function resolveActInteractionTimeoutMs(timeoutMs?: number): number {
31+
const normalized =
32+
typeof timeoutMs === "number" && Number.isFinite(timeoutMs)
33+
? Math.floor(timeoutMs)
34+
: ACT_DEFAULT_INTERACTION_TIMEOUT_MS;
35+
return Math.max(ACT_MIN_TIMEOUT_MS, Math.min(ACT_MAX_INTERACTION_TIMEOUT_MS, normalized));
36+
}
37+
38+
export function resolveActWaitTimeoutMs(timeoutMs?: number): number {
39+
const normalized =
40+
typeof timeoutMs === "number" && Number.isFinite(timeoutMs)
41+
? Math.floor(timeoutMs)
42+
: ACT_DEFAULT_WAIT_TIMEOUT_MS;
43+
return Math.max(ACT_MIN_TIMEOUT_MS, Math.min(ACT_MAX_WAIT_TIMEOUT_MS, normalized));
44+
}

extensions/browser/src/browser/pw-ai.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export {
2929
dragViaPlaywright,
3030
emulateMediaViaPlaywright,
3131
evaluateViaPlaywright,
32+
executeActViaPlaywright,
3233
fillFormViaPlaywright,
3334
getConsoleMessagesViaPlaywright,
3435
getNetworkRequestsViaPlaywright,

0 commit comments

Comments
 (0)