Commit graph

13713 commits

Author SHA1 Message Date
devin-ai-integration[bot]
d392e7faae
feat(alerting): add native Microsoft Teams alerting destination (#38367)
* feat(alerting): add native Microsoft Teams alerting destination

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(alerting): preserve active destinations on MS Teams save and confirm health test delivery

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(ui): read persisted alerting destinations at MS Teams save time

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 16:19:22 -07:00
tin-berri
44d84360fb
fix(anthropic): carry the adaptive effort tier to every bridged Claude target (#38533)
/v1/messages forwarded `thinking` verbatim for a Claude-family model and then returned,
carrying `output_config.effort` only when the model string started with a Bedrock prefix.
Every other bridged provider got a bare adaptive thinking block, so the caller's effort did
nothing: max and minimal produced byte-identical upstream bodies.

Send those targets the tier as `reasoning_effort`, which is the param they take. Bedrock keeps
taking `output_config`, since the two are not interchangeable there: an application inference
profile ARN resolves to no chat config, so `reasoning_effort` is dropped and the tier vanishes,
and a provider that rebuilds `output_config` from it overwrites a caller-set `thinking.display`
on the way. The tier stays a plain string, the summary already travelling inside the forwarded
`thinking` block. Adaptive with no tier, and budgeted thinking, both stay exactly as they were.
2026-08-27 15:48:42 -07:00
tin-berri
30ff3723b2
feat(model_prices): let a map entry declare its exact reasoning_effort levels (#38481)
Kimi K3 accepts exactly low, high and max, defaults to max, and always thinks.
The map could not say that: medium and high have no supports_*_reasoning_effort
flag because every other reasoning model takes them, so the ten kimi-k3 entries
carried supports_reasoning alone and resolved to unknown. The dashboard then fell
back to a capability-blind level list that deliberately omits max, which is why a
kimi-k3 tier cannot be set to max thinking today.

Add reasoning_effort_levels, an array key in the shape the map already uses for
supported_endpoints and supported_modalities. Where present it is read first and
wins whole; every other entry keeps answering through the per-level flags,
unchanged. It is deliberately a different name from the computed
ModelGroupInfo.supported_reasoning_efforts, which stays derived from a group's
deployments and is never seeded from one deployment's model_info.

The levels are per entry rather than per model, because the deployments differ:
Moonshot, Together, Fireworks and Azure Foundry all forward the level unchanged
and get the model's own low/high/max, while Perplexity documents a six-value
enum it maps down internally and gets that. The /v1/messages degradation chain
consults the same declaration, so the level the map advertises is the level that
path forwards.
2026-08-27 15:38:01 -07:00
Mateo Wang
a6816f0e96
Merge pull request #38486 from BerriAI/litellm_together_glm53_flash
feat(together_ai): add zai-org/GLM-5.3-Flash to the model registry
2026-08-27 15:24:30 -07:00
yuneng-jiang
9d1348c1a4
Merge pull request #38575 from BerriAI/litellm_e2e-vision-own-image
test(e2e): serve the vision image from our own fixture
2026-08-27 15:24:09 -07:00
Mateo Wang
4ef1c28877
Merge pull request #38431 from BerriAI/litellm_fix_messages_native_tools
fix(anthropic-adapter): pass provider-native and OpenAI-format tools through on /v1/messages
2026-08-27 15:24:07 -07:00
Mateo Wang
649dc23d6a
Merge pull request #38465 from BerriAI/litellm_lit6103_tool_reference_passthrough
fix(anthropic): carry tool_reference tool results through the guardrail translation round trip
2026-08-27 15:23:51 -07:00
Mateo Wang
0c0a1f4eb1
Merge pull request #38457 from BerriAI/litellm_realtime_audio_output_tokens
fix(realtime): bill Gemini Live native-audio output tokens at the audio rate
2026-08-27 15:23:46 -07:00
Mateo Wang
66ea1bbbe8
Merge pull request #38458 from BerriAI/litellm_streaming_flex_service_tier
fix(streaming): preserve provider service-tier metadata so Vertex flex streams bill at flex rates
2026-08-27 15:23:43 -07:00
Mateo Wang
e5b2f5bec2
Merge pull request #38561 from BerriAI/litellm_transcription_srt_vtt_synthesis
fix(transcription): synthesize srt/vtt output for adapters without native subtitle formats
2026-08-27 15:23:38 -07:00
Mateo Wang
55c1537497
Merge pull request #38376 from BerriAI/devin_ai_bedrock_guardrail_external_id
fix(guardrails): forward aws_external_id when the bedrock guardrail assumes a role
2026-08-27 15:22:11 -07:00
Mateo Wang
dc1b847c4f
Merge pull request #38280 from BerriAI/litellm_together_cache_pricing
fix(cost): apply Together AI cache read pricing and per-model registry rates
2026-08-27 15:20:09 -07:00
mateo-berri
1665214bbd feat(together_ai): flag prompt caching on GLM-5.3-Flash like its sibling entries 2026-08-27 15:13:42 -07:00
mateo-berri
ae89f9cf74 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_together_glm53_flash 2026-08-27 15:12:35 -07:00
Mateo Wang
a2c814654e
Merge pull request #38449 from BerriAI/litellm_dashscope_qwen_image_3
feat(dashscope): support qwen-image-3.0 and qwen-image-3.0-pro image generation
2026-08-27 15:08:39 -07:00
Yuneng Jiang
49170695ce
test(e2e): drop the fixture helper docstring
The why belongs in the commit message and the PR, not above a one-line
helper whose name already says what it returns.
2026-08-27 14:50:17 -07:00
Mateo Wang
7083c47998
Merge pull request #38263 from BerriAI/litellm_together_reasoning_effort
feat(together_ai): map reasoning_effort per model class
2026-08-27 14:42:07 -07:00
mateo-berri
9e9c7e621f Merge branch 'litellm_internal_staging' of https://github.com/BerriAI/litellm into litellm_together_reasoning_effort
# Conflicts:
#	litellm/llms/together_ai/chat/transformation.py
#	tests/test_litellm/llms/together_ai/chat/test_together_ai_chat_transformation.py
2026-08-27 14:33:47 -07:00
tin-berri
40ff01b987
feat(mcp): let a resolved OAuth token target a custom upstream header (#38456)
An MCP server behind an API gateway needs two credentials on one request: the
gateway's own token on a private header, and a separate bearer on Authorization
for the server behind it. Every arm that minted or held a token hardcoded
Authorization, and the conflict rule then dropped the operator's static
Authorization to make room, so the second credential never arrived.

ApiKeyConfig already modelled this as header_name plus value_prefix behind a
header() method. Extend that carrier to the four minted-token configs, have each
resolver arm ask its config which header to use instead of naming one, and drop
only the header the resolved credential is about to occupy.

Operators set it per server via upstream_token_header, plumbed through
config.yaml, the credentials blob, the management API and the admin form, on the
M2M, token-exchange, authorization-code and ID-JAG arms. It is non-secret so it
stays plaintext and round-trips on admin reads. Unset keeps today's behaviour.

Moving a credential off Authorization means it stops inheriting what Authorization
gets for free, so the slot now carries those protections itself. httpx drops
Authorization when a redirect crosses origin and keeps every other header, so a
custom slot is dropped by the client on the same condition, mirroring httpx's own
scheme/host/port rule with an agreement test that fails if the two ever diverge.
The v1 path also mirrors the v2 conflict rule, so an injected header cannot shadow
the credential the gateway resolved for that slot.

Which header a credential occupies, and what counts as being that header, was
answered independently in nine places by four hand-rolled comparisons. same_header,
has_header and without_header in litellm/types/mcp.py are now the one owner, shared
by both MCP stacks, and the client derives its slot once instead of three times.

The header name reaches egress verbatim, so the RFC 7230 grammar lives in one
place and is checked where servers are built: a bad value fails the config load
and the management API returns 400, rather than raising while a spec is built
and emptying the aggregate tool list for every other server. A blank means unset,
matching what the endpoint already accepts.
2026-08-27 14:32:01 -07:00
Yuneng Jiang
ff418ffb9c
test(e2e): serve the vision image from our own fixture
The two vision tests pointed at a Wikipedia-hosted cat photo, so every run
depended on upload.wikimedia.org staying up and unthrottled. It throttled,
and the 429 surfaced as a bedrock APIConnectionError, which reads as a
gateway failure rather than what it was.

The image is now a fixture in the repo, passed as a data URL. That also puts
the two providers on the same bytes: litellm downloads the image itself for
bedrock, while openai is handed the link and fetches it from its own servers,
so the hosted URL quietly meant the two tests were not testing the same thing.

The image was generated for this repo rather than borrowed, so nothing here
carries a third-party license. Also drops a stale comment about openai prompt
caching that sat above the vision helper; no caching test uses it.
2026-08-27 14:29:53 -07:00
mateo-berri
dbadee7210 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_together_cache_pricing
# Conflicts:
#	litellm/model_prices_and_context_window_backup.json
#	model_prices_and_context_window.json
#	tests/test_litellm/test_cost_calculator.py
2026-08-27 14:29:46 -07:00
mateo-berri
c860d511db Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_realtime_audio_output_tokens 2026-08-27 14:25:08 -07:00
yuneng-jiang
852cb3abbe
Merge pull request #38567 from BerriAI/litellm_together-parallel-tool-calls
test(e2e): let the together tool tests accept parallel calls
2026-08-27 14:24:18 -07:00
Mateo Wang
5cab47ee3e
Merge pull request #38487 from BerriAI/litellm_fix_together_ai_fail_open_test
test(together_ai): assert fail-open supported params for models missing from the registry
2026-08-27 14:23:19 -07:00
Mateo Wang
67c7b97fd2
Merge pull request #38207 from BerriAI/litellm_registry_audit_bedrock_sol_anthropic_1hr
fix(model_prices): rolling registry audit - verified models and rates for Novita, DeepInfra, W&B, Bedrock Sol, Gemini, Fireworks, Azure gpt-5.6, Mistral, Together
2026-08-27 13:42:51 -07:00
Mateo Wang
0441faadca
Merge pull request #37833 from BerriAI/litellm_deflake_20260821
fix: roll up the open deflake fixes for the MCP logging queue, PTU rollup, license gate, and pricing test isolation
2026-08-27 13:42:26 -07:00
yucheng-berri
88cb83484b
fix(otel): anchor MCP tool-call spans to the gateway's own trace, link the client's context (#38317)
Under otel_v2, a client that propagates W3C trace context in params._meta
(SEP-414) pulled the tools/call span out of the gateway's trace:
resolve_mcp_span_context parented the MCP span to the client's remote
context and demoted the gateway's own transport span to a span link. The
gateway's tracing backend only ever receives the gateway's half of such a
trace, so the span was unreachable from the trace view and the POST
transaction showed a dangling link.

Invert the anchoring: the MCP tool-call and tools/list spans now always
nest under the transport span of the request carrying the message, and the
client's propagated context is recorded as the span link instead, so the
correlation survives while every trace stays renderable. With no transport
at all the span roots its own trace and still carries the link, keeping a
single shape for the event. Both returned contexts are built on an
explicitly empty base so ambient session state can never leak in, and the
span inherits the transport's sampling decision like every other
request-level span.
2026-08-27 13:41:30 -07:00
mateo-berri
5d8eb049b5 fix(transcription): drop words from srt/vtt replies when synthesis falls back 2026-08-27 13:36:31 -07:00
Yuneng Jiang
2cab010c73
test(e2e): check the tool input on the messages path too
The /v1/messages validator checked a tool_use block's name and id but not its
input, so a block whose location came back empty or wrong still passed, while
the chat side rejected the same damage. That gap predates this branch; it is
worth closing here because the point of the change is that every parallel call
is checked rather than counted.

AnthropicContentBlock now declares input as a typed field. It already survived
on extra="allow", but reaching it from a test needs a real field to keep the
e2e basedpyright gate at zero. Serialization is unchanged: bodies are dumped
with exclude_none, so a block without an input still replays exactly as before.
2026-08-27 13:34:09 -07:00
yuneng-jiang
c39bf62936
Merge pull request #38448 from BerriAI/litellm_/e2e-test-coverage-c87d3a
test(e2e): cover key generate and update on the Admin UI path
2026-08-27 13:29:33 -07:00
Yuneng Jiang
474fbea81f
test(e2e): let the together tool tests accept parallel calls
The together backend is picked as the cheapest chat row that supports both
tools and reasoning, which currently resolves to together_ai/openai/gpt-oss-120b.
That row is marked supports_parallel_function_calling, so one weather prompt
can legitimately come back as several get_weather calls. Both tool tests
asserted exactly one call, so a parallel answer failed them even though the
gateway handled it correctly.

They now check every returned call instead of counting them: each one has to
be a get_weather naming Paris, with an id a tool result can answer. Dropping,
misnaming, or mangling a call is still red; only the count is the model's
business. The round trips answer every call rather than just the first, which
is also what the Anthropic Messages spec asks for.
2026-08-27 13:20:28 -07:00
Mateo Wang
d8415c42e6
Merge pull request #38563 from BerriAI/litellm_lit6324_flush_trailing_live_audio
fix(realtime): bill trailing audio when a Gemini transcribe Live session closes
2026-08-27 13:18:17 -07:00
mateo-berri
f2e64d9818 fix(gemini): ignore non-string response_format when deciding on word timestamps 2026-08-27 13:15:17 -07:00
tin-berri
71449b9c55
fix(ui): open select popups below the trigger instead of over it (#38554)
The shared SelectContent wrapper defaulted alignItemWithTrigger to true,
which puts Base UI's positioner into item-aligned mode and places the
popup so the active item sits on top of the trigger. In that mode the
side and sideOffset the wrapper passes two lines above are ignored, and
the popup reports data-side="none".

The overlap only becomes visible once the items are tall enough to
matter, which is why the autorouter Template picker shows it clearly:
its options are three-line cards, so the popup covers both the select
box and its own label.

No call site in the dashboard asked for item-aligned mode. 21 of them
across 15 files already passed alignItemWithTrigger={false} by hand to
undo the default, and the remaining 127 inherited the bug. Flipping the
default makes side and sideOffset live, so collision handling works and
a select with no room below now flips above the trigger rather than
covering it. The 21 hand-written opt-outs are deleted as redundant.
2026-08-27 13:08:13 -07:00
devin-ai-integration[bot]
fe87b187c6
fix: keep schema reconciliation from fighting a partitioned LiteLLM_SpendLogs (#38452)
* fix: keep schema reconciliation from fighting a partitioned LiteLLM_SpendLogs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: scope partitioned SpendLogs detection to Prisma's target schema

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: default partition detection to Prisma's public schema, not current_schema()

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:52:52 -07:00
devin-ai-integration[bot]
6b1844442c
fix(key_management): allow /key/update to keep or shrink MCP server grants the key already holds (#38463)
* fix(key_management): allow /key/update to keep or shrink MCP server grants the key already holds

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(key_management): reuse key row's included object_permission instead of a second lookup

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:51:17 -07:00
devin-ai-integration[bot]
390595c626
fix(auth): skip guaranteed-miss team lookup for the litellm-dashboard sentinel (#38471)
* fix(auth): skip guaranteed-miss team lookup for the litellm-dashboard sentinel

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* style: ruff format

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test: assert builder result instead of swallowing exceptions; drop redundant comment

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:48:11 -07:00
devin-ai-integration[bot]
de53283356
feat(proxy): opt-in budget rollover carrying overage into the next window (#38514)
* feat(proxy): opt-in budget rollover carrying overage into the next window

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(proxy): zero under-cap rows before decrementing over-cap rows in cascade resets

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:46:09 -07:00
devin-ai-integration[bot]
f864908cd7
fix: suppress misleading register_model unresolved-cost warnings for entries without custom pricing (#38542)
* fix: suppress misleading register_model unresolved-cost warnings for entries without custom pricing

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: do not warn about zero cache costs for tiered pricing entries

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:45:30 -07:00
devin-ai-integration[bot]
e16aa9f512
fix(mcp): keep upstream OAuth Authorization when jwt signer hook injects one on tools/call (#38555)
* fix(mcp): keep upstream OAuth Authorization when jwt signer hook injects one on tools/call

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(mcp): only treat server credential as occupying Authorization when it maps to that header

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 12:44:36 -07:00
mateo-berri
c251703e8b fix(realtime): bill trailing audio when a Gemini transcribe Live session closes 2026-08-27 12:43:28 -07:00
mateo-berri
5b80fb0fc0 fix(transcription): synthesize srt/vtt output for adapters without native subtitle formats
Extract the Soniox SRT/VTT cue grouping and rendering into a shared
litellm_core_utils/audio_utils/subtitle_utils module, have Gemini
transcription request word timestamps whenever response_format is srt or
vtt, and let the http handler rewrite the response text into the
synthesized subtitle document (dropping the internally requested words
array) for any provider config that opts in via
supports_subtitle_synthesis
2026-08-27 12:30:13 -07:00
Mateo Wang
452254963e
feat(health): opt-in model-group allowlist for background health checks and health-check routing (#38539)
* feat(health): opt-in model-group allowlist for background health checks and health-check routing

* fix(health): merge shared health states per writer scope instead of replacing

* refactor(health): drop restating comment and parameterize test scope annotations

* chore: remove stray generated prisma migration file

* fix(health): merge health states against the Redis snapshot, not the pod-local copy

* fix(health): fall back to the pod-local snapshot when the Redis read returns nothing
2026-08-27 12:25:56 -07:00
Mateo Wang
493bca667b
Merge pull request #38540 from BerriAI/litellm_gemini_35_transcribe
feat(gemini): day-0 support for gemini-3.5-transcribe and transcribe-live
2026-08-27 12:09:40 -07:00
yuneng-jiang
63cb18db7d
Merge pull request #38435 from BerriAI/litellm_e2e_deflake_fallback_cache
test(e2e): de-flake the cost-header cache read and the router fallback control
2026-08-27 12:01:09 -07:00
devin-ai-integration[bot]
2d0c9eed4d
feat(otel): support per-team/per-key service.name for OTel v2 destinations (#38532)
* feat(otel): support per-team/per-key service.name for OTel v2 destinations

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* test(otel): pin key-level otel_service_name_override surviving team metadata merge

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): key-level otel_service_name outranks team's after metadata merge

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: yassin <yassin@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-27 11:50:41 -07:00
yuneng-jiang
9d03b46889
Merge branch 'litellm_internal_staging' into litellm_/e2e-test-coverage-c87d3a 2026-08-27 11:24:44 -07:00
yuneng-jiang
938ed2c2a5
Merge branch 'litellm_internal_staging' into litellm_e2e_deflake_fallback_cache 2026-08-27 11:23:44 -07:00
mateo-berri
462942de65 fix(gemini): bill transcribe-live sessions from streamed audio duration
Gemini Live sends no usageMetadata and no turnComplete for
gemini-3.5-transcribe-live sessions, so realtime spend logged as 0.0.
Attach estimated usage to the input_audio_transcription.completed event
using Google's published billing estimate (25 audio tokens/sec of input,
175 text tokens/min of output) derived from the streamed pcm16 audio
duration, gated to audio_transcription-mode models so conversational
Live models keep billing through usageMetadata. Also capture that usage
in the provider_config backend path so realtime cost calculation sees it.
2026-08-27 11:03:41 -07:00
Mateo Wang
ca9007be39
Merge pull request #38093 from BerriAI/litellm_lit5458_rerank_sigv4_bearer_fix
fix(bedrock): sign rerank requests with the shared header-filtered SigV4 helper (internal copy of #36462)
2026-08-27 10:57:10 -07:00