Skip to content

fix(cli): set User-Agent on /v1/models probe (Cloudflare 1010)#12999

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-738955d8
Apr 20, 2026
Merged

fix(cli): set User-Agent on /v1/models probe (Cloudflare 1010)#12999
teknium1 merged 1 commit into
mainfrom
hermes/hermes-738955d8

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Salvage of #12906 by @farion1231.

probe_api_models() sends requests with Python's default Python-urllib/3.x User-Agent. Custom Claude proxies fronted by Cloudflare with Browser Integrity Check reject that signature with HTTP 403 (error 1010). The blanket except Exception: continue swallows the error, surfacing as a misleading "Could not reach the API" message.

Changes

  • hermes_cli/models.py: Set User-Agent: hermes-cli/<version> in the probe headers dict
  • tests/hermes_cli/test_model_validation.py: 2 tests verifying UA is sent (with and without API key)

Validation

Before After
CF 1010 proxy 403 → swallowed → "Could not reach API" 200 → models listed

65/65 tests pass in test_model_validation.py.

Custom Claude proxies fronted by Cloudflare with Browser Integrity Check
enabled (e.g. `packyapi.com`) reject requests with the default
`Python-urllib/*` signature, returning HTTP 403 "error code: 1010".
`probe_api_models` swallowed that in its blanket `except Exception:
continue`, so `validate_requested_model` returned the misleading
"Could not reach the <provider> API to validate `<model>`" error even
though the endpoint is reachable and lists the requested model.

Advertise the probe request as `hermes-cli/<version>` so Cloudflare
treats it as a first-party client. This mirrors the pattern already used
by `agent/gemini_native_adapter.py` and `agent/anthropic_adapter.py`,
which set a descriptive UA for the same reason.

Reproduction (pre-fix):

    python3 -c "
    import urllib.request
    req = urllib.request.Request(
        'https://www.packyapi.com/v1/models',
        headers={'Authorization': 'Bearer sk-...'})
    urllib.request.urlopen(req).read()
    "
    urllib.error.HTTPError: HTTP Error 403: Forbidden
    (body: b'error code: 1010')

Any non-urllib UA (Mozilla, curl, reqwest) returns 200 with the
OpenAI-compatible models listing.

Tested on macOS (Python 3.11). No cross-platform concerns — the change
is a single header addition to an existing `urllib.request.Request`.
@teknium1 teknium1 merged commit 23b81ab into main Apr 20, 2026
3 of 6 checks passed
@teknium1 teknium1 deleted the hermes/hermes-738955d8 branch April 20, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants