fix(commands): clamp gateway agent timeout

This commit is contained in:
Peter Steinberger
2026-05-30 16:47:07 -04:00
parent 1c1f42a74a
commit 2cbfb910f2
2 changed files with 17 additions and 4 deletions
+7
View File
@@ -5,6 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { loggingState } from "../logging/state.js";
import type { RuntimeEnv } from "../runtime.js";
import { MAX_TIMER_TIMEOUT_MS } from "../shared/number-coercion.js";
import { agentCliCommand, agentViaGatewayTesting } from "./agent-via-gateway.js";
import type { agentCommand as AgentCommand } from "./agent.js";
@@ -245,6 +246,12 @@ describe("agentCliCommand", () => {
});
});
it("clamps oversized gateway timeout seconds", () => {
expect(agentViaGatewayTesting.resolveGatewayAgentTimeoutMs(Number.MAX_SAFE_INTEGER)).toBe(
MAX_TIMER_TIMEOUT_MS,
);
});
it("rejects partial gateway timeout values", async () => {
await withTempStore(async () => {
await expect(
+10 -4
View File
@@ -1,4 +1,5 @@
import { randomUUID } from "node:crypto";
import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion";
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import {
@@ -129,6 +130,7 @@ export const agentViaGatewayTesting = {
agentSessionModulePromise = undefined;
agentSessionModuleLoader = loader;
},
resolveGatewayAgentTimeoutMs,
};
function protectJsonStdout(opts: Pick<AgentCliOpts, "json">): void {
@@ -150,6 +152,13 @@ function parseTimeoutSeconds(opts: { cfg: OpenClawConfig; timeout?: string }) {
return raw;
}
function resolveGatewayAgentTimeoutMs(timeoutSeconds: number): number {
if (timeoutSeconds === 0) {
return NO_GATEWAY_TIMEOUT_MS;
}
return resolveTimerTimeoutMs((timeoutSeconds + 30) * 1000, 10_000, 10_000);
}
function getGatewayDispatchConfig(): OpenClawConfig {
// Scoped gateway turns need core agent/session/gateway fields only. The
// running gateway owns plugin validation and plugin metadata freshness.
@@ -580,10 +589,7 @@ async function agentViaGatewayCommand(
}
}
const timeoutSeconds = parseTimeoutSeconds({ cfg, timeout: opts.timeout });
const gatewayTimeoutMs =
timeoutSeconds === 0
? NO_GATEWAY_TIMEOUT_MS // no timeout (timer-safe max)
: Math.max(10_000, (timeoutSeconds + 30) * 1000);
const gatewayTimeoutMs = resolveGatewayAgentTimeoutMs(timeoutSeconds);
const sessionKey =
classifySessionKeyShape(explicitSessionKey) === "agent"