From cec50aa047ac51dc4d35cb4e13a5c75c48a1f130 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 30 May 2026 03:52:29 -0400 Subject: [PATCH] fix(browser): cap act action timeouts --- .../browser/routes/agent.act.normalize.test.ts | 15 +++++++++++++++ .../src/browser/routes/agent.act.normalize.ts | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/extensions/browser/src/browser/routes/agent.act.normalize.test.ts b/extensions/browser/src/browser/routes/agent.act.normalize.test.ts index 1dcab073318..bdd33a223d1 100644 --- a/extensions/browser/src/browser/routes/agent.act.normalize.test.ts +++ b/extensions/browser/src/browser/routes/agent.act.normalize.test.ts @@ -1,3 +1,4 @@ +import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime"; import { describe, expect, it } from "vitest"; import { normalizeActRequest } from "./agent.act.normalize.js"; @@ -32,6 +33,20 @@ describe("normalizeActRequest numeric fields", () => { }); }); + it("caps oversized action timeouts", () => { + expect( + normalizeActRequest({ + kind: "wait", + text: "ready", + timeoutMs: String(Number.MAX_SAFE_INTEGER), + }), + ).toMatchObject({ + kind: "wait", + text: "ready", + timeoutMs: MAX_TIMER_TIMEOUT_MS, + }); + }); + it("rejects loose integer tokens for action durations and timeouts", () => { expect(() => normalizeActRequest({ diff --git a/extensions/browser/src/browser/routes/agent.act.normalize.ts b/extensions/browser/src/browser/routes/agent.act.normalize.ts index 599eb3d07c9..50595fb013a 100644 --- a/extensions/browser/src/browser/routes/agent.act.normalize.ts +++ b/extensions/browser/src/browser/routes/agent.act.normalize.ts @@ -1,3 +1,4 @@ +import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime"; import { ACT_MAX_BATCH_ACTIONS, ACT_MAX_CLICK_DELAY_MS, @@ -88,7 +89,8 @@ function readActionNonNegativeInteger( } function readActionTimeoutMs(body: Record): number | undefined { - return readActionPositiveInteger(body, "timeoutMs"); + const timeoutMs = readActionPositiveInteger(body, "timeoutMs"); + return timeoutMs === undefined ? undefined : resolveTimerTimeoutMs(timeoutMs, 1); } function readBoundedActionDurationMs(