The LangChain tool promises a five-minute wall clock per sandbox_exec (CALL_TIMEOUT in sdk/langchain/cocoonsandbox_langchain/toolkit.py). Since #179 the run itself honours it: the toolkit computes one deadline across claim, dial and command and passes the remainder to Sandbox.run(timeout=). The claim leg does not: Client (sdk/python/cocoonsandbox/client.py) gives every control-plane request, and every redirect target it follows on a warm miss, a fresh client.timeout (300 s in the toolkit). Two black-holed redirect candidates in a row therefore consume up to 600 s before the tool's own budget check runs, so the tool can exceed its promise on a cluster with unreachable peers.
Fix shape: give the Python client an absolute-deadline form for claim (deadline: float | None threaded through new, _scatter and the redirect walk, each request bounded by min(timeout, deadline - now) and refused once it is spent), and have the toolkit pass its deadline. This is a client API addition, which is why it stayed out of #179 and #180. Codex raised it in every round from 2 to 7; the run-side half landed as d66e083 and c209a6d.
Test: a fake node that redirects to two addresses that accept TCP and never answer; the toolkit must fail before its promised wall clock, not after 2x.
The LangChain tool promises a five-minute wall clock per
sandbox_exec(CALL_TIMEOUTinsdk/langchain/cocoonsandbox_langchain/toolkit.py). Since #179 the run itself honours it: the toolkit computes one deadline across claim, dial and command and passes the remainder toSandbox.run(timeout=). The claim leg does not:Client(sdk/python/cocoonsandbox/client.py) gives every control-plane request, and every redirect target it follows on a warm miss, a freshclient.timeout(300 s in the toolkit). Two black-holed redirect candidates in a row therefore consume up to 600 s before the tool's own budget check runs, so the tool can exceed its promise on a cluster with unreachable peers.Fix shape: give the Python client an absolute-deadline form for claim (
deadline: float | Nonethreaded throughnew,_scatterand the redirect walk, each request bounded bymin(timeout, deadline - now)and refused once it is spent), and have the toolkit pass its deadline. This is a client API addition, which is why it stayed out of #179 and #180. Codex raised it in every round from 2 to 7; the run-side half landed as d66e083 and c209a6d.Test: a fake node that redirects to two addresses that accept TCP and never answer; the toolkit must fail before its promised wall clock, not after 2x.