Commit graph

51406 commits

Author SHA1 Message Date
Mateo Wang
4eb13a0b2a
Merge pull request #41843 from BerriAI/litellm_lit8064_unpin_derived_pricing
fix(proxy): unpin cost-map pricing copied into model_info and report pricing overrides
2026-09-18 22:58:04 -07:00
mateo-berri
5f6ffdc333 test: drop the docstring that restated the payload test's name 2026-09-18 22:48:42 -07:00
Yuneng Jiang
3d2ec85215
chore(proxy): keep the new config-owned refusals inside the LIT002 ceiling 2026-09-18 22:45:27 -07:00
Yuneng Jiang
3a480a5d6c
Merge remote-tracking branch 'origin/main' into litellm_settings_store_immutable 2026-09-18 22:39:29 -07:00
Yuneng Jiang
a987efca2c
fix(proxy): refuse runtime writes to config-owned settings
A write into a settings store for a key the config file declares used to
land in the runtime layer and then lose to the config on every read, so
the caller saw success while nothing changed. It now raises
ConfigOwnedKeyError, and the allowed-IP routes turn that into a 400
naming the key instead of reporting success on a list they never changed.

Both allowed-IP routes now build a new list rather than mutating the one
the config layer holds, and the os.environ resolver rebuilds the config
it is given instead of writing back into it, so a reader can no longer
corrupt the raw values the store keeps for provenance.

The database reload leaves a config-owned key alone rather than writing a
normalized copy back over it, which would now raise and abort the rest of
the reconcile pass.
2026-09-18 22:39:27 -07:00
Mateo Wang
b7f07469bc
Merge pull request #41564 from BerriAI/litellm_responses_bridge_message_item_lit4622
fix(responses): announce message item before text events in the chat completions bridge
2026-09-18 22:36:28 -07:00
mateo-berri
5783a38e27 fix(proxy): enforce the unified batch model grant before the DB shortcut and skip it for registry-routed vector store models
retrieve_batch returned a terminal batch from the DB before checking that the key may use the model encoded in a unified batch id; the grant check now runs right after pre-call processing. The vector store file list helper authorized data["model"] through handle_model_based_routing even when the vector store registry set it server-side and even with no caller, which crashed on a None key; it now authorizes only a caller-supplied hint and resolves credentials directly.
2026-09-18 22:30:07 -07:00
mateo-berri
ddac683ec6 fix(exceptions): keep internal_server_error as the public type of an upstream 500
PR #40243 started carrying the upstream error body on InternalServerError so the Responses response.failed event can report the provider's code and message, and openai's APIError.__init__ took the body's type along with it. The proxy then answered an OpenAI-compatible upstream 500 with type server_error while a 502 and a 503 kept internal_server_error, and the integration contract in test_observed_routing.py went red. Pin the type the way RateLimitError pins throttling_error, keeping the body.
2026-09-18 22:28:58 -07:00
mateo-berri
12f831e863 Merge origin/main into feat/websearch-multi-query-schema
Resolves handler.py against main's SearchOutcome refactor: the file is
main's version plus this PR's substantive hunks only (the RichWebSearchInput
import, the rich= wiring at the three _execute_search call sites, the
_rich_search_input and _provider_supports_rich_search helpers, and the
_execute_search forwarding), so the 88-column re-wrap noise the PR carried
is gone and the diff against main is the feature alone. RichWebSearchInput
sits beside main's new SearchSucceeded/SearchFailed types, and main's two
_execute_search test stubs accept the new rich argument.
2026-09-18 22:15:35 -07:00
yuneng-jiang
12ddb35aad
Merge pull request #41924 from BerriAI/litellm_role_permissions_normalization
fix(proxy): parse role_permissions where it is read
2026-09-18 22:15:20 -07:00
mateo-berri
f3b198c1b7 fix(mistral): accept user_data as the OCR file purpose and keep OCR cost warnings single-line 2026-09-18 21:56:43 -07:00
mateo-berri
fb76b67e78 Merge remote-tracking branch 'origin/main' into litellm_mistral_ocr_batches
# Conflicts:
#	litellm/batches/batch_utils.py
2026-09-18 21:51:33 -07:00
Mateo Wang
faed57f92c
Merge pull request #41918 from BerriAI/litellm_websearch_followup_api_base
fix(websearch): forward the deployment api_base to agentic follow-up calls on /v1/messages
2026-09-18 21:41:41 -07:00
mateo-berri
4468c9fdcb fix(responses): close the reasoning item before announcing the message item 2026-09-18 21:37:01 -07:00
Mateo Wang
078a60478f
Merge pull request #41485 from BerriAI/litellm_jwt_token_exchange_grant
feat(proxy): add RFC 8693 token exchange for IdP JWTs on the gateway token endpoint
2026-09-18 21:27:20 -07:00
Mateo Wang
b46612cfeb
Merge pull request #41893 from BerriAI/litellm_fix_responses_ws_encrypted_content_affinity
fix(responses): restore encrypted_content and apply affinity on the native WebSocket relay
2026-09-18 21:09:17 -07:00
kerry
ed0c32cdb0 test(integration): drive cost tracking from literal request/response data
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 04:04:40 +00:00
Yuneng Jiang
044f88ee91
fix(proxy): register transcribe as a known provider for model grants
#41515 added the cost map entry transcribe/StartTranscriptionJob under a
new litellm_provider value "transcribe" without registering that provider
anywhere else, so litellm.models_by_provider had no "transcribe" key.

test_models_by_provider derives its provider set from the cost map itself,
so it went red on main. The user-visible half is that get_provider_models
returned None for the provider, which get_known_models_from_wildcard turns
into an empty list, leaving a transcribe/* key or team grant resolving to
no models.

Mirror the aws_polly registration: an enum member, a model set, an
ingestion branch, and a models_by_provider entry. Amazon Transcribe is
reached through the pass-through route rather than the Add Model form, so
it joins the frozen unlisted set the Add Model drift test tracks.
2026-09-18 21:04:25 -07:00
Yujong Lee
1ee4b62e9c fix(rust): honor vertex_project, vertex_location and enable_azure_ad_token_refresh globals
Python resolves the Vertex project and location as call params, then the
litellm.vertex_project / litellm.vertex_location globals, then env, and
Azure AD token refresh from litellm.enable_azure_ad_token_refresh alone.
Native OCR skipped the globals, so a config.yaml litellm_settings value
silently fell through to the credential's project and us-central1, and a
managed identity setup without an API key failed. The bridge now reads
them through a provider_defaults settings group into OcrSettings, and
VertexConfig / AzureAuthInputs slot them in at Python's precedence.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 21:01:37 -07:00
Yuneng Jiang
800b09ba41
Merge remote-tracking branch 'origin/main' into litellm_role_permissions_normalization 2026-09-18 21:00:23 -07:00
Yuneng Jiang
ef34e44d8b
fix(proxy): parse role_permissions where it is read
load_config used to return a local general_settings dict that it had
normalized in place, turning the configured role_permissions entries into
RoleBasedPermissions objects. It now returns the SettingsStore, which never
saw that write, so JWT auth received raw dicts and every request failed with
"'dict' object has no attribute 'role'" whenever role_permissions was set.

Convert the entries in the consumer instead, with a TypeAdapter, so the value
is parsed wherever it comes from. load_config keeps validating at boot, so a
malformed entry still fails startup rather than the first request.
2026-09-18 21:00:18 -07:00
mateo-berri
33223920ca refactor(responses): build the routed websocket request and relay frames without in-place mutation 2026-09-18 20:57:56 -07:00
Yujong Lee
0d76359dc9 fix(rust): resolve OCR provider env fallbacks through the secret manager
Python reads every provider credential fallback (MISTRAL_API_KEY,
AZURE_AI_API_KEY, AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT, Azure AD and
Vertex env, ...) through get_secret_str, which consults the configured
key_management_system before os.environ. Native OCR read std::env
directly, so a key held only in the vault went missing and a stale env
copy silently won. OcrClient now carries an injected secret Lookup that
the connection exposes to providers and auth crates; the bridge backs it
with settings.secret -> get_secret_str, pure Rust keeps the process env.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:57:24 -07:00
Yujong Lee
c0705f31b4 fix(rust): read OCR env-backed constants instead of hardcoding their defaults
Native OCR hardcoded the default of five Python constants that come from
env vars, so an operator setting them saw no effect:
REQUEST_TIMEOUT (Rust used 600s, Python 6000s), MAX_IMAGE_URL_DOWNLOAD_SIZE_MB
(0 disables document downloads), AZURE_OPERATION_POLLING_TIMEOUT,
AZURE_DOCUMENT_INTELLIGENCE_API_VERSION and
AZURE_DOCUMENT_INTELLIGENCE_DEFAULT_DPI. OcrSettings reads them through
Lookup with Python's parsing, the bridge builds it per call and OcrClient
carries it into the connection. A zero per-call timeout now falls back to
REQUEST_TIMEOUT, matching `timeout or request_timeout`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:51:55 -07:00
Mateo Wang
c1de8665ff
Merge pull request #34267 from BerriAI/litellm_claude_code_gateway_protocol
feat(proxy): serve the Claude Code gateway protocol under /claude_code_gateway
2026-09-18 20:49:48 -07:00
Yujong Lee
d77c144c6c refactor(rust): split custom_httpx into litellm-http and the OCR handler
custom_httpx mirrored a Python module that mixes transport plumbing with
OCR orchestration. The transport half (media fetcher, transport errors,
request and header helpers) now lives in litellm-http next to the pool,
TLS, proxies and settings, and the OCR request handler moves to
base_llm/ocr/handler.rs. Drops the unused deserialize_optional_param and
stale dead_code allows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:46:36 -07:00
Yujong Lee
a41885e48e refactor(rust): read proxy env vars through the settings lookup
reqwest and hyper each read HTTP(S)_PROXY, ALL_PROXY and NO_PROXY from the
process on their own, so tests could not inject them and the pooled client
key ignored proxy changes. EnvironmentProxies now reads them through
Lookup with the same precedence hyper used, the resolved config carries
them (empty when the transport does not trust the env), and both the
provider clients and the media fetcher build from that one value.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:41:07 -07:00
yujonglee
1c432dbc5f
Merge pull request #41921 from BerriAI/litellm_agents_md_consolidation
chore: consolidate CLAUDE.md into AGENTS.md
2026-09-18 20:40:33 -07:00
Yujong Lee
caf37c8b6f refactor(rust): share settings lookup and layer merge through core-utils
Settings sources beyond HTTP (media fetch, Azure Document Intelligence,
Vertex, timeouts) need the same env lookup and precedence merge, so move
them out of litellm-http into core_utils::settings. Lookup readers name the
Python idiom they mirror: get keeps a present empty value like
os.getenv(X, fallback), truthy drops it like an `or` chain, enabled only
switches on for "true". SSL_CERT_FILE now reads through truthy, matching
Python's `if ssl_cert_file and ...` check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-18 20:36:07 -07:00
Mateo Wang
9486caf584
Merge pull request #41721 from BerriAI/litellm_vertex_chirp3_streaming_stt
feat(vertex_ai): stream Chirp speech-to-text over /v1/realtime
2026-09-18 20:34:56 -07:00
Yujong Lee
d8d0e343e1 docs: drop stale Black, MyPy, and isort mentions from README and pyproject
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:28:18 +00:00
Yujong Lee
3157a8a3ca docs: replace poetry run with uv run in script instructions
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:27:17 +00:00
Yujong Lee
92ea8adb3b docs: replace stale Black formatting instructions with ruff format
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:27:17 +00:00
kerry
57d2fefa8d test(integration): derive scripted shapes from litellm provider configs
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 03:16:16 +00:00
yujonglee
b00d066ec2
Merge pull request #41897 from BerriAI/litellm_rust_http_pool_ocr
feat(rust): add litellm-http client pool and inject it into the OCR route
2026-09-18 20:09:12 -07:00
kerry-berri
f26afabe6d
Merge pull request #41914 from BerriAI/litellm_xai_audio_transcription
feat(xai): add speech-to-text (Grok Voice Transcribe) via /v1/audio/transcriptions
2026-09-18 20:03:00 -07:00
kerry-berri
a1f3124e18
Merge pull request #41891 from BerriAI/litellm_overhead_window_from_proxy_receive
fix(timing): anchor response duration and overhead at proxy receive time
2026-09-18 20:01:31 -07:00
Yujong Lee
bae4f22d3a refactor(rust): merge http settings from per-source layers
Each source (per-call kwargs, environment variables, the Python module) now
builds an HttpSettingsLayer, and HttpSettings::from_layers merges them with
explicit precedence. The aiohttp and httpx proxy-env rule is resolved once in
the merge, so HttpSettings carries a single trust_proxy_env flag
2026-09-18 19:53:14 -07:00
mubashir1osmani
8cf2606e2d fix(batches): mask pre-signed request auth headers before raw-request logging
A pre-signed batch/file request (Mistral, Bedrock) carries its auth header
inside the transformed request body, which pre_call logs verbatim into
raw_request_typed_dict and raw-request callbacks, leaking the provider key.
Mask the nested headers channel before handing the request to pre_call.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-18 22:50:19 -04:00
Yujong Lee
80dbb2a28a refactor(rust): resolve the http client config through From and TryFrom
HttpClientConfig::resolve becomes From<&HttpSettings> for Resolution and client_builder becomes TryFrom<&HttpClientConfig> for reqwest::ClientBuilder, matching the rustls conversion. The verify decision moves into From<&HttpSettings> for Verify, and the proxy environment rule moves next to its flags as HttpSettings::trusts_proxy_env. The curve and cipher results are read with transpose and a default selection, which removes the tuple destructuring
2026-09-18 19:48:34 -07:00
Yujong Lee
ffbfe7205f refactor(rust): parse TLS settings through FromStr, From and TryFrom
KeyExchangeGroup and Tls12CipherSuite parse with FromStr and fail with Unsupported, so a setting rustls cannot honor is a typed error instead of a missing value. The cipher string conversions cannot fail and use From. The rustls ClientConfig is built with TryFrom<&HttpClientConfig>, and the built-in root store is constructed in one expression
2026-09-18 19:40:16 -07:00
Yujong Lee
51010ea486 feat(rust): serve every gateway HTTP setting natively instead of declining to Python
litellm-http now builds the rustls config itself, so one route-neutral place covers roots, the client certificate, ALPN, ssl_ecdh_curve and ssl_security_level. A curve picks the single key exchange group. A cipher string restricts the TLS 1.2 suites it names, and entries rustls cannot express, such as @SECLEVEL=1, are logged once and skipped.

user_url_validation and user_url_allowed_hosts are applied by the media fetcher. Document downloads honor the environment proxy whenever provider calls do, keeping the per-hop address check, and stay on the pinned resolver when no proxy applies.

AIOHTTP_SO_KEEPALIVE, AIOHTTP_TCP_KEEPIDLE, AIOHTTP_TCP_KEEPINTVL, AIOHTTP_TCP_KEEPCNT and AIOHTTP_KEEPALIVE_TIMEOUT map onto the client. A client= argument and a live SSLContext are ignored
2026-09-18 19:39:07 -07:00
Yujong Lee
fb41bc3ed6 revert(ocr): stop forwarding client= on the Python path
Python becomes a thin SDK interface over Rust, so a live Python HTTP client has no effect on either route. This puts the Python OCR path back to what main does
2026-09-18 19:39:07 -07:00
Yujong Lee
bf7d1c0733 chore: consolidate CLAUDE.md into AGENTS.md
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 02:30:35 +00:00
kerry-berri
c4ddea7cfc
Merge pull request #41917 from BerriAI/litellm_fireworks_cache_read_default_discount
fix(cost_calc): default fireworks cached input to the documented 50% discount when the map has no cache-read rate
2026-09-18 18:48:58 -07:00
Yujong Lee
0119f50015 fix(rust): restore the 10s connect timeout and share media clients across proxy settings
Python OCR passes the call timeout per request, so its connect timeout is the call timeout and never the 5s handler default. 10s is what every Rust route uses on main. The media client never uses a proxy, so trust_proxy_env no longer splits its pool key
2026-09-18 18:47:36 -07:00
Yujong Lee
c635c35b3d fix(rust): keep native OCR on the proxy by declining only a supplied client
The proxy attaches its shared aiohttp session to every request as shared_session, so declining on it sent every proxy OCR call to Python, which never uses that session for OCR. aclient_session is a litellm global and never a call argument, so that check could not match. The proxy-shaped lifecycle test now asserts the call was served by Rust
2026-09-18 18:47:36 -07:00
kerry
380ec1a004 docs(integration): keep cost map loading note in README
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 01:43:00 +00:00
kerry
6ccba7fdb5 test(integration): drive scripted wires and provider wiring from data
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 01:41:19 +00:00
kerry
4e38f1845d refactor(xai): move native stt routing opt-out behind the provider config
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-19 01:40:00 +00:00