Commit graph

46518 commits

Author SHA1 Message Date
mateo
b761277740 fix(models): drop inherited retirement dates from azure/us-gov entries pending a Government schedule source
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 15:09:49 +00:00
mateo-berri
6b83b16559 feat(gemini): day-0 pricing for gemini-3.8-flash
Gemini 3.8 Flash launches today with the same promotional pricing, limits,
and thinking settings as Gemini 3.7 Flash, so the gemini/, vertex_ai/, and
bare cost map entries mirror the 3.7 Flash ones. Regression tests lock the
launch prices, the 4096-token cache minimum, and the gemini-3 thought
signature gate in for the new model.
2026-09-02 08:04:14 -07:00
Oliver Jensen
8588a2ea42
fix(docker): install saml extra in litellm-backend image (#39291)
The monolithic images install the saml extra but the split backend image
did not, so /sso/saml/* returned 501 on Helm split-image deployments.
The gateway image is unchanged since /sso/ routes are backend-only.
2026-09-02 08:01:54 -07:00
mateo
a7836ede15 fix(models): absorb open registry PRs: govcloud bedrock and mantle, azure gov, openai tiered long-context, scaleway, together qwen3.8, azure ai cache and kimi k2.7 code, azure mai deprecations
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 14:48:51 +00:00
mateo
23977fc290 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_registry_audit_2026_09_01 2026-09-02 13:03:24 +00:00
mateo
1400070d71 chore(techdebt): clear fresh debt from the 2026-09-01 window
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 07:58:09 +00:00
mateo
385957e830 fix: reject constructor-managed router settings
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 07:49:25 +00:00
mateo
77aa22e065 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_techdebt_20260901 2026-09-02 07:44:53 +00:00
mateo
aba9644297 fix: avoid router settings update name collision
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 07:10:04 +00:00
mateo
95e09db661 style: apply ruff format to router settings merge
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 06:56:27 +00:00
Devin AI
2d643a8683 chore: merge litellm_internal_staging into litellm_realtime_router_session_model
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 06:37:16 +00:00
mateo
974b331a4d fix: accept persistable router settings
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 06:15:52 +00:00
mateo-berri
7cde2cd77f test(guardrails): type the presidio sibling test helpers precisely 2026-09-01 22:39:17 -07:00
mateo-berri
c18511be7d fix(guardrails): track and tear down presidio sibling callbacks
initialize_presidio registers up to three callbacks per guardrail but the
registry only kept the first, so deleting or re-syncing the guardrail left
the post_call siblings serving the old config. The initializer now returns
every callback it registered, the registry tracks primary and siblings per
guardrail id, delete purges all of them from every callback list, and
update pushes the new params into each while siblings keep their stage.
2026-09-01 22:28:38 -07:00
Mateo Wang
31ca4ddf32
Merge pull request #39166 from BerriAI/litellm_bedrock_bearer_token_converse_crash
fix(bedrock): stop Converse crashing on bearer-token auth without SigV4 credentials
2026-09-01 22:24:30 -07:00
James Liounis
e2c3f51c46
fix(search): forward search-tool params through the router, complete Parallel AI v1 param mapping (#37883)
* fix(search): forward search-tool params through the router, complete Parallel AI v1 param mapping

SearchAPIRouter dropped every parameter configured on a search tool, forwarding
only per-request kwargs. Any tool-level setting (mode, max_results, ...) was
silently lost on the way to the adapter, for every search provider.

Also completes the Parallel AI v1 search surface: after_date, fetch_policy,
location and include_domains now nest under advanced_settings instead of being
sent as unknown top-level fields, responses preserve search_id / session_id /
warnings / raw excerpts, and search cost is derived from the request mode and
the provider's reported usage rather than a single flat rate.

* fix(parallel_ai): stop a caller from pricing its own search request

`_parallel_ai_usage` carries the provider's reported usage into cost
calculation. It was only written when the response contained a usage block, so
a caller could pass `_parallel_ai_usage=[{"name": "sku_search", "count": 0}]`
and, whenever the provider omitted usage, bill $0.00 instead of $0.005 — the
value also reached the upstream request body as an unknown field.

The key is now stripped from inbound params and written unconditionally from
the parsed response, so only the provider can populate it.

* fix(parallel_ai): price fast search mode correctly

* test(parallel_ai): fake search at HTTP boundary

* fix(parallel_ai): tolerate null search result fields

---------

Co-authored-by: khushishelat <shelatkhushi@gmail.com>
2026-09-01 21:46:46 -07:00
moe-berri
6adc14b4b1 fix(router): preserve Claude subagent fallbacks 2026-09-01 21:13:45 -07:00
moe-berri
8a0967443d fix(router): isolate Claude session binding cache 2026-09-01 20:38:13 -07:00
mateo
1d3e26fd98 fix: preserve shared optional callbacks
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 03:28:04 +00:00
mateo
70a4f74a0d test: allow callback state fixture mutation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:56:23 +00:00
mateo
3dea586d3b test: cover runtime callback reconciliation
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:48:09 +00:00
mateo
7b86b7f4cd test: isolate router callback state
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:45:45 +00:00
mateo
e67f98feb1 fix: reconcile runtime pre-call checks
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:44:17 +00:00
mateo
29f0110fe0 test: pass request to config update test
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:29:41 +00:00
mateo
cb511f70cc fix: preserve config update authorization order
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:20:51 +00:00
mateo
0608f0a00f fix: reject unknown runtime router settings
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 02:17:02 +00:00
mateo-berri
f49a3e15a8 test(e2e): read JUnit properties off the real collected pytest Item
tests/e2e/test_junit_properties.py fed a hand-rolled FakeItem to
result_properties and attach_result_properties, both typed pytest.Item,
so uv run basedpyright tests/e2e reported 3 reportArgumentType errors on
litellm_internal_staging and every make check that scopes a litellm/ or
tests/e2e/ Python file failed.

Each test now looks up its own collected Item in request.session.items
and applies the covers marker at run time through request.applymarker,
so the coverage registry's collect-only pass never sees the test ids and
the production functions keep their pytest.Item signatures. No casts, no
ignores.

Resolves LIT-6669
2026-09-01 19:12:07 -07:00
mateo-berri
863199c09b Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_bedrock_bearer_token_converse_crash 2026-09-01 19:07:43 -07:00
mateo-berri
de0a4c1b0a Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_stream_usage_cost_default
# Conflicts:
#	litellm/responses/streaming_iterator.py
2026-09-01 18:53:50 -07:00
mateo-berri
0e7a05d878 test(bedrock): read the sent bearer header off the mock instead of a hand-rolled recorder 2026-09-01 18:46:41 -07:00
Mateo Wang
92d453373a
Merge pull request #39036 from BerriAI/litellm_fix_stream_modify_response_chunks
fix(guardrails): deliver modify_response block as valid SSE on streaming chat and Responses
2026-09-01 18:44:10 -07:00
Moe Khalil
46502f5804 Revert "fix(router): keep serving when Claude Code session router cleanup fails"
This reverts commit 2d4301589c.
2026-09-02 01:11:23 +00:00
Moe Khalil
2d4301589c fix(router): keep serving when Claude Code session router cleanup fails
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 01:10:31 +00:00
yucheng-berri
62f032cca5
fix(proxy): keep passthrough logging metadata and model_info dicts when team callbacks are wired (#39216)
* fix(proxy): keep passthrough logging metadata and model_info dicts when team callbacks are wired

Passing team callback vars into Logging(kwargs=...) makes get_litellm_params materialize a full litellm_params, where metadata and model_info default to None instead of being absent. Readers that resolve them as .get(key, {}).get(...) then raise, so any passthrough request from a team with logging callbacks 500s once a pre-call guardrail is on, and the router strategy loggers log a traceback per request.

* test(proxy): annotate the closure dicts the passthrough logging tests record into
2026-09-01 18:07:04 -07:00
Mateo Wang
364c9be2e0
Merge pull request #39211 from BerriAI/litellm_fix_default_api_key_limit_leak
fix: stop deployment default API key limits leaking into provider requests
2026-09-01 18:06:43 -07:00
yucheng-berri
4b87fd5718
fix: normalize provider-specific cache token fields in OTel v2 usage (#39202)
* fix: normalize provider-specific cache token fields in OTel v2 usage

* fix: use an immutable empty mapping for the cache token details fallback

* fix: ignore malformed cache token values instead of emitting or raising
2026-09-01 18:06:35 -07:00
devin-ai-integration[bot]
2b616fc479
feat(scim): add placeholder listing and merge so a shadowed account can be healed (#39231)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-02 01:04:53 +00:00
devin-ai-integration[bot]
6d0367ce35
feat(prometheus): expose per-key and per-team rate limit allowed and used gauges (#39236)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 18:03:18 -07:00
mateo-berri
6d8c18d518 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_gateway_injection_scope 2026-09-01 18:02:02 -07:00
tin-berri
81277252e1
fix(datadog_llm_obs): send tool calls, tool results and cache tokens in DD's own fields (#39222)
The LLM Obs callback copied litellm's OpenAI-shaped objects into the span
verbatim, so every field Datadog names differently landed somewhere it does
not read: tool calls kept their nested `function` wrapper instead of DD's
name/arguments/tool_id, tool messages carried no result linking them to their
call, the request's tools were never sent, and prompt-cache counts sat inside
meta.metadata rather than the span metrics its cache dashboards chart.

One rule governs the message mapper: add the fields Datadog declares, and never
destroy content it did not understand. Content collapses to its text only when
it has text, so a content list carrying tool or image blocks rides along
unchanged, and absent messages map to an empty input rather than a fabricated
turn. Tool calls and results are read from both dialects, the OpenAI
`tool_calls` / `role: tool` shape and the Anthropic `tool_use` / `tool_result`
content blocks, so /v1/messages sessions gain tool linking they never had.

Cache counts come from the same owners the savings dashboard uses, so every
provider spelling resolves through one place rather than a second local guess.
The three cache metrics partition the input count: litellm's normalized prompt
total includes both cache categories, as the cost calculator's pricing helper
documents, so the non-cached residual subtracts reads AND writes. Counting a
primed prefix as ordinary input had inflated non-cached usage by exactly the
cache-write count on every priming request.

Correlating a result to its call reads ids and names structurally and parses no
arguments, so a tool call's arguments are decoded once per span rather than
once per pass, and arguments past a size bound ship as the raw string instead
of paying a decode that multiplies memory on hostile compact JSON.

The flat `output_tool_calls.*` metadata copies go away with this: they were a
second representation of a fact that now has its own field on the same span.
2026-09-01 18:01:13 -07:00
tin-berri
48dd06e841
fix(bedrock): gate Converse cachePoint emission on model prompt caching support (#39210)
Bedrock rejects requests carrying cachePoint blocks for models whose entry in the cost map does not declare supports_prompt_caching (403 "You invoked an unsupported model or your request did not allow prompt caching"). Clients like Claude Code attach cache_control to every request, so any such model behind the gateway failed on every call. The new bedrock_model_accepts_cache_points predicate drops cachePoint emission for map-known non-caching models at all three emission funnels, keeps emitting for unmapped ids (application inference profile ARNs), and skips the gateway injection credit when the tool_config point is not placed.
2026-09-01 18:00:31 -07:00
devin-ai-integration[bot]
c001975152
fix(aiohttp_transport): map transport-internal CancelledError to a retryable ConnectError (#39240)
aiohttp shields its DNS resolution task; when the connector closes it cancels
that child, so the request task sees CancelledError without ever being
cancelled itself. map_aiohttp_exceptions() only caught Exception, so the
BaseException skipped transport mapping, router retries and proxy error
handling, and /v1/responses answered 500 "No response returned".

Catch CancelledError in the mapper, re-raise when the current task is really
being cancelled (Task.cancelling() > 0), and otherwise map it to
httpx.ConnectError so the usual retry, fallback and error mapping apply.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:55:47 -07:00
devin-ai-integration[bot]
93219a9257
fix(docker): install bedrock-realtime extra in monolith proxy images (#39223)
The Dockerfile, docker/Dockerfile.non_root and docker/Dockerfile.database uv sync stages never passed --extra bedrock-realtime, so aws-sdk-bedrock-runtime was absent from the image venv and Bedrock Nova Sonic /v1/realtime sessions failed with 'Missing aws_sdk_bedrock_runtime'. gateway/Dockerfile already had the extra (PR #34426).

Adds a static check over every uv sync in the proxy Dockerfiles and an image-level import probe that the image-scan workflow runs against the built root, non-root and gateway images.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:51:55 -07:00
devin-ai-integration[bot]
47b9d838aa
perf(scim): resolve group members with one user table read per member (#39228)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:49:40 -07:00
devin-ai-integration[bot]
04a25083a6
fix(cost-map): retry transient boot fetch failures and recover config deployments dropped by a stale cost map (#39230)
Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:49:06 -07:00
devin-ai-integration[bot]
69029c139e
fix(mcp): report per-server outcomes in aggregate REST tools/list (#39232)
GET /mcp-rest/tools/list without server_id returned only the tools of
the servers that answered and silently dropped any server whose listing
failed (for example an OAuth-protected server without credentials), so
clients could not tell a partial listing from a complete one.

The aggregate response now carries a server_outcomes map keyed by server
alias with the same classified outcome (ok/auth_required/forbidden/...)
that the MCP protocol path already puts in _meta. Healthy tools and the
HTTP 200 status are unchanged.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:48:01 -07:00
moe-berri
e3a61c82da test(router): register indirect session routing coverage 2026-09-01 17:46:41 -07:00
devin-ai-integration[bot]
b0041f32a2
fix(helm): reuse the generated master key Secret on helm upgrade (#39219)
The generated masterkey Secret rendered a fresh randAlphaNum value on every
release, so any helm upgrade with masterkeySecretName and masterkey unset
rotated the master key and invalidated every client holding the old one.
Look up the existing Secret in the release namespace and reuse its value,
falling back to a random key only on first install.

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-01 17:45:59 -07:00
mateo-berri
ac19d0dbdf fix(spend): keep every-deployment scope on gateway cache-injection marks
The caching-savings marker litellm_gateway_injected_cache credits gateway-earned
prompt-caching savings to the deployment it names, or to every deployment via
the empty-string sentinel. Two paths lost that scope:

- the router prompt-management factory stamps a provisional deployment's
  model_info into kwargs before the prompt pass runs, so an injection recorded
  there named that provisional pick and a differently-billed deployment lost
  the credit
- record_gateway_injection overwrote on every positive delta, so a per-leg
  stamp (the Bedrock converse tool_config one included) downgraded an
  existing every-deployment mark and the leg billed after a failover lost
  the credit

record_gateway_injection now takes injected_for_every_deployment, the two
pre-choice callers declare it, and an every-deployment mark is never narrowed
by a later per-leg stamp. Per-leg marks still overwrite each other. Spend
amounts are untouched; only the savings attribution is affected.

Also unblocks make lint at the staging tip: tests/e2e/test_junit_properties.py
landed three basedpyright reds via an e2e-only PR whose lint job skipped, now
suppressed as the deliberate duck-typed double they are.
2026-09-01 17:44:29 -07:00
moe-berri
82d046c428 fix(router): make Claude session cleanup best effort 2026-09-01 17:43:48 -07:00