Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
844 commits
Select commit Hold shift + click to select a range
1a43168
Merge pull request #38306 from BerriAI/litellm_/page-header-spec-roll…
yuneng-berri Aug 26, 2026
a5d8963
Merge pull request #38308 from BerriAI/litellm_key-update-redis-evict
yuneng-berri Aug 26, 2026
c66c5eb
Merge pull request #38400 from BerriAI/litellm_lit_3369_global_ssl_ve…
mateo-berri Aug 26, 2026
99d4741
fix(team): allow no-reset default budgets for team members
milan-berri Aug 20, 2026
f2f389c
fix(ui): keep an untouched member budget duration distinct from never…
ryan-crabbe-berri Aug 26, 2026
57f553a
fix(caching): treat an empty cache namespace as no namespace
mateo-berri Aug 26, 2026
3c24f37
Merge pull request #38394 from BerriAI/litellm_lit6253_cache_hit_call…
mateo-berri Aug 26, 2026
2720765
fix(gemini-realtime): drop OpenAI stock voice names instead of pairin…
yucheng-berri Aug 26, 2026
6fa5164
fix(prompts): reject keyed prompt_data with prompt_id and populate pr…
mateo-berri Aug 26, 2026
6d1b295
fix(proxy): stop empty DB router_settings lists from clobbering yaml …
mateo-berri Aug 26, 2026
caa97ee
fix(cost-map): correct prompt_cache_min_tokens for Claude Fable 5 and…
mateo-berri Aug 26, 2026
870328f
test(team): fake the budget table instead of patching new_budget and …
ryan-crabbe-berri Aug 26, 2026
f57e4b8
Merge pull request #38403 from BerriAI/litellm_lit3373_valkey_acl
mateo-berri Aug 26, 2026
465ebb1
fix(mcp): join discovery for a clientless DCR bridge still missing it…
mateo-berri Aug 26, 2026
951cef1
fix(cost_calculator): strip duplicated region segment from alias cost…
mateo-berri Aug 26, 2026
f334108
docs(prompts): sync lazy openapi snapshot and dashboard schema with t…
mateo-berri Aug 26, 2026
dbc819d
fix(prompts): apply prompt templates before routing on /v1/responses …
mateo-berri Aug 26, 2026
43b8ed0
fix(prompts): validate only the litellm_params a PATCH sends
mateo-berri Aug 26, 2026
f772cad
fix(cost-map): backfill prompt_cache_min_tokens for the remaining Cla…
mateo-berri Aug 26, 2026
afe5a24
fix(proxy): regenerate lazy OpenAPI snapshot and guard it in CI
mateo-berri Aug 26, 2026
3b9f6ee
fix(proxy): apply empty DB router_settings lists only where yaml sets…
mateo-berri Aug 26, 2026
898ff74
refactor(proxy): type the snapshot fragments and wrap a long test line
mateo-berri Aug 26, 2026
2548e96
fix(cost-map): correct Gemini TTS and native-audio rates
mateo-berri Aug 26, 2026
e9f3963
refactor(proxy): build snapshot fragments immutably to satisfy the ty…
mateo-berri Aug 26, 2026
16e9efc
Merge pull request #38404 from BerriAI/litellm_fix_prompt_data_double…
mateo-berri Aug 26, 2026
9888830
Merge pull request #38344 from ksk2023/fix-cost-alias-double-prefix
mateo-berri Aug 26, 2026
77bce45
Merge pull request #38405 from BerriAI/litellm_lit6243_prompt_cache_m…
mateo-berri Aug 26, 2026
4148cf7
Merge pull request #38309 from BerriAI/litellm_azure_ai_unprocessable…
yuneng-berri Aug 26, 2026
f0a122d
refactor(ui): read the auto-router tier set through one row list (#38…
tin-berri Aug 26, 2026
3576c77
fix(proxy): serialize the search tool router refresh
yuneng-berri Aug 26, 2026
b687fe2
fix(prompts): propagate PATCHed prompt templates to every worker and pod
mateo-berri Aug 26, 2026
cd9dcb5
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 26, 2026
aabbc32
fix(gemini-realtime): drop the native-audio speechConfig strip on Goo…
mateo-berri Aug 26, 2026
632a007
Merge pull request #38406 from BerriAI/litellm_fix_db_router_settings…
mateo-berri Aug 26, 2026
f824ca7
fix(responses): run prompt hook before provider credential resolution…
mateo-berri Aug 26, 2026
3418d7b
fix(speech): keep proxy metadata and completion cost through the TTS …
mateo-berri Aug 26, 2026
6918214
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 26, 2026
52b7bea
Merge pull request #37708 from BerriAI/litellm_team_member_budget_no_…
ryan-crabbe-berri Aug 26, 2026
d565860
fix(cost-map): correct gemini-live native-audio text input rate
mateo-berri Aug 26, 2026
5130baf
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 26, 2026
fd751a5
fix(proxy): key lazy openapi stubs off registered features, not sys.m…
mateo-berri Aug 26, 2026
fb13b47
test: type the pricing test helpers
mateo-berri Aug 26, 2026
416984a
fix(health): make the image_edit health probe moderation-safe
mateo-berri Aug 26, 2026
4d1d7b4
test(speech): type the bridge spend regression test helpers
mateo-berri Aug 26, 2026
b9a7908
fix(gemini): bill Google Maps grounding as its own SKU
mateo-berri Aug 26, 2026
ce8d6f7
fix(mcp): token refresh and M2M egress honor the admin-entered token URL
mateo-berri Aug 26, 2026
a8f3a74
Merge pull request #38397 from BerriAI/litellm_deepseek_vision_forwar…
mateo-berri Aug 26, 2026
241daa4
Merge branch 'litellm_internal_staging' of https://github.com/BerriAI…
mateo-berri Aug 26, 2026
5d4f8b3
fix(fireworks_ai): stop using the trace id as the session affinity ke…
Hamjaster Aug 26, 2026
54b5757
test: restore model cost map via monkeypatch
mateo-berri Aug 26, 2026
f722055
Merge pull request #38395 from BerriAI/litellm_gemini_live_voice
mateo-berri Aug 26, 2026
9003b02
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 26, 2026
6df307f
fix(prompts): validate a prompt replacement before swapping and isola…
mateo-berri Aug 26, 2026
31f0d82
fix(ptu): zero the Maps grounding rate on PTU deployments
mateo-berri Aug 26, 2026
2f79653
test(health): parse the probe PNG without mutation
mateo-berri Aug 26, 2026
ab1b7bf
fix(cost): price gemini-live-2.5-flash-native-audio realtime sessions
mateo-berri Aug 26, 2026
855a8bc
Merge pull request #36397 from ousamabenyounes/litellm_fix_gemini_web…
mateo-berri Aug 26, 2026
9e6d9e5
Merge pull request #38417 from BerriAI/litellm_image_edit_health_prob…
mateo-berri Aug 26, 2026
7e7ac69
test: gate the test tree on fifteen assertion and handler rules it al…
ryan-crabbe-berri Aug 26, 2026
fdeab57
fix(speech): forward api_key to the TTS bridge and isolate response h…
mateo-berri Aug 26, 2026
0243c5d
fix(model_prices): correct gemini-3.5-flash-lite flex cache-read pricing
mateo-berri Aug 26, 2026
93e7e8d
fix(mcp): token exchange rejoins discovery for a clientless DCR bridg…
mateo-berri Aug 26, 2026
b48bff7
fix(cost_calculator): require real values when detecting declared rea…
mateo-berri Aug 26, 2026
dca5144
Merge branch 'litellm_internal_staging' of https://github.com/BerriAI…
mateo-berri Aug 26, 2026
6c07fd5
test: accept the Maps grounding rate in the intended cost map schema
mateo-berri Aug 26, 2026
ac3f987
fix: thread service_tier through vertex cost_per_character fallbacks
mateo-berri Aug 26, 2026
f758e9c
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 26, 2026
b98b2d5
Merge pull request #38416 from BerriAI/litellm_fix_lazy_openapi_stubs…
mateo-berri Aug 26, 2026
e7b843d
test: trim realtime cost test docstrings to one line
mateo-berri Aug 26, 2026
885d95d
Merge remote-tracking branch 'origin/litellm_internal_staging' into p…
mateo-berri Aug 26, 2026
d8edfb6
fix(proxy): derive auto-router health from its underlying models (#38…
tin-berri Aug 26, 2026
cebf0d6
fix(responses): let cache-control injection reach the system prompt f…
tin-berri Aug 26, 2026
fed7a48
Merge remote-tracking branch 'origin/litellm_internal_staging' into d…
mateo-berri Aug 26, 2026
ad00d90
Merge pull request #38418 from BerriAI/litellm_gemini_maps_grounding_…
mateo-berri Aug 26, 2026
bd75c38
fix(model_prices): scope flash-lite flex cache-read cut to vertex ent…
mateo-berri Aug 26, 2026
d77eef3
Merge pull request #38414 from BerriAI/litellm_fix_speech_metadata_sp…
mateo-berri Aug 26, 2026
40005cf
Merge pull request #37724 from bisma-nawaz/fix-37647-staging
mateo-berri Aug 26, 2026
1e1c231
fix(model_prices): bill gemini -latest/preview alias cache reads at 1…
mateo-berri Aug 26, 2026
057781a
test(pass_through): pin stream pricing tests to injected divergent ra…
mateo-berri Aug 26, 2026
8a9d5b1
feat(langfuse): support langfuse_environment as a per-key dynamic cal…
devin-ai-integration[bot] Aug 26, 2026
5461bb3
fix(prompts): sync only the newest row when environments share a vers…
mateo-berri Aug 27, 2026
cbefebb
Merge branch 'litellm_internal_staging' into litellm_/search-tools-sy…
yuneng-berri Aug 27, 2026
901bea4
Merge branch 'litellm_internal_staging' of https://github.com/BerriAI…
mateo-berri Aug 27, 2026
e80ba92
Merge pull request #38313 from BerriAI/litellm_/hide-unhealthy-virtua…
yuneng-berri Aug 27, 2026
c0f9af0
fix(cost): make cost-breakdown headers respect service tier
mateo-berri Aug 27, 2026
39dd463
Merge pull request #38379 from BerriAI/litellm_mcp_oauth_admin_entere…
mateo-berri Aug 27, 2026
4e295e8
Merge pull request #38422 from BerriAI/litellm_gemini35_flashlite_fle…
mateo-berri Aug 27, 2026
b54f750
Merge pull request #38419 from BerriAI/litellm_gemini_live_realtime_cost
mateo-berri Aug 27, 2026
1ac39b1
Merge pull request #38412 from BerriAI/litellm_fix_gemini_tts_native_…
mateo-berri Aug 27, 2026
e8ec34c
refactor(google_genai): pick the stream logging endpoint type at cons…
mateo-berri Aug 27, 2026
53a607e
Merge pull request #38411 from BerriAI/litellm_fix_prompt_patch_sync
mateo-berri Aug 27, 2026
d8595cb
Merge pull request #38423 from BerriAI/litellm_gemini_latest_cache_re…
mateo-berri Aug 27, 2026
f677292
Merge pull request #38392 from BerriAI/litellm_/search-tools-sync-iss…
yuneng-berri Aug 27, 2026
ac2e07f
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
8697a9f
Merge branch 'litellm_internal_staging' of https://github.com/BerriAI…
mateo-berri Aug 27, 2026
ecc4976
feat(guardrails): track Azure Prompt Shield usage and cost with spend…
yucheng-berri Aug 27, 2026
4d6786d
fix(budget): serialize model_max_budget before the /budget/update write
yuneng-berri Aug 27, 2026
595ada1
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
yuneng-berri Aug 27, 2026
c23ce40
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
e8a683e
test(cost): cover warm prefix cache spanning text and image tokens
mateo-berri Aug 27, 2026
5175fda
Merge pull request #38407 from BerriAI/litellm_fix_dotprompt_model_swap
mateo-berri Aug 27, 2026
e0248ac
Merge pull request #38424 from BerriAI/litellm_flex_breakdown_tier
mateo-berri Aug 27, 2026
147fcf7
Merge pull request #38399 from BerriAI/litellm_mcp_http_extra
mateo-berri Aug 27, 2026
f7af44a
fix(anthropic-adapter): pass provider-native and OpenAI-format tools …
mateo-berri Aug 27, 2026
315144c
test(budget): annotate the new locals with Final
yuneng-berri Aug 27, 2026
84dfc18
test(e2e): de-flake the cost-header cache read and the router fallbac…
yuneng-berri Aug 27, 2026
1df25e2
revert(proxy): remove router_model_name from auto-routed response bod…
tin-berri Aug 27, 2026
26b7bc3
fix(prompts): propagate prompt deletes to every worker and pod
mateo-berri Aug 27, 2026
77765fd
Merge pull request #36055 from BerriAI/devin_ai_fix_gemini_stream_bil…
mateo-berri Aug 27, 2026
4f56e8a
test(e2e): un-skip the per-model budget update case
yuneng-berri Aug 27, 2026
815fa0f
fix(anthropic_adapter): carry web search usage into /v1/messages cost…
mateo-berri Aug 27, 2026
ba7c268
fix(proxy): enforce tool allowlist on OpenAI-format tools sent to /v1…
mateo-berri Aug 27, 2026
4fd7b99
fix(prompts): keep prompts created mid-sync out of the deleted-row sweep
mateo-berri Aug 27, 2026
4bf40c4
fix(logging): stop billing and logging response reads as LLM calls (#…
devin-ai-integration[bot] Aug 27, 2026
3eba0b3
Merge pull request #38430 from BerriAI/litellm_/budget-update-e2e-ski…
yuneng-berri Aug 27, 2026
5c6623c
Merge branch 'litellm_internal_staging' into litellm_budget-update-e2…
yuneng-berri Aug 27, 2026
ff7ba4c
fix(ui): block the auto-router submit on a missing classifier model a…
tin-berri Aug 27, 2026
b958011
fix(e2e): only the negative fallback assertion needs every replica to…
yuneng-berri Aug 27, 2026
f7c9c87
feat(dashscope): support qwen-image-3.0 and qwen-image-3.0-pro image …
devin-ai-integration[bot] Aug 27, 2026
d53c2c8
test(e2e): cover key generate and update on the Admin UI path
yuneng-berri Aug 27, 2026
3047cd2
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
yuneng-berri Aug 27, 2026
587f227
feat(complexity_router): heuristic-first classifier chaining (#38428)
tin-berri Aug 27, 2026
e73e645
Merge pull request #38437 from BerriAI/litellm_budget-update-e2e-unskip
yuneng-berri Aug 27, 2026
0203512
Merge pull request #37407 from Srivatsa03/fix-overlapping-cached-moda…
mateo-berri Aug 27, 2026
71c70b7
style(gemini): drop redundant web search cost comments
mateo-berri Aug 27, 2026
6d7fafa
fix(anthropic): close hybrid tool-name allowlist gap and keep native …
mateo-berri Aug 27, 2026
1fcdb3d
feat(ui): add Teams list CSV export with budgets, model grants, and r…
devin-ai-integration[bot] Aug 27, 2026
ee76c9a
fix(mcp): accept raw x-litellm-api-key on streamable HTTP admission (…
devin-ai-integration[bot] Aug 27, 2026
172e3ac
fix: bound row count on GET /spend/logs to stop unbounded LiteLLM_Spe…
devin-ai-integration[bot] Aug 27, 2026
2e2c820
fix(scim): apply default_team_params (incl. models) to SCIM-created t…
devin-ai-integration[bot] Aug 27, 2026
a215eca
fix(e2e): move the vertex realtime suite off the retired Live preview…
yuneng-berri Aug 27, 2026
aedaf4d
Merge pull request #38434 from BerriAI/litellm_propagate_prompt_deletes
mateo-berri Aug 27, 2026
449c091
fix(realtime): carry audio output tokens into response.done usage so …
mateo-berri Aug 27, 2026
3b50819
Merge pull request #38439 from BerriAI/litellm_messages_tool_usage_co…
mateo-berri Aug 27, 2026
f7228a4
fix(streaming): preserve parsed-chunk provider_specific_fields so Ver…
mateo-berri Aug 27, 2026
ab71807
test(streaming): drop redundant docstrings from flex-tier regression …
mateo-berri Aug 27, 2026
99af9ad
fix(anthropic): carry tool_reference tool results through the guardra…
mateo-berri Aug 27, 2026
1666949
fix(ui): show custom technical keywords on every router whose scorer …
tin-berri Aug 27, 2026
8741e8a
test(e2e): create the key under the dashboard session key
yuneng-berri Aug 27, 2026
e26ea0b
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
807ee7f
Merge pull request #38454 from BerriAI/litellm_e2e_vertex_live_model
yuneng-berri Aug 27, 2026
2e55fa1
fix(e2e): size the mid-conversation-system cache prefix above the min…
yuneng-berri Aug 27, 2026
0ec2d95
fix(e2e): disable thinking on the gemini chat cost test instead of ra…
yuneng-berri Aug 27, 2026
8ebcb3e
feat(newrelic): per-team cost and usage metrics via team callbacks (#…
yucheng-berri Aug 27, 2026
edde2e5
fix(openai): drop tool_reference parts from tool messages at the chat…
mateo-berri Aug 27, 2026
81dc8db
fix(ui): carry a preset's per-tier litellm_params through the prefill…
tin-berri Aug 27, 2026
2e2d68e
Merge pull request #38468 from BerriAI/litellm_e2e_deflake_cacheable_…
yuneng-berri Aug 27, 2026
192ccaa
Merge pull request #38469 from BerriAI/litellm_e2e_gemini_chat_thinki…
yuneng-berri Aug 27, 2026
586e3d8
Merge branch 'litellm_internal_staging' into litellm_e2e_deflake_fall…
yuneng-berri Aug 27, 2026
cd63c7e
feat(ui): put the auto-router savings hero on a spend rail and a four…
tin-berri Aug 27, 2026
63d7920
refactor: dedupe server_tool_use web search reads and type fresh test…
devin-ai-integration[bot] Aug 27, 2026
b4c6e01
feat(together_ai): add zai-org/GLM-5.3-Flash to the model registry
mateo-berri Aug 27, 2026
bcb6a0a
test(together_ai): assert fail-open supported params for models missi…
mateo-berri Aug 27, 2026
ae95acf
fix(exception_mapping_utils): map unmapped exceptions when model and …
mateo-berri Aug 27, 2026
09ff5bf
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
devin-ai-integration[bot] Aug 27, 2026
4b3e82b
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
devin-ai-integration[bot] Aug 27, 2026
5d26ae0
fix(model_prices): absorb Databricks/Z.AI and xAI registry PRs, add T…
devin-ai-integration[bot] Aug 27, 2026
86ef1fb
Merge pull request #38391 from BerriAI/litellm_toggle_internal_health…
mateo-berri Aug 27, 2026
98d231c
Merge pull request #38398 from daniel-meismer-zocdoc/litellm_mcp_bear…
mateo-berri Aug 27, 2026
a0689f0
fix(model_prices): cap ministral-3-3b at Mistral API's 131072 and mir…
mateo-berri Aug 27, 2026
8636526
Merge pull request #38484 from BerriAI/litellm_techdebt_20260827
mateo-berri Aug 27, 2026
982d3a5
Merge pull request #38496 from BerriAI/litellm_fix_exception_type_unb…
mateo-berri Aug 27, 2026
ef4c84d
feat(gemini): day-0 support for gemini-3.5-transcribe and transcribe-…
mateo-berri Aug 27, 2026
a21eed6
build(ui): bump nginx to 1.31-alpine
aharden Aug 27, 2026
02dcc4d
fix(ui_sso): resolve highest privilege Entra app role, not first in c…
imranismail Aug 27, 2026
e44e2fe
fix(gemini): keep transcription-only Live turn usage when generationC…
mateo-berri Aug 27, 2026
62341e9
Merge pull request #38410 from BerriAI/litellm_regenerate_lazy_openap…
mateo-berri Aug 27, 2026
a7da792
feat(ui): add cache hit/miss filter to Request Logs (#38432)
devin-ai-integration[bot] Aug 27, 2026
ca9007b
Merge pull request #38093 from BerriAI/litellm_lit5458_rerank_sigv4_b…
mateo-berri Aug 27, 2026
462942d
fix(gemini): bill transcribe-live sessions from streamed audio duration
mateo-berri Aug 27, 2026
6a766ae
fix(gemini): add tpm and rpm to the gemini-3.5-transcribe registry en…
mateo-berri Aug 27, 2026
938ed2c
Merge branch 'litellm_internal_staging' into litellm_e2e_deflake_fall…
yuneng-berri Aug 27, 2026
9d03b46
Merge branch 'litellm_internal_staging' into litellm_/e2e-test-covera…
yuneng-berri Aug 27, 2026
490face
fix(ui): order the auto-routers table newest first so a new router la…
tin-berri Aug 27, 2026
0fba058
feat(ui): run the Anthropic Family preset's reasoning tier on Opus 5 …
tin-berri Aug 27, 2026
955b26a
Merge pull request #38541 from BerriAI/devin_ai_34831_nginx_1_31
ryan-crabbe-berri Aug 27, 2026
2d0c9ee
feat(otel): support per-team/per-key service.name for OTel v2 destina…
devin-ai-integration[bot] Aug 27, 2026
63cb18d
Merge pull request #38435 from BerriAI/litellm_e2e_deflake_fallback_c…
yuneng-berri Aug 27, 2026
493bca6
Merge pull request #38540 from BerriAI/litellm_gemini_35_transcribe
mateo-berri Aug 27, 2026
4522549
feat(health): opt-in model-group allowlist for background health chec…
mateo-berri Aug 27, 2026
5b80fb0
fix(transcription): synthesize srt/vtt output for adapters without na…
mateo-berri Aug 27, 2026
c251703
fix(realtime): bill trailing audio when a Gemini transcribe Live sess…
mateo-berri Aug 27, 2026
e16aa9f
fix(mcp): keep upstream OAuth Authorization when jwt signer hook inje…
devin-ai-integration[bot] Aug 27, 2026
f864908
fix: suppress misleading register_model unresolved-cost warnings for …
devin-ai-integration[bot] Aug 27, 2026
de53283
feat(proxy): opt-in budget rollover carrying overage into the next wi…
devin-ai-integration[bot] Aug 27, 2026
390595c
fix(auth): skip guaranteed-miss team lookup for the litellm-dashboard…
devin-ai-integration[bot] Aug 27, 2026
6b18444
fix(key_management): allow /key/update to keep or shrink MCP server g…
devin-ai-integration[bot] Aug 27, 2026
fe87b18
fix: keep schema reconciliation from fighting a partitioned LiteLLM_S…
devin-ai-integration[bot] Aug 27, 2026
5ea81a0
perf(subtitle_utils): make cue grouping linear in cue count
mateo-berri Aug 27, 2026
71449b9
fix(ui): open select popups below the trigger instead of over it (#38…
tin-berri Aug 27, 2026
f2e64d9
fix(gemini): ignore non-string response_format when deciding on word …
mateo-berri Aug 27, 2026
d8415c4
Merge pull request #38563 from BerriAI/litellm_lit6324_flush_trailing…
mateo-berri Aug 27, 2026
17136e5
bump: litellm-enterprise 0.1.60 -> 0.1.61, litellm-proxy-extras 0.4.8…
yuneng-berri Aug 27, 2026
474fbea
test(e2e): let the together tool tests accept parallel calls
yuneng-berri Aug 27, 2026
c39bf62
Merge pull request #38448 from BerriAI/litellm_/e2e-test-coverage-c87d3a
yuneng-berri Aug 27, 2026
2d5e49d
Merge pull request #38566 from BerriAI/litellm_/release-version-bump-…
yuneng-berri Aug 27, 2026
3746ba5
fix(ui): let the paginated search select keep what the user types (#3…
yuneng-berri Aug 27, 2026
2cab010
test(e2e): check the tool input on the messages path too
yuneng-berri Aug 27, 2026
5d8eb04
fix(transcription): drop words from srt/vtt replies when synthesis fa…
mateo-berri Aug 27, 2026
88cb834
fix(otel): anchor MCP tool-call spans to the gateway's own trace, lin…
yucheng-berri Aug 27, 2026
0441faa
Merge pull request #37833 from BerriAI/litellm_deflake_20260821
mateo-berri Aug 27, 2026
67c7b97
Merge pull request #38207 from BerriAI/litellm_registry_audit_bedrock…
mateo-berri Aug 27, 2026
bf86ead
fix(ui): take whole-selection edits verbatim in the paginated search …
ryan-crabbe-berri Aug 27, 2026
3ea5014
fix(router): authorize config-level fallback targets against the call…
ryan-crabbe-berri Aug 27, 2026
141c914
fix(ui): reason-gate the remaining server-searched comboboxes
ryan-crabbe-berri Aug 27, 2026
5cab47e
Merge pull request #38487 from BerriAI/litellm_fix_together_ai_fail_o…
mateo-berri Aug 27, 2026
852cb3a
Merge pull request #38567 from BerriAI/litellm_together-parallel-tool…
yuneng-berri Aug 27, 2026
c860d51
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
10480b8
refactor(dashscope): drop redundant routing comment
mateo-berri Aug 27, 2026
dbadee7
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
ff418ff
test(e2e): serve the vision image from our own fixture
yuneng-berri Aug 27, 2026
40ff01b
feat(mcp): let a resolved OAuth token target a custom upstream header…
tin-berri Aug 27, 2026
9e9c7e6
Merge branch 'litellm_internal_staging' of https://github.com/BerriAI…
mateo-berri Aug 27, 2026
7083c47
Merge pull request #38263 from BerriAI/litellm_together_reasoning_effort
mateo-berri Aug 27, 2026
4917069
test(e2e): drop the fixture helper docstring
yuneng-berri Aug 27, 2026
a2c8146
Merge pull request #38449 from BerriAI/litellm_dashscope_qwen_image_3
mateo-berri Aug 27, 2026
ae89f9c
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
mateo-berri Aug 27, 2026
d18bfe1
fix(proxy): fail closed when fallback authorization lookup errors
ryan-crabbe-berri Aug 27, 2026
1665214
feat(together_ai): flag prompt caching on GLM-5.3-Flash like its sibl…
mateo-berri Aug 27, 2026
dc1b847
Merge pull request #38280 from BerriAI/litellm_together_cache_pricing
mateo-berri Aug 27, 2026
55c1537
Merge pull request #38376 from BerriAI/devin_ai_bedrock_guardrail_ext…
mateo-berri Aug 27, 2026
e5b2f5b
Merge pull request #38561 from BerriAI/litellm_transcription_srt_vtt_…
mateo-berri Aug 27, 2026
66ea1bb
Merge pull request #38458 from BerriAI/litellm_streaming_flex_service…
mateo-berri Aug 27, 2026
0c0a1f4
Merge pull request #38457 from BerriAI/litellm_realtime_audio_output_…
mateo-berri Aug 27, 2026
649dc23
Merge pull request #38465 from BerriAI/litellm_lit6103_tool_reference…
mateo-berri Aug 27, 2026
4ef1c28
Merge pull request #38431 from BerriAI/litellm_fix_messages_native_tools
mateo-berri Aug 27, 2026
9d1348c
Merge pull request #38575 from BerriAI/litellm_e2e-vision-own-image
yuneng-berri Aug 27, 2026
a6816f0
Merge pull request #38486 from BerriAI/litellm_together_glm53_flash
mateo-berri Aug 27, 2026
3c41392
Merge pull request #38574 from BerriAI/litellm_combobox_server_search…
ryan-crabbe-berri Aug 27, 2026
30ff372
feat(model_prices): let a map entry declare its exact reasoning_effor…
tin-berri Aug 27, 2026
d4c3b3e
feat(proxy): gate fallback model access enforcement behind enforce_fa…
ryan-crabbe-berri Aug 27, 2026
44d8436
fix(anthropic): carry the adaptive effort tier to every bridged Claud…
tin-berri Aug 27, 2026
42774ea
chore(ui): regenerate schema.d.ts for enforce_fallback_model_access
ryan-crabbe-berri Aug 27, 2026
d392e7f
feat(alerting): add native Microsoft Teams alerting destination (#38367)
devin-ai-integration[bot] Aug 27, 2026
49affa7
chore(proxy): resync the generated API artifacts with the current mod…
tin-berri Aug 27, 2026
ec94a1f
fix(router): reject complexity-router settings written outside comple…
tin-berri Aug 28, 2026
eb0e3f8
feat(ui): session-level cache observability in request logs (#38442)
devin-ai-integration[bot] Aug 28, 2026
3ec3933
fix(ui): link Virtual Keys hint through the migrated /ui route
yassin-berriai Aug 28, 2026
76e7bd4
Merge remote-tracking branch 'origin/litellm_internal_staging' into l…
ryan-crabbe-berri Aug 28, 2026
e6c4580
Merge pull request #38596 from BerriAI/litellm_fix_componentized_ui_v…
ryan-crabbe-berri Aug 28, 2026
1ab6fd8
fix(anthropic): carry the effort tier only where the target declares …
tin-berri Aug 28, 2026
239ec95
fix(presidio): chunk oversized text before /analyze so large content …
yucheng-berri Aug 28, 2026
22a349e
fix(logging): stop stream-based log collectors classifying INFO logs …
yucheng-berri Aug 28, 2026
77bbf4b
feat(ui): dry-run an auto-router config against the backend before sa…
tin-berri Aug 28, 2026
74050e0
fix(guardrails): add fail-open mode to CrowdStrike AIDR guardrail (#3…
yucheng-berri Aug 28, 2026
272458b
fix(router): copy instead of mutating caller metadata when scrubbing …
yucheng-berri Aug 28, 2026
32b8edb
Merge pull request #38572 from BerriAI/litellm_fallback_access_group_…
ryan-crabbe-berri Aug 28, 2026
bb72815
fix(langfuse): warn and drop invalid LANGFUSE_TRACING_ENVIRONMENT ins…
yucheng-berri Aug 28, 2026
10cd925
Merge pull request #38100 from FelipeRodriguesGare/bugfix/tencent-thi…
mateo-berri Aug 28, 2026
09b2374
feat(proxy): dry-run a real request body on /auto_router/test_routing…
tin-berri Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/ui/ @yuneng-berri @ryan-crabbe-berri
/litellm/proxy/_experimental/out/ @yuneng-berri @ryan-crabbe-berri
/ui/Dockerfile
/ui/nginx.conf
/ui/litellm-dashboard/src/lib/http/schema.d.ts
/ui/litellm-dashboard/tsconfig.tsbuildinfo
/model_prices_and_context_window.json @mateo-berri
/litellm/model_prices_and_context_window_backup.json @mateo-berri
/litellm-proxy-extras/litellm_proxy_extras/migrations/ @yuneng-berri @ryan-crabbe-berri
Expand Down
5 changes: 5 additions & 0 deletions .github/mutmut-coverage.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# mutmut's gather_coverage() looks covered lines up by absolute path, so the
# repo's `relative_files = true` makes every lookup miss and mutmut generates
# zero mutants. Point COVERAGE_RCFILE here for mutation runs only.
[run]
relative_files = false
23 changes: 19 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<!-- The whole description's target audience is humans, not AI agents: write it in plain, simple,
everyday engineering language, extremely parsable and readable at a glance. This goes double for
the TLDR, User Flow, and Caveats sections -->

## TLDR

<!-- Fill in the bullets below and keep each one short and concrete: one line per bullet, roughly 10 words max
This section must be extremely human parsable, comprehensible, and readable: its target audience is humans, not AI agents -->
<!-- Fill in the bullets below and keep each one short and concrete: one line per bullet, roughly 10 words max -->

Problem this solves:

Expand Down Expand Up @@ -110,8 +113,20 @@ If you're seeing a delay in your PR being merged, ping the LiteLLM Team on [Slac

## Caveats (if any)

<!-- Short bullet points, just like the TLDR: one line per bullet, roughly 10 words max
<!-- Group caveats under severity subheadings (### Severe, ### High, ### Medium, ### Low), with
short bullet points inside each, just like the TLDR: one line per bullet, roughly 10 words max
Call out known limitations, follow-up work, or anything a reviewer should watch out for
Include only the tiers that have caveats; drop the empty ones
- Severe: inherent to what the PR deliberately ships, there even when the code works as intended:
it can degrade or take down a running deployment (e.g. a slow or table-locking boot migration),
rewrite data by design, break an existing workflow on purpose, or change auth behavior. An
operator must plan around it before rollout
- High: an unintended hole: a correctness, security, data-loss, or backward-compatibility bug,
unsafe to ship as is
- Medium: a real gap someone can hit, but with a workaround or a narrow blast radius
- Low: anything else worth noting: naming, cleanup, an edge case nobody hits
Nest bullets as deep as helps: hierarchy beats one long line when it makes things clearer to a
human reader
Leave this section empty if there are none -->

## QA runbook
Expand All @@ -134,6 +149,6 @@ Example checklists:
- [ ] Sanity check: this test makes sense to add and is not hand-wavey (e.g., assert actual expected spend instead of just spend > 0) or potentially flaky
-->

### Final Attestation
## Final Attestation

- [ ] The tests check the right things, including the edge cases, and regressions in the respective real-world customer use-cases are not possible after this PR
198 changes: 198 additions & 0 deletions .github/scripts/e2e_egress_sentinel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
"""Prove an e2e replay run makes zero outbound provider calls, by counting them.
`serve` pins each provider host (`--host`) to a local sink address in the hosts
file and binds a counting listener on that address, so any connection the proxy
or the record/replay edge opens to a real provider is redirected to the sink,
recorded as one line in `--hits-file`, and never leaves the box. The record and
replay edge only ever dials `127.0.0.1:<edge-port>` (a different host than the
pinned provider names), so in a clean replay the sink sees nothing; a single hit
means a provider call escaped the bundle. `assert-empty` turns that hit file into
the pass/fail check.
Stdlib only, so CI runs it under the system interpreter as root (binding :443 and
editing the hosts file both need root); `--sink-address`, `--port`, and
`--hosts-file` are injectable so it runs unprivileged against a temp hosts file on
a high port under test.
"""

# ruff: noqa: T201 # CLI script: its stdout/stderr progress and results are the interface
from __future__ import annotations

import argparse
import json
import os
import signal
import socket
import sys
import threading
import time
from dataclasses import dataclass
from pathlib import Path
from types import FrameType
from typing import Final

_BLOCK_BEGIN: Final = "# BEGIN e2e-egress-sentinel"
_BLOCK_END: Final = "# END e2e-egress-sentinel"


@dataclass(frozen=True, slots=True)
class ServeConfig:
hosts: tuple[str, ...]
sink_address: str
ports: tuple[int, ...]
hits_file: Path
hosts_file: Path
ready_file: Path | None
pid_file: Path | None


def _pin_block(sink_address: str, hosts: tuple[str, ...]) -> str:
lines = "\n".join(f"{sink_address}\t{host}" for host in hosts)
return f"\n{_BLOCK_BEGIN}\n{lines}\n{_BLOCK_END}\n"


def _install_pins(hosts_file: Path, sink_address: str, hosts: tuple[str, ...]) -> bytes:
original = hosts_file.read_bytes() if hosts_file.exists() else b""
hosts_file.write_bytes(original + _pin_block(sink_address, hosts).encode())
return original


def _restore_pins(hosts_file: Path, original: bytes) -> None:
hosts_file.write_bytes(original)


def _bind(sink_address: str, port: int) -> socket.socket:
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind((sink_address, port))
listener.listen(128)
return listener


@dataclass(frozen=True, slots=True)
class _HitLog:
path: Path
_lock: threading.Lock

def record(self, *, port: int, peer: tuple[str, int]) -> None:
entry = json.dumps({"ts": time.time(), "port": port, "peer": list(peer)})
with self._lock:
with self.path.open("a", encoding="utf-8") as handle:
handle.write(entry + "\n")


def _serve_socket(listener: socket.socket, port: int, hits: _HitLog, stop: threading.Event) -> None:
while not stop.is_set():
try:
conn, peer = listener.accept()
except OSError:
return
hits.record(port=port, peer=(peer[0], peer[1]))
try:
conn.close()
except OSError:
pass


def serve(config: ServeConfig) -> int:
config.hits_file.write_text("", encoding="utf-8")
original_hosts = _install_pins(config.hosts_file, config.sink_address, config.hosts)
try:
listeners = tuple(_bind(config.sink_address, port) for port in config.ports)
except OSError as exc:
_restore_pins(config.hosts_file, original_hosts)
print(f"egress sentinel could not bind a sink: {exc}", file=sys.stderr)
return 1

stop = threading.Event()
hits = _HitLog(path=config.hits_file, _lock=threading.Lock())
threads = tuple(
threading.Thread(target=_serve_socket, args=(listener, port, hits, stop), daemon=True)
for listener, port in zip(listeners, config.ports)
)
for thread in threads:
thread.start()

def _handle(_signum: int, _frame: FrameType | None) -> None:
stop.set()
for listener in listeners:
try:
listener.close()
except OSError:
pass

signal.signal(signal.SIGTERM, _handle)
signal.signal(signal.SIGINT, _handle)

if config.pid_file is not None:
config.pid_file.write_text(str(os.getpid()), encoding="utf-8")
if config.ready_file is not None:
config.ready_file.write_text("ready", encoding="utf-8")
print(
f"egress sentinel up: pinned {', '.join(config.hosts)} to {config.sink_address} "
f"on port(s) {', '.join(str(p) for p in config.ports)}",
flush=True,
)

stop.wait()
_restore_pins(config.hosts_file, original_hosts)
if config.ready_file is not None and config.ready_file.exists():
config.ready_file.unlink()
if config.pid_file is not None and config.pid_file.exists():
config.pid_file.unlink()
return 0


def assert_empty(hits_file: Path) -> int:
if not hits_file.exists():
print(f"egress sentinel recorded no provider calls ({hits_file} absent): zero egress")
return 0
hits = [line for line in hits_file.read_text(encoding="utf-8").splitlines() if line.strip()]
if not hits:
print("egress sentinel recorded no provider calls: zero egress")
return 0
print(f"egress sentinel recorded {len(hits)} provider call(s); replay was not hermetic:", file=sys.stderr)
for line in hits:
print(f" {line}", file=sys.stderr)
return 1


def _serve_from_args(args: argparse.Namespace) -> int:
config = ServeConfig(
hosts=tuple(args.host),
sink_address=args.sink_address,
ports=tuple(args.port),
hits_file=Path(args.hits_file),
hosts_file=Path(args.hosts_file),
ready_file=Path(args.ready_file) if args.ready_file else None,
pid_file=Path(args.pid_file) if args.pid_file else None,
)
return serve(config)


def main(argv: tuple[str, ...]) -> int:
parser = argparse.ArgumentParser(description="count outbound provider calls during an e2e replay")
sub = parser.add_subparsers(dest="command", required=True)

serve_parser = sub.add_parser("serve", help="pin provider hosts and count connection attempts")
serve_parser.add_argument("--host", action="append", required=True, help="provider host to pin and watch")
serve_parser.add_argument("--sink-address", default="127.0.0.1")
serve_parser.add_argument("--port", action="append", type=int, default=None)
serve_parser.add_argument("--hits-file", required=True)
serve_parser.add_argument("--hosts-file", default="/etc/hosts")
serve_parser.add_argument("--ready-file", default=None)
serve_parser.add_argument("--pid-file", default=None)

assert_parser = sub.add_parser("assert-empty", help="exit non-zero if any provider call was recorded")
assert_parser.add_argument("--hits-file", required=True)

args = parser.parse_args(argv)
if args.command == "serve":
if args.port is None:
args.port = [443]
return _serve_from_args(args)
return assert_empty(Path(args.hits_file))


if __name__ == "__main__":
raise SystemExit(main(tuple(sys.argv[1:])))
55 changes: 55 additions & 0 deletions .github/scripts/e2e_fetch_fixture_bundle.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail

REPO="${1:-${GITHUB_REPOSITORY:?REPO required}}"
ARTIFACT_NAME="${2:-e2e-fixtures-bundle}"
BASE_BRANCH="${3:?base branch required}"
DEST_DIR="${4:?destination bundle dir required}"

: "${GH_TOKEN:?GH_TOKEN required to query and download artifacts}"

WORKDIR="$(mktemp -d)"
trap 'rm -rf "${WORKDIR}"' EXIT

echo "resolving newest non-expired '${ARTIFACT_NAME}' artifact on ${REPO}@${BASE_BRANCH}"

SELECTED="$(
gh api "repos/${REPO}/actions/artifacts" -X GET -f per_page=100 --paginate \
--jq ".artifacts[] | select(.name == \"${ARTIFACT_NAME}\" and .expired == false and .workflow_run.head_branch == \"${BASE_BRANCH}\") | {id, digest, created_at, run_id: .workflow_run.id, run_number: .workflow_run.run_number}" \
| jq -s 'sort_by(.created_at) | reverse | .[0] // empty'
)"

if [[ -z "${SELECTED}" ]]; then
echo "no usable '${ARTIFACT_NAME}' artifact on ${BASE_BRANCH}: the last record run produced none (a red Saturday), so there is nothing fresh to replay; failing loudly instead of replaying a stale bundle" >&2
exit 1
fi

RUN_ID="$(echo "${SELECTED}" | jq -r '.run_id')"
RUN_NUMBER="$(echo "${SELECTED}" | jq -r '.run_number')"
ARTIFACT_ID="$(echo "${SELECTED}" | jq -r '.id')"
GH_DIGEST="$(echo "${SELECTED}" | jq -r '.digest // "unknown"')"
CREATED_AT="$(echo "${SELECTED}" | jq -r '.created_at')"

echo "pinned bundle: run #${RUN_NUMBER} (run_id=${RUN_ID}, artifact_id=${ARTIFACT_ID}), recorded ${CREATED_AT}, github digest ${GH_DIGEST}"

gh run download "${RUN_ID}" --repo "${REPO}" -n "${ARTIFACT_NAME}" -D "${WORKDIR}"

TARBALL="$(find "${WORKDIR}" -name '*.tar.gz' -type f | head -n 1)"
if [[ -z "${TARBALL}" ]]; then
echo "downloaded artifact contained no tarball" >&2
exit 1
fi
SIDECAR="${TARBALL}.sha256"
if [[ ! -f "${SIDECAR}" ]]; then
echo "downloaded artifact has no ${SIDECAR}: cannot verify the bundle digest" >&2
exit 1
fi

echo "verifying bundle against its recorded sha256 digest"
( cd "$(dirname "${TARBALL}")" && sha256sum -c "$(basename "${SIDECAR}")" )

mkdir -p "${DEST_DIR}"
tar xzf "${TARBALL}" -C "${DEST_DIR}"

echo "extracted bundle into ${DEST_DIR}"
python3 -c "import json,sys; m=json.load(open(sys.argv[1])); print(' recorded_at', m['recorded_at'], 'harness', m['harness_version'], 'format_version', m['format_version'])" "${DEST_DIR}/manifest.json"
36 changes: 36 additions & 0 deletions .github/scripts/e2e_pack_fixture_bundle.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail

if [[ $# -ne 2 ]]; then
echo "usage: $0 <bundle-dir> <out-tarball>" >&2
exit 2
fi

BUNDLE_DIR="$1"
OUT_TARBALL="$2"

MANIFEST="${BUNDLE_DIR}/manifest.json"
if [[ ! -f "${MANIFEST}" ]]; then
echo "no ${MANIFEST}: refusing to publish a bundle with no manifest (record produced nothing)" >&2
exit 1
fi

echo "packing fixture bundle from ${BUNDLE_DIR}"
python3 -c "import json,sys; m=json.load(open(sys.argv[1])); print(' format_version', m['format_version'], 'recorded_at', m['recorded_at'], 'harness', m['harness_version'])" "${MANIFEST}"

TEST_DIRS=$(find "${BUNDLE_DIR}" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')
if [[ "${TEST_DIRS}" -eq 0 ]]; then
echo "bundle at ${BUNDLE_DIR} has a manifest but no recorded interactions; refusing to publish an empty bundle" >&2
exit 1
fi
echo " ${TEST_DIRS} recorded test director(ies)"

mkdir -p "$(dirname "${OUT_TARBALL}")"
tar czf "${OUT_TARBALL}" -C "${BUNDLE_DIR}" .

OUT_DIR="$(cd "$(dirname "${OUT_TARBALL}")" && pwd)"
OUT_BASE="$(basename "${OUT_TARBALL}")"
( cd "${OUT_DIR}" && sha256sum "${OUT_BASE}" > "${OUT_BASE}.sha256" )

echo "wrote ${OUT_TARBALL} ($(du -h "${OUT_TARBALL}" | cut -f1)) and ${OUT_BASE}.sha256"
cat "${OUT_DIR}/${OUT_BASE}.sha256"
18 changes: 18 additions & 0 deletions .github/workflows/check-ui-api-types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,24 @@ jobs:
if: steps.changes.outputs.relevant == 'true'
run: uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma

- name: Regenerate the lazy OpenAPI snapshot
if: steps.changes.outputs.relevant == 'true'
run: uv run --no-sync python -m litellm.proxy._lazy_openapi_snapshot

- name: Fail if the lazy OpenAPI snapshot is stale
if: steps.changes.outputs.relevant == 'true'
run: |
if ! git diff --exit-code -- litellm/proxy/_lazy_openapi_snapshot.json; then
echo "::error file=litellm/proxy/_lazy_openapi_snapshot.json::The lazy OpenAPI snapshot is out of sync with the lazily loaded routes."
echo ""
echo "A lazily loaded route or model changed without regenerating the snapshot that /openapi.json serves for unloaded features."
echo "To fix, run from the repo root:"
echo " uv run python -m litellm.proxy._lazy_openapi_snapshot"
echo "then run npm run gen:api from ui/litellm-dashboard and commit both files."
exit 1
fi
echo "_lazy_openapi_snapshot.json is in sync with the lazily loaded routes."

- name: Set up Node.js
if: steps.changes.outputs.relevant == 'true'
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
Expand Down
Loading