Backport of #44614 to lts/1.108.x.
Cherry-picked from ba61ecdf57 (main). The line has no splits_stream_timeout on _update_kwargs_with_deployment, so only the _video_call_pin wrapping is added around deployment selection. The line has no litellm/llms/base_llm/videos/async_task_utils.py, so its _id_safe_name dedupe is applied to the dashscope video transformation that holds the same helper on this line.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Backport of #48490 to lts/1.108.x.
Cherry-picked from 76d001a7c0 (main). The line has no wildcard_routed_models helper and no get_models_by_pattern, so only wildcard_route_deployments is changed.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
completion() loaded the MCP gateway handler for any request with tools,
and the handler pulls in mcp 2.x only code, so tool calls failed on
installs with mcp 1.x (google-adk 1.36.1) or no mcp at all
Cherry-picked from 783cf06f31. Only conflict was import context in
litellm/responses/main.py
(cherry picked from commit 783cf06f31)
MiniMax-M3 reached its 2026-11-06 deprecation date in the cost map, which names MiniMax-M3.1-Flash as its successor
(cherry picked from commit 90f7ab6fe6)
The router-model pass-through dropped a Bedrock deployment's guardrailConfig, so converse, converse-stream, invoke and invoke-with-response-stream reached Bedrock unguarded while /v1/chat/completions on the same deployment was blocked. The signer now sends it the way Bedrock reads it, in the body for Converse and as the X-Amzn-Bedrock-Guardrail* headers for Invoke, replacing any guardrail the caller sent
Adapted to the line, which does not have #47040. The guardrail headers are merged through merge_bedrock_invoke_headers without the request metadata header, and the unit tests drop the request metadata assertions and the identity argument that only #47040 needs
Backports test-only changes from main so the line's integration signal stops reporting stale helpers as failures.
Gateway.database_url and Gateway.rows come from #47213 (fc27dfdc7d), and the name keyword on Scenario.model comes from #48917 (ebf84f8649). Only those hunks of tests/integration/_support/client.py are taken. The rest of #47213 gives each owned proxy its own database and Redis, which none of the line's tests need, and the workers field from a later main change is left out.
The MCP progress and cancellation test wraps its upstream in _acknowledge_notifications_after_dispatch, from #49967 (b5952f243a). The helper is already on the line.
The resent-failure retry predicate returned true for BaseException
subclasses such as asyncio.CancelledError, so a cancelled
acompletion_with_retries or aresponses_with_retries call could start
another provider call. Retry only Exception subclasses again, as
tenacity's default did, while still skipping a resent failure.
A transient 429 or 500 on a /v1/messages turn that carries a replayed encrypted
block was retried by an SDK call's num_retries loop, which sent the block again
until every retry was rejected. On async calls the loop then raised the first
transient error, so the turn failed instead of being sent again without the
block. The retry loop now stops at that rejection and passes it on, so the turn
is sent again once without encrypted blocks.
A rejected first try on a sync call also cleared the process-wide
litellm.num_retries, so later calls in the process were no longer retried. That
setting now stays as configured.
A /v1/messages turn whose replayed encrypted block the backend rejects is sent
once more without it. The rejected first attempt no longer fires failure
callbacks or releases its parallel slot and budget reservation, so only the
turn sent again is logged and counted.
Success logs for a Messages client now keep every reasoning item of a
non-streamed turn, matching the reply the client got.
This line's transform_request rewrites the logging call_type to responses, so the non-streamed reply read the Messages-client check after the rewrite and kept only the last reasoning item. The bridge handler now reads it before the request transform and passes it to transform_response, as the streamed path already does.
Backport of #49076 to lts/1.108.x.
Ported from cadfe1d179 (cursor/chatgpt-encrypted-reasoning-messages-1723) onto the line's pass_through/adapters layout.
The openai/ Responses path on /v1/messages had no retry, so a chatgpt/ block left in history answered 400 on every later openai/ turn. That path now sends the turn once more without encrypted reasoning, the same way the chat bridge does. The retry matches only invalid_encrypted_content or a "could not be verified" message naming the content, so the exception mapper's own hint no longer triggers it. The xAI web search keep path is backed out, since xAI sends no encrypted reasoning over the bridge.
Backport of 15e6017012 from #49076 to lts/1.108.x, ported by hand onto the pass_through modules.
Co-authored-by: DDT <141296842+Hugo-DDT@users.noreply.github.com>
A summary delta carries no item index, so the next item's summary joined the block that already got its signature. A thinking chunk after an indexed signature now opens a new block.
The backported Responses bridge tags each reasoning item's thinking block with its output index, but this line's Anthropic stream wrapper only opened a new block when the block type changed, so a second reasoning item of the same type was dropped. This ports the index check from #46863, which main already has.
The retry warning keeps provider, model, status, and error code, and leaves the ciphertext out.
Backport of the third #49076 commit to lts/1.108.x. Cherry-picked from c62c92d2ad.
Co-authored-by: DDT <141296842+Hugo-DDT@users.noreply.github.com>
With use_chat_completions_url_for_anthropic_messages on, an openai model with thinking enabled is rewritten to openai/responses/, which accepts the same organization's encrypted reasoning. The keep check now uses the same routing predicate, so turn 2 replays the block instead of stripping it.
* ci: run the dashboard API types check on every change that can alter the OpenAPI spec
* chore: shorten the spec_pattern comment to a pointer at the CI filter
* chore: drop the spec_pattern comment
* docs: name the full ui-api-types trigger set in the make check header and dashboard AGENTS.md
* test: check make check and CI pick the same files for the API-type sync
* ci: run the Terraform provider endpoint audit on enterprise route changes
* test: keep the Terraform trigger test in the mapped workflow test file
---------
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
(cherry picked from commit e73f06ecdc)
* test(mcp): move the MCP OAuth happy path from a live Linear e2e to an integration test
GitHub Actions now runs unit tests only, and the MCP OAuth happy path needed a
captured Linear browser login to click through a real consent page. The OAuth
flows it exercised are already integration tests against an owned
authorization-server double, except one behavior: the stored per-user token
must be served by a proxy process that never saw the consent, with no shared
Redis to fall back on. That case is now in test_mcp_oauth_flows.py
The e2e test, its owned-gateway helper, its workflow, the mcp_oauth_live marker
and the JUnit gate script only that workflow used are removed
* test(mcp): chat completions run an OAuth server tool with the caller's own stored token
* test(e2e): drop the Linear chat-completion MCP OAuth e2e and its helpers
The behavior it checked, a chat completion running an OAuth server's tool with
the caller's stored per-user token, is now an integration test in
test_mcp_llm_endpoints.py that needs no saved Linear browser login
* test(mcp): decode the stored per-user credential as urlsafe base64
The plaintext check used b64decode, which drops the - and _ of a urlsafe value
and raised on roughly one ciphertext in five
* test(mcp): drop the chat OAuth integration test that duplicates test_mcp_slots F2-chat
security/test_mcp_slots.py already sends a per-user OAuth token through
/v1/chat/completions and asserts the peer receives it. Every mutant the new test
killed was also killed by the existing suite, so it added no signal
(cherry picked from commit 44fcbc30b0)
* test(e2e): retire the quiet_stack lock
quiet_stack held an exclusive host-wide lock for six tests, draining every
other xdist worker while they ran. On the full e2e lane that left 35-38% of
worker time idle. Each of those tests now lives where it can run without
pausing the suite
- the two memory tests move to perf/ behind the perf marker, so the perf lane
runs them on its own fresh stack. Their refusing deployments use a literal
key because the perf stack carries no provider keys
- the stored-request size check from the memory test becomes an integration
test on an owned proxy that stores prompts
- the discount and margin spend-row tests are dropped from e2e. Their
breakdown assertions join the existing integration pricing test, which
already owns the discount and margin repricing flow
- the Bedrock guardrail cost test stays in e2e without the pricing reset
fixture, since nothing else on the stack writes pricing config now
- the MCP semantic tool filter test turns on a proxy-wide setting, so it gets
a new proxy_wide_config opt-in marker and runs after the main run
* test(e2e): register the claude_code deployments as one batch
The claude_code session fixture registered its 24 deployments one at a time on every xdist worker, and each one waited out the 15 s propagation window on its own, about 6 minutes per worker. ProxyClient.register_models posts the whole batch, polls each model until every replica serves it, then waits out propagation once from the last write. A model that fails to post or never becomes servable comes back as ModelNotRegistered, and an unservable one is deleted, so the fixture keeps reporting per-deployment failures the way it did
(cherry picked from commit b18188dee2)
Upgrade to MCP SDK 2.3.0 and raise the per-event SSE size cap so MCP
tool results over 1 MiB stop failing with "SSE stream ended without a
response"
(cherry picked from commit 4aec80f5ee)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Backport of #50300 to lts/1.108.x
Cherry-picked from 2b4485dee5 (main)
Conflicts in litellm/integrations/custom_guardrail.py and litellm/proxy/utils.py came from code the
line does not have (the pydantic import, _REQUEST_FIELDS and _guardrails_listed_in in
custom_guardrail.py, the stream token-id helpers in proxy/utils.py). Kept the line's code, added the
pick's helpers and pydantic import, and defined _REQUEST_FIELDS in both files next to the line's own
module-level TypeAdapter constants
Drops a second ScriptedBedrockInvoke class (F811) whose wider first definition already covers it, and a repeated supports_bedrock_native_structured_output key (F601) with the same value, both from merging two earlier backports. No behavior change.
Backport of the unmerged main fix to lts/1.108.x.
Cherry-picked from 92221383e5, 2d243a3f4a and c3a12326df (litellm_messages_reject_background).
Adapted to the line: background false worked here before, so false and null still pass and are left off the wire, while main answers 400 to any value.
Backport of the second #49076 commit to lts/1.108.x. Cherry-picked from 10c953d855.
Adapted to the line: chat_completion_ends_in_responses_api has no deployment_model_info
parameter here, so only tools, reasoning_effort, and api_base are threaded through, and
the moved tests import the adapters from pass_through instead of messages.
The chat bridge stored encrypted reasoning on reasoning_items, the Anthropic
adapter never read that field, stream chunks that only carried thinking
blocks were dropped, and the messages adapter stripped the signed blocks
before a chatgpt request could turn them back into reasoning items.
Backport of #49076 to lts/1.108.x. Cherry-picked from ea9e29b1a8 (cursor/chatgpt-encrypted-reasoning-messages-1723).
The line keeps the reasoning helpers in common_utils and the adapters under pass_through,
gains resolve_model_and_provider_for_metadata, and streams redacted_thinking as its own block.
Co-authored-by: DDT <141296842+Hugo-DDT@users.noreply.github.com>
Co-authored-by: DDT <1786035110@qq.com>