Add per-model-call wall-clock ceiling + h2 PING keepalives on the default provider client - #124
Conversation
…tinyhumansai#123) The budget for an individual model call was solely the run's remaining wall-clock budget, which conflates hang detection with runaway-run bounding: a generous run ceiling lets a wedged call hold the run for the whole ceiling, while a tight one kills late calls in long productive runs (observed in the field: a call granted 56s of a 600s turn after earlier calls legitimately consumed the rest). The model-call budget is now min(remaining, max_model_call_ms), computed fresh per attempt so every retry gets its own window while never overshooting the run deadline. Tool calls deliberately keep the remaining-only budget: a sub-agent delegation is a tool call wrapping an entire child run and must not inherit a model-call-sized cap. The timeout message now names which ceiling fired (per-model-call ceiling vs remaining wall-clock budget) so field triage can tell a wedged call from an exhausted run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… tool exemption (tinyhumansai#123) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ansai#123) Streaming calls deliberately carry no overall request timeout, so until now a dead peer during an app-silent stretch (e.g. hidden reasoning) was indistinguishable from a thinking model until a harness budget fired. With h2 negotiated via ALPN, PING keepalives fail the in-flight call in about a minute when the peer stops acking, with zero false positives on legitimately slow calls. Plaintext HTTP/1.1 endpoints are unaffected; caller-owned clients (with_client) keep their own transport policy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (8)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe change adds an optional per-model-call timeout ceiling, preserves run-budget handling for tools, improves timeout diagnostics, and configures HTTP/2 keepalives for default OpenAI provider clients. ChangesModel Call Reliability
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to This PR adds per-call model time limits and HTTP/2 keepalives without any identified merge-blocking correctness or availability risk; it is merge-ready after normal checks and review. Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Warning Your free Security trial is over. An organization admin can activate billing to continue. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
How this change flows1 changed behaviour across 7 relationships. 4 surrounding behaviours are shown (60 graph nodes walked). 31 further behaviours left out to keep the diagram readable. flowchart LR
n0["OpenAiModel<br/>changed"]:::changed
n1["Send"]:::impacted
n2["AgentHarness"]:::impacted
n3["ModelCallBase"]:::impacted
n4["ChatModel"]:::impacted
n0 -->|implements| n4
n2 -->|uses| n1
n3 -->|uses| n1
n3 -->|uses| n2
n3 -->|uses| n4
n4 -->|uses| n1
n4 -->|implements| n1
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Green: changed behaviour. Grey: surrounding behaviour. Arrows name the call, use, implementation, or test relationship. Orange: has findings. Red: has a finding that blocks the merge. |
Closes #123.
What
1.
RunLimits::max_model_call_ms— a per-model-call wall-clock ceiling (defaultNone, today's behavior). The model-call budget becomesmin(remaining run budget, per-call ceiling), recomputed for every call and every retry attempt, so each attempt gets its own fresh window while never overshooting the run deadline.2. Tool calls are deliberately exempt.
call_budget()(remaining-only) stays the tool path's budget: a sub-agent delegation is a tool call wrapping an entire child run and must not inherit a model-call-sized cap. Tools remain bounded by their ownToolTimeoutSettingsplus the run remainder. Pinned byper_model_call_ceiling_does_not_bound_tool_calls.3. The timeout message names which ceiling fired —
per-model-call ceilingvsremaining wall-clock budget— so field triage can tell "this one call wedged" from "the run is out of time".4. HTTP/2 PING keepalives on the default provider client (
http2reqwest feature +http2_keep_alive_{interval,timeout}(30s)+while_idle). Streaming calls deliberately carry no overall request timeout, so a dead peer during an app-silent stretch (hidden reasoning) was previously indistinguishable from a thinking model until a harness budget fired. PINGs fail the in-flight call in ~1 min when the peer stops acking, with zero false positives on legitimately slow calls. Plaintext HTTP/1.1 endpoints (local Ollama/LM Studio — no ALPN) are unaffected; caller-owned clients (with_client) keep their own transport policy, unchanged.Why
Observed in the field (OpenCompany workflow, via openhuman's 600s turn ceiling): a model call late in a long, productive run was granted the run's remainder — 56s — and was killed mid-flight, failing the whole run. The single
max_wall_clock_msknob conflates hang detection with runaway-run bounding, forcing hosts to trade "long runs allowed" against "hang-detection latency" 1:1. This decouples them: hosts can raise the run ceiling to a generous runaway guard while a wedged call still dies at the per-call ceiling.Sizing note: a hidden-reasoning call can legitimately be app-silent for minutes — the ceiling is a backstop for calls that will never return, not a latency target. Host wiring (env knob, defaults) lands separately in openhuman.
Commands run locally
cargo fmt --checkcargo clippy --all-targets -- -D warningscargo test— 1781 lib + all integration suites + doctests, 0 failuresAPI changes
RunLimits::max_model_call_ms+with_max_model_call_msbuilder.TinyAgentsError::Timeoutmessage text for model calls bounded by the new ceiling says "exceeded its per-model-call ceiling" (run-bounded calls keep the existing "remaining wall-clock budget" phrasing).http2feature (ALPN-negotiated; no behavior change for plaintext endpoints).Summary by CodeRabbit
New Features
Bug Fixes