⛲ fix: Prevent Agent Model Stream Idle Timeouts - #16201
Conversation
|
Ready for review at exact head |
|
Updated review head: |
|
Updated review head: |
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c8d997b1d1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| mergeFetchOptions(configOptions, { | ||
| dispatcher: proxyDispatcher ?? getDirectDispatcher(transportTimeouts), |
There was a problem hiding this comment.
Apply transport timeouts to direct-endpoint fetches
When a custom endpoint sets directEndpoint: true, getOpenAIConfig later replaces the fetch implementation with createFetch, which calls node-fetch; that implementation ignores the Undici dispatcher installed here. Consequently, neither configured timeout is enforced on this supported path—for example, modelResponseHeadersTimeoutMs: 1000 can still wait indefinitely for response headers. Pass the timeout policy into the custom fetch or retain an Undici-based fetch so the documented operator settings work consistently.
AGENTS.md reference: AGENTS.md:L66-L68
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in ae6711f. Direct Agent endpoints now rewrite only the URL and use Undici with the configured dispatcher instead of node-fetch. Real Agent SDK/socket tests verify header and body-idle timeouts on both standard and direct endpoints, exact URL preservation, cancellation, non-streaming response bounds, and SSRF redirect rejection. The legacy no-policy fetch path is unchanged.
| tenantId: headerContext.tenantId, | ||
| body: headerContext.requestBody, | ||
| }), | ||
| transportTimeouts: resolveModelTransportTimeouts(appConfig?.endpoints?.agents), |
There was a problem hiding this comment.
Cover cross-provider built-in summarizers
When a non-OpenAI agent, such as an Anthropic agent, selects summarization.provider: openAI, this timeout-aware resolver is not used because resolveOpenAISummarization is called only for Azure agents. The request instead goes through resolveBuiltInClientOverrides, whose getOpenAIConfig call omits transportTimeouts and whose returned shaping deliberately excludes configuration, so both the new defaults and explicit operator overrides are ignored and the summarization stream retains Undici's five-minute idle timeout. Apply the policy to this built-in cross-provider path as well.
AGENTS.md reference: AGENTS.md:L66-L68
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in ae6711f. The built-in cross-provider OpenAI-family path now supplies the resolved timeout dispatcher without replacing credentials, base URLs, or model settings. Explicit URL overrides retain timeout policy but do not acquire first-party request shaping. Same-provider summaries continue inheriting their Agent client's configuration. The full summarization test file passes (208 tests), including policy defaults, operator overrides, disabled timers, and existing Azure/subagent paths.
|
Updated review head: Both inline findings are addressed: direct endpoints now enforce policy through Undici, and cross-provider built-in summaries receive the configured dispatcher. Also fixed the formatting failure and restricted runtime cache inputs to the options represented by cache keys. Verification:
Subsystem self-review covered direct vs SDK fetch paths, cross-provider and inherited summarization, cancellation, retry preservation, SSRF/proxy composition, and cache identity. No persistence or authorization contract is changed. CI is running; a maintainer can trigger review of this exact head. Correction to the previous handoff: the earlier remote SHA was |
|
Updated review head: Addresses both errors from TypeScript job 106739412963:
All 9 real-socket Agent transport regressions passed in two short runs. Affected-file static checks passed on the full committed 17-file PR diff. Local A new exact-head review is pending. The previous head's reviews do not cover this correction. |
|
@codex review the latest head |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
* 🌊 fix: Prevent Agent Model Stream Idle Timeouts * fix: Preserve Default Proxy Dispatcher Construction * test: Assert Agent Transport Timeout Policy * test: Cover Direct Model Dispatcher Reuse * fix: Scope Agent Model Transport Timeouts * fix: Enforce Agent Timeouts Across Direct and Summary Clients * fix: Align Model Transport Adapter Types --------- Co-authored-by: Lia <lia@librechat.ai>
Summary
OpenAI-compatible Agent model calls can fail with
terminatedwhen Undici's five-minute body-idle timeout expires, even when the SDK request timeout is longer. MCP's transport fixes do not configure the model client. The SDK timer ends when response headers arrive; it is not a total-response deadline.This change supplies an explicit, configurable transport policy for OpenAI-compatible Agent calls and summarization, including built-in cross-provider summaries and
directEndpointcustom URLs. Non-Agent callers ofgetOpenAIConfigretain their existing behavior unless they explicitly supply the policy.The defaults are a finite 15-minute body-idle allowance and a five-minute header allowance. Values are integer milliseconds from 0 through 86400000; 0 explicitly disables that transport timer. Received body chunks reset the idle timer. These settings do not define total run duration and do not replace the SDK's timeout or cancellation. An earlier SDK timeout can still win while waiting for headers. Native non-OpenAI providers and MCP timeouts are unchanged.
Direct Agent endpoints retain their exact URL while using Undici so the same timeout, proxy, and SSRF policy is enforced. Cached dispatchers accept only numeric timeout options; private SSRF connection policies remain isolated. Cancellation and retry policy are unchanged.
Related to #16195. The transport failure is reproduced locally through the real locked Agent model client; the reporter's deployment has not been independently reproduced.
Change Type
Testing
npm run static-checks -- --against origin/dev: all affected checks passed across 17 files, including ESLint, Prettier, imports, and circular dependencies.npx tsc --noEmitinpackages/apiwas stopped at a 20-second execution limit, without a result. Not claimed as passing. No long build, install, full suite, or full static-check run was performed for this revision.Remaining verification
CI and a new review must cover the latest pushed head. The earlier review does not cover these corrections.