feat(anthropic): support ANTHROPIC_CUSTOM_HEADERS for anthropic_messages models - #50796
Open
danliustc wants to merge 2 commits into
Open
feat(anthropic): support ANTHROPIC_CUSTOM_HEADERS for anthropic_messages models#50796danliustc wants to merge 2 commits into
danliustc wants to merge 2 commits into
Conversation
5 tasks
Contributor
|
Thanks for identifying a real Anthropic-wire gap. Current main still excludes custom-provider headers from this path: Problems
Suggested changes
This is an automated hermes-sweeper review. |
…ges models Custom models on the anthropic_messages wire format had no way to attach custom request headers: the OpenAI-side model.default_headers mechanism explicitly skips anthropic_messages/bedrock_converse modes, and the env var was not read anywhere. Add ANTHROPIC_CUSTOM_HEADERS (newline-separated `Name: Value` pairs, mirroring Claude Code's convention) and merge it onto the client-level default_headers in build_anthropic_client, the Entra-bearer-hook client, and the Bedrock client. User values take precedence over SDK/provider defaults (e.g. anthropic-beta) while preserving them, letting custom endpoints behind a gateway send headers like `x-project`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address hermes-sweeper review on NousResearch#50796: - Reuse the existing endpoint-scoped extra_headers resolution (hermes_cli.config.get_custom_provider_extra_headers) for Anthropic Messages clients, matching providers/custom_providers entries by base_url. Config headers take precedence over the env var. - Scope ANTHROPIC_CUSTOM_HEADERS to clients targeting an explicit custom base_url: native Anthropic (no base_url) and Bedrock never see it, so a proxy's tenant/auth header cannot leak to other providers. - Match config entries against both the caller's original base_url and its normalized (v1-stripped) form, since config may record either. - Add regression tests: bearer-hook constructor (env + config headers, beta preservation), Bedrock exclusion, native-Anthropic exclusion, config-over-env precedence, and normalized-URL matching. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
danliustc
force-pushed
the
feat/anthropic-custom-headers
branch
from
July 15, 2026 05:57
b8371ef to
7cc7476
Compare
Author
|
Thanks for the review — addressed in 7cc7476 (branch also rebased onto current main). Endpoint scoping (problem 1):
Test coverage (problem 2): added constructor-specific regression tests:
Docs updated to present config |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds support for the
ANTHROPIC_CUSTOM_HEADERSenvironment variable socustom(and other) models running on theanthropic_messageswire format can attach arbitrary request headers.Why
Custom models on the Anthropic-wire format had no way to inject custom request headers:
model.default_headersmechanism explicitly skipsanthropic_messages/bedrock_conversemodes (run_agent.py:4039returns early for those api_modes).ANTHROPIC_CUSTOM_HEADERSwas not read anywhere in the codebase.This blocks Anthropic-compatible gateways that require extra headers for project/tenant routing, WAF tokens, etc. (e.g.
x-project: <project>).How
_parse_anthropic_custom_headers()parses the env var following Claude Code's convention: oneName: Valuepair per line (newline-separated), whitespace-trimmed, lines without a:ignored._apply_anthropic_custom_headers()merges those headers onto the client-leveldefault_headers, with user values taking precedence over SDK/provider defaults (e.g.anthropic-beta) while preserving them.build_anthropic_client,_build_anthropic_client_with_bearer_hook(Azure Entra), andbuild_anthropic_bedrock_client.Usage
This mirrors Claude Code's
ANTHROPIC_CUSTOM_HEADERSconvention; the OpenAI-wire equivalent remainsmodel.default_headersinconfig.yaml.Tests
tests/agent/test_anthropic_adapter.py: single header, multiple headers, and no-op when unset. All pass.Docs
website/docs/integrations/providers.mdnext to theanthropic_messagescustom-provider example.🤖 Generated with Claude Code