Summary
EnvironmentWorker / SessionToolRunner wrap every tool call in a hardcoded 150 s outer timeout (anthropic/lib/tools/_beta_session_runner.py, TOOL_TIMEOUT = 150.0). There is no constructor parameter or environment variable to change it. For a self-hosted environment worker whose agents run builds and test suites through the bash tool, this makes the bash tool's own timeout_ms argument effectively capped at ~150 s regardless of what the caller passes, and the cancellation that fires is the outer one, so a custom bash tool's own timeout handling never runs.
Where
_beta_session_runner.py: TOOL_TIMEOUT = 150.0, used as with anyio.fail_after(TOOL_TIMEOUT): around each tool call. The comment there documents the invariant that it must exceed agent_toolset.BASH_DEFAULT_TIMEOUT (120 s) by a margin.
SessionToolRunner.__init__(client, session_id, *, tools, max_idle=60.0, environment_key=None, extra_headers=None) and EnvironmentWorker.__init__(...) expose max_idle but no per-tool-call timeout.
Reproduced on 0.105.2 and 1.8.0.
Request
Expose the outer per-tool-call timeout as a constructor argument on EnvironmentWorker (threaded to SessionToolRunner), e.g. tool_timeout: float | None = 150.0, keeping the current default. Ideally keep the documented margin invariant enforceable: either validate that a custom bash tool's default stays below it, or let a tool declare its own expected maximum so the runner can size the outer scope per call.
Why
Self-hosted workers running real repositories routinely need a single bash call (make check, a full pytest run) to exceed 150 s. Today the only options are to split the work, to background it inside the container and poll (which loses the tool-call result contract), or to monkeypatch the private constant. A configurable timeout with the same default would keep hosted behaviour unchanged.
Summary
EnvironmentWorker/SessionToolRunnerwrap every tool call in a hardcoded 150 s outer timeout (anthropic/lib/tools/_beta_session_runner.py,TOOL_TIMEOUT = 150.0). There is no constructor parameter or environment variable to change it. For a self-hosted environment worker whose agents run builds and test suites through the bash tool, this makes the bash tool's owntimeout_msargument effectively capped at ~150 s regardless of what the caller passes, and the cancellation that fires is the outer one, so a custom bash tool's own timeout handling never runs.Where
_beta_session_runner.py:TOOL_TIMEOUT = 150.0, used aswith anyio.fail_after(TOOL_TIMEOUT):around each tool call. The comment there documents the invariant that it must exceedagent_toolset.BASH_DEFAULT_TIMEOUT(120 s) by a margin.SessionToolRunner.__init__(client, session_id, *, tools, max_idle=60.0, environment_key=None, extra_headers=None)andEnvironmentWorker.__init__(...)exposemax_idlebut no per-tool-call timeout.Reproduced on 0.105.2 and 1.8.0.
Request
Expose the outer per-tool-call timeout as a constructor argument on
EnvironmentWorker(threaded toSessionToolRunner), e.g.tool_timeout: float | None = 150.0, keeping the current default. Ideally keep the documented margin invariant enforceable: either validate that a custom bash tool's default stays below it, or let a tool declare its own expected maximum so the runner can size the outer scope per call.Why
Self-hosted workers running real repositories routinely need a single bash call (
make check, a full pytest run) to exceed 150 s. Today the only options are to split the work, to background it inside the container and poll (which loses the tool-call result contract), or to monkeypatch the private constant. A configurable timeout with the same default would keep hosted behaviour unchanged.