Commit graph

5939 commits

Author SHA1 Message Date
yassin
f29be6e1ee fix(ui): save the MCP private ranges and client allowlist sequentially
The proxy stores both fields with a whole-row read-modify-write of
general_settings, so two concurrent writes from one save can drop one
of them. Also drops docstrings and suppressions the diff did not need

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:05:35 +00:00
mateo
221dc23ce2 refactor(ui): drop unused cost-tracking barrel re-exports and response types
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:05:06 +00:00
mateo
40782a8bd5 refactor(ui): remove unused createCredentialFromModel helper and CredentialValues interface
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:04:52 +00:00
mateo
b57104be33 chore(ui): remove dead compareUI ModelSelector and its test
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:04:26 +00:00
mateo
b9bfe74628 chore(ui): remove never-rendered GuardrailConfig mock component and its test
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:04:10 +00:00
mateo
be74d2b01f chore(ui): remove orphaned ROLE_STYLES and RoleStyle from pretty messages view
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:04:02 +00:00
mateo
726c2bb6df chore(ui): remove unused NewBadge component and its test
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:03:53 +00:00
mateo
9cbad58a70 refactor(ui): remove unused HelpLink and HelpIcon components
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 20:03:49 +00:00
yassin
d5acbbde6f chore(ui): regenerate schema.d.ts for end_user_budget_id docstrings
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 19:57:44 +00:00
yassin
322262db01 style(ui): format add_agent_form test with prettier
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 19:42:56 +00:00
yassin
5e7888f44d fix(ui): save MCP allowed clients independently of private IP ranges
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 19:34:42 +00:00
mubashir1osmani
9066a32363 Merge remote-tracking branch 'berri/main' into litellm_mistral_ocr_batches
# Conflicts:
#	litellm/batches/batch_utils.py
#	tests/test_litellm/llms/mistral/ocr/test_mistral_ocr_cost.py
2026-09-17 15:34:20 -04:00
ryan-crabbe-berri
648373a260 feat(management_v1): bulk update team member budgets
Adds POST /management/v1/teams/{team_id}/members/bulk_update, a merge patch
over per-member limits (max_budget_in_team, tpm_limit, rpm_limit,
budget_duration, allowed_models) for up to 500 members in one transaction.

Editing a team's default member budget has never reached members who already
have a budget row, because /team/member_add clones the default per member.
This gives admins one call to roll a new cap out across the roster, and each
result carries max_budget_source so a caller can see whether a member is on
their own cap or on the team default.

Reads run on the writer inside the batch transaction, and any budget row more
than one membership points at is cloned before it is written, so raising one
member's cap never moves another's.
2026-09-17 12:30:46 -07:00
yassin
cc11653152 feat(proxy): per-key default budget for dynamically created customers
A service-account key can now carry end_user_budget_id in its metadata. When a request through that key names a customer that does not exist yet, the key's budget is applied to the new customer from the first request and wins over the proxy-wide max_end_user_budget_id. A customer with an explicitly assigned budget keeps it. The Admin UI exposes the setting on service-account key creation and key edit, and only proxy admins may set or clear it.

Resolves LIT-7996

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 19:28:53 +00:00
yassin
b84f8b6a77 feat(agents): attach access groups to agents and enforce them for models, MCP servers and agent calls
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 19:24:14 +00:00
yassin
4212e1ff6f Merge remote-tracking branch 'origin/main' into litellm_transcribe_passthrough 2026-09-17 19:11:49 +00:00
yassin
701c880922 feat(ui): temporary budget increase controls for team members
Adds temp_budget_increase and temp_budget_expiry to the team member edit form with pair validation,
seeds stored values into edit mode, sends both through /team/member_update, and adds cached-key auth
and reservation regression tests for active and expired increases

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 18:56:30 +00:00
yassin
a705e0396e refactor(mcp): type the allowlist 403 body and replay consumed messages immutably
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 18:55:47 +00:00
yassin
47be6c8aeb feat(mcp): allowlist client applications for MCP gateway access
Adds the mcp_allowed_clients general setting, enforced against the
clientInfo.name each MCP client sends in its initialize request. A client
not on the list, or one that does not identify itself, is rejected with
403 before any stateful session is created. The setting is configurable
from config.yaml and from the Admin UI MCP network settings page

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 18:34:36 +00:00
yassin
cf07ee1dec Merge remote-tracking branch 'origin/main' into litellm_usage_key_free_aggregate_split
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 17:55:10 +00:00
Devin AI
7c1eb197bf chore(ui): regenerate dashboard API types for team member temp budget fields
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 17:52:20 +00:00
mateo
9b7fcd0480 feat(router): add TypeSafe Jev as a complexity router classifier
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 17:05:07 +00:00
Tin Chi Lo
2fa115db2b feat(router): add maintained Fuse model and harness presets 2026-09-17 12:53:15 -04:00
mateo
7fca7fae37 fix(proxy): satisfy TypeSafe CI gates
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 16:20:47 +00:00
yucheng
9a365d2021 feat(proxy): hard-block throttled Admin UI sign-ins with no credential bypass
A blocked source, or source and username pair, is now refused with 429 before the database lookup and password check, in place of the soft block that held wrong guesses for 30 seconds and let a correct password through. The env admin credentials and the master key typed into the login form are refused like any other credential while blocked; recovery is the master key as an API bearer token, which never goes through the sign-in path

trusted_proxy_ranges: [] now means clients connect directly, so the peer address is the source and the per-source limit stays on. Only an unset or malformed value leaves the topology unknown, warns at startup and turns the per-source limit off

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 16:10:23 +00:00
yucheng
8164189237 test(ui): cover a negative policy attachment priority typed keystroke by keystroke
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 07:56:43 +00:00
yucheng
669a66499c feat(policy_engine): bound priority to int32 and expose it in the Admin UI
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 06:47:53 +00:00
Devin AI
1b1f6ada46 fix(policy_engine): make priority migration idempotent
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 06:12:42 +00:00
ryan-crabbe-berri
8b64f1ef03
Merge pull request #41525 from BerriAI/litellm_team_admin_rpm_budget_fields
feat(proxy): let team admins edit rpm_limit and max_budget when enabled
2026-09-16 20:39:05 -07:00
yassin
2e8dc0a627 feat(proxy): add Azure AI Speech pass-through route
Adds /azure_speech/{endpoint:path}, an authenticated pass-through for the Azure AI Speech REST APIs: short-audio recognition on <region>.stt.speech.microsoft.com and batch transcription on <region>.api.cognitive.microsoft.com. The proxy resolves the subscription key through PassthroughEndpointRouter (AZURE_SPEECH_API_KEY or an Admin UI credential), picks the host from AZURE_SPEECH_REGION or AZURE_SPEECH_API_BASE, injects Ocp-Apim-Subscription-Key, strips the caller's Authorization and subscription-key headers, forwards the raw audio body byte for byte, and records a zero-cost SpendLogs row tagged azure_speech since the price map has no Azure Speech STT entry

Resolves LIT-7939

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 03:03:19 +00:00
yassin
15bfe8f28a feat(vault): add separate login and secret namespaces for HashiCorp Vault
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-17 01:41:48 +00:00
mateo-berri
d8c3a38a51 Merge remote-tracking branch 'origin/main' into litellm_jwt_token_exchange_grant
# Conflicts:
#	tests/test_litellm/proxy/auth/test_auth_checks.py
2026-09-16 18:17:57 -07:00
ryan-crabbe-berri
d3f0607820 test(ui): find the max_budget checkbox by its new label 2026-09-16 17:50:57 -07:00
yassin
291a43c409 Merge remote-tracking branch 'origin/main' into litellm_transcribe_passthrough 2026-09-17 00:44:17 +00:00
ryan-crabbe-berri
37c56df054 feat(proxy): let team admins edit rpm_limit and max_budget when enabled
Adds both fields to the team admin editable allow-list and the dashboard's team admin form. The existing budget authority check still stops a team admin from raising or removing a standalone team's budget.
2026-09-16 17:25:36 -07:00
ryan-crabbe-berri
3dfd24a8da
Merge pull request #41445 from BerriAI/litellm_ui_url_state_orgs-projects
feat(ui): persist organizations and projects list, detail tab and key table state in the URL
2026-09-16 17:17:01 -07:00
ryan-crabbe-berri
43713f7508
Merge pull request #39996 from BerriAI/litellm_team_admin_editable_fields
feat(proxy): let proxy admins choose which team fields team admins may edit
2026-09-16 17:07:13 -07:00
yassin
8bd598f13c feat(proxy): add Amazon Transcribe SigV4 pass-through routes
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:48:15 +00:00
ryan-crabbe-berri
3ee8d43fdd fix(ui): send only a changed TPM limit from the team admin settings form
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled
Save stays disabled until the value differs from the team's, so an unchanged form never reaches /team/update
2026-09-16 16:37:35 -07:00
ryan-crabbe-berri
249a23b09c chore(ui): prune stale eslint suppressions for projects page 2026-09-16 16:12:48 -07:00
ryan-crabbe-berri
ef8e066c77 fix(ui): address review on orgs-projects url state
Keep /projects list paging as a pushed history entry, validate the
project key table page size against its offered options, and clear the
key table params through the table-state setters instead of a copied
key list.
2026-09-16 16:12:48 -07:00
ryan-crabbe-berri
df2dd9b7f2 feat(ui): keep projects search and project key table state in the URL
The projects list search lives in ?project_search= and its pagination now goes through useUrlTableState, keeping the page and page_size keys. The key table inside a project reads keys_search, keys_page and keys_page_size, resets to its first page on a new search, and no longer snaps a deep-linked page while the key fetch is failing. Closing a project drops its keys_ params so they do not leak into the next project
2026-09-16 16:12:47 -07:00
ryan-crabbe-berri
417cc5c4fb feat(ui): keep organizations list and detail tab state in the URL
The organizations list now reads its search (org_search), org ID filter (filter_org_id), sort (sort_by, sort_order) and pagination (page, page_size) from the URL through useUrlTableState. The detail view tabs are controlled by ?org_tab=, and the Edit row action opens ?org=<id>&org_tab=settings in one history entry instead of passing an editOrg flag
2026-09-16 16:12:47 -07:00
yucheng
db97616149 chore: merge main into litellm_lit5285_login_rate_limit_v2
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-16 23:02:23 +00:00
ryan-crabbe-berri
d29753c521 fix(ui): let another tab's column save replace a toggle this tab could not save
A column toggle that localStorage refused was kept in memory and read ahead of storage, so a later save from another tab stayed hidden until this tab saved again. A storage event now drops the in-memory copy for its key, or all of them when another tab clears storage
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
adc937c493 fix(ui): read persisted column visibility from storage instead of a mounted copy
usePersistedColumnVisibility kept a useState copy seeded once at mount, so a later tableId or defaults change showed the old table's columns and saved them under the new key. It now reads localStorage through useSyncExternalStore, keeping only writes that storage refused in memory, so the hook has no copy to go stale. Stored choices are layered over the defaults on every read, and changes saved in another tab show up.
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
4d30bbce45 fix(ui): keep controlled client-side table pages across data reloads
Controlled client-mode DataTables no longer let TanStack reset the page index when rows change, since the owner of the pagination state decides the page. Once rows settle, a page past the end snaps back to the last page, matching server mode
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
eda81fff59 feat(ui): shared URL-state layer for tables and tabs
Add useUrlTableState (search, sort, page, page size and filter_<column>
in the query string via one nuqs useQueryStates call, with keyPrefix and
urlKeys for routes that host two tables or need legacy key names) and
useUrlTab (validated ?tab= param with a role-aware fallback). Migrate
the Virtual Keys table onto useUrlTableState with a byte-identical URL
contract and bind the Playground tab strip to ?tab=.

DataTable gains controlled columnVisibility/onColumnVisibilityChange
plus usePersistedColumnVisibility (localStorage per table id), and an
isError prop that keeps the server page clamp from rewriting a
deep-linked ?page= after a failed fetch. Virtual Keys uses both.

The expired-session redirect in handleError now keeps the query string
and hash so the return URL captured on re-login restores the filtered
view instead of the bare list.

Delete useTabRouting and tabRoutes, the pathname tab router left over
from the reverted path-per-tab attempt (#34327, reverted in #34629);
tab persistence has to be a query param on the static export.
2026-09-16 15:51:45 -07:00
ryan-crabbe-berri
cac521246a style(ui): right-align the Save banner button 2026-09-16 15:38:30 -07:00
ryan-crabbe-berri
d9de2fc5f7 style(ui): right-align the team admin editable fields Save button 2026-09-16 15:38:30 -07:00