Skip to content

fix(image-gen): bypass macOS system proxy for custom endpoints - #64893

Open
asdlem wants to merge 2 commits into
NousResearch:mainfrom
asdlem:fix/upstream-image-gen-macos-proxy-bypass
Open

fix(image-gen): bypass macOS system proxy for custom endpoints#64893
asdlem wants to merge 2 commits into
NousResearch:mainfrom
asdlem:fix/upstream-image-gen-macos-proxy-bypass

Conversation

@asdlem

@asdlem asdlem commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

The OpenAI image generation provider currently creates its SDK client with the default environment-aware httpx transport. On macOS, that can route a custom OPENAI_BASE_URL through the system proxy even when the endpoint is listed in the system proxy exceptions, because those exceptions are not exposed through urllib.request.getproxies().

This change reuses Hermes' existing build_keepalive_http_client() policy whenever a custom image endpoint is configured. The default OpenAI client behavior remains unchanged when OPENAI_BASE_URL is not set.

Related Issue

Fixes #64888

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • Update plugins/image_gen/openai/__init__.py to inject Hermes' custom httpx client when OPENAI_BASE_URL is configured.
  • Add a regression test that simulates a macOS system proxy and verifies the custom endpoint client has no HTTPProxy transport.
  • Preserve the SDK's existing default behavior when no custom base URL is configured.

How to Test

  1. Configure a macOS HTTP/HTTPS system proxy and set OPENAI_BASE_URL to a local or custom OpenAI-compatible endpoint.
  2. Run scripts/run_tests.sh tests/plugins/image_gen/test_openai_provider.py -q and verify all 30 tests pass.
  3. Run Ruff for the two changed files and python3 scripts/check-windows-footguns.py plugins/image_gen/openai/__init__.py tests/plugins/image_gen/test_openai_provider.py.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.3

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A: no user-facing configuration or behavior contract changed
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A: no config keys changed
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A: no architecture or workflow changes
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — the existing default path is unchanged and the footgun scan passes
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A: no tool schema changed

Screenshots / Logs

Targeted verification:

  • scripts/run_tests.sh tests/plugins/image_gen/test_openai_provider.py -q: 30 passed
  • Ruff on both changed files: all checks passed
  • git diff --check: passed
  • Windows footgun scan on both changed files: passed

@alt-glitch alt-glitch added type/bug Something isn't working comp/plugins Plugin system and bundled plugins tool/vision Vision analysis and image generation provider/openai OpenAI / Codex Responses API P3 Low — cosmetic, nice to have needs-repro Bug needs reproduction steps labels Jul 15, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for carrying the proxy policy into the OpenAI image provider. The production change targets a live gap: current main still constructs this client with openai.OpenAI() at plugins/image_gen/openai/__init__.py:273, while agent/process_bootstrap.py:151-157 documents the shared transport's macOS system-proxy safeguard.

Problems

  • tests/plugins/image_gen/test_openai_provider.py:122 patches macOS proxy discovery but leaves explicit HTTP(S)_PROXY / ALL_PROXY variables intact. The helper intentionally honors those variables (agent/process_bootstrap.py:153-196), so the assertion can fail in a proxy-configured test runner. The analogous regression test explicitly clears them at tests/agent/test_auxiliary_client_proxy_env.py:27-29.

Suggested changes

  • Clear upper- and lowercase explicit proxy variables, plus NO_PROXY variants, before the patched getproxies() call. That makes the test specifically verify system-proxy bypass.

Automated hermes-sweeper review.

@@ -120,6 +121,24 @@ def test_config_top_level_model(self, tmp_path):
assert model_id == "gpt-image-2-high"
assert meta["quality"] == "high"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clear explicit HTTPS_PROXY/HTTP_PROXY/ALL_PROXY (including lowercase and NO_PROXY variants) before this test. build_keepalive_http_client() intentionally honors explicit proxy env vars, so this assertion can fail on a proxy-configured runner even though the macOS system-proxy bypass works. See tests/agent/test_auxiliary_client_proxy_env.py:27-29 for the established isolation pattern.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 16, 2026
The macOS system proxy bypass test previously only mocked
urllib.request.getproxies() but left explicit HTTP_PROXY / HTTPS_PROXY /
ALL_PROXY env vars intact.  The shared transport helper intentionally
honors those variables (agent/process_bootstrap.py:153-196), so a
proxy-configured test runner could cause the assertion to fail.

Mirror the pattern from tests/agent/test_auxiliary_client_proxy_env.py
and clear upper- and lowercase proxy env vars before the assertion,
so the test specifically verifies system-proxy bypass.

Review: NousResearch#64893 (review)
@GottZ

GottZ commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Summary

One PR addresses #64888. #64893 changes the image provider to use build_keepalive_http_client(base_url) for custom OPENAI_BASE_URL values, directly targeting the reported macOS system-proxy routing, and adds a regression test while leaving default client construction unchanged when no custom URL is configured.

Related pull requests

  • fix(image-gen): bypass macOS system proxy for custom endpoints #64893 best fix — (+41/-1) — n/a: The production diff passes the shared Hermes HTTP client to openai.OpenAI() for custom endpoints, addressing the reported proxy-policy gap. The contributor’s keep_open review flagged proxy-environment leakage in the test; the visible diff addresses that objection by clearing upper- and lowercase HTTP(S)_PROXY, ALL_PROXY, and NO_PROXY variables before asserting that no HTTPProxy transport is installed.

Suggested consolidation

Keep #64893 open with a salvage path: retain the targeted _openai_client_kwargs() production change and its focused regression test. This follows the contributor’s keep_open review, and the visible diff addresses that review’s documented test-isolation objection; there are no duplicate PRs to close.

Complex graph

flowchart LR
    classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
    classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
    classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
    classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
    classDef best stroke-width:3px,stroke:#b45309
    classDef target stroke-width:3px,stroke:#4338ca
    I64888(["issue #64888 (open)"])
    P64893["PR #64893 (open)"]
    P64893 -->|best fix| I64888
    class I64888 open
    class P64893 open
    class P64893 best
    class P64893 target
    click I64888 "https://github.com/NousResearch/hermes-agent/issues/64888"
    click P64893 "https://github.com/NousResearch/hermes-agent/pull/64893"
Loading

Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label).

Cross-PR triage: Reviewed 1 pull request and 1 issue in this complex. Each diff was read against this issue; Assessment working set: 3 kB of PR diffs, 7 kB of issue/PR text, 1 kB of discussion (1 comments), 2 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins needs-repro Bug needs reproduction steps P3 Low — cosmetic, nice to have provider/openai OpenAI / Codex Responses API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/vision Vision analysis and image generation type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: OpenAI image generation ignores macOS proxy exceptions for local/custom base URLs

4 participants