Skip to content

Commit 7ea91fa

Browse files
cteclaude
andauthored
fix(cli): ignore model-provided timeout in CLI runtime (#11835)
In CLI runtime, stdin harnesses expect command lifetime to be governed solely by commandExecutionTimeout (user setting), not model-provided background timeouts. Extract resolveAgentTimeoutMs() and return 0 when ROO_CLI_RUNTIME=1. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 941e6de commit 7ea91fa

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/core/tools/ExecuteCommandTool.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ interface ExecuteCommandParams {
2929
timeout?: number | null
3030
}
3131

32+
export function resolveAgentTimeoutMs(timeoutSeconds: number | null | undefined): number {
33+
const requestedAgentTimeout = typeof timeoutSeconds === "number" && timeoutSeconds > 0 ? timeoutSeconds * 1000 : 0
34+
35+
// In CLI runtime, stdin harnesses expect command lifetime to be governed
36+
// solely by commandExecutionTimeout (user setting), not model-provided
37+
// background timeouts.
38+
return process.env.ROO_CLI_RUNTIME === "1" ? 0 : requestedAgentTimeout
39+
}
40+
3241
export class ExecuteCommandTool extends BaseTool<"execute_command"> {
3342
readonly name = "execute_command" as const
3443

@@ -87,7 +96,7 @@ export class ExecuteCommandTool extends BaseTool<"execute_command"> {
8796
const commandExecutionTimeout = isCommandAllowlisted ? 0 : commandExecutionTimeoutSeconds * 1000
8897

8998
// Convert agent-specified timeout from seconds to milliseconds
90-
const agentTimeout = typeof timeoutSeconds === "number" && timeoutSeconds > 0 ? timeoutSeconds * 1000 : 0
99+
const agentTimeout = resolveAgentTimeoutMs(timeoutSeconds)
91100

92101
const options: ExecuteCommandOptions = {
93102
executionId,

src/core/tools/__tests__/executeCommandTool.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe("executeCommandTool", () => {
4848
let mockHandleError: any
4949
let mockPushToolResult: any
5050
let mockToolUse: ToolUse<"execute_command">
51+
const originalCliRuntime = process.env.ROO_CLI_RUNTIME
5152

5253
beforeEach(() => {
5354
// Reset mocks
@@ -106,6 +107,10 @@ describe("executeCommandTool", () => {
106107
}
107108
})
108109

110+
afterEach(() => {
111+
process.env.ROO_CLI_RUNTIME = originalCliRuntime
112+
})
113+
109114
/**
110115
* Tests for HTML entity unescaping in commands
111116
* This verifies that HTML entities are properly converted to their actual characters
@@ -285,5 +290,15 @@ describe("executeCommandTool", () => {
285290
expect(mockOptions.command).toBeDefined()
286291
expect(mockOptions.commandExecutionTimeout).toBeDefined()
287292
})
293+
294+
it("should ignore model timeout in CLI runtime", () => {
295+
process.env.ROO_CLI_RUNTIME = "1"
296+
expect(executeCommandModule.resolveAgentTimeoutMs(30)).toBe(0)
297+
})
298+
299+
it("should honor model timeout outside CLI runtime", () => {
300+
delete process.env.ROO_CLI_RUNTIME
301+
expect(executeCommandModule.resolveAgentTimeoutMs(30)).toBe(30_000)
302+
})
288303
})
289304
})

0 commit comments

Comments
 (0)