Commit graph

47921 commits

Author SHA1 Message Date
mateo-berri
edde95197a test(proxy): cover every /v1/files route error type and param 2026-09-08 11:11:48 -07:00
mateo-berri
57fd8f6f49 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_openai_error_payload_non_llm_routes
# Conflicts:
#	litellm/proxy/anthropic_endpoints/endpoints.py
#	litellm/proxy/image_endpoints/endpoints.py
2026-09-08 11:09:54 -07:00
mateo-berri
deaadc21d3 fix(fireworks_ai): fold instructions and developer items into one leading system message on the Responses path 2026-09-08 11:08:03 -07:00
Mateo Wang
82e6b84f5a
Merge pull request #39384 from BerriAI/litellm_fix_invalid_index_after_migration_deadlock
fix(proxy-extras): rebuild indexes left INVALID by a migration deadlock
2026-09-08 10:35:40 -07:00
yassin
84a5136f45 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_invalid_index_after_migration_deadlock 2026-09-08 17:25:50 +00:00
Mateo Wang
9b74e6f34e
Merge pull request #40009 from BerriAI/litellm_lit_7039_least_busy_shared_counts
fix(least-busy): share in-flight request counts across proxy workers
2026-09-08 10:21:32 -07:00
Mateo Wang
f769aa4675
fix(router): give cooldowns their own cache so siblings see a bench in ~1s (#40025)
Cooldown entries rode the router-wide DualCache, which re-reads a key that is
missing from memory at most once every 10s. A deployment benched on one replica
therefore kept taking traffic on its siblings for up to 10 seconds, and the same
shared in-memory tier could evict a live cooldown once 200 unrelated router keys
crowded it out, which sent even the benching replica back to the dead deployment.

CooldownCache now owns a DualCache over the router's Redis with a 1s read
interval and an in-memory tier that only holds cooldown keys. Redis is attached
lazily because the router builds the cooldown cache before it wires Redis up.
2026-09-08 10:11:20 -07:00
yassin
eeef03f122 chore: merge litellm_internal_staging into litellm_lit_7039_least_busy_shared_counts
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 17:11:05 +00:00
Mateo Wang
a85c3152ca
fix(proxy): load db credentials in the model reconcile so a worker never serves a model before its credential (#39876)
* fix(proxy): load db credentials inside the model reconcile so a worker never serves a model before its credential

* fix(proxy): load db credentials in the model read-through so a request miss never adds a model before its credential

* fix(proxy): read credentials from the writer db before the router update and look a credential up once

* test(proxy): assert the credential is loaded when db models reach the router instead of the call order
2026-09-08 10:08:24 -07:00
yassin
6a30467948 chore: merge litellm_internal_staging into litellm_fix_invalid_index_after_migration_deadlock
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 17:07:34 +00:00
Mateo Wang
99824533ff
fix(proxy): kill the whole prisma process group when a boot migration command times out (#39509)
* fix(proxy): kill the whole prisma process group when a boot migration command times out

* fix(proxy): keep boot alive when the installed proxy extras has no prisma runner
2026-09-08 10:06:53 -07:00
devin-ai-integration[bot]
978f93ce9c
fix(tool_permission): log expected skip and deny events below WARNING (#40208)
The no-tools skip path in async_pre_call_hook now logs at DEBUG and the
denied-by-rule messages in async_pre_call_hook and _evaluate_tool_calls
log at INFO. The malformed tool arguments warning is unchanged. Adds
regression tests pinning each level

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 10:05:32 -07:00
Clement
95c0f9db7d
fix(router): rank streaming latency routing by raw TTFT, not TTFT per token (#40202)
* fix(router): rank streaming latency routing by raw TTFT, not TTFT per token

Latency-based routing divided time-to-first-token by completion_tokens
before storing it, so a deployment that streamed a long answer looked
faster to first token than one that answered briefly. TTFT is now stored
as plain seconds (first token time minus request start) in both the sync
and async success handlers, which is what the routing decision compares.

Non-streaming latency normalization per output token is unchanged.

Claude-Session: https://claude.ai/code/session_01Ttd5Q9ZhRPB4ch5guos3rj

* fix(router): store streaming TTFT under a seconds-only cache key

Workers on the previous release keep writing seconds-per-token samples
under "time_to_first_token" in the shared router cache during a rolling
deploy, so mixing the new raw-seconds samples into the same list averaged
incompatible units. Raw TTFT now lives under "time_to_first_token_seconds"
and routing reads only that key.

Also fix the regression test's token counts: with 50 tokens on the fast
deployment and 500 on the slow one the old per-token formula picks the
slow deployment, so the routing assertion now catches the bug.

Claude-Session: https://claude.ai/code/session_01Ttd5Q9ZhRPB4ch5guos3rj

* test(router): cover the TTFT sliding window from the unit-test shard

Move the TTFT list trimming checks from the CircleCI-only suite into the
mapped unit test file as one sync/async parametrized test, so the changed
lines in lowest_latency.py are exercised by the GitHub unit-test shard
that reports patch coverage.

Claude-Session: https://claude.ai/code/session_01Ttd5Q9ZhRPB4ch5guos3rj
2026-09-08 10:05:23 -07:00
Oliver Jensen
992ee37258
Update litellm/proxy/health_endpoints/_health_endpoints.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-09-08 13:21:45 +02:00
Oliver Jensen
78893723f7 fix(auth): drop env-credential hint from 401 when env login is disabled 2026-09-08 13:05:38 +02:00
Yuneng Jiang
0c519b162f
fix: preserve MongoDB deadlines and secure remote sidecar transport 2026-09-07 23:43:21 -07:00
tin-berri
1af7a403c6
feat(mcp): start the named server's OAuth directly for a resource-scoped gateway flow (#39933)
An aggregate gateway DCR authorize whose RFC 8707 resource resolves to exactly one
gateway-managed oauth2 server sealed that server into the flow and then sent the browser to
the generic connect grid anyway, so the user had to find the server the client had already
named and click Connect.

The connect URL now carries only the flow handle. GET /authorize/flow classifies the sealed
flow as unscoped, interactive, M2M, or stale, and returns the matching state to the page.
Interactive flows require a live per-user vendor credential before minting and do not burn the
flow on an early submit. M2M flows use the gateway's configured service credential and finish
without an interactive OAuth trip. Stale flows fail closed instead of becoming unscoped.
The existing explicit Finish action and a new Cancel path preserve deliberate user intent.
2026-09-07 23:40:02 -07:00
tin-berri
9a9b4c4c25
feat(ui): show auto-router classification rate (#40192) 2026-09-07 23:37:42 -07:00
tin-berri
1a6aa98230
fix(spend): compare auto-router targets by deployment identity (#40206)
Preserve deployment identity through savings calculation, with canonical model fallback only when either ID is absent. Cover negotiated rates, unchanged deployments, alias/base-model cache accounting and missing IDs.

Fixes #38811. Based on the deployment-identity approach proposed by @QuantumBreakz in #38834.

Co-authored-by: Claude Code <noreply@anthropic.com>
2026-09-07 23:29:42 -07:00
Yuneng Jiang
5c037299f4
feat: move MongoDB vector search to an optional sidecar 2026-09-07 23:02:27 -07:00
mateo-berri
3cadf2f8f7 test(azure_ai): charge the router fee over cached prompt tokens too 2026-09-07 22:35:19 -07:00
mateo-berri
5706952588 fix(azure_ai): drop gpt-chat-latest effort levels, test prices via calculator
litellm's azure_ai config rejects reasoning_effort for gpt-chat-latest and Azure documents a fixed reasoning level for it, so the entry no longer advertises reasoning_effort_levels. The catalog metadata tests compare cost_per_token and the whisper transcription cost with the entry the calculator read instead of with list-price literals, the pattern #40195 removed
2026-09-07 22:22:51 -07:00
mateo-berri
704013dbb6 fix(init): keep non-flag LITELLM_DROP_PARAMS values on with a warning
The merge base read the variable by truthiness, so any non-empty value
turned the global flag on. Parsing it as a flag made a value such as
temperature or enabled silently turn it off, and the only docs for the
variable describe it as a list of parameter names, so keep those values
on and log a warning that asks for true or false. A blank value stays off
without a warning
2026-09-07 22:13:23 -07:00
mateo-berri
08b60c409a refactor(guardrails): drop the unused rewrites_streamed_output hook
Nothing calls it since the streaming pipeline detects rewrites at run time
through the stream observer, so the base method and the content filter's
override were dead code with dead tests
2026-09-07 21:53:26 -07:00
mateo-berri
d08a177bc7 fix(policy_engine): keep a policy-added guardrail's other stages when a pipeline steps it
A policy that both adds a guardrail and steps it in a post_call pipeline
used to drop the guardrail from the request's guardrail list outright, so
its pre_call stage never ran. The per-hook loops already skip guardrails
by pipeline mode, so the mode-agnostic subtraction only lost coverage
2026-09-07 21:51:34 -07:00
mateo-berri
91fc1b2010 fix(policy_engine): record a streaming pipeline step once and in the applied guardrails header
CustomGuardrail.__init_subclass__ wrapped _StreamRewriteObserver.apply_guardrail in log_guardrail_information, so every streaming step recorded a second standard_logging_guardrail_information entry and span next to the inner guardrail's own. The observer's method now carries the marker that skips the wrapper. The step also adds the guardrail to the applied guardrails header the way the non-streaming unified path does, so streamed spend rows name the guardrail that scanned them
2026-09-07 21:48:19 -07:00
mateo-berri
69d2ac1edb fix(policy_engine): run iterator-hook guardrails whose post_call pipeline cannot stream
The streaming loop skipped every guardrail stepped by a post_call pipeline, even when the pipeline was dropped from the stream for lacking the unified apply_guardrail interface, so a default_on guardrail that only implements async_post_call_streaming_iterator_hook stopped governing streams it governed on the merge base. The skip set now comes from the pipelines that will gate the stream
2026-09-07 21:46:00 -07:00
mateo-berri
55c10c1983 fix(azure_ai): charge the router fee once for any router name and price grok-4-20 cache reads
Direct litellm.cost_per_token callers that name a Model Router deployment as
the model get the routing fee again, as they did before this branch, and the
fee is still charged exactly once on every completion_cost path. The
grok-4-20 entries bill cached prompt tokens at the input rate, since Azure has
no cached-input meter for them, and the model_router twin carries the same
limits and retirement date as model-router. The catalog test now exercises
the cost calculator and map relations instead of pinning map fields.
2026-09-07 21:34:34 -07:00
mateo-berri
c02f2dc0fe fix(azure_ai): keep the request_model keyword on cost_per_token
Restores the public keyword removed at 415bdbfd8f. A direct caller that
names the Model Router as the request model gets the routing fee folded
into the prompt cost once; completion_cost never passes it and charges
the fee through the additional-costs hook as before
2026-09-07 21:10:54 -07:00
mateo-berri
d594b9385e fix(drop_params): warn when a deployment or env drop_params value is not a flag
A deployment drop_params string that is not a flag value (a typo like ture) stayed silently off. The router now logs one warning per deployment. LITELLM_DROP_PARAMS and litellm_settings.drop_params share the same helper, so a non-flag value there warns as well instead of flipping silently from on to off
2026-09-07 21:05:01 -07:00
mateo-berri
415bdbfd8f fix(azure_ai): charge the Model Router fee once and correct catalog limits
The router fee was folded into azure_ai.cost_per_token and then added again
by the additional_costs hook, so every routed request paid it twice. The hook
now owns the fee, the entry named by the deployment supplies the price, and a
response priced as the router entry itself is not charged again

model-router, gpt-chat-latest and cohere-command-a carry the limits from the
Foundry models page, and model-router and grok-4-20-* carry their retirement
dates. The router tests now run at the completion_cost level with a Logging
object, which is the path the proxy takes, and fail at the merge base
2026-09-07 20:46:39 -07:00
Mateo Wang
9dbfb060bd
Merge pull request #39668 from BerriAI/litellm_lit6899_vertex_batch_tuned_endpoints
fix(vertex_ai): support fine-tuned Gemini endpoints in managed batches
2026-09-07 20:28:02 -07:00
Mateo Wang
ecd8bab0a6
Merge pull request #40195 from BerriAI/litellm_remove_static_cost_map_tests 2026-09-07 19:56:04 -07:00
mateo
adcfe8cb7f test: pin redirected xai slugs to the target's tier field set
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:44:52 +00:00
mateo
dc035cba62 test: preserve live xai pricing invariant
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:33:04 +00:00
mateo
5cfe20a68d test: collapse blank lines left by removed tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:21:55 +00:00
mateo
ac573fd66e test: remove remaining static cost assertions
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:20:39 +00:00
mateo
3023497590 test: drop static cost-map value assertions
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-08 02:19:32 +00:00
mateo-berri
0c6d4c5399 feat(cost_map): say on the card that Last run is deployment-wide while provenance is per worker 2026-09-07 19:06:30 -07:00
mateo-berri
b7c2decb7d fix(drop_params): honor string values in litellm_params and the LITELLM_DROP_PARAMS env var
get_litellm_params normalizes drop_params once, so a client-body string and
router_settings.default_litellm_params reach the anthropic, bedrock, and
azure_ai gates as a bool. LITELLM_DROP_PARAMS=false now means off. A value
that is neither a flag nor a string logs one warning and counts as unset,
both in the deployment validator and in litellm_settings.
2026-09-07 19:00:47 -07:00
mateo-berri
6076e9f611 chore(cost_calc): drop the query count section label comment 2026-09-07 18:54:31 -07:00
mateo-berri
a601c00afd fix(bedrock): pass litellm_params into the Bedrock embedding call so drop_params reaches Marengo 3.0 2026-09-07 18:47:25 -07:00
yujonglee
13df85cceb
test: add Rust extension pytest contract (#40181)
* test: add Rust extension pytest contract

* test: prove native OCR execution

* test: isolate Rust extension pytest collection

* ci: register Rust extension test coverage

* test: prove native OCR at wire boundary
2026-09-07 18:46:29 -07:00
mateo-berri
9c980b96d6 fix(budget_reservation): exempt vertex and bedrock count-tokens routes from budget reservation
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
Terraform Modules / fmt, validate, test (aws) (push) Has been cancelled
Terraform Modules / fmt, validate, test (gcp) (push) Has been cancelled
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
2026-09-07 18:44:04 -07:00
mateo-berri
80fea089b6 fix(bedrock): reject Marengo 2.7-only and misplaced media params on 3.0 unless drop_params
Marengo 3.0 requests now get a 400 naming any textTruncate, lengthSec,
useFixedLengthSec, or minClipSec parameter, and any video or audio option
sent with a text, image, text_image, or multi_input request, instead of
silently dropping them. drop_params (global, per deployment, or per
request) drops them instead. Pydantic validation errors name the field
and the reason, and the 3.0 marker is the exact "marengo-embed-3-" model
id segment.
2026-09-07 18:40:31 -07:00
ryan-crabbe-berri
ba91588b15 fix(proxy): price one cost estimate at one moment
The totals, the per-token-type lines and the reported rates each resolved off-peak pricing on their own clock read, so a quote taken as a window opened could bill on one side of the boundary and report rates from the other. /cost/estimate now pins a billing moment for the whole quote, and every rate lookup answers for the pinned moment instead of reading the clock again

Claude-Session: https://claude.ai/code/session_011Tn3657NkV6ojLqewL64Kb
2026-09-07 18:38:12 -07:00
mateo-berri
95402ccb71 test(azure_ai): move the Foundry catalog metadata test into the mapped azure_ai directory
The new metadata test sat at the top of tests/test_litellm. The azure_ai metadata tests live in tests/test_litellm/llms/azure_ai next to the cost calculator test, so this moves it there and bumps its repo-root lookup by the two extra directory levels. No test changes.
2026-09-07 18:36:40 -07:00
mateo-berri
bb52fd44fa fix(cost_map): label the card's loaded_at as per-worker and cover the integrity-failure fallback 2026-09-07 18:20:41 -07:00
mateo-berri
86790a7723 fix(bedrock): bill Marengo embeddings per request instead of per estimated token
AWS prices Marengo 2.7 and 3.0 text and image embeddings per request, never per
token, and their responses carry no token count. The old transform estimated
prompt tokens from the vector length, which billed a text request at 128 tokens
times the per-token rate (0.00896 instead of 0.00007). Marengo responses now
report zero tokens with query_count and image_count derived from the request
batch, and all six Marengo cost-map entries price per request (with the video
and audio per-second and per-image rates on the base entries). query_count is a
new prompt_tokens_details field wired to input_cost_per_query in the cost
calculator.
2026-09-07 18:20:28 -07:00
yucheng-berri
9bc9104102
fix(proxy): log budget reservation notice once at config load (#40167)
* fix(proxy): log disable_budget_reservation notice once at config load

The disabled-budget-reservation reminder fired as a WARNING inside request
authentication, so every authenticated request on a proxy that deliberately
set the flag produced one warning line. The notice now runs once per worker
when general_settings loads, at INFO, and the request path only skips the
reservation. Reservation skipping and read-time budget checks are unchanged

* fix(proxy): keep budget notice sentinel with constants

* fix(proxy): expose shared budget notice state
2026-09-07 18:18:28 -07:00