Commit graph

1340 commits

Author SHA1 Message Date
devin-ai-integration[bot]
cad49ee171
fix(proxy): gate disable_global_guardrails on keys and teams to proxy admins (#42699)
* fix(proxy): gate disable_global_guardrails on keys and teams to proxy admins

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

* test: cover metadata smuggle with explicit false and UI toggle gating

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

* test(proxy): satisfy PT017 in resend-stored guardrail flag test

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

* refactor(proxy): keep regenerate_key_fn under the C901 ceiling via a guardrail opt-out helper

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

* chore(ui): regenerate schema.d.ts for guardrail opt-out docstrings

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

* fix(proxy): gate disable_global_guardrails on caller-sent metadata, not server defaults

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

* test(integration): audit cells for disable_global_guardrails admin gate

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

* test(integration): restore contracts.json formatting

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

* test(integration): share guardrail opt-out helpers

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

* fix(ui): hide the team disable_global_guardrails switch from non proxy admins

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

* test(integration): drop covers markers and bound the slow sink check to the sink delay

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-23 18:03:02 -07:00
devin-ai-integration[bot]
ce582affaa
fix(mcp): reject duplicate MCP server names and aliases (#42791)
* fix(mcp): reject duplicate MCP server names and aliases

MCP server_name and alias were unchecked at write time, so two servers
could share one tool prefix and tool routing resolved to an arbitrary
winner. Writes now run inside an advisory-locked transaction that
rejects a collision on either column case-insensitively with a 400
naming the colliding identifier, covering create, edit, connector
import and restricted-admin submission. Server reload logs one warning
per identifier already shared in the database.

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix(ui): block duplicate MCP server names and aliases before submit

The create and edit forms now check the normalized name/alias against
the loaded server list (case-insensitive, spaces to underscores, own
row excluded on edit) and show a field error instead of submitting.
Structured proxy error bodies are unwrapped so a 400 no longer renders
as 'Error: [object Object]'.

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix(mcp): check identifier conflicts when an alias is cleared

Clearing an alias drops the tool prefix to the stored server_name, so
that name must go through the conflict check too; an explicit alias:null
is now treated as an identifier write. Also narrows the new db tests to
behavioral assertions instead of pinning prisma where shapes.

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix(mcp): treat an empty alias as a clear in conflict checks

An empty-string alias was written unchecked even though the prefix falls
back to server_name; the update path now treats any falsy alias like a
clear. The edit form likewise compares a cleared alias as empty instead
of re-checking the alias being removed.

Co-Authored-By: bot_apk <apk@cognition.ai>

* test(mcp): cover clearing an alias to an empty string

Co-Authored-By: bot_apk <apk@cognition.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-09-23 17:50:27 -07:00
devin-ai-integration[bot]
6593566cdb
fix(key_management): invalidate cached object permissions on key update (#36719)
* fix(key_management): invalidate cached object permissions on key update

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

* fix(key_management): broadcast permission cache eviction and cover key regenerate

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

* fix(key_management): evict object permission rows through evict_and_broadcast

Co-Authored-By: bot_apk <apk@cognition.ai>

* test(integration): cover mcp tool permission widen, narrow and clear on both workers

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix(key_management): evict object permission rows before the key object

Co-Authored-By: bot_apk <apk@cognition.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-09-23 15:55:09 -07:00
devin-ai-integration[bot]
cddc53464e
test: deflake fuzzy picker, breached-password HIBP, and MCP stdio timeout tests (rolling deflake 2026-09-22) (#42125)
* test(autoroute): wait for a valid fuzzy selection index and cancel the prompt on driver failure

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

* test(autoroute): read the fuzzy selection through the public InquirerPy property

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

* test(proxy): inject the HIBP client into change_password so the breached-password test never touches the network

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

* test(mcp): only use the 200ms read timeout in the silent mode of the transport completion test

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

* test(proxy): record HIBP requests so the ordering test asserts no lookup happened

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

* ci(codeql): filter the weak-sensitive-data-hashing false positive on the HIBP k-anonymity lookup

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-23 08:44:59 -07:00
devin-ai-integration[bot]
5028f9ec59
fix(proxy): validate model credential name only when it changes (#42701)
PATCH /model/{id}/update rejected read-modify-write edits that resent an unchanged but dangling litellm_credential_name. Existence validation now runs only when the requested name differs from the stored one; empty string and non-admin detach rejections are unchanged

Co-authored-by: yuneng <yuneng@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-23 07:34:32 -07:00
Oliver Jensen
bc3b5b1d5b
fix(proxy): revoke UI session tokens on logout and password change (#42463)
* fix(proxy): revoke UI session tokens on logout and password change

Adds POST /session/logout to revoke the presented UI session key server
side (previously logout was client-side only and the key stayed valid
until expiry). Password changes now revoke the user's other UI sessions:
self-change keeps the caller's session, admin reset and onboarding claim
revoke all. The BYOK OAuth cookie auth now re-resolves the embedded key
against the DB so revoked sessions get a 401.

* fix(proxy): satisfy B008 budget and backend allowlist for /session/logout

* refactor(proxy): satisfy type-discipline budget in session_endpoints
2026-09-23 10:31:38 +02:00
moe-berri
2157351004
feat(ui): simplify auto-router setup and clarify feature limits (#42625)
* feat(ui): simplify auto-router setup and clarify feature limits

* fix(ui): validate auto-router drafts before saving

* fix: keep auto-router allowances consistent after deletes and refreshes
2026-09-22 18:03:32 -07:00
devin-ai-integration[bot]
da82ea8e94
fix(ui): let the Create Key user picker find users by user_id, not just email (#41687)
* feat(ui): search users by id or email when assigning a key owner

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

* fix(ui): label users without an email by user id in key owner picker

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

* fix(proxy): freeze merged user-filter where, format create key test

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

* test(proxy): suppress module-global patch findings in ui_view_users search test

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

* fix(proxy): keep merged user-filter where as a plain dict for prisma serialization

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

* fix(ui): forward search param from userFilterUICall to /user/filter/ui

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

* fix(ui): mention user ID in the Create Key user picker helper text

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

---------

Co-authored-by: jesus <jesus@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 16:30:29 -07:00
devin-ai-integration[bot]
d7c27cdc08
feat(proxy): configurable key_alias_pattern for key generate, update, and regenerate (#42553)
* feat(proxy): configurable key_alias_pattern for key generate, update, and regenerate

Adds litellm_settings.key_alias_pattern, a regex every key_alias sent to
/key/generate, /key/service-account/generate, /key/update, and
/key/{key}/regenerate has to fully match. A non-matching alias gets a 400
that names the setting and the pattern. When set, it replaces the built-in
rule enable_key_alias_format_validation turns on, and the baseline
unsafe-name check still runs first. An invalid regex fails config load.

* fix(proxy): cap key_alias length under key_alias_pattern and type the test fixtures

* style(proxy): declare key_alias_pattern with a PEP 604 union

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-22 14:52:01 -07:00
yuneng-jiang
666f6b01b4
fix: enforce disable_custom_api_keys from general_settings (#42437)
* fix: enforce disable_custom_api_keys from general_settings

The gate in _check_custom_key_allowed read the persisted UI settings row
through get_ui_settings_cached, which had two consequences.

A config-file general_settings.disable_custom_api_keys was never enforced,
because the gate only ever looked at the stored ui_settings row. POST
/key/generate with a custom key value returned 200 even with the flag set
to true in config.yaml.

The read went through a DualCache with a 600s TTL, which is per worker
without Redis, and only the worker that served PATCH /update/ui_settings
refreshed it. A gate flipped through the UI was then a coin flip across
workers for up to ten minutes.

Both go away by routing the flag the way the other runtime UI flags are
already routed. Adding it to _RUNTIME_GENERAL_SETTINGS_FLAGS and to the
settings rules' _UI_SETTINGS_FIELDS makes SettingsStore resolve it from the
ui_settings row with the config file winning, and every pod re-reads it on
its own settings sync rather than holding a private cached copy. The two
lists have to stay in step: a flag in one and not the other resolves
against the wrong stored row and silently never reaches a reader, so there
is a test for that invariant.

Writes to the ui_settings table did not publish on the config-sync channel,
so other pods only discovered a change on their next periodic reload. Adding
litellm_uisettings to _CONFIG_SYNCED_TABLE_NAMES puts it on the same pubsub
path model and SSO config writes already use, which cuts cross-pod
propagation from tens of seconds to a few.

The value reaching the gate is run through coerce_bool first. Resolution
hands back the raw YAML value, so a quoted "true" in config.yaml is a str
and the old `is True` check let custom keys straight through.

* test: assert both directions of the coerced config value

* test: assert the runtime flags read back instead of inspecting the registry
2026-09-22 13:28:31 -07:00
tin-berri
3b9c9e0523
feat(router): add group-scoped priority routing strategy (#42378)
* feat(router): add group-scoped priority routing strategy

* fix(router): satisfy priority routing type-discipline checks
2026-09-22 13:09:38 -07:00
devin-ai-integration[bot]
f3a0bb7249
fix(proxy): write key deleted audit logs for cascade and alias key deletions (#42446)
* fix(proxy): write key deleted audit logs for cascade and alias key deletions

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

* test(proxy): assert persisted key deleted audit rows for cascade paths

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

* test(e2e): route /audit and /v2/login to the control plane in split transport

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-22 11:52:08 -07:00
devin-ai-integration[bot]
b673ee61e7
feat(arize): per-team success and error sampling rates for the Arize AX callback (#42383)
* feat(arize): per-team success and error sampling rates for the Arize AX callback

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

* fix(arize): fail open on invalid sampling rates and type the new sampling code

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

* test(arize): type the sampling test helpers and parametrized fixture

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-09-22 11:21:40 -05:00
joshua-berri
25af172b85
fix(mcp): keep config-defined servers read-only (#42299)
* fix(mcp): persist config server edits in the database

* test(mcp): cover config loading and failed promotion responses

* test(mcp): preserve auth policy during config server promotion

* fix(mcp): preserve existing YAML metadata during config loading

* fix(mcp): reuse bounded traversal for config secret checks

* fix(mcp): honor database access groups after config promotion

* fix(mcp): keep config-defined servers read-only

* fix(ui): clear frontend warnings and require warning-free green checks

* fix(ui): preserve legacy MCP access group labels

* ci: remove remaining frontend action runtime warnings

* fix(mcp): limit read-only fix to ticket scope

* fix(mcp): preserve API stability and remove unrelated guidance

---------

Co-authored-by: Joshua Valluru <326636767+joshua-berri@users.noreply.github.com>
2026-09-21 22:56:21 -07:00
devin-ai-integration[bot]
fa8483b6ae
fix(proxy): answer 503 no_db_connection on management routes when the caller's user read hits a database outage (#42410)
* fix(proxy): answer 503 no_db_connection on management routes when the caller's user read hits a database outage

Under allow_requests_on_db_unavailable, once the caller's key row lapses the
request runs as the restricted fallback identity, and its own user read fails
on the outage. /v2/team/list, /user/list, and /user/filter/ui answered a bare
500 for that; every route now answers the same 503 body auth gives, through
one shared builder consulted by the generic exception handler and by
ui_view_users' own catch-all

* fix(proxy): log the database outage before answering 503 on user search

* chore(proxy): drop the docstrings on the db outage 503 helper and its tests

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-09-21 22:37:33 -07:00
devin-ai-integration[bot]
5d3d99eb9f
fix(proxy): drop cost-map metadata echoed back on model save (#41944)
* fix(proxy): drop cost-map metadata echoed back on model save

Filter unchanged cost-map fields from model-info save echoes while preserving edited overrides.

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

* fix(proxy): drop a stored override when an echoed save resets it to the cost-map value

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

* fix(proxy): compare model_info echo against the deployment's cost-map lookup

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

* fix(proxy): decrypt the stored model before the cost-map lookup

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

* fix(proxy): treat a reset to the bundled catalog value as an echo even after router registration

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

* fix(proxy): compare the reset against the catalog as loaded, not only the bundled backup

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

* fix(types): type the catalog snapshot and echo filter parameters as Mapping[str, object]

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

* test(proxy): inject the loaded catalog into update_db_model instead of patching the class

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

* fix(proxy): use contextlib.suppress for cost-map lookup miss to stay under BLE001 budget

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

---------

Co-authored-by: ryan <ryan@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:33:16 -07:00
mateo-berri
1c6c1e568d Merge remote-tracking branch 'origin/main' into litellm_mcp_tools_camelcase_keys 2026-09-21 17:21:46 -07:00
Yassin Kortam
9cc5b78c33
Merge pull request #41634 from BerriAI/litellm_agent_access_groups
feat(agents): attach access groups to agents and enforce them for models, MCP servers and agent calls
2026-09-21 19:13:46 -05:00
yuneng-jiang
1f4b595072
Merge pull request #41788 from BerriAI/litellm_config_read_source
feat(proxy): report the source of alerting, UI and router settings on read
2026-09-21 17:02:18 -07:00
yuneng-jiang
6b254b6be2
Merge pull request #41769 from BerriAI/litellm_model-actor-edges
test(model_management): cover actor edges and wildcard models
2026-09-21 16:43:24 -07:00
tin-berri
c1c1ec4f84
Merge pull request #42026 from BerriAI/litellm_user_jwt_savings
feat(ui): add internal-user savings and auto-router usage
2026-09-21 16:41:16 -07:00
mateo-berri
b58c9349dd test(mcp): drop the docstring from the wire spelling regression test 2026-09-21 16:15:43 -07:00
joshua-berri
1baa26d36b
Merge pull request #41074 from BerriAI/litellm_mcp_server_list_stable_order
fix(mcp): keep server lists stable across refreshes
2026-09-21 23:06:09 +00:00
Yuneng Jiang
143725fc06
Merge remote-tracking branch 'origin/main' into litellm_config_read_source 2026-09-21 15:54:52 -07:00
mateo-berri
51aa021c6e fix(mcp): return camelCase tool keys from /v1/mcp/tools after the SDK 2 upgrade
SDK 2 spells the Tool model's Python attributes in snake_case behind camelCase aliases, so dumping attribute names handed scripts input_schema and output_schema instead of the inputSchema and outputSchema v1.102.0 returned. Dump each tool by its MCP wire aliases, as the other list routes do, and pin the shape with a regression test. Also drop an unused tools dict in the Responses MCP stream iterator.
2026-09-21 15:38:06 -07:00
ryan
8a1c6e49fb feat(auth): only allow password-login dashboard sessions to call /user/password/change
Password login now stamps login_method=username_password into the UI session key
metadata, and change_password rejects any caller that is not a litellm-dashboard
key carrying that marker with 403 before the user row is read. SSO sessions and
user-associated virtual keys can no longer use the endpoint as a current_password
guessing oracle. The forced-reset session is still minted by the password login
path, so it keeps access to the endpoint

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 22:22:12 +00:00
ryan
28f70c75d1 fix(auth): reject unchanged password on /user/password/change
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 22:02:05 +00:00
Yuneng Jiang
1cc38f05f4
test(proxy): type the router settings source test parameters 2026-09-21 15:00:24 -07:00
ryan
7c8aed072f chore: merge main into litellm_cherry_pick_password_breach_reset
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 21:54:35 +00:00
Mateo Wang
4b54897b36
Merge pull request #42315 from BerriAI/litellm_scim_delete_evict_user_cache
fix(proxy): evict the cached user row when SCIM or /user/delete removes a user
2026-09-21 14:51:53 -07:00
Joshua Valluru
5ec61e7a0b chore: merge main into MCP ordering fix 2026-09-21 14:36:41 -07:00
yucheng-berri
79d6e236f9
Merge pull request #39805 from BerriAI/litellm_mcp_admin_api_preserve_oauth_scopes
fix(mcp): keep oauth scopes in admin api credential redaction
2026-09-21 14:29:13 -07:00
Yuneng Jiang
4602376977
fix(proxy): report a stored alerting value as db even when it is null
A stored null or empty list for a nested alerting field is still the value
the proxy serves when the config file leaves alerting_args alone, so the
source is db. Keying off the value rather than its presence reported those
fields as default and hid a stored setting that is genuinely in effect.

Presence in the stored row now decides, with the config file still checked
first so a config-owned key keeps reporting config. Test helpers are typed
and the router test injects a stub rather than patching a class attribute.
2026-09-21 14:24:32 -07:00
yuneng-jiang
5e0512b611
Merge pull request #42291 from BerriAI/litellm_lit7597_detach_credential
fix(proxy): detach stored credential when model editor selects None
2026-09-21 14:05:28 -07:00
mateo-berri
d8ce49de06 fix(proxy): evict the cached user row when SCIM or /user/delete removes a user 2026-09-21 13:51:26 -07:00
Yuneng Jiang
ddf6565970
Merge remote-tracking branch 'origin/main' into litellm_config_read_source 2026-09-21 13:25:45 -07:00
Yuneng Jiang
be2f0d081b
fix(proxy): report sources only on the read endpoints main does not cover
/config/field/info and /config/list already report per-key source on main,
so this drops the branch's versions of those and keeps /alerting/settings,
/get/ui_settings and /router/settings.

Read endpoints no longer write the freshly read database row back into the
shared settings store; the reload path already keeps it current, and a GET
that mutates global state leaks across callers.

Regenerates the lazy OpenAPI snapshot on Python 3.12, matching CI, and the
dashboard API types for the two new response fields.
2026-09-21 13:25:39 -07:00
ryan
baee50546f chore: merge main into litellm_cherry_pick_password_breach_reset
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:54:40 +00:00
yuneng
d69eb7f095 fix(proxy): fall back to the credentials table when validating litellm_credential_name
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:47:27 +00:00
tin-berri
457b01e96d
Merge pull request #42055 from BerriAI/litellm_prompt_caching_request_table
feat(ui): show prompt caching requests and net savings
2026-09-21 12:45:11 -07:00
Joshua Valluru
68074da1d1 test(mcp): cover stable server ordering and sort priorities 2026-09-21 12:39:47 -07:00
Yuneng Jiang
86c4021e83
Merge branch 'main' into litellm_config_read_source
The shared settings-store work this branch was stacked on landed on main,
along with source reporting for /config/field/info and /config/list.
Resolved by taking main for the store, the config routes and their tests,
and re-applying only the read surfaces main does not cover:
/alerting/settings, /get/ui_settings and /router/settings.
2026-09-21 12:36:15 -07:00
Joshua Valluru
f5d511b3f9 Merge remote-tracking branch 'origin/main' into litellm_mcp_server_list_stable_order 2026-09-21 12:33:27 -07:00
yuneng
177021b2ac fix(proxy): gate explicit credential detach only on PATCH /model/{id}/update
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:22:57 +00:00
yuneng
10d343c3ee fix(proxy): detach stored credential when model editor selects None (LIT-7597)
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 19:22:57 +00:00
moe-berri
a83773cfa5
Merge pull request #41886 from BerriAI/litellm_jev_autorouter_launch_1789767495
feat(auto-router): add JEV classifier alongside LLM classifier
2026-09-21 11:55:44 -07:00
ryan
3fe405a5cc feat(auth): breached password detection, self-service change-password and forced password reset
Cherry-pick of merge commit b3882d8e43 (PRs #39321, #39562, #40107), which landed on litellm_internal_staging instead of main.

Co-authored-by: ojensen-berri <ojensen@berri.ai>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 18:48:35 +00:00
ryan-crabbe-berri
5573265013
Merge pull request #41906 from BerriAI/litellm_team_member_budget_source_reset
feat(team): show whether a member follows the team default budget and allow resetting to it
2026-09-21 10:34:08 -07:00
Moe Khalil
bb46e8b774 chore(auto-router): merge main and preserve JEV configuration
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-21 17:16:18 +00:00
yucheng-berri
51ae7ab1fd
Merge pull request #41588 from BerriAI/litellm_ui_session_personal_key_budget_ceiling
* fix(key_generate): use user's budget for UI session personal keys

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

* Update litellm/proxy/management_endpoints/key_management_endpoints.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(user_update): evict cached user on max_budget change so the personal key ceiling refreshes on every worker

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: jesus-berri <jesus@berri.ai>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: yucheng <yucheng@berri.ai>
2026-09-21 10:11:29 -07:00