Commit graph

43876 commits

Author SHA1 Message Date
yuneng-jiang
c9917cbf99
Merge pull request #36918 from BerriAI/litellm_shadcn_modelhub_0814
refactor(ui): move the model hub and model select onto shadcn primitives
2026-08-14 10:33:24 -07:00
yuneng-jiang
5156bf04b6
Merge pull request #36915 from BerriAI/litellm_shadcn_settings_0814
refactor(ui): migrate router settings and shared badges off antd and tremor
2026-08-14 10:28:02 -07:00
Armaan Sandhu
e1f3d6e158
feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery (#35455)
* feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery

* refactor(proxy): move Anthropic model-list formatter into llms/anthropic/common_utils

* fix(proxy): make model_list request param optional for direct callers

* style: apply ruff format to changed lines

* style: satisfy ruff strict-rule budget (UP006, I001)

* style: satisfy type-discipline budget (LIT002 mutable-ok, LIT009 pyright ignore)

* style: satisfy LIT001/LIT010 and drop explanatory comment per contributor rules

* fix(proxy): translate team model names in the Anthropic /v1/models response

* ci: trigger buildkite status report

* feat(proxy): carry token limits into the Anthropic-native /v1/models entries

* fix(proxy): cast the injected request so the anthropic-version guard is a real comparison

* fix(proxy): explain the model listing casts so the type-discipline gate passes

---------

Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-08-14 10:22:58 -07:00
yuneng-jiang
3d35cff9f5
Merge pull request #36913 from BerriAI/litellm_shadcn_permissions_0814
refactor(ui): migrate key info and permissions views off antd and tremor
2026-08-14 10:15:28 -07:00
yuneng-jiang
10df18be66
Merge pull request #36910 from BerriAI/litellm_shadcn_common_0814
refactor(ui): migrate shared common_components off antd and tremor
2026-08-14 10:11:52 -07:00
yuneng-jiang
609ecf06c2
Merge pull request #36866 from BerriAI/litellm_/remove-test-migrate-gha-d1eae8
ci: drop the duplicate proxy_unit_tests letter-shard workflow
2026-08-14 10:11:08 -07:00
Yuneng Jiang
693683c013
Merge branch 'litellm_internal_staging' into litellm_shadcn_modelhub_0814 2026-08-14 09:59:57 -07:00
Yuneng Jiang
30c1b972d4
Merge branch 'litellm_internal_staging' into litellm_shadcn_settings_0814 2026-08-14 09:59:20 -07:00
Yuneng Jiang
e897e2b0aa
Merge branch 'litellm_internal_staging' into litellm_shadcn_permissions_0814 2026-08-14 09:59:12 -07:00
Yuneng Jiang
da339a7e8a
Merge branch 'litellm_internal_staging' into litellm_shadcn_common_0814 2026-08-14 09:57:34 -07:00
Yuneng Jiang
7e375ed6e8 chore: retrigger e2e gate 2026-08-14 09:48:49 -07:00
yuneng-jiang
b77923fc87
Merge pull request #36955 from BerriAI/litellm_shadcn_next_0814
refactor(ui): move the cost tracking components onto shadcn primitives
2026-08-14 09:46:30 -07:00
yuneng-jiang
48a3423aed
Merge pull request #36936 from BerriAI/litellm_shadcn_rootbig_0814
refactor(ui): move the settings page and bulk user invite onto shadcn primitives
2026-08-14 09:41:07 -07:00
yuneng-jiang
8c168177ec
Merge pull request #36927 from BerriAI/litellm_shadcn_rootcomponents_0814
refactor(ui): move the root-level dashboard components onto shadcn primitives
2026-08-14 09:40:54 -07:00
yuneng-jiang
cb33d204f4
Merge pull request #36924 from BerriAI/litellm_shadcn_dropdowns_0814
refactor(ui): move the shared dropdowns and selectors onto shadcn primitives
2026-08-14 09:40:49 -07:00
yuneng-jiang
de57ebbad9
Merge pull request #36908 from BerriAI/litellm_shadcn_aihub_0814
refactor(ui): migrate AI Hub off antd and tremor to shadcn
2026-08-14 09:39:00 -07:00
yuneng-jiang
5ab91b3f07
Merge pull request #36904 from BerriAI/litellm_shadcn_viewlogs_0814
refactor(ui): migrate log details drawer off antd to shadcn
2026-08-14 09:38:51 -07:00
yuneng-jiang
5374e0b0c7
Merge pull request #36902 from BerriAI/litellm_shadcn_navbar_0814
refactor(ui): migrate Navbar off antd to shadcn
2026-08-14 09:36:38 -07:00
Yuneng Jiang
035f8d5f8a
refactor(ui): move the cost tracking components onto shadcn primitives
Rebuilds the provider discount and margin tables, the pricing calculator and
its multi-cost results on the in-repo shadcn layer, and swaps the imperative
antd modal.confirm removals for AlertDialog. Row actions gained accessible
names, which replace the Tremor stub mocks the tests used to drive.
cost_tracking_settings keeps its two antd Modals and Forms, since they wrap
the two add forms that stay on antd for now.
2026-08-14 09:36:16 -07:00
Shivi Jain
312d12fe0c fix(proxy): enforce project ITPM/OTPM quota on every Responses WebSocket frame
The connection-level pre-call hook only ran once per WebSocket
connection, so a project caller could send unlimited high-token
response.create frames after a single minimal reservation. Adds
enforce_project_io_token_quota_for_frame to the v3 rate limiter and
wires it into both the native and managed WebSocket handlers via a
duck-typed litellm.callbacks lookup, so the SDK layer stays free of
proxy imports. A rejected frame gets an error event; the connection
stays open for the client to retry.

Also fixes the RET504 and BLE001 strict-lint-budget violations the
litellm_internal_staging merge introduced in
parallel_request_limiter_v3.py, which were failing the lint check.
2026-08-14 21:39:34 +05:30
pokepoke81
732e23a4f9
Remove comment about prompt-cache usage in test
Remove outdated comment regarding prompt-cache counts in chunk_parser.
2026-08-14 11:24:30 -04:00
Shivi Jain
a9227057a1 Resolving merge conflicts and verai comment for batch 2026-08-14 20:52:05 +05:30
Yuneng Jiang
3170fff768
refactor(ui): move the settings page and bulk user invite onto shadcn primitives
Rebuilds settings.tsx and bulk_create_users_button.tsx on the in-repo shadcn
layer. The settings callback form moves from antd Form to react-hook-form with
the shared Field primitives, and the CSV drop zone replaces antd Upload with a
native file input plus drag handlers. Both public prop signatures are
unchanged, so no caller moves.
2026-08-14 07:49:33 -07:00
pokepoke81
ce66cbce0e fix(databricks): surface prompt-cache token counts in streaming usage
chunk_parser built ModelResponseStream without passing usage, so the
cache_read_input_tokens and cache_creation_input_tokens that Databricks
returns for Anthropic models never reached the cost calculator. Every
streamed request was billed at the full input rate even when served
from cache.

ModelResponseStream already coerces a usage dict into Usage, which maps
those keys into prompt_tokens_details, so passing the chunk's usage
through is sufficient.
2026-08-14 10:45:21 -04:00
Yuneng Jiang
4544f7dbad
revert(ui): keep the onboarding link modal on antd
The invitation dialog opens over the still-antd Invite User modal. Lifting
only the shadcn dialog content above antd's mask leaves its own backdrop
underneath, so an outside click reaches the wrong modal. Adding a second
backdrop stops that but does not restore dismissal, and the same hazard
already ships in three guardrails modals, so the stacking needs one shared
fix rather than a fourth local workaround.
2026-08-14 07:10:13 -07:00
Yuneng Jiang
15a331f6df
refactor(ui): move the root-level dashboard components onto shadcn primitives
Rebuilds nine components under src/components on the in-repo shadcn layer:
both banners, the navbar chrome, the onboarding link dialog, the model
filters, the model group alias table, the object permissions and logging
settings views, and the user dashboard grid. Every public prop signature is
unchanged, so no caller moves.
2026-08-14 06:52:06 -07:00
Yuneng Jiang
362875a7e6
fix(ui): hold the delete dialog open mid-deletion and keep unmatched select values
DeleteResourceModal let escape, the backdrop and the close button dismiss it
while the delete request was still in flight. SearchSelect blanked its field
whenever the value was missing from options, which happens while they load;
it now falls back to the raw value the way PaginatedSearchSelect already did.
2026-08-14 06:29:49 -07:00
Yuneng Jiang
d7ec4d98b1
test(ui): spread the real lucide-react module in the KeyInfoView mock
The mock returned only CopyIcon and CheckIcon, so any icon a child later
imports resolves to undefined. DeleteResourceModal now renders CircleAlert,
which broke all twelve cases in this file.
2026-08-14 06:22:06 -07:00
Yuneng Jiang
0ee47a0028
test(ui): cover appending a second model in ModelSelect
The rewritten suite only ever picked one ordinary model, so a
regression that replaced the selection instead of appending to it
would have gone unnoticed. The case passes against the antd version
too, so it pins behavior the migration preserves rather than adds.
2026-08-14 06:12:28 -07:00
Devin AI
b066ed3e31 fix(model_prices): correct Gemini 2.5 shutdown dates and DeepSeek V4 max output tokens
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-14 13:10:27 +00:00
Yuneng Jiang
afff1b08fa
refactor(ui): move the shared dropdowns and selectors onto shadcn primitives
Rebuilds the thirteen form-free components under common_components on
the in-repo shadcn layer, so they inherit the dashboard's design tokens
instead of styling themselves through Ant Design and Tremor.

SearchSelect and the three dropdowns that wrap it now forward an
optional input id, so an antd Form.Item label still resolves to its
control. The e2e steps that reached into antd's Select and Modal
internals now go through the test id, role and data-slot.
2026-08-14 06:09:10 -07:00
Yuneng Jiang
26e055248b
refactor(ui): give MemberTable its own extra-column type
extraColumns was typed as antd's ColumnsType while the adapter only
honoured string/ReactNode titles, plain-string dataIndex values and
element/string/number render results, so several valid antd column
forms produced blank cells. MemberTableColumn now describes exactly
what the table renders, and a column with a dataIndex but no render
falls back to the member value instead of rendering nothing.
2026-08-14 04:57:13 -07:00
Yuneng Jiang
3a537cce4d
refactor(ui): move the model hub and model select onto shadcn primitives
Rebuilds public_model_hub, MakeSkillPublicForm, ModelSelect and the
guardrail LogViewer on the in-repo shadcn layer, so they inherit the
dashboard's design tokens instead of styling themselves through Ant
Design and Tremor.

Public prop signatures are unchanged, so no caller moves. The two
teams e2e steps that reached into antd's Select internals now drive
the combobox through its test id, role and data-slot instead.
2026-08-14 04:48:49 -07:00
Yuneng Jiang
3465ba4914
refactor(ui): migrate router settings and shared badges off antd and tremor
Replaces Ant Design and Tremor in the fallbacks views, the router general
settings panel, and the two shared banner and badge components.

- Tremor Card, Table and Icon become the ui/card, ui/table and lucide
  equivalents, reproducing Tremor's icon box so click targets keep their size
- antd Alert becomes a composed role="alert" region, since the shadcn CLI's
  alert pulls in class-variance-authority, which this repo does not have
- antd InputNumber becomes a native number input, and Switch onChange becomes
  onCheckedChange
- shadcn TableCell ships whitespace-nowrap where Tremor's did not, so cells
  holding model names and setting descriptions get whitespace-normal back
- adds a DeprecationBanner test covering naming, the link, and dismissal,
  proven against the antd version first and mutation checked
- drops the eslint suppressions these files no longer need
2026-08-14 03:52:41 -07:00
Yuneng Jiang
617ad8194c
refactor(ui): migrate key info and permissions views off antd and tremor
Replaces Ant Design and Tremor in the key info header and detail view, the
agent and vector store permission panels, and the team member permissions
table.

- antd Popover, Dropdown and Modal become HoverCard, DropdownMenu and Dialog,
  and Tremor TabGroup becomes Tabs with keepMounted so panel state survives
  a tab switch the way Tremor's did
- the key id copy control moves to the shared CopyButton, which also fixes an
  icon that rendered at 24px because it inherited the heading font size
- antd Checkbox onChange becomes onCheckedChange
- every public prop signature is unchanged, since these are shared views
- three member permission tests were passing vacuously: they searched for an
  unchecked box by reading .checked, which is undefined on a Base UI checkbox,
  so the assertions sat inside an if that never ran. They now scope the
  checkbox to its own row and assert the toggle, the save and the revert
- drops the eslint suppressions these files no longer need
2026-08-14 03:30:31 -07:00
Yuneng Jiang
fbc56c3b7b
test(ui): assert the publish button is disabled while submitting
The migration closed a double submit hole that antd left open, but the
rewritten tests only proved the flow had not completed, so removing the
guard would not have failed them. Verified by mutation: dropping
disabled={loading} fails exactly this case.
2026-08-14 02:57:55 -07:00
Yuneng Jiang
a98f2380f8
refactor(ui): migrate shared common_components off antd and tremor
Replaces Ant Design and Tremor in the six shared components under
src/components/common_components, which between them are reached by
nine routes.

- antd Table becomes the ui/table primitives, and the Actions column keeps
  antd's fixed: "right" behaviour via a sticky cell
- Tremor Icon, Text and Badge become a plain span, p and StatusBadge
- antd Tooltip and Typography copyable become the shadcn Tooltip and the
  shared CopyButton
- every public prop signature is unchanged, since these are shared components
  and a renamed prop would break callers far from this folder
- two tests dropped assertions on antd internal class names and on DOM
  structure, and gained cases proving a disabled action does not fire onClick

MemberTable keeps a type-only import of antd's ColumnsType because a consumer
annotates its own column array with it. No antd code ships from the file.
2026-08-14 02:55:16 -07:00
Yuneng Jiang
c344b9a052
fix(ui): give the request details drawer an accessible name
Screen readers announced an unnamed dialog. The visible header is a custom
layout, so the title is visually hidden to keep the drawer layout unchanged.
2026-08-14 02:25:18 -07:00
Yuneng Jiang
07492314a8
fix(ui): announce the account popover as a dialog, not a menu
The panel holds switches and ordinary buttons rather than menu items, so
menu semantics promised keyboard behavior it does not provide.
2026-08-14 02:23:24 -07:00
Yuneng Jiang
9b8f9c69ad
refactor(ui): migrate AI Hub off antd and tremor to shadcn
Replaces Ant Design and Tremor across src/components/AIHub, so the model,
agent, MCP and skill hub views compose @/components/ui primitives.

- Modal becomes Dialog, tremor TabGroup becomes Tabs, tremor Card and Table
  become their shadcn counterparts, and Tag and tremor Badge become Badge
- the three publish forms wrapped antd Form around zero Form.Item fields, so
  the wrapper became a div and the dead useForm and resetFields calls went
  with it, rather than pulling in react-hook-form for a form with no fields
- antd Steps has no shadcn equivalent, so each form inlines a small ol stepper
- cells holding model names, server ids and URLs gained min-w-0 and break-words
  so a long value cannot bleed into the neighbouring column
- the three form tests dropped assertions invented by their antd mocks in
  favour of roles and rendered text
- drops the eslint suppressions these files no longer need
2026-08-14 02:21:42 -07:00
Ishaan
81c27fc4a0 fix: report real token usage on guardrail-blocked /v1/responses replies
## TLDR

Signed-off-by: Ishaan <ishaangupta0408@gmail.com>
2026-08-14 09:15:33 +00:00
Yuneng Jiang
03d2b16bcb
refactor(ui): migrate log details drawer off antd to shadcn
Replaces Ant Design across every source file under src/components/view_logs,
so the request log drawer and its viewers compose @/components/ui primitives.

- Drawer becomes Sheet, Collapse becomes Collapsible, Segmented and Radio.Group
  become Tabs, Tag becomes Badge, Descriptions becomes a local grid helper
- every lucide icon carries an explicit size class, since antd icons render at
  1em while lucide defaults to 24px
- two tests dropped assertions on antd internal class names in favour of
  rendered text and roles, and the Pretty/JSON case now proves the toggle
  actually swaps the body rather than only that both controls render
- drops the eslint suppressions these files no longer need
2026-08-14 01:51:24 -07:00
Yuneng Jiang
0cb48cf23c
refactor(ui): migrate Navbar off antd to shadcn
Replaces Ant Design with the in-repo shadcn layer across every Navbar
component, removing the last antd imports from src/components/Navbar.

- CommunityEngagementButtons, NotificationsBell, ViewSwitcher, BlogDropdown,
  WorkerDropdown and UserDropdown now compose @/components/ui primitives
- antd icons render at 1em while lucide defaults to 24px, so every icon
  carries an explicit size class matching what it replaced
- UserDropdown uses Popover rather than DropdownMenu: its panel holds
  switches and badges, and form controls inside role="menu" are invalid
- WorkerDropdown moves to Combobox since shadcn Select has no search
- drops the nine no-restricted-imports suppressions these files no longer need
2026-08-14 01:20:57 -07:00
yucheng-berri
423b791ee0
fix(langfuse): source the emitted metadata blob from StandardLoggingPayload (#36744)
Request metadata carries the whole UserAPIKeyAuth object, whose team_metadata
holds the customer's own langfuse callback_vars. The only filter on the emitted
blob was a four key deny list written as a circular reference crash guard, so
those credentials reached the customer's own langfuse traces.

The emitted blob is now the StandardLoggingPayload allowlist plus the litellm
computed enrichments, and nothing is copied across from raw request metadata.
That makes the credential exclusion structural rather than a filter someone has
to keep correct. Steering keys keep reading raw metadata, matching literal_ai.

Proxy callers are unaffected: their request metadata already rides under the
allowlisted requester_metadata key, nesting intact.

debug_langfuse dumped raw request metadata into the trace as a second copy of
the same leak. It now emits caller scalars only.

When StandardLoggingPayload is absent the trace is still emitted with the
existing trace_id fallback, so failure traces survive.
2026-08-14 07:01:35 +00:00
Yuneng Jiang
28c1e43196
feat(ui): standardize the Teams page header 2026-08-14 00:01:16 -07:00
yuneng-jiang
26c5ec3c8b
ci: drop the CircleCI ui_build and ui_unit_tests jobs (#36893)
Both are covered on GitHub Actions. test-litellm-ui-build.yml runs the
dashboard build on every PR, and test-litellm-ui-unit.yml runs the vitest
suite with ui-unit-tests already a required check, so neither CircleCI job
gates anything that GHA does not already gate.

ui_build additionally produced nothing anyone consumed. It persisted
litellm/proxy/_experimental/out to the workspace, and the only job
downstream of it was ui_unit_tests, which never attached the workspace and
reinstalled from source instead. The requires edge was pure sequencing, so
the build output was written and discarded on every client-touching PR.

One real narrowing comes with this, and it is deliberate. ui_unit_tests ran
the full vitest suite on PRs, while the GHA job scopes PR runs to tests
reachable from the diff and keeps the full suite on pushes to staging. That
split was a measured decision in #34175 and it still holds: the suite is
252s and 248s of that is CreateMCPServer.integration.test.tsx alone, so
running everything per PR buys about four minutes to re-run one file.

Note that assert-ci-coverage does not speak to this. It walks
tests/**/test_*.py only, so it is blind to vitest files by construction;
it stays green here because no Python test lost a runner, which is a
narrower claim than the UI side being unaffected.

auth_ui_unit_tests is a different job, a Python suite on a Postgres
sidecar, and is untouched
2026-08-13 23:52:46 -07:00
Yuneng Jiang
a0c27b320f
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_/remove-test-migrate-gha-d1eae8 2026-08-13 23:38:50 -07:00
Marty Sullivan
c9e9c279fe fix(batches): decide batch cost ownership once per retrieve
The ownership question was asked twice for one retrieve: once before the provider
call to decide whether to suppress inline accounting, and again afterwards to
decide whether to mark the batch accounted. Between those two points the poller
can complete its first successful filtered query and become usable, so the two
answers disagree. The retrieve then accounts for the batch inline, having decided
the poller was unusable, while the later check sees a usable poller and leaves the
marker unset, so the poller accounts for the same batch again and its spend is
counted twice.

The retrieve now decides once and passes that decision to
update_batch_in_database, which prefers it over re-deriving one. Callers that
record no cost of their own leave it unset and keep deriving it as before, so the
cancel path is unchanged.
2026-08-14 02:18:40 -04:00
Marty Sullivan
ec52858865 fix(batches): only hand accounting to the poller once it can mark batches done
The handoff asked whether the poller was running, when what matters is whether it
will actually account for the batch. Those differ on a schema without the
batch_processed column: the poller cannot filter on it, so it falls back to a
query that excludes complete and completed rows, and it cannot set it either. A
caller retrieving a provider-completed batch before the poller saw it therefore
suppressed inline accounting, then marked the row complete, and the fallback query
could never find it again. Nobody accounted for that batch, so its cost escaped
the caller's budget entirely.

The poller now publishes batch_processed_support_confirmed, set only once a
filtered query has actually succeeded, and the handoff requires it. Defaulting to
unconfirmed keeps accounting on the retrieve path in exactly the cases the poller
would drop the batch, including the window before the poller's first cycle. All
four combinations account exactly once: unconfirmed leaves the retrieve
accounting and setting the marker, whether or not the column exists, and
confirmed is only reachable when the column is present, where the poller accounts
and sets it.

A scheduler that hands back something other than a bound method leaves no poller
to interrogate, which reads as unconfirmed rather than as working.
2026-08-14 01:46:56 -04:00
Marty Sullivan
5649098e1b fix(batches): account a managed batch's cost exactly once
Two components computed a managed batch's cost and each assumed it was the only
one. Retrieving a batch computed it through the @client decorator's success
callback, and CheckBatchCost computed it on its own schedule. Whichever observed
completion first decided the outcome, so cost was either counted once per
retrieve or not at all.

The lockout is the worse half. Retrieving a batch that had reached completion set
batch_processed=True, which is what takes a batch out of CheckBatchCost's queue,
since it selects batch_processed=False. That write claimed the cost had been
accounted for on behalf of a callback that had not run yet and was not awaited.
When the callback then failed the cost was gone permanently, with the poller
already retired and no retry left. Observed on a live proxy: two completed
batches whose callbacks raised inside the logging worker, one on a provider
output path that did not resolve and one on a batch whose output file id was
still None, both left marked processed with no spend row and no way to recover
them. Nothing logged at error level for the batches themselves.

The over-count is the other half. Nothing suppressed recomputation, so each
retrieve of an already-completed batch recorded that batch's full cost again. A
caller polling its own batch to see whether it had finished inflated spend by
however many times it looked.

The flag now means what its name says, and only the component that actually
recorded the cost sets it. When the poller is running it owns accounting, so
retrieving a managed batch records no cost and leaves the flag alone; the poller
computes once and sets it. When the poller cannot be relied on, either because
polling is disabled by config or because the enterprise job never registered,
the retrieve path is the only accountant and behaves exactly as before. Batches
with no managed object row are untouched either way, since neither the flag nor
the poller queue applies to them.
2026-08-14 01:36:52 -04:00