Skip to content

feat(providers): honor ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN#129

Open
kk7453603 wants to merge 1 commit into
firstbatchxyz:mainfrom
kk7453603:feat/anthropic-base-url-override
Open

feat(providers): honor ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN#129
kk7453603 wants to merge 1 commit into
firstbatchxyz:mainfrom
kk7453603:feat/anthropic-base-url-override

Conversation

@kk7453603

Copy link
Copy Markdown

What

Adds env-var overrides to AnthropicProvider so watchmen works against any
Anthropic-compatible proxy without code changes.

  • ANTHROPIC_BASE_URL — redirect the Messages API endpoint (z.ai,
    Bedrock reverse-proxy, Azure Anthropic, internal gateways).
  • ANTHROPIC_AUTH_TOKEN — switch auth from x-api-key to
    Authorization: Bearer (matches Claude Code's env semantics).

Env vars are read via config.read_env_var() — process env first, then
~/.config/watchmen/.env, same lookup path as every other watchmen env var.
Mirrors the official anthropic SDK's contract, so the same env that drives
claude / pi.dev drives watchmen.

ClaudePro (subclass) is intentionally untouched: its OAuth flow always
targets api.anthropic.com, an env override would break it.

Why

Users behind Anthropic-compatible proxies currently have to maintain a fork
just to change two hardcoded URLs (providers.py:294, providers.py:441)
and the auth header scheme. The env-var contract is the standard pattern —
the anthropic SDK, Claude Code, LangChain, and most third-party tools honor
these two variables.

Concrete use case: z.ai's Coding Plan gives Anthropic-API-compatible access
to GLM models at https://api.z.ai/api/anthropic. Verified end-to-end:

ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
  watchmen settings api-key --provider anthropic --set <zai-token>
# → ✓ valid · 8 models accessible

Changes

  • src/watchmen/providers.py:
    • endpoint: class attr → @property reading ANTHROPIC_BASE_URL
      (default unchanged).
    • headers(): bearer-path when ANTHROPIC_AUTH_TOKEN is set.
    • probe(): same env override for URL + auth.
  • tests/test_providers.py:
    • test_anthropic_headers_use_x_api_key: hardened — explicitly clears
      ANTHROPIC_AUTH_TOKEN so the test no longer leaks env contamination
      (pre-existing latent bug independent of this PR).
    • 4 new tests: default endpoint, env override, bearer auth, probe URL.

Backward compatibility

No behavior change when env vars are unset. All 568 existing tests pass.
Existing ANTHROPIC_API_KEY-only installs keep working as before.

Test plan

  • `uv run pytest tests/test_providers.py` — 40/40 pass (36 existing + 4 new)
  • `uv run pytest` (full suite) — 568/568 pass
  • Live probe against `https://api.z.ai/api/anthropic\` — `✓ valid · 8 models accessible`
  • Verified no behavior change when env vars unset (default endpoint preserved)

…nthropicProvider

Make the Messages API endpoint and auth scheme env-overridable so watchmen
works against any Anthropic-compatible proxy (z.ai, AWS Bedrock reverse-proxy,
Azure Anthropic, internal gateways) without code changes.

Changes to AnthropicProvider:
- endpoint: class attr → property that reads ANTHROPIC_BASE_URL (default
  https://api.anthropic.com). Trailing slash tolerated.
- headers(): when ANTHROPIC_AUTH_TOKEN is set, switch from x-api-key to
  Authorization: Bearer — matches Claude Code's env semantics so the same
  env that drives claude / pi.dev drives watchmen.
- probe(): same env override for URL + auth, otherwise `watchmen settings
  api-key --check` would always hit api.anthropic.com and report proxy
  tokens as invalid.

Env vars are read via config.read_env_var(), so they resolve from process
env first, then ~/.config/watchmen/.env — same lookup path as every other
watchmen env var.

ClaudePro (subclass) keeps its hardcoded endpoint + OAuth headers: that
flow always targets api.anthropic.com, env override would break it.

Tests:
- test_anthropic_headers_use_x_api_key: hardened — explicitly clears
  ANTHROPIC_AUTH_TOKEN so the test no longer flips auth schemes under
  env contamination (pre-existing latent bug).
- test_anthropic_endpoint_defaults_to_api_anthropic_com: backward-compat
  assertion — when env unset, endpoint is unchanged.
- test_anthropic_endpoint_honors_base_url_env: env override + trailing
  slash tolerance.
- test_anthropic_headers_use_bearer_when_auth_token_set: Bearer path.
- test_anthropic_probe_hits_env_base_url: probe honors env override for
  URL + auth. Patches httpx.get via monkeypatch (no module-swap leak).

All 568 existing tests + 4 new ones pass.

Verified end-to-end against z.ai's Anthropic-compatible endpoint:
  ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
  watchmen settings api-key --provider anthropic --set <zai-token>
  → ✓ valid · 8 models accessible
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.

1 participant