From 75c011b60694f773b46df4ea5b09aeac9a4e3e6d Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 29 May 2026 05:29:44 -0400 Subject: [PATCH] fix(subagents): ignore unsafe log limits --- .../reply/commands-subagents-log.test.ts | 18 ++++++++++++++++++ .../reply/commands-subagents/action-log.ts | 8 ++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/auto-reply/reply/commands-subagents-log.test.ts b/src/auto-reply/reply/commands-subagents-log.test.ts index 7aadca8cc4a..34f09f04f18 100644 --- a/src/auto-reply/reply/commands-subagents-log.test.ts +++ b/src/auto-reply/reply/commands-subagents-log.test.ts @@ -71,4 +71,22 @@ describe("subagents log", () => { params: { sessionKey: "agent:main:subagent:log", limit: 5 }, }); }); + + it("clamps a zero history limit to one", async () => { + await handleSubagentsLogAction(buildLogContext(["1", "0"], [makeRun()])); + + expect(callGatewayMock).toHaveBeenCalledWith({ + method: "chat.history", + params: { sessionKey: "agent:main:subagent:log", limit: 1 }, + }); + }); + + it("ignores unsafe history limit tokens", async () => { + await handleSubagentsLogAction(buildLogContext(["1", "9007199254740992"], [makeRun()])); + + expect(callGatewayMock).toHaveBeenCalledWith({ + method: "chat.history", + params: { sessionKey: "agent:main:subagent:log", limit: 20 }, + }); + }); }); diff --git a/src/auto-reply/reply/commands-subagents/action-log.ts b/src/auto-reply/reply/commands-subagents/action-log.ts index 372135a9b13..70a1254e574 100644 --- a/src/auto-reply/reply/commands-subagents/action-log.ts +++ b/src/auto-reply/reply/commands-subagents/action-log.ts @@ -1,4 +1,5 @@ import { callGateway } from "../../../gateway/call.js"; +import { parseStrictNonNegativeInteger } from "../../../shared/number-coercion.js"; import { normalizeLowercaseStringOrEmpty } from "../../../shared/string-coerce.js"; import type { CommandHandlerResult } from "../commands-types.js"; import { formatRunLabel } from "../subagents-utils.js"; @@ -23,8 +24,11 @@ export async function handleSubagentsLogAction( const includeTools = restTokens.some( (token) => normalizeLowercaseStringOrEmpty(token) === "tools", ); - const limitToken = restTokens.slice(1).find((token) => /^\d+$/.test(token)); - const limit = limitToken ? Math.min(200, Math.max(1, Number.parseInt(limitToken, 10))) : 20; + const limitToken = restTokens + .slice(1) + .find((token) => parseStrictNonNegativeInteger(token) !== undefined); + const parsedLimit = parseStrictNonNegativeInteger(limitToken); + const limit = parsedLimit === undefined ? 20 : Math.min(200, Math.max(1, parsedLimit)); const targetResolution = resolveSubagentEntryForToken(runs, target); if ("reply" in targetResolution) {