Commit graph

5475 commits

Author SHA1 Message Date
yucheng
c37e2488de feat(langfuse): migrate the sdk callback to langfuse v4
Replace the v2 trace()/generation()/span() calls with SDK v4 observations exported over OpenTelemetry, with one isolated tracer provider per Langfuse credential set, a discarding exporter for mock mode, and v4 trace and observation id normalization. Keeps the session-header trace provenance logic from main so each call under a session alias still gets its own trace

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 21:14:31 +00:00
Yassin Kortam
4123b4bc2b
Merge pull request #41086 from BerriAI/litellm_team_list_org_admin_membership_lit3723
fix(proxy): keep org admins' own team memberships in other orgs visible on team list
2026-09-14 13:57:08 -07:00
tin-berri
2cad7a49af
Merge pull request #41116 from BerriAI/litellm_auto_router_session_api_access
fix(proxy): allow LLM API keys to read auto-router sessions
2026-09-14 13:49:03 -07:00
Yassin Kortam
161ae2f3b4
Merge pull request #41107 from BerriAI/litellm_hide_credentials_hint_when_ui_password_set
fix(proxy): hide default credentials login hint when UI_PASSWORD is set
2026-09-14 13:44:09 -07:00
Tin Chi Lo
3177c37e22 fix(cli): show routed models and session stats for LLM API keys 2026-09-14 13:36:00 -07:00
Yassin Kortam
856aedd14a
Merge pull request #40817 from BerriAI/litellm_redis_timeout_log_throttle
fix(redis): log a timeout streak once per interval instead of one line per cache call
2026-09-14 13:34:45 -07:00
yassin
39f6ac4788 perf(proxy): serialize /model/info listing once with orjson
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 19:47:51 +00:00
Yassin Kortam
f67cc62032
Merge pull request #40995 from BerriAI/litellm_all_deployments_cooldown_error
fix(router): name the all-deployments-in-cooldown error on 429 responses
2026-09-14 12:39:42 -07:00
Yassin Kortam
7c55c4ba7d
Merge pull request #40925 from BerriAI/litellm_proxy_error_headers_from_litellm_response_headers
fix(proxy): forward provider request id headers on mapped error responses
2026-09-14 12:36:59 -07:00
yassin
f9d0cd6409 chore(proxy): drop explanatory docstrings from credentials hint helper and tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 19:29:30 +00:00
yassin
53c8a82a31 Merge remote-tracking branch 'origin/main' into pr-40817
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

# Conflicts:
#	litellm/caching/redis_cache.py
#	litellm/proxy/proxy_server.py
#	tests/test_litellm/caching/test_redis_cache.py
2026-09-14 19:11:03 +00:00
yassin
ba171d9eb4 fix(proxy): hide default credentials login hint when UI_PASSWORD is set
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 19:06:04 +00:00
yassin
ce0301c23f refactor(proxy): drop redundant docstrings from upload allowlist helpers and tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 19:00:49 +00:00
yassin
82ef6ea6ab feat(proxy): add general_settings.allowed_file_extensions for /v1/files
Opt-in allowlist for upload filename extensions, checked before the existing blocked_file_extensions blocklist and mapped through the same upload validation failure path. None keeps today's behaviour, [] rejects every upload, matching is case-insensitive on both sides, and a filename with no extension is rejected when the allowlist is set.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 18:53:29 +00:00
yassin
4b39344d13 fix(proxy): only treat a missing user as no memberships on team list, surface db errors
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 16:49:54 +00:00
yassin
dc30be006b refactor(proxy): read org admin's own team ids via get_user_object(check_db_only=True)
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 16:27:31 +00:00
yassin
d643909789 fix(proxy): read org admin's own team ids from db and assert v2 list results
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 16:03:23 +00:00
yassin
8d9edfc03c fix(proxy): keep /team/list self query for org admins membership-only across orgs
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 15:40:41 +00:00
yassin
58c3ccf668 fix(proxy): keep org admins' own team memberships in other orgs visible on team list
An org admin listing their own teams on GET /team/list and GET /v2/team/list
only saw teams in the orgs they administer. Teams they belong to in other
orgs were dropped because the org scope and the membership scope were ANDed.
A self query now unions the two, while a query for another user keeps the
org boundary intersection.

Resolves LIT-3723

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 15:27:06 +00:00
yassin
10f411e60d fix(router): name the all-deployments-in-cooldown error on 429 responses
RouterRateLimitError now carries the model group's deployment ids so it
can tell when every deployment is cooled down, and exposes that as
type=all_deployments_in_cooldown with an explicit message. A partial
cooldown keeps type=rate_limit_error. Either way the proxy no longer
reports type=internal_server_error next to code 429

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-13 09:34:16 +00:00
yassin
e0cf63c5fa Merge remote-tracking branch 'origin/main' into litellm_per_issuer_virtual_key_claim_field 2026-09-13 05:00:54 +00:00
yassin
268b9b167f Merge remote-tracking branch 'origin/main' into litellm_proxy_error_headers_from_litellm_response_headers 2026-09-13 04:24:01 +00:00
ryan-crabbe-berri
760119681c
Merge pull request #40814 from BerriAI/litellm_gate_health_services_alert_tests
fix(proxy): gate the webhook test alert on proxy admins
2026-09-12 21:13:30 -07:00
Mateo Wang
70e3f5a02e
Merge pull request #39836 from BerriAI/litellm_lit_6975_bedrock_files_delete_list
feat(bedrock): support file delete and list for S3-backed managed files
2026-09-12 21:13:27 -07:00
ryan-crabbe-berri
1ce3690257
Merge pull request #40657 from BerriAI/litellm_lit_7358_session_token_grant_resolver
fix(auth): refresh lite login session token grants from the live user and team rows
2026-09-12 21:13:25 -07:00
mateo-berri
8608a03bd8 Merge origin/litellm_internal_staging into litellm_spend_log_request_id_call_id
Keeps the base's rule that a non-admin id lookup matching no spend-log row answers 403, so the detail route never consults cold storage without an owner row
2026-09-12 21:04:25 -07:00
joshua-berri
b7f4258e32
Merge pull request #40923 from BerriAI/litellm_fix_mcp_delegated_auth_tracking_6970
fix(mcp): require admission for delegated OAuth
2026-09-12 19:11:35 -07:00
devin-ai-integration[bot]
56045503db
fix(proxy): bound tool and guardrail index create_many by the spend-log statement budgets (#40561)
* fix(proxy): bound tool and guardrail index create_many by the spend-log statement budgets

One flush drains up to MAX_LOGS_PER_INTERVAL source transactions or logs, but a
transaction fans out to one LiteLLM_SpendLogToolIndex row per tool and a log
to one LiteLLM_SpendLogGuardrailIndex row per guardrail, so the index
create_many payload was unbounded. Both index writes now go through
spend_log_write_batches(SPEND_LOG_WRITE_BATCH_MAX_BYTES, SPEND_LOG_WRITE_BATCH_MAX_ROWS).
The tool index write moves out of the rollup batch_() so the split reduces
the query-engine payload; replayed index rows are no-ops under
skip_duplicates, and the daily rollup upserts stay in one transaction

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

* test(proxy): pin the row budget in the index fan-out tests

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 19:00:47 -07:00
Joshua Valluru
939fa4ee73 test(mcp): remove unrelated formatting changes 2026-09-12 18:27:20 -07:00
yassin
f41c8556b5 feat(jwt): allow virtual_key_claim_field per issuer
Multi-IdP deployments can now set virtual_key_claim_field and
unregistered_jwt_client_behavior on a JWTIssuerConfig entry. Tokens from
that issuer use the issuer-specific claim path and no-match policy for the
virtual key mapping lookup; issuers that omit them keep the global values.
The auth flow now enters the mapping lookup when any issuer configures the
field, not only when the global field is set.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-13 00:41:08 +00:00
ryan-crabbe-berri
76cb0fec1c fix(model_management): stop persisting cost map pricing as a deployment override
/model/info fills a deployment's missing pricing in from the model cost map so the
Admin UI has a rate to display. Clients echo that whole model_info blob back on save,
and update_db_model merged it into the row, so editing an unrelated setting turned
that day's catalog price into a real per-deployment override. After that the
deployment ignored the cost map and Reload Price Data could no longer move it,
because the reload replays each deployment's stored pricing over the fresh catalog.

Drop the derived pricing from incoming model_info on the two write paths. The
drop-set is read off the same objects the read path uses, CustomPricingLiteLLMParams
plus the tiered *_above_N_tokens pattern that get_model_info passes through and no
model declares, so it cannot drift as new rates are added. output_vector_size is
exempt: it lives on the pricing model but is an embedding dimension, not a rate.

A deployment's own pricing still rides litellm_params, which is untouched, as is the
explicit-null clear, which reads the incoming model rather than the filtered dict.
The filter sits in the endpoint bodies rather than _add_model_to_db, which master-key
rotation reuses to re-serialize every stored deployment.
2026-09-12 17:29:35 -07:00
Joshua Valluru
f33bac8080 test(mcp): model delegated hook credentials 2026-09-12 17:29:26 -07:00
Joshua Valluru
364e466210 fix(mcp): strip duplicate delegated credentials 2026-09-12 17:18:54 -07:00
yassin
8577d63ff5 fix(proxy): forward provider request id headers on mapped error responses
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-13 00:14:49 +00:00
Joshua Valluru
97b964dd9a fix(mcp): prevent delegated admission key forwarding 2026-09-12 17:00:21 -07:00
Joshua Valluru
94e4dd725f fix(mcp): require admission for delegated OAuth 2026-09-12 16:41:23 -07:00
ryan
8ccde3879d Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_key_alias_substring_non_admin 2026-09-12 23:06:23 +00:00
devin-ai-integration[bot]
b1360efc2f
fix(proxy): attribute gate-rejected requests to their endpoint in cache analytics (#40824)
* fix(proxy): attribute gate-rejected requests to their endpoint in cache analytics

Requests rejected before dispatch (bad key, blocked key, budget, rate limit, malformed body) were spend-logged with an empty call_type because the synthesized logging object never reached the failure lifter. The caching dashboard rolled all of them, plus failed calls on info routes such as /model/info, into one Unknown group.

Resolve call_type from the matched route first, falling back to body shape, and keep the synthesized logging object on request_data so the lifter sees it. Log bare auth exceptions with the 401 ProxyException the client gets so error_code is never empty. Exclude info routes from the cache analytics groups and error breakdown. The dashboard explains the Unknown group when older rows still produce one.

Resolves LIT-5884

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

* fix(proxy): keep the raw auth exception for failure callbacks

Record the client-facing status in the spend log through a separate client_exception argument so custom failure callbacks still receive the exception auth raised.

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

* fix(proxy): keep the route for multi-operation endpoints and exclude info routes from cache filter options

Routes such as /v1/files map to several operations (create, list) and the
method is not available in the failure hook, so a rejected request there is
filed under its route instead of the first mapped call type. The key alias and
model filter-option queries now apply the same info-route exclusion as the
groups and error breakdown, so every offered filter value returns data. The
info-route exclusion and Unknown grouping are now covered against a real
Postgres in tests/proxy_behavior/spend/test_cache_activity.py

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

* fix(proxy): drop client_exception, the spend log row never used it

The DB spend row for a gate rejection is written by _ProxyDBLogger from the
original exception, so the status-bearing copy only reached the in-memory
logging payload. Live runs at the tip still recorded bare auth exceptions as
Unknown/Exception, the same as the base branch. Removing the plumbing keeps
this PR to endpoint attribution and the info-route exclusion

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

---------

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 16:03:38 -07:00
ryan
02dbff485b test(proxy): mark prisma_client patch in /key/list alias test with test-quality reason
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 22:32:14 +00:00
Mateo Wang
fe5ff9d3b0
Merge pull request #40771 from BerriAI/litellm_regression_coverage_followup
test: tighten regression tests added in #37974
2026-09-12 15:29:36 -07:00
Mateo Wang
e1bff56f0b
Merge pull request #40772 from BerriAI/litellm_lit6982_bucket_config_includes
fix(proxy): resolve config include directives for bucket-hosted configs
2026-09-12 15:21:56 -07:00
Mateo Wang
c040061f15
Merge pull request #40766 from BerriAI/litellm_fix_v1_messages_disconnect_partial_cost
fix(anthropic): price recovered tokens when a /v1/messages client disconnects mid-stream
2026-09-12 15:21:43 -07:00
Mateo Wang
d72ae3b9a2
Merge pull request #39895 from BerriAI/litellm_deflake_20260905
test: deflake redis semantic cache sys.modules leak, LangSmith init loop patch, wall-clock stagger assertion, and zombie grandchild check in the fake prisma cli
2026-09-12 15:20:26 -07:00
Mateo Wang
fc053dae3e
Merge pull request #40770 from BerriAI/litellm_lit6996_agent_skills_wellknown
feat(proxy): serve registered skills as an Agent Skills well-known index
2026-09-12 15:20:20 -07:00
Mateo Wang
f531537aa3
Merge pull request #40768 from BerriAI/litellm_prisma_cli_resolve
fix(proxy): run migrations through python -m prisma when the prisma console script is not on PATH
2026-09-12 15:20:06 -07:00
ryan
df6ec79810 test(proxy): assert /key/list alias substring results end to end for non-admins
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 22:15:11 +00:00
ryan-crabbe-berri
ba6a0c9fc6
Merge pull request #40652 from BerriAI/litellm_key_activity_search
feat(ui): search Key Activity by key alias, key hash, user id, or email
2026-09-12 15:05:53 -07:00
ryan
20787ba186 fix(proxy): allow key_alias substring matching on /key/list for non-admins
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 21:52:49 +00:00
yuneng-jiang
883b722fd2
Merge pull request #40895 from BerriAI/litellm_budget_clear_persistence
fix(ui): persist cleared budgets and reset intervals
2026-09-12 14:22:24 -07:00
devin-ai-integration[bot]
311d9bba37
perf(policy_engine): dedup attachments in one pass after sorting (#40883)
get_attached_policies_with_reasons rescanned the sorted matches with next() once
per distinct policy, which is quadratic and misses the one second budget past a
few thousand global attachments. Build a policy to broadest attachment map in one
pass instead, keeping the specificity sort and result order.

Co-authored-by: yucheng <yucheng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-12 14:19:20 -07:00