Commit graph

39445 commits

Author SHA1 Message Date
yuneng-jiang
6dc995d37f
Merge pull request #31177 from BerriAI/litellm_backport_1_87_x_stream_cost_0623
chore(release): backport #30787, #30788, #27346, #31035, #31133 to stable/1.87.x
2026-06-24 10:51:45 -07:00
yucheng-berri
36031e6c39
fix(docker): bump wolfi-base digest to patch openssl CVE-2026-34182 (#31133)
Re-pins LITELLM_BUILD_IMAGE and LITELLM_RUNTIME_IMAGE across all 6 Dockerfiles
from the prior digests (openssl 3.6.2-r3) to the current chainguard wolfi-base
digest c61ac691 (openssl 3.6.3-r2, >= the fixed 3.6.3-r0). The runtime stage is
the shipped image, so the runtime digest is what actually resolves the
customer-facing CVE; the build image is bumped too for hygiene. Two Dockerfiles
tracked a second equally-stale digest; both are unified onto the patched one.

(cherry picked from commit fda08dd727)
2026-06-23 21:16:15 -07:00
Yassin Kortam
b77cbbdcc9
fix(passthrough,streaming): recover cost on interrupted and agentic Anthropic streams (#31035)
Streaming and pass-through requests could be logged with $0 cost or dropped from
SpendLogs entirely while the upstream provider still billed every token. This
closes the leak paths not already covered by #30160, #30787 and #30788.

- Catch a stream_chunk_builder raise in the core CustomStreamWrapper (sync and
  async). Large agentic tool-use / thinking streams can make assembly re-raise
  as APIError from inside the except-StopIteration handler, where the sibling
  except does not catch it, so it escaped __next__/__anext__ and dropped the
  request; recover best-effort usage from the raw chunks instead
- Add a usage-only fallback for Anthropic streaming pass-through: when
  stream_chunk_builder returns None or raises, rebuild usage from the
  message_start / message_delta SSE events via AnthropicConfig.calculate_usage so
  cache, web-search and geo tokens are priced instead of left at $0
- Decode buffered pass-through bytes with errors="replace" so a stream cut
  mid-multibyte-sequence still logs the usage events already received
- Record response_cost into model_call_details on the pass-through success path
  (it is read from there, not from kwargs), matching the gemini/cohere/openai
  handlers
- Name the key (alias + masked key) in the virtual-key BudgetExceededError so
  operators don't have to reverse-map spend back to a key

(cherry picked from commit b24b964e04)
2026-06-23 21:16:15 -07:00
ishaan-berri
dabf43b594
fix: completion_cost AttributeError on streaming Anthropic web_search responses (#26153) (#27346)
* fix: coerce server_tool_use dict to ServerToolUse in Usage.__init__ (#26153)

* fix: coerce server_tool_use to ServerToolUse in stream_chunk_builder (#26153)

* fix: dict/pydantic-tolerant access in tool_call_cost_tracking (#26153)

* fix: dict/pydantic-tolerant access in anthropic cost_calculation (#26153)

* test: assert ServerToolUse type in existing stream_chunk_builder anthropic web search test

* test: regression test for #26153 (stream_chunk_builder server_tool_use type)

* test: dict/pydantic safety for tool_call_cost_tracking helper

* test: dict/pydantic safety for anthropic web_search cost

* refactor: consolidate _get_web_search_requests into shared cost-calc utils

* test(realtime): use gpt-realtime; openai retired gpt-4o-realtime-preview

OpenAI shut down the gpt-4o-realtime-preview family (incl. the undated
alias) on 2026-05-07, causing the live realtime test to fail with a
4000 invalid_request_error.invalid_model close. gpt-realtime is the GA
successor; switch the live-call tests to it, matching the base branch.

* refactor(types): drop redundant server_tool_use coercion in Usage.__init__

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
(cherry picked from commit 4a3860df1f)

[backport note -- stable/1.87.x] Aggregator-provenance pick, user-approved: #27346's
content reached litellm_internal_staging only via the squashed OSS sync (#29932 /
32c88ca74f), so merge 4a3860df1f is not an ancestor of staging tip; its post-image is
content-identical to staging. Also restored the 2-line server_tool_use dict->ServerToolUse
coercion in litellm/types/utils.py: it is #27346's own first commit, dropped from the squash
("refactor(types): drop redundant server_tool_use coercion") only because staging already
carried it via the OSS sync. 1.87.x predates that, and #31035's usage-only fallback needs it.
Mirrors the stable/1.88.x precedent (24b9655cd4).
2026-06-23 21:16:05 -07:00
Yassin Kortam
433d016f0c
fix(proxy): record partial spend on the failure row for interrupted streams (#30788)
A streaming request that breaks mid-flight, for example on a mid-stream read
timeout, still bills the provider for the chunks already delivered, yet the proxy
recorded that interrupted request as a zero-spend failure. An earlier revision
logged the recovered partial usage through the success path, which mislabeled a
failed request as a success and produced a misleading spend row

This recovers the partial usage where the failure is actually logged. The
streaming handler assembles the usage from the chunks seen so far and stashes it,
with its cost, on the logging object before firing the failure handlers. The
proxy failure hook lifts that usage and cost onto request_data before the
non-serialisable logging object is popped, and the spend-log writer records the
real partial spend on the failure row instead of a hardcoded zero;
get_logging_payload honors the recovered usage for the token columns and
_failure_handler_helper_fn preserves the recovered cost so the non-DB failure
loggers stay consistent

A request that recovers via a successful fallback is unaffected: the failure hook
only fires when the whole request fails, so the fallback's combined-usage success
row stays the single source of truth and there is no double counting

Resolves LIT-3825

Co-authored-by: veria-ai[bot] <224490171+veria-ai[bot]@users.noreply.github.com>
(cherry picked from commit 4847fa5dd5)
2026-06-23 21:00:05 -07:00
Yassin Kortam
58660e1c55
fix(passthrough): recover output tokens for interrupted anthropic streams (#30787)
(cherry picked from commit bd74c62ff1)
2026-06-23 20:44:26 -07:00
yuneng-jiang
dbe32d319e
Merge pull request #31166 from BerriAI/litellm_/xenodochial-mcclintock-9f21a9
chore(ui): rebuild dashboard build artifacts for stable/1.87.x
2026-06-23 20:15:44 -07:00
Yuneng Jiang
4866d65cd2
chore: update Next.js build artifacts (2026-06-24 03:11 UTC, node v20.20.2) 2026-06-23 20:11:59 -07:00
yuneng-jiang
d26bf1da35
Merge pull request #31159 from BerriAI/litellm_backport_1_87_x_no_mcp_sentinel
chore(release): backport #31029 to stable/1.87.x and cut 1.87.5
2026-06-23 20:01:25 -07:00
Yuneng Jiang
d00fbad49c
chore: refresh uv.lock for 1.87.5 2026-06-23 18:56:41 -07:00
Yuneng Jiang
598c73795b
bump: version 1.87.4 → 1.87.5 2026-06-23 18:56:03 -07:00
ryan-crabbe-berri
ade37bc049
feat(mcp): scope a key to zero MCP servers with no-mcp-servers sentinel (#31029)
* feat(mcp): scope a key to zero MCP servers with no-mcp-servers sentinel

A key under a team that has MCP servers had no way to opt out of them;
an empty list has always meant "inherit the team". This adds a
no-mcp-servers sentinel (mirroring no-default-models for models) so a key
can declare an explicit zero that overrides team inheritance, additive
grants, and allow_all_keys servers, surfaced as an exclusive "No MCP
Servers" option in the key create/edit UI.

* refactor(ui): centralize no-mcp-servers sentinel in a shared constant

The sentinel string was defined under two different local names and
inlined in two more files; a single exported constant removes the drift
risk flagged in review.

* fix(mcp): enforce no-mcp-servers sentinel on toolset-scoped routes

Toolset scoping replaced a key's mcp_servers with the toolset's servers,
dropping the no-mcp-servers sentinel, so a key opted out of all MCP could
still execute a granted toolset's tools via /toolset/{name}/mcp. Deny
toolset access when the key carries the sentinel, checked before the admin
branch to match get_allowed_mcp_servers.

(cherry picked from commit 19a29e0579)
2026-06-23 18:55:18 -07:00
yuneng-jiang
faa2f13a05
Merge pull request #30890 from BerriAI/litellm_backport_1_87_x_0620
chore(release): backport #29311, #29444, #29447, #29598, #30480, #30543, #30542, #30573 to stable/1.87.x and cut 1.87.4
2026-06-20 14:44:03 -07:00
Yuneng Jiang
963d0c2414
chore: refresh uv.lock for 1.87.4 2026-06-20 12:23:21 -07:00
Yuneng Jiang
147a63de35
bump: version 1.87.3 → 1.87.4 2026-06-20 12:22:17 -07:00
ryan-crabbe-berri
91c6fa975d
fix(guardrails): return 400 not 500 when AIM blocks a request (#30573)
* fix(guardrails): return 400 not 500 when AIM blocks a request

AIM guardrail blocks raised a bare HTTPException whose type and param
serialized as the literal string "None", which broke OpenAI-SDK error
parsing for downstream consumers. Switching AIM to raise a ProxyException
surfaced a second bug: the shared error funnel re-derived the HTTP status
from a nonexistent status_code attribute and downgraded the 400 to a 500.
The funnel now honors an already-normalized ProxyException rather than
rebuilding it, and ProxyException is excluded from llm_exceptions alerting
so a content-policy block no longer pages on-call as an LLM API failure

Resolves LIT-3751

* fix(guardrails): route all AIM rejection paths through ProxyException

The block-action fix left two AIM rejection paths raising a bare
HTTPException: the multimodal anonymize rejection and the output-side
block. Both serialized type and param as the literal string "None", the
same malformed shape the block fix removed. Funnel all three through a
shared _rejection helper so they return a conformant OpenAI error body.
The output block carries content_policy_violation; the multimodal
rejection stays a plain invalid_request_error because it is a usage
error, not a policy violation

Resolves LIT-3751

* fix(guardrails): record AIM ProxyException blocks in failure logs

Switching AIM blocks from HTTPException to ProxyException made
_is_proxy_only_llm_api_error return False for them, so
_handle_logging_proxy_only_error was skipped and the blocked prompt was
dropped from the configured failure loggers. Classify ProxyException as a
proxy-only error alongside HTTPException so guardrail blocks are recorded
again, matching the prior behavior. The llm_exceptions alert suppression
is a separate check and stays in place

Resolves LIT-3751

* style(guardrails): use str | None over Optional[str] in AIM _rejection

* style(guardrails): collapse AIM _rejection signature per black

(cherry picked from commit b5fcd859be)
2026-06-20 12:13:02 -07:00
Yassin Kortam
7b8a6d0885
fix(guardrails): stop re-initializing DB guardrails on every poll (#30542)
* fix(guardrails): stop re-initializing DB guardrails on every poll

InMemoryGuardrailHandler._has_guardrail_params_changed compared the
in-memory LitellmParams against the raw dict loaded from the DB. The
in-memory side carries every field default and coerces enums via
model_dump(), while the DB side only holds the keys originally stored,
so the two shapes never compared equal and the guardrail was rebuilt on
every poll cycle.

Each rebuild created a fresh instance, but delete_in_memory_guardrail
only removed the old callback from litellm.callbacks. Request handling
promotes guardrail callbacks into the success/failure/async lists, so
the previous instance stayed referenced there and instances accumulated.

Normalize both sides through LitellmParams(...).model_dump() before
diffing, and purge the callback from every callback list on delete.

* refactor(guardrails): narrow params-normalization fallback to ValidationError

The comparison normalizer caught a bare Exception and silently fell back
to the raw dict, which hid the cause and quietly degraded the affected
guardrail back to re-initializing on every poll. Catch only the
ValidationError that LitellmParams construction can raise, log a warning
so the offending row is diagnosable, and let any other error surface
instead of being swallowed.

* refactor(callbacks): add remove_callback_from_all_lists helper to manager

Move the knowledge of which callback lists a callback can be promoted
into out of the guardrail registry and into LoggingCallbackManager, where
the rest of the callback-list bookkeeping already lives. delete_in_memory_guardrail
now delegates to the new helper instead of iterating the lists itself.

(cherry picked from commit 9fa74ad8b4)
2026-06-20 11:57:13 -07:00
Yassin Kortam
d8f6bd1741
fix(guardrails): run pre_call hook once for model-level guardrails (#30543)
* fix(guardrails): run pre_call hook once for model-level guardrails

A CustomGuardrail attached to a deployment via litellm_params.guardrails
gets its async_pre_call_hook invoked twice per request: once by the proxy
pre-call loop and again by async_pre_call_deployment_hook after the router
spreads the model-level guardrails into the top-level request kwargs.

Record in request metadata that the proxy pre-call loop already ran a given
guardrail, and have the deployment hook skip it when the marker is present.
Direct-SDK usage never runs the proxy loop, so the deployment hook stays the
sole invocation there and still fires exactly once.

The marker key is stripped from untrusted caller metadata so a request body
cannot suppress a model-only guardrail by pre-seeding it.

* fix(guardrails): mark pre_call dedup on the post-hook request data

Record the exactly-once marker after async_pre_call_hook runs, on the data
object that flows downstream, rather than before it. A guardrail whose hook
returns a brand-new request dict (instead of mutating or spreading the one it
received) would otherwise discard the marker, letting the deployment hook
re-run the guardrail a second time.

(cherry picked from commit 4faeabc254)
2026-06-20 11:57:05 -07:00
Shivam Rawat
f1f8701d65
fix(integrations): cap Anthropic cache_control injection at 4 blocks (#30480)
* fix(integrations): cap Anthropic cache_control injection at 4 blocks

Respect Anthropic's 4 cache_control breakpoint limit by counting client-supplied blocks, skipping messages that already carry cache_control, and stopping further auto-injection once the limit is reached.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(integrations): reserve cache slot for tool_config and short-circuit cap

Address review feedback on the cache_control cap: break out of the injection loop before resolving target indices once the limit is reached, and reserve one of the four breakpoint slots when a tool_config injection point is present so the cachePoint appended by the Bedrock transform does not push the total past Anthropic's limit.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit fc9d789d24)
2026-06-20 11:55:38 -07:00
Mateo Wang
9fa03d4ee3
fix: passthrough endpoints duplicate logs (#29598)
* fix duplicate cost callbacks for anthropic streaming pass-through

Two bugs caused _PROXY_track_cost_callback to see stream=True +
complete_streaming_response=None on every streaming pass-through request,
making the dedup guard in dispatch_success_handlers permanently inactive:

1. pass_through_endpoints.py created the Logging object with stream=False
   for all requests. _is_assembled_stream_success short-circuits on
   self.stream is not True, so has_dispatched_final_stream_success was
   never set and any second dispatch went through unchecked.
   Fix: set logging_obj.stream = True after stream detection.

2. _create_anthropic_response_logging_payload set complete_streaming_response
   inside the try block after litellm.completion_cost(), so a pricing error
   caused an early return without setting it on model_call_details.
   Fix: set complete_streaming_response before the try block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix stream

* add stream to logging obj

* test(pass_through): give mock logging object a real model_call_details dict

The anthropic passthrough logging payload now records the assembled
response on model_call_details before cost calculation, which requires
model_call_details to support item assignment. In production it is always
a dict; the existing unit test stubbed the logging object with a bare Mock
whose attribute is not subscriptable, so the new assignment raised
TypeError. Use a real dict to match the production logging object.

* test(pass_through): cover streaming logging-obj stream flag

The streaming branch of pass_through_request that marks the logging object
as streaming (logging_obj.stream and model_call_details["stream"]) had no
unit coverage, so the patch coverage gate flagged it. Add a regression test
that drives a streaming pass-through request through pass_through_request and
asserts the logging object is flagged as a stream before dispatch.

* test(pass_through): cover SSE-response stream flag fallback branch

The auto-detected streaming branch of pass_through_request (when a request
that was not flagged as streaming returns a text/event-stream response) sets
logging_obj.stream and model_call_details["stream"] but had no unit coverage,
so the codecov patch gate failed at 60%. Drive a non-streaming pass-through
request whose upstream response is SSE through pass_through_request and assert
the logging object is flagged as a stream before dispatch.

* fix(pass_through): gate complete_streaming_response on stream flag

perform_redaction only scrubs complete_streaming_response when
model_call_details["stream"] is True. Setting it unconditionally for
non-streaming Anthropic pass-through responses left the assembled
response unredacted in model_call_details, which is handed to logging
callbacks as kwargs when message logging is disabled. Only record it for
actual streaming responses so redaction always applies.

---------

Co-authored-by: mubashir1osmani <mubashir.osmani777@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit 2bbdbfa5c3)
2026-06-20 11:55:29 -07:00
Mateo Wang
63a66efbbc
fix: stop use_chat_completions_api flag from leaking into provider request body (#29447)
* fix: stop use_chat_completions_api flag from leaking into provider request body

use_chat_completions_api is a LiteLLM control flag that forces the
/responses -> /chat/completions bridge. It was missing from
all_litellm_params, so get_non_default_completion_params treated it as a
model-specific param and forwarded it to the upstream provider. A
model-level "use_chat_completions_api: true" in the proxy config therefore
reached the chat-completions path and was rejected by strict providers
(OpenAI/Anthropic) with HTTP 400 for an unknown body field.

Register it as a known internal param so it is stripped on every path
(completion, the responses bridge that calls litellm.completion, and
filter_out_litellm_params).

Adds a regression test driving litellm.completion() with a mocked OpenAI
client that asserts the flag never reaches the request body.

* test: clarify extra_body assertion in use_chat_completions_api leak test

Replace the misleading 'not in ... or {}' precedence idiom with an explicit
parenthesized guard that also handles extra_body being None.

(cherry picked from commit 65b6e04da6)
2026-06-20 11:53:49 -07:00
Yassin Kortam
d3ee4103ab
fix(datadog): split oversized batches on 413 instead of re-queueing forever (#29444)
(cherry picked from commit fe108580d7)
2026-06-20 11:53:49 -07:00
Mateo Wang
5eb3fafd6e
[internal copy of #29089] fix: duplicate claude code traces (#29311)
(cherry picked from commit 581c30f1e8)
2026-06-20 11:53:06 -07:00
yuneng-jiang
5c8b847d8e
Merge pull request #30405 from BerriAI/litellm_backport_1_87_x_0613
chore(release): backport #29493, #29983, #29984, #29986, #30160, #30202, #30327, #30220 to stable/1.87.x and cut 1.87.3
2026-06-13 17:37:18 -07:00
Yuneng Jiang
88f33365a1
chore: refresh uv.lock and dashboard package-lock for 1.87.3
uv.lock: litellm 1.87.3, pypdf 6.13.1, tornado 6.5.7 (aiohttp held at 3.13.5).
package-lock.json: vitest family 3.2.6 and brace-expansion 5.0.6.
2026-06-13 16:37:32 -07:00
Yuneng Jiang
5ec458c48c
bump: version 1.87.2 → 1.87.3 2026-06-13 16:37:32 -07:00
Yuneng Jiang
14093fc4b7
chore(deps): bump pypdf, tornado, aiohttp constraints and vitest for stable/1.87.x
Backport of #30220 dependency bumps adapted to this line: pypdf pinned to
6.13.1 (this line exact-pins these dependencies), tornado and aiohttp held via
[tool.uv] constraint-dependencies (tornado>=6.5.6; aiohttp>=3.13.5,<3.14 so a
lock regeneration cannot move onto 3.14 while vcrpy is incompatible), and the
dashboard vitest devDependencies raised 3.2.4 -> 3.2.6. Locks refreshed in a
follow-up commit.
2026-06-13 16:37:06 -07:00
yuneng-jiang
323d11d489
fix(proxy): return deprecated-key lookup result directly in get_data combined view (#30327)
The grace-period branch assigned the recursive get_data result (a
finished LiteLLM_VerificationTokenView) back into the variable that the
combined-view dict normalization then subscripts, raising TypeError on
every request made with a rotated key inside its grace window; auth
surfaced that as a 401. Return the recursive result directly instead.

Regression test drives the full get_data flow: old hash misses the view,
deprecated table resolves to the active token, and the call must return
the view object

(cherry picked from commit 5047eaf7f0)
2026-06-13 16:21:13 -07:00
Sameer Kankute
e254e3e90e
fix(passthrough): skip [DONE] sentinels and non-JSON SSE frames in Anthropic streaming logging
Targeted subset of staging commit cfcdf8714a (#30202): only the
anthropic_passthrough_logging_handler.py hardening hunks and their four
tests are taken; the rest of that staging batch is intentionally excluded.

(cherry picked from commit cfcdf8714a)
(cherry picked from commit 973c7eb8d6)
2026-06-13 16:21:13 -07:00
Yassin Kortam
b5b86a3563
fix(passthrough): resolve costing model when body model is unknown (#30160)
(cherry picked from commit 1828a7c6f0)
2026-06-13 16:21:13 -07:00
Yassin Kortam
a41012cbf2
fix(proxy): return 5xx on DB infra errors during auth; reserve 401 for genuine auth failures (#29986)
(cherry picked from commit da9d64b4de)
2026-06-13 16:21:02 -07:00
Yassin Kortam
1fd61f2d20
feat(proxy): add option to disable server-side prepared statements for DB lookups (#29984)
(cherry picked from commit dff25fef44)
2026-06-13 16:08:56 -07:00
Yassin Kortam
25ea23cb0f
fix(proxy): recover from cached-plan errors by reconnecting the Prisma client (#29983)
(cherry picked from commit 3bd3951e37)
2026-06-13 16:08:30 -07:00
Armaan Sandhu
54b031b59c
feat(proxy): add disable_budget_reservation general setting (#27639) (#29493)
* feat(proxy): add disable_budget_reservation general setting (#27639)

* feat(proxy): register disable_budget_reservation in ConfigGeneralSettings (#27639)

* docs(proxy): document disable_budget_reservation concurrency tradeoff (#27639)

* ci: re-trigger flaky docker build (prisma generate ECONNRESET)

* fix(proxy): warn and document budget enforcement tradeoff when disable_budget_reservation is set (#27639)

(cherry picked from commit 1032dd751f)
2026-06-13 16:07:46 -07:00
Mateo Wang
1296275dc5
Merge pull request #30146 from BerriAI/litellm_fable5_stable_1_87_x
chore(release): backport Fable 5, batch-file auth, CrowdStrike AIDR, and Mantle Responses SigV4 to stable/1.87.x and cut 1.87.2
2026-06-10 21:47:54 -07:00
mateo-berri
f6bd1df2a0
style: format CrowdStrike parametrized test for this branch's black 2026-06-11 03:07:30 +00:00
mateo-berri
42d2ac2561
chore: refresh uv.lock for 1.87.2 2026-06-11 03:06:28 +00:00
mateo-berri
0494180e01
bump: version 1.87.1 → 1.87.2 2026-06-11 03:06:28 +00:00
Kent
63edbf3fa2
feat(bedrock_mantle): add SigV4/IAM auth to Responses API route (#29788)
Applied as the squash diff of PR #29788 (head 9800b2f17c), which landed
upstream inside the litellm_oss_staging_080626 sync (32c88ca74f, #29932)
and has no standalone commit to cherry-pick.
2026-06-11 03:03:39 +00:00
Kent
dad0894dff
feat(bedrock_mantle): route Responses API to native OpenAI endpoint (#29490)
Backport prerequisite for #29788. Applied as the squash diff of PR #29490
(head 50ab150fa6^..), which landed upstream inside the litellm_oss_staging_040626
sync (cb041966bf, #29671) and has no standalone commit to cherry-pick.
2026-06-11 03:03:22 +00:00
yuneng-jiang
88d9d5ea2b
fix(guardrails): read CrowdStrike AIDR identity from both metadata bags (#29991)
Capture user_id and extra_info from metadata or litellm_metadata. The single-bag read dropped identity whenever a request carried a present litellm_metadata field (null or a user-supplied dict), since /chat/completions routes the authenticated identity into metadata while the guardrail read litellm_metadata first

(cherry picked from commit 1bbaf1c39d)
2026-06-11 03:03:00 +00:00
Kenan Yildirim
a77bf66c71
feat(guardrails): capture user and model metadata in CrowdStrike AIDR
(cherry picked from commit 6fc715c5bd)
2026-06-11 03:02:23 +00:00
Sameer Kankute
403acba5ec
fix(proxy): authorize batch files using upload target_model_names (LIT-3593) (#30009)
* fix(proxy): authorize batch files using upload target_model_names (LIT-3593)

After replace_model_in_jsonl, body.model is a stripped provider id. Reverse-mapping it via resolve_model_name_from_model_id is first-match on model_list and caused false 403s when multiple deployments share the same stripped name. Use target_model_names from the unified file id instead.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(proxy): restore resolve_model_name_from_model_id for JSONL fallback path (LIT-3593)

Restores the reverse-lookup for the JSONL body.model fallback path so that
legacy/pre-target_model_names managed files still map stripped provider IDs
back to proxy aliases before auth. Also cleans up redundant `or None`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Revert "fix(proxy): restore resolve_model_name_from_model_id for JSONL fallback path (LIT-3593)"

This reverts commit 30d2e96f77.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit 2cd7e87485)
2026-06-11 03:00:42 +00:00
Mateo Wang
2de74e3199
Add Claude Fable 5 across Anthropic, Bedrock, Vertex AI, and Azure AI (#30064)
* Add Claude Fable 5 across Anthropic, Bedrock, Vertex AI, and Azure AI

Adds cost map entries for claude-fable-5 ($10/$50 per MTok, 1M context,
128K output, adaptive thinking only) on the Anthropic API, Bedrock
converse (base, global, and us/eu geo inference profiles at the 10%
regional premium), Vertex AI, and Azure AI (Microsoft Foundry, which
serves Fable 5 with the full 1M context window unlike Opus 4.8).

Registers anthropic.claude-fable-5 in BEDROCK_CONVERSE_MODELS, lists the
model in the setup wizard, and extends the reasoning effort e2e grid.
The Bedrock, Vertex, and Azure grid cells carry fail_reason markers
until the CI accounts are provisioned: Bedrock needs the provider data
sharing opt-in Fable 5 requires, and the Foundry resource needs a
claude-fable-5 deployment.

The first-party entry carries provider_specific_entry {us: 1.1} for the
inference_geo premium and deliberately no fast multiplier since Fable 5
has no fast mode.

https://claude.ai/code/session_01MZarYYT3aS7DxaNjoax6Gm

* Drop removed sampling params for Claude 4.7+ when drop_params is set

Fable 5, Opus 4.7, and Opus 4.8 removed sampling params: the API rejects
top_p, top_k, and any temperature other than 1 with a 400. LiteLLM was
forwarding them even with drop_params enabled because the Anthropic and
Bedrock converse transformations passed temperature/top_p through
unconditionally.

Mirror the GPT-5/o-series handling: temperature=1 still passes through,
other values and any top_p are dropped when drop_params is set, and
without drop_params a clean client-side UnsupportedParamsError tells the
caller how to opt in, instead of surfacing the raw provider error.

https://claude.ai/code/session_01MZarYYT3aS7DxaNjoax6Gm

* Drive sampling param gating from the cost map and cover top_k

Greptile review follow-ups on the sampling param fix: the restriction for
Fable 5 / Opus 4.7 / 4.8 is now declared as supports_sampling_params: false
on every affected cost map entry (perplexity excluded; that route is
OpenAI-compatible and maps sampling params upstream) and read back through
a tri-state map lookup, keeping the name check only as a fallback for
provider-routed ids whose hosted map entries predate the flag, the same
layering supports_adaptive_thinking uses. top_k bypasses map_openai_params
as a provider-specific kwarg, so it is gated at the shared
AnthropicConfig.transform_request boundary (direct, Bedrock invoke, Vertex,
Azure) and in the Bedrock converse _handle_top_k_value path, with
drop_params threaded through the converse transform helpers.

Also updates the reasoning effort grid cell count assertion for the four
Fable 5 rows added on this branch (29 x 11 cells).

https://claude.ai/code/session_01MZarYYT3aS7DxaNjoax6Gm

* Declare supports_sampling_params in the cost map schema

The model map validation schema uses additionalProperties: false, so the
new flag must be declared for the 28 entries that carry it; this was the
one failing job (misc / Run tests) on the previous commit.

https://claude.ai/code/session_01MZarYYT3aS7DxaNjoax6Gm

* fix(bedrock): gate top_k=0 on converse to match Anthropic boundary

Truthiness check let top_k=0 silently disappear on models that removed
sampling params, while AnthropicConfig.transform_request treats 0 as
present and raises UnsupportedParamsError (or drops when drop_params is
set). Switch to 'is not None' so converse, direct Anthropic, invoke,
Vertex, and Azure all behave the same for top_k=0.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-10 18:20:42 +00:00
Mateo Wang
cc9b99c2e3
Merge pull request #29645 from BerriAI/litellm_unbump_stable_1_87_x
chore: restore stable/1.87.x to 1.87.1 (revert premature 1.87.2 bump)
2026-06-03 21:54:19 -07:00
mateo-berri
515e8747f7
chore: restore stable/1.87.x to 1.87.1 (revert premature 1.87.2 bump)
The latest 1.87.x GitHub release is v1.87.0, so the branch should sit one patch
ahead at 1.87.1 as the patch-to-be. The GHSA-q775 backport (#29636) additionally
bumped 1.87.1 -> 1.87.2, cutting a version ahead of release. This reverts just the
version bump and its uv.lock refresh, keeping the backported fix and hardening
2026-06-04 02:38:20 +00:00
Mateo Wang
cc2aff371f
Merge pull request #29636 from BerriAI/litellm_cherrypick_1_87_2
chore(release): backport #29612 (session-token budget-ceiling exemption) into stable/1.87.x and cut 1.87.2
2026-06-03 19:20:41 -07:00
mateo-berri
efeb101ec6
fix(key_generate): harden GHSA-q775 session-token exemption against default_key_generate_params
Capture _requested_team_id before the default_key_generate_params loop runs and
key the UI/CLI session-token budget-ceiling exemption off it, instead of the
post-defaults data.team_id. On an install that sets
default_key_generate_params.team_id, a session token requesting a personal key
(no explicit team_id) would otherwise have data.team_id auto-filled, flipping
is_ui_session_team_key on and bypassing the delegated-authority ceiling -- the
exact escalation GHSA-q775 closed. Mirrors the existing pre-defaults capture of
_requested_max_budget. Adds a regression test.

https://claude.ai/code/session_01RT583b1khYC3wjLrQ5hT5h
2026-06-04 01:16:13 +00:00
mateo-berri
951012ccfe
chore: update uv.lock for 1.87.2 2026-06-04 00:06:48 +00:00
mateo-berri
d97882eea5
bump: version 1.87.1 → 1.87.2 2026-06-04 00:06:48 +00:00