fix(agentrun): bound events timeout to 60m

This commit is contained in:
Codex
2026-07-15 06:08:41 +02:00
parent 968ffa3ecf
commit 82b48a00fa
2 changed files with 25 additions and 5 deletions
+21 -1
View File
@@ -164,7 +164,7 @@ describe.serial("AgentRun events manager-held long polling", () => {
}, async () => {
const invalid = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--expect", "2", "--timeout", "3minutes", "-o", "json"]);
expect(invalid.ok).toBe(false);
expect(renderedText(invalid)).toContain("--timeout must use an integer duration");
expect(renderedText(invalid)).toContain("--timeout must use a positive integer duration with ms, s, or m units");
expect(requests).toBe(0);
const failed = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--expect", "2", "--timeout", "1s", "-o", "json"]);
@@ -182,4 +182,24 @@ describe.serial("AgentRun events manager-held long polling", () => {
expect(renderedText(result)).toContain("must include boolean timedOut and non-negative observed fields");
});
});
test("accepts 60m and rejects zero, values above 60m, and hour units before request", async () => {
let requests = 0;
await withManager((request) => {
requests += 1;
const url = new URL(request.url);
expect(url.searchParams.get("timeoutMs")).toBe("3600000");
return Response.json({ ok: true, data: { items: [], timedOut: true, observed: 0, nextAfterSeq: 0, completionReason: "timeout" } });
}, async () => {
const accepted = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--expect", "1", "--timeout", "60m", "-o", "json"]);
expect(accepted.ok).toBe(true);
expect(requests).toBe(1);
for (const invalidDuration of ["0ms", "61m", "1h"]) {
const invalid = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--expect", "1", "--timeout", invalidDuration, "-o", "json"]);
expect(invalid.ok).toBe(false);
}
expect(requests).toBe(1);
});
});
});
+4 -4
View File
@@ -360,12 +360,12 @@ function parsePositiveInt(raw: string | null, flag: string): number {
export function parseDurationMs(raw: string | null, flag: string): number {
if (raw === null || raw.length === 0) throw new Error(`${flag} requires a duration`);
const match = /^(\d+)(ms|s|m|h)$/u.exec(raw.trim());
if (match === null) throw new Error(`${flag} must use an integer duration such as 500ms, 120s, 3m, or 1h`);
const match = /^(\d+)(ms|s|m)$/u.exec(raw.trim());
if (match === null) throw new Error(`${flag} must use a positive integer duration with ms, s, or m units, such as 500ms, 120s, or 3m`);
const amount = Number(match[1]);
const multiplier = match[2] === "ms" ? 1 : match[2] === "s" ? 1_000 : match[2] === "m" ? 60_000 : 3_600_000;
const multiplier = match[2] === "ms" ? 1 : match[2] === "s" ? 1_000 : 60_000;
const value = amount * multiplier;
if (!Number.isSafeInteger(value) || value < 1 || value > 86_400_000) throw new Error(`${flag} must be between 1ms and 24h`);
if (!Number.isSafeInteger(value) || value < 1 || value > 3_600_000) throw new Error(`${flag} must be between 1ms and 60m`);
return value;
}