feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery - #35455
Conversation
Greptile SummaryAdds Anthropic-native model discovery responses to the existing authenticated model-list routes while preserving the default OpenAI response.
Confidence Score: 5/5The PR appears safe to merge with no concrete changed-code failure identified. The negotiated response is selected only for requests carrying the Anthropic-specific header, after the existing authorization and model-visibility filtering, while direct callers and default OpenAI clients retain their prior behavior.
|
| Filename | Overview |
|---|---|
| litellm/proxy/proxy_server.py | Negotiates the model-list response from the request header after existing authorization and visibility filtering, with no accepted correctness issue. |
| litellm/llms/anthropic/common_utils.py | Adds a focused formatter for the Anthropic Models API envelope, including safe empty-list handling. |
| tests/e2e/proxy_client.py | Adds deadline-aware continuous model-visibility polling before E2E callers use newly created deployments. |
| tests/e2e/transport.py | Adds an optional per-call GET timeout and propagates it through both HTTP and split transports. |
| tests/test_litellm/llms/anthropic/test_anthropic_common_utils.py | Covers the populated and empty Anthropic model-list envelopes. |
| tests/test_litellm/proxy/proxy_server/test_routes_models.py | Verifies header-based negotiation on both model-list route aliases while existing tests retain the default OpenAI contract. |
Reviews (1): Last reviewed commit: "fix(proxy): make model_list request para..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
chore(ci): promote internal staging to main
chore(ci): promote internal staging to main
…eat-anthropic-native-v1-models-2
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
| from litellm.llms.anthropic.common_utils import ( | ||
| create_anthropic_model_list_response, | ||
| ) |
|
@Ar-maan05 any update on this? We are running into the same issue in our org trying to implement LiteLLM |
|
This is green and merges cleanly, please review for merge. Worth adding max_input_tokens and max_tokens to the Anthropic entries, create_model_info_response already computes both |
…eat-anthropic-native-v1-models-2
Head branch was pushed to by a user without write access
|
|
e1f3d6e
into
BerriAI:litellm_internal_staging
Re-lands #30273 (reverted during staging). No functional changes to the original; rebased onto current main and refactored so the diff is purely additive.
The problem
Claude Code 2.1.126+ added gateway model discovery: when ANTHROPIC_BASE_URL points at a gateway, it queries {base_url}/v1/models at startup and populates the /model picker with the discovered models. That discovery only parses the Anthropic-native Models API shape, so against litellm - which returns OpenAI's {id, object, created, owned_by} list - Claude Code finds nothing and the picker stays empty, even though /v1/messages already works.
The fix
This serves the Anthropic-native shape from the same /v1/models route via content negotiation on the anthropic-version header. Claude Code already sends that header for /v1/messages, so when it is present the endpoint returns the Anthropic Models envelope (type / display_name / created_at per entry, plus top-level has_more / first_id / last_id); otherwise the response is byte-for-byte the existing OpenAI shape, so aider and other OpenAI-compatible clients are unaffected.
Entries also carry the model's token limits when litellm knows them: max_input_tokens as-is, and the output budget as max_tokens, the name the Messages API uses for it. Both come from create_model_info_response, the same helper the OpenAI listing goes through, so cost-map values and router-configured overrides resolve identically in either shape
A separate endpoint was not used because Claude Code discovers at the gateway root's /v1/models, and a global config flag would break the OpenAI clients that share the route.
Design notes
Tests
All three affected test files pass locally (215 tests). No server-side state or config changes.