Summary
defaultDispatchCandidateTimeoutMS = 60000 (internal/proxy/handler.go:62) silently kills any upstream call that takes over 60 seconds — which reasoning models on /v1/responses routinely do on tool-result follow-up rounds. The failure presents as a bare 502 context deadline exceeded with no hint that a configurable local deadline fired rather than the provider failing, and the runner's whole-turn retry loop then multiplies token spend.
Observed (emmett pod, gpt-5.6-luna via the Responses adapter, 2026-08-03)
- 5 of 7 wake attempts died at 63.5–64.8s with
Post "https://api.openai.com/v1/responses": context deadline exceeded → surfaced to the runner as 502.
- Each attempt had already executed a managed tool round; the deadline killed the follow-up dispatch. The runner (hermes) retried the entire turn each time: ~12.6k prompt tokens per attempt, ~88k tokens for one logical wake.
- We first mis-attributed it to
tool-policy.total_timeout_ms (120s) and raised that to 300s — no effect, because the 60s per-candidate dispatch deadline binds first. Nothing in the telemetry distinguishes the two budgets.
Asks
- Reasoning-aware default or model-class override. 60s is a fine default for chat models and wrong for reasoning models; a per-model or per-provider
dispatch_timeout_ms in the provider pool config would let one pod mix both.
- Telemetry should name the budget that fired. The error line already logs
latency_ms; add deadline: dispatch_candidate | stream_first_byte | stream_idle | tool_policy_total so operators stop bisecting timeouts by redeploying.
- Document the interaction: dispatch-candidate deadline binds per upstream POST, inside tool-mediation rounds, underneath
tool-policy.total_timeout_ms. We found the relationship only by reading source.
Workaround in use: CLLAMA_DISPATCH_CANDIDATE_TIMEOUT_MS=300000 on the sidecar env.
Summary
defaultDispatchCandidateTimeoutMS = 60000(internal/proxy/handler.go:62) silently kills any upstream call that takes over 60 seconds — which reasoning models on/v1/responsesroutinely do on tool-result follow-up rounds. The failure presents as a bare 502context deadline exceededwith no hint that a configurable local deadline fired rather than the provider failing, and the runner's whole-turn retry loop then multiplies token spend.Observed (emmett pod, gpt-5.6-luna via the Responses adapter, 2026-08-03)
Post "https://api.openai.com/v1/responses": context deadline exceeded→ surfaced to the runner as 502.tool-policy.total_timeout_ms(120s) and raised that to 300s — no effect, because the 60s per-candidate dispatch deadline binds first. Nothing in the telemetry distinguishes the two budgets.Asks
dispatch_timeout_msin the provider pool config would let one pod mix both.latency_ms; adddeadline: dispatch_candidate | stream_first_byte | stream_idle | tool_policy_totalso operators stop bisecting timeouts by redeploying.tool-policy.total_timeout_ms. We found the relationship only by reading source.Workaround in use:
CLLAMA_DISPATCH_CANDIDATE_TIMEOUT_MS=300000on the sidecar env.