fix: apply custom_headers to Anthropic requests and honor API context_length#2848
Open
romiluz13 wants to merge 1 commit intoantinomyhq:mainfrom
Open
Conversation
…_length Two bugs fixed: 1. Provider-level `custom_headers` from config are parsed but never injected into Anthropic HTTP requests. This breaks proxies that require alternative header names (e.g. Azure APIM's `api-key` instead of `x-api-key`). Fix: append custom_headers in `get_headers()` after standard headers. 2. The `Model` struct ignores the `context_length` field returned by the API's `/v1/models` endpoint. Instead, `get_context_length()` hardcodes all Claude models to 200K. This prevents operators from advertising larger context windows (e.g. 1M with the `context-1m-2025-08-07` beta). Fix: deserialize `context_length` from the API response and prefer it over the hardcoded fallback.
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.
Summary
Bug 1:
custom_headersnot applied to Anthropic requests — Provider-levelcustom_headersdefined in.forge.tomlare parsed during config loading but never injected into outgoing HTTP requests for Anthropic-type providers. This breaks any proxy that requires alternative header names (e.g., Azure APIM expectsapi-keyinstead ofx-api-key). Fixed by appendingcustom_headersinget_headers()after standard headers are built.Bug 2: API-reported
context_lengthignored — TheModelstruct in the Anthropic response DTO only deserializesidanddisplay_name, discarding thecontext_lengthfield returned by/v1/models. Instead,get_context_length()hardcodes all Claude models to 200K. This prevents custom providers from advertising larger context windows (e.g., 1M tokens with thecontext-1m-2025-08-07beta header). Fixed by addingcontext_length: Option<u64>toModeland preferring the API value over the hardcoded fallback.Motivation
When using Forge with Azure APIM-based proxies (which require
api-keyheader instead ofx-api-key), the[providers.custom_headers]config option has no effect for Anthropic providers. Users have to stand up a local reverse proxy just to translate headers — defeating the purpose of the config.Similarly, operators serving a custom
/v1/modelsendpoint that reports 1M context windows (enabled via the Anthropic beta header) cannot propagate that information to Forge because thecontext_lengthfield is never deserialized.Changes
crates/forge_repo/src/provider/anthropic.rsprovider.custom_headersinget_headers()+ testcrates/forge_app/src/dto/anthropic/response.rscontext_lengthfield toModel, prefer API value over fallback + testsTest plan
test_get_headers_includes_custom_headers— verifies custom headers are appended alongside standard headerstest_model_conversion_api_context_length_takes_precedence— verifies API-reported 1M overrides hardcoded 200Ktest_model_conversion_unknown_model_with_api_context_length— verifies unknown models work with API context_lengthcontext_length: Noneto match new struct fieldcargo testpasses (no Rust toolchain available locally — relying on CI)