Honor proxy env for runtime undici dispatcher#42320
Honor proxy env for runtime undici dispatcher#42320wuxudongxd wants to merge 5 commits intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR makes the undici global dispatcher honor proxy environment variables when the current dispatcher is a plain Key changes:
Minor behavioural note: once the dispatcher has been upgraded to Confidence Score: 4/5
Last reviewed commit: 71bdebe |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 71bdebe58d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const kind = | ||
| currentKind === "agent" && hasProxyEnvConfigured() ? ("env-proxy" as const) : currentKind; |
There was a problem hiding this comment.
Fall back to Agent when env proxy upgrade fails
When hasProxyEnvConfigured() is true, this forces the dispatcher mode to env-proxy even if the proxy env value is malformed or unsupported; in that case new EnvHttpProxyAgent(...) can throw, the catch block swallows it, and no tuned Agent is applied. This is a regression from the previous behavior, where the default Agent path still set stream timeouts, so users with bad proxy env values can silently lose the timeout hardening and hit premature request timeouts.
Useful? React with 👍 / 👎.
|
Addressed the fallback issue in e45225c.\n\nIf env-proxy upgrade throws (for example due to malformed/unsupported proxy env values), we now fall back to a hardened Agent so body/header timeouts are still preserved. Also added a regression test covering that fallback path. |
|
We need this for auto proxy, please help to resolve the conflicts and merge this PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b821aee74c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -1,11 +1,13 @@ | |||
| import * as net from "node:net"; | |||
| import { Agent, EnvHttpProxyAgent, getGlobalDispatcher, setGlobalDispatcher } from "undici"; | |||
| import { hasProxyEnvConfigured, hasEnvHttpProxyConfigured } from "./proxy-env.js"; | |||
There was a problem hiding this comment.
Remove unresolved hasEnvHttpProxyConfigured import
src/infra/net/undici-global-dispatcher.ts now imports hasEnvHttpProxyConfigured from src/infra/net/proxy-env.ts, but proxy-env.ts only exports hasProxyEnvConfigured. In ESM this is a load-time failure (Export named ... not found), so any path that imports the dispatcher module (including the embedded runner before requests are sent) will crash before timeout/proxy hardening executes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c69480f250
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const envProxyKey = envProxyRequested | ||
| ? resolveDispatcherKey({ kind: "env-proxy", timeoutMs, autoSelectFamily }) | ||
| : null; | ||
| const appliedKey = envProxyKey ?? agentKey; | ||
| if (lastAppliedTimeoutKey === appliedKey) { |
There was a problem hiding this comment.
Reapply env-proxy when dispatcher reverts to Agent
When hasEnvHttpProxyConfigured("https") is true, appliedKey is forced to the env-proxy key even if the current dispatcher is now a plain Agent, so a later call can hit the lastAppliedTimeoutKey === appliedKey fast path and return without reinstalling EnvHttpProxyAgent. This means if any code resets Undici's global dispatcher after an earlier successful hardening pass, subsequent runtime attempts can silently stay on an unproxied Agent in proxy-only environments and fail outbound requests.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a585ce16b3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| @@ -1,11 +1,13 @@ | |||
| import * as net from "node:net"; | |||
| import { Agent, EnvHttpProxyAgent, getGlobalDispatcher, setGlobalDispatcher } from "undici"; | |||
| import { hasEnvHttpProxyConfigured } from "./proxy-env.js"; | |||
There was a problem hiding this comment.
Import the exported proxy-env helper
undici-global-dispatcher.ts now imports hasEnvHttpProxyConfigured, but src/infra/net/proxy-env.ts only exports hasProxyEnvConfigured. In ESM this throws at module load (does not provide an export named ...), so any runtime path that imports this dispatcher (including embedded attempt startup) can fail before request timeout/proxy hardening is applied.
Useful? React with 👍 / 👎.
|
Closing this as implemented after Codex review. Current What I checked:
So I’m closing this as already implemented rather than keeping a duplicate issue open. Review notes: reviewed against 7d9172d5e093; fix evidence: release v2026.4.22, commit 00bd2cf7a376. |
Summary
This PR makes the runtime undici dispatcher honor proxy env in the common
Agentcase.In proxy-only environments,
openai-codexruntime requests could fail even after OAuth succeeded, because the runtime dispatcher path stayed on a plainAgentinstead of switching to env-proxy mode.With this change, when proxy env vars are present and the current global dispatcher is the default
Agent, OpenClaw upgrades it toEnvHttpProxyAgentbefore applying stream timeout tuning.This keeps the existing behavior for:
EnvHttpProxyAgentdispatchersProxyAgentRelated:
What changed
hasProxyEnvConfigured()intosrc/infra/net/undici-global-dispatcher.tsAgentand proxy env is configured, treat the effective mode asenv-proxyWhy this is minimal
This PR intentionally does not:
NODE_USE_ENV_PROXY=1globallyIt only makes the runtime dispatcher reuse OpenClaw's existing env-proxy capability when proxy env vars are already configured.
Validation
Ran:
corepack pnpm -C /home/dong/openclaw exec vitest run src/infra/net/undici-global-dispatcher.test.tsResult: