Commit graph

41660 commits

Author SHA1 Message Date
Mateo Wang
053e64e11b
Merge pull request #32979 from BerriAI/litellm_anchor_bedrock_routing_regex
fix(proxy-auth): stop unrecognized model namespaces slipping through provider wildcard keys
2026-07-11 19:18:27 -07:00
Abhimanyu Kapur
d6883d15b0 fix(auto_router): flag name field and tier fields together on empty submit
Clicking Add Auto Router with the name empty returned early with only a
toast, so blank tier selects never got their inline error state. The
empty-name branch now sets showValidationErrors and triggers antd
validation on the name field, so every unfilled mandatory field is
flagged at once. Adds a regression test for the tab component.
2026-07-11 19:08:07 -07:00
Abhimanyu Kapur
3464b5e7df fix(auto_router): reset inline validation errors when switching router type 2026-07-11 19:03:48 -07:00
mateo-berri
d0d1c0e346 fix(proxy-auth): deny provider-wildcard access inferred through an unrecognized model namespace 2026-07-11 19:00:03 -07:00
mateo-berri
2ed4ceb12e fix(model-cost-map): anchor the bedrock-claude-ids routing rule to the start of the id 2026-07-11 19:00:03 -07:00
Abhimanyu Kapur
0de308a5b8 fix(auto_router): filter embedding models out of tier selects, require all tiers, add inline validation
The Add Auto Router complexity tab let chat models fill the embedding-model
slot (and vice versa) since neither dropdown filtered on ModelGroup.mode, and
submit only required at least one of the four tiers instead of all four. Adds
getMissingTiersError alongside the existing getSemanticConfigError, and
highlights unfilled tier/embedding selects inline once a submit attempt fails.
2026-07-11 18:18:37 -07:00
ryan-crabbe-berri
5fc1a3c671
refactor(ui): convert endpoint usage charts to shadcn/recharts (#32723)
* refactor(ui): convert endpoint usage charts to shadcn/recharts

Adds a LineChart wrapper to the shared charts kit, mirroring the
BarChart/AreaChart composition with connectNulls and curveType props,
and converts EndpointUsageBarChart and EndpointUsageLineChart from
tremor to the shared wrappers. Both endpoint chart tests now assert on
real recharts SVG output instead of tremor mocks.

* refactor(ui): drop unused endpointData prop from EndpointUsageLineChart

* fix(ui): point endpoint chart test type imports at the UsagePage types alias after colocation move
2026-07-11 18:16:18 -07:00
mateo-berri
0008d96af4 docs(github): add Final Attestation and per-test sanity-check step to QA runbook 2026-07-11 18:07:37 -07:00
ryan-crabbe-berri
b6dbda48f9
refactor(ui): colocate the mcp-servers view, keeping the shared mcp_tools surface (#32968)
* refactor(ui): colocate the usage view, keeping the shared usage components

Split for the usage (UsagePage) segment. Most of the folder is the usage page's
own view, but four pieces are reused elsewhere and stay in @/components/UsagePage:
TopKeyView (old-usage), KeyModelUsageView and value_formatters (activity_metrics),
and the shared types (activity_metrics, chartUtils). The other 21 files move into
usage/_components, preserving the folder structure.

The external consumers import only the retained files, so they are untouched. The
moved files' imports of the retained files become @/components/UsagePage paths,
other escaping relative imports are absolutized, and lint suppressions are re-keyed
for moved files only. No behavior change.

* refactor(ui): colocate the mcp-servers view, keeping the shared mcp_tools surface
2026-07-11 18:01:41 -07:00
ryan-crabbe-berri
8c5473f198
feat(ui): adopt openapi-react-query ($api) and convert useCustomers (#32949)
* feat(ui): adopt openapi-react-query and convert useCustomers to $api

Add openapi-react-query and expose $api = createQueryClient(fetchClient)
alongside fetchClient. Rewrite useCustomers as
$api.useQuery("get", "/customer/list", {}, { enabled, select }), which
derives the query key from method + path (dropping the hand-written
createQueryKeys entry and the manual key) and forwards the request signal
for cancellation. The response type still flows from schema.d.ts as
CustomerResponse[]. Tests assert the path, the admin/token enabled gate,
and the empty-body select fallback.

* test(ui): read the last render's options in useCustomers helper

The lastCallOptions helper was named for the last call but read
mock.calls[0]. Harmless while each test renders once, but it would
silently assert against first-render options if a test ever re-renders.
Read the final call instead.
2026-07-11 18:01:33 -07:00
yucheng-berri
f947ef14a2
fix(xecguard): use StandardLoggingGuardrailInformation in logging hook (#32911)
XecGuard's async_logging_hook wrote a bare dict to
standard_logging_object["guardrail_information"] while the typed
contract is Optional[List[StandardLoggingGuardrailInformation]].
Readers that iterated the field walked dict keys, raised on
info.get, or silently dropped the entry from guardrail usage
tracking and spend-log writes

Construct the typed entry and append it to the existing list or
create a new one, matching the shared helper pattern. Record the
configured guardrail name instead of a hardcoded "xecguard" and
pass the GuardrailEventHooks enum for guardrail_mode
2026-07-11 17:50:13 -07:00
Abhimanyu Kapur
81db114c40
Merge pull request #32950 from BerriAI/litellm_auto_router_test_connection
feat(ui): working Test Connection for the complexity auto router
2026-07-11 17:45:46 -07:00
yuneng-jiang
10d5804b3e
Merge pull request #32884 from BerriAI/litellm_internal_staging
Some checks failed
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
CodSpeed Benchmarks / benchmarks (push) Has been cancelled
Helm unit test / unit-test (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
GitHub Actions Security Analysis / zizmor (push) Has been cancelled
chore(ci): promote internal staging to main
2026-07-11 17:42:56 -07:00
ryan-crabbe-berri
d37ba79ebd
refactor(ui): convert projects page chart to shadcn/recharts (#32722) 2026-07-11 17:22:42 -07:00
mateo-berri
a6c8fb2d1c docs(github): shape QA runbook examples as node id plus behavior bullets 2026-07-11 17:21:36 -07:00
mateo-berri
1d589832c7 docs(github): scope the QA runbook to tests/e2e edits and add example checklists 2026-07-11 17:18:22 -07:00
mateo-berri
2deeeb73a7 docs(github): add QA runbook section to the PR template 2026-07-11 17:12:38 -07:00
mateo-berri
a76dd9bf8e test(e2e): cover model-aware mid-conversation system handling on Bedrock Invoke /v1/messages 2026-07-11 17:08:16 -07:00
yuneng-jiang
4baeb283f3
chore: update Next.js build artifacts (2026-07-11 23:35 UTC, node v20.20.2) (#32960) 2026-07-11 17:02:04 -07:00
ryan-crabbe-berri
ca877c78c3
refactor(ui): colocate the usage view, keeping the shared usage components (#32952)
Split for the usage (UsagePage) segment. Most of the folder is the usage page's
own view, but four pieces are reused elsewhere and stay in @/components/UsagePage:
TopKeyView (old-usage), KeyModelUsageView and value_formatters (activity_metrics),
and the shared types (activity_metrics, chartUtils). The other 21 files move into
usage/_components, preserving the folder structure.

The external consumers import only the retained files, so they are untouched. The
moved files' imports of the retained files become @/components/UsagePage paths,
other escaping relative imports are absolutized, and lint suppressions are re-keyed
for moved files only. No behavior change.
2026-07-11 16:51:44 -07:00
ryan-crabbe-berri
cb24864a7f
feat(proxy): add expires filter to GET /key/list (#32953)
* feat(proxy): add expires filter to GET /key/list

Add an opt-in expires query param to GET /key/list so callers can fetch
only expired or only active keys without paginating every page and
filtering client-side. 'expired' matches keys whose expires is in the
past (NULL expires excluded); 'active' matches keys that never expire or
expire in the future. Omitting the param preserves existing behavior for
every caller. An unrecognized value returns HTTP 400 rather than silently
returning all keys.

The filter is pushed to the database via the existing Prisma where
builder so callers avoid pulling the full key table into application
memory.

Resolves LIT-3387

* refactor(proxy): declare VALID_EXPIRES_FILTER_VALUES before its first use
2026-07-11 16:48:25 -07:00
yuneng-jiang
03970d7c3a
bump: litellm-proxy-extras 0.4.75 -> 0.4.76 (#32957) 2026-07-11 16:48:08 -07:00
mateo-berri
cc27528d4f test(main): assert the responses bridge forwards static aws keys as well as web identity params 2026-07-11 16:47:00 -07:00
Abhimanyu Kapur
a80f85692b fix(ui): drop max_tokens from the auto-router connection probe
max_tokens=1 makes reasoning models (o1/o3/...) return a 400 "max_tokens
reached" because reasoning tokens count against the cap, so a reachable
reasoning tier showed a false failure in Test Connection. Live-verified: o3
400s with the cap and succeeds without it.

Extract the request shape into a pure buildModelGroupTestRequest and cover it
with a test asserting the chat body carries no max_tokens (or
max_completion_tokens), so this regression is caught in unit tests instead of
only against a live reasoning model.
2026-07-11 16:43:36 -07:00
Mateo Wang
5e1928c753
Merge pull request #32928 from BerriAI/litellm_quota_management_registry
refactor(e2e): bucket rate limits, budgets, and spend tracking under quota_management
2026-07-11 16:40:43 -07:00
mateo-berri
201730efe5 fix(bedrock): allow bedrock-mantle:CreateInference in the web identity session policy 2026-07-11 16:35:13 -07:00
yucheng-berri
e7f41442d0
feat(guardrails): add pre_mcp_call support to Content Filter (#32936)
* feat(guardrails): add pre_mcp_call support to Content Filter

* test(guardrails): cover canonical MCP key gate under pre_mcp_call mode

* fix(guardrails): scan MCP arguments per value and gate mixed-mode scans by call type

* fix(guardrails): cap MCP argument scan depth and register the walker with the recursion detector

* test(guardrails): update LIT-4226 UI settings tests for content filter pre_mcp_call support

* fix(guardrails): use builtin generics in MCP scan annotations to satisfy strict-rule budget

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 16:17:49 -07:00
mateo-berri
36dff0f63a test(e2e): source the ratelimit suite's model from E2E_CHEAP_ANTHROPIC_MODEL 2026-07-11 16:15:16 -07:00
mateo-berri
ca55fc2deb refactor(e2e): model the tpm spend loop's two outcomes as values 2026-07-11 16:15:16 -07:00
mateo-berri
9f55925c31 test(e2e): name the tpm window deadline's latency margin 2026-07-11 16:15:16 -07:00
mateo-berri
6f2435b54a test(e2e): fail the rpm reset test when the limiter resets early 2026-07-11 16:15:16 -07:00
mateo-berri
1ca1a9cd03 test(e2e): assert the tpm block at its exact token crossing instead of a call-count heuristic 2026-07-11 16:15:16 -07:00
mateo-berri
b9aef1b810 test(e2e): cover key rpm/tpm rate limiting, window reset, and pacing headers 2026-07-11 16:15:16 -07:00
mateo-berri
d37daf0b9f refactor(e2e): move budgets and spend_tracking suites under quota_management 2026-07-11 16:14:21 -07:00
mateo-berri
8225ddf2a4 fix(e2e): name the route the spend_calculate registry cell actually exercises 2026-07-11 16:13:48 -07:00
mateo-berri
320a55f01f refactor(e2e): bucket rate limits, budgets, and spend tracking under quota_management 2026-07-11 16:13:48 -07:00
ryan-crabbe-berri
0710cf2990
refactor(ui): convert entity usage and usage page charts to shadcn/recharts (#32729)
* refactor(ui): convert entity usage and usage page charts to shadcn/recharts

Swap the tremor BarChart/DonutChart render sites in EntityUsage,
SpendByProvider, TopKeyView, TopModelView, KeyModelUsageView and
UsagePageView to the shared shadcn/recharts wrappers. Convert the two
sole-chart Daily Spend cards and the KeyModelUsageView card to the
shadcn Card primitives.

Close the donut parity gap with strictly additive optional DonutChart
props: showLabel/label render a center total (tremor showed
valueFormatter(sum) by default) and startAngle/endAngle forward to the
Pie so both provider donuts keep tremor's clockwise-from-12 layout.
Defaults preserve the previous wrapper behavior.

DailyData and two site-local row types move from interface to type
alias so they satisfy the wrappers' Record<string, unknown> constraint;
interfaces lack implicit index signatures.

Tests now assert on real recharts output: bar/sector counts, cyan
fills, axis labels, donut center totals, and the TopKeyView bar-click
drill-down into the key info modal. The dead tremor chart mocks in
UsagePageView.test.tsx are removed and lint metrics/suppressions are
regenerated for the dropped tremor imports.

* fix(ui): compute donut center label only when shown and assert Model Usage renders as a card title
2026-07-11 16:11:05 -07:00
mateo-berri
e0463a38ff fix(completion): forward aws credential kwargs into litellm_params so the responses bridge keeps WIF auth
Chat-completions requests to responses-only Bedrock Mantle models are
bridged to the Responses API, but completion() forwarded only
aws_bedrock_project_id into get_litellm_params, so aws_role_name,
aws_web_identity_token, aws_session_name and the other SigV4 credential
kwargs never reached sign_request and botocore fell back to the default
credential chain ("Bedrock Mantle auth failed: no Bearer token and no
usable AWS credentials"). Forward the whole AWS credential kwarg family,
extracted from the OPTIONAL_KWARGS_KEYS set get_litellm_params already
supports.
2026-07-11 16:10:39 -07:00
Abhimanyu Kapur
ddc13b331a fix(ui): probe auto-router tiers via real proxy routing, not /health/test_connection
Live testing showed the first cut was broken: /health/test_connection merges
{...configParams, ...requestParams}, so passing the public model_group name as
the request model overrode the resolved provider model and every tier failed
with "LLM Provider NOT provided". The frontend only has the public group name,
not the underlying litellm_params, so it cannot build the request that endpoint
needs.

Switch to testing each model group the way production actually routes it: send a
minimal request to /v1/chat/completions (or /v1/embeddings for the embedding
model) by public group name through the shared apiClient. The router resolves
the group, credentials, and provider itself, so a green row means the tier is
genuinely reachable. Verified live: voyage embedding returns 200, a tier with a
bad key returns the real provider auth error.

Also address Greptile feedback: rows now update progressively as each probe
settles instead of all at once, and TIER_ORDER is derived through a
`satisfies Record<keyof ComplexityTiers, null>` guard so adding a tier without
listing it is a compile error.
2026-07-11 16:04:04 -07:00
yuneng-jiang
f2fb6b8e73
refactor(ui): extract a shared CopyButton and fix the sidebar copy confirmation (#32945)
* fix(ui): show sidebar copy confirmation only on a successful write

The sidebar account menu's copy button switched to the checkmark
synchronously, before the clipboard write settled, so it confirmed a
copy that never happened when navigator.clipboard was undefined on
non-secure origins or when writeText rejected. The handler now guards
navigator.clipboard, awaits the write, and flips to the checkmark only
on success

Also updates the header accent emoji in the same menu

* refactor(ui): extract a shared CopyButton for the sidebar account menu

The copy-icon-to-checkmark pattern was hand-rolled in several places,
including the sidebar account menu whose private copy button held the
false-confirmation bug. Extract a single canonical CopyButton into
components/shared, built on the Button primitive with a guarded and
awaited clipboard write so the checkmark appears only on a real
success, and have SidebarAccountMenu consume it

The success and failure-mode coverage now lives in the shared
component's own test; the sidebar test keeps one case asserting the
email row is wired to it
2026-07-11 15:47:03 -07:00
Abhimanyu Kapur
2b2e8cf2bf feat(ui): working Test Connection for the complexity auto router
The consolidated auto-router tab dropped the Test Connection button because
the shared prepareModelAddRequest helper returns an empty array for an auto
router (it has no model_mappings), so the caller crashed destructuring
result[0].litellmParamsObj. That is the crash in #31590 and the open PR
#31794. #31794 only silenced the crash by pointing the test at
auto_router/complexity_router, which is not a provider model, so the
/health/test_connection health check (a real litellm.ahealth_check
completion) would still error.

Bring the button back and make it meaningful: an auto router dispatches to
saved model groups, so Test Connection now probes those directly. It builds
a deduped target list from the configured tiers (tiers sharing a model group
collapse to one probe) plus the embedding model when semantic keyword
matching is on, then runs a live /health/test_connection against each and
shows per-target pass/fail. This never touches prepareModelAddRequest, so the
original destructure crash cannot recur.

Scope is the recommended complexity router only; the to-be-deprecated
semantic router is untouched. No backend changes.

Supersedes #31794. Resolves #31590.
2026-07-11 15:44:50 -07:00
Shivam Rawat
173193d717
Merge pull request #32942 from BerriAI/litellm_dashscope_price_issues
fix(proxy): enforce budget and cost tracking for Dashscope tiered pricing
2026-07-11 15:40:20 -07:00
Abhimanyu Kapur
922e2480e5
Merge pull request #32876 from BerriAI/litellm_opus_4_5_effort_comment
docs(anthropic): clarify the Opus 4.5 branch in adaptive-effort translation
2026-07-11 15:35:25 -07:00
ryan-crabbe-berri
0ebcda3027
refactor(ui): convert user agent and per-user usage charts to shadcn/recharts (#32725)
* refactor(ui): convert user agent and per-user usage charts to shadcn/recharts

Swap the tremor BarChart import for the shared shadcn/recharts wrapper in
user_agent_activity.tsx (DAU/WAU/MAU charts) and per_user_usage.tsx (usage
distribution histogram). All chart props are unchanged; the wrapper exposes
the same tremor prop surface with matching defaults.

Extend user_agent_activity.test.tsx and add per_user_usage.test.tsx with
parity assertions on the real recharts SVG output: bar series per category,
stacked x positions, resolved fill colors, axis bucket labels, legend text,
and value formatter output on axis ticks. Remove the dead ResizeObserver
polyfill in user_agent_activity.test.tsx now that the scoped global mock in
tests/setupTests.ts renders charts, which also lowers the no-explicit-any
metric by one.

* test(ui): harden bar x-position parsing against recharts path format
2026-07-11 15:20:18 -07:00
tin-berri
0772668f33
Merge pull request #32824 from BerriAI/litellm_lit4338_delegate_admission
feat(mcp): admit dcr_bridge oauth_delegate clients via a single envelope bearer
2026-07-11 14:59:35 -07:00
Abhimanyu Kapur
7d1e48d8b1
Merge pull request #32943 from BerriAI/litellm_complexity_router_logging
feat(complexity_router): log the cause of each routing decision
2026-07-11 14:55:38 -07:00
Shivam Rawat
0bd831dc5e fix(proxy): reserve tiered output at the higher reasoning rate
Some tiered Dashscope models price reasoning output above standard output
(output_cost_per_reasoning_token > output_cost_per_token). The reservation charged
all output at the standard rate, so a reasoning-heavy request reserved too little
and concurrent calls could exceed the budget before reconciliation. The reasoning
share is unknown before the request runs, so reserve every output token at the
higher of the two configured rates, for both tiered and flat pricing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 14:55:32 -07:00
yucheng-berri
69c5839cc0
fix(guardrails): filter Add-Guardrail mode dropdown per provider (#32712)
* fix(guardrails): filter Add-Guardrail mode dropdown per provider

The GET /guardrails/ui/add_guardrail_settings endpoint returned every
GuardrailEventHooks value in one flat supported_modes list, so the Admin
UI rendered pre_mcp_call as a selectable Mode for every guardrail. Saving
Content Filter or Tool Permission with pre_mcp_call then failed with a
400 because those guardrails' server-side supported_event_hooks list
excludes it.

Expose each guardrail's supported hooks as a get_supported_event_hooks
classmethod on CustomGuardrail (mirrors the existing get_config_model
pattern) and have the endpoint iterate guardrail_class_registry to build
a supported_modes_by_provider map. The UI Mode dropdown filters by that
map when the selected provider is known and falls back to the global
list otherwise. __init__ now sources its own supported_event_hooks list
from the classmethod so the two sides can't drift.

Also register BedrockGuardrail, ToolPermissionGuardrail, lakera,
lakera_v2, and presidio in guardrail_class_registry so they participate
in the map (they were previously only in guardrail_initializer_registry
and had no class-registry entry).

Behavior change: guardrails that previously had no supported_event_hooks
declared (aim, javelin, azure/text_moderation, cato_networks,
crowdstrike_aidr, headroom, hiddenlayer, lasso, noma, onyx,
prompt_security, qualifire, repelloai, zscaler_ai_guard, aporia_ai,
lakera_ai, lakera_ai_v2, mcp_jwt_signer, model_armor, presidio) now
validate the configured mode at instantiation. Existing configs where
the mode was silently a no-op will fail at proxy startup with a clear
validation error rather than running as a broken guardrail.

Resolves LIT-4226

* fix(guardrails): add LITELLM_STRICT_GUARDRAIL_MODES escape hatch, preserve current mode in edit form

Address Greptile P1 (startup break) and P2 (edit form UX):

LITELLM_STRICT_GUARDRAIL_MODES defaults to true (raise on unsupported
event_hook, unchanged behavior for the guardrails validated pre-PR).
Setting it to false logs a warning and continues, giving deployments an
opt-out while they fix configs that now surface as errors instead of
silently no-op'ing. Regression test covers both modes.

Edit form now surfaces the currently-saved mode even when it is not in
the filtered per-provider list, so a legacy row (e.g. content_filter
saved with pre_mcp_call before this fix) no longer disappears from the
dropdown; the option renders with a 'not supported by <provider>' note
so the user knows to pick another.

* fix(guardrails): correct audited hook lists, prune stale modes on provider switch, clean form lint

Audited every get_supported_event_hooks classmethod against the hooks
each guardrail's own tests exercise and its handler methods. Five were
too narrow and their tests caught it in CI: rubrik gains pre_call,
presidio gains during_call and pre_mcp_call, prompt_security, onyx and
qualifire gain during_call. The remaining classes match either their
original __init__ declarations or their exercised modes exactly.

Cursor review fixes: the Add form now drops selected modes the new
provider does not support when the user switches providers, so a
pre_mcp_call selection cannot ride along into a provider that rejects
it at save; the edit form handles list-shaped stored modes instead of
treating mode as always a string.

Extracted shared toModeArray and getSupportedModesForProvider helpers
into guardrail_info_helpers so both forms use one implementation, typed
the remaining any usages in both forms, removed nested ternaries, and
committed the ratcheted-down eslint metrics and pruned suppressions
2026-07-11 14:51:27 -07:00
Abhimanyu Kapur
a5b0f32a84 test(bedrock-converse): cover adaptive-thinking drop when max_tokens too small
Adds the regression test for the warning-drop branch in the Converse
adaptive-thinking translation, mirroring the chat completions path's
test_raw_adaptive_thinking_dropped_when_max_tokens_too_small.
2026-07-11 14:50:32 -07:00
Abhimanyu Kapur
b58ccb092e fix(anthropic): pass resolved provider to adaptive-thinking check
The rebase onto staging changed _is_adaptive_thinking_model to require
custom_llm_provider (no default), so the one-arg call in the raw adaptive
thinking branch raised TypeError at runtime for any /chat/completions
caller sending thinking={type: adaptive}. Use self._resolved_provider,
matching the reasoning_effort branch just below. Caught by Greptile.
2026-07-11 14:48:14 -07:00