fix(v1): restore the unbounded model-call timeout - #2304
Merged
Conversation
#2218 consolidated client construction into build_async_openai/DEFAULT_TIMEOUT and, in doing so, replaced the relay client's explicit # No timeout: agentic completions are slow and the rollout timeout is the real backstop. timeout=None with a 600s read timeout "mirroring the OAI SDK defaults". That cap now applies to every model-call path, since DEFAULT_TIMEOUT feeds the relay client in clients/eval.py as well as build_async_openai, which judge.py and clients/train.py both use. 600s is fine for chat-shaped evals and wrong for RL. A single agentic turn on a long SWE trajectory routinely runs past ten minutes, and when it does httpx raises TimeoutException, clients/eval.py maps it to a 504 model_error, and the rollout dies as `ProviderError: Request timed out`. The rollout is lost even though the model was still producing, and long trajectories are exactly the ones RL cares about, so the failures are biased rather than uniform. Observed on a 6-node SWE RL run against a local vLLM fleet. Restore the pre-#2218 behaviour for read/write/pool. The rationale that #2218 deleted is put back with it: verifiers already bounds rollouts properly through RolloutTimeouts (setup/agent/episode/finalize), so a transport-level read timeout is redundant with the real backstop and only truncates slow but healthy generations. One deliberate difference from a pure revert: connect stays at 5.0 rather than going back to a blanket timeout=None, so an unreachable endpoint still fails fast instead of hanging until the rollout deadline. Only the timeouts that bound generation are lifted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mikasenghaas
marked this pull request as ready for review
August 9, 2026 04:28
Contributor
ApprovabilityVerdict: Approved 5167355 Small configuration change removing bounded HTTP timeouts for model calls, with clear documentation that the rollout timeout serves as the actual backstop. The author is the original author of this file and provided appropriate rationale. You can customize Macroscope's approvability policy. Learn more. |
samsja
approved these changes
Aug 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What broke
#2218 consolidated client construction into
build_async_openai/DEFAULT_TIMEOUT. In doing so it replaced the relay client's explicit no-timeout:The comment explaining why there was no timeout was removed along with it.
The cap now applies to every model-call path, because
DEFAULT_TIMEOUTfeeds both the relay client inclients/eval.pyandbuild_async_openai, whichjudge.pyandclients/train.pyuse.Why it matters for RL
600s is a reasonable default for chat-shaped evals and the wrong one for RL. A single agentic turn on a long SWE trajectory routinely runs past ten minutes. When it does:
httpxraisesTimeoutExceptionclients/eval.pymaps it to a 504 viamodel_errorProviderError: Request timed outThe rollout is lost even though the model was still producing. Worse, the loss is biased, not uniform — it selectively kills the longest trajectories, which are the ones RL cares most about. Observed on a 6-node SWE RL run against a local vLLM fleet.
The fix
Restore the pre-#2218 behaviour for
read/write/pool, and put back the rationale that was deleted with it:This isn't leaving rollouts unbounded — verifiers already bounds them properly through
RolloutTimeouts(setup/agent/episode/finalize). A transport-level read timeout is redundant with that real backstop and only truncates slow but healthy generations.One deliberate difference from a pure revert:
connectstays at5.0rather than reverting to a blankettimeout=None, so an unreachable endpoint still fails fast instead of hanging until the rollout deadline. Only the timeouts that bound generation are lifted.🤖 Generated with Claude Code
Note
Restore unbounded read/write/pool timeouts in
DEFAULT_TIMEOUTfor model callsSets
read,write, andpooltimeouts toNonein base.py, removing the previous 600s limits. Theconnecttimeout remains bounded at 5s. Behavioral Change: any httpx client usingDEFAULT_TIMEOUTwill no longer time out on slow or long-running model responses.Macroscope summarized 5167355.
Note
Medium Risk
Shared HTTP client defaults affect every eval/train/judge model path; removing read timeouts can let hung provider connections run until rollout timeouts unless those layers fire reliably.
Overview
DEFAULT_TIMEOUTinverifiers/v1/clients/base.pyno longer caps long model responses at 600s.read,write, andpoolare set back toNone;connectstays at 5.0s so dead endpoints still fail quickly.That shared default is used by
build_async_openai(train/judge paths) and the eval relayhttpx.AsyncClient, so the change applies across all v1 model-call clients. Rollout limits viaRolloutTimeoutsremain the intended backstop; the restored comment documents that agentic generations should not be cut off by transport read timeouts.Reviewed by Cursor Bugbot for commit 5167355. Bugbot is set up for automated code reviews on this repo. Configure here.