Commit graph

43012 commits

Author SHA1 Message Date
Yuneng Jiang
e897e2b0aa
Merge branch 'litellm_internal_staging' into litellm_shadcn_permissions_0814 2026-08-14 09:59:12 -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
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
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
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
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
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
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
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
Yassin Kortam
6704a105ee
fix(access groups): sync assigned_team_ids from the team write paths (#36825) 2026-08-14 04:45:36 +00:00
Mateo Wang
c278455655
test(proxy): stop monkeypatch.undo re-planting fixture-mocked prisma_client (#36872) 2026-08-13 20:51:59 -07:00
lostmartian
7a519e26ec
fix(proxy): track spend for OpenAI passthrough /v1/embeddings (#36660)
* fix(proxy): track spend for OpenAI passthrough /v1/embeddings

OpenAI passthrough embeddings returned 200 but wrote no spend because the
route was unsupported and Cohere's /v1/embed prefix stole the match.

* fix(proxy): clear embeddings lint and Greptile comment nits

Inline embeddings cost tracking to avoid new LIT001/002 hits, trim
redundant doc comments, and cover the Cohere /v1/embeddings collision.

* fix(proxy): drop unreachable embeddings TypeError guard

convert_to_model_response_object with response_type=embedding already
returns EmbeddingResponse; the isinstance check was dead patch coverage.
2026-08-13 20:48:16 -07:00
Mateo Wang
3c57e9f4ad
Merge pull request #36864 from BerriAI/litellm_make_check_run_summary
fix(scripts): end make check with a ran/skipped summary and verdict
2026-08-13 20:45:38 -07:00
Mateo Wang
784259bbd9
Merge pull request #36769 from BerriAI/litellm_nvidia_riva_ui_provider
fix(ui): add nvidia riva to the model provider list
2026-08-13 20:39:24 -07:00
yucheng-berri
0a25756e78
fix(ptu): stop per-token billing on a PTU-configured deployment (#36829)
A deployment with PTU flat-cost attribution also billed every request per
token, so a team paid for reserved capacity and again for the traffic that
capacity serves. Nothing set the per-token price and an unset price falls
back to the public cost map, which made the double charge the default.

/model/new and /model/{id}/update now store zero for every pricing field the
cost map could otherwise fill, refuse a price the caller supplies alongside
PTU config with a 400 naming the field, zero a price already on the row
rather than rejecting later edits of unrelated fields, and drop the zeros
again when the PTU config goes.

A PTU deployment is no longer read as a free model by the budget checks,
which would have waived every budget for it.
2026-08-13 20:16:12 -07:00
mateo-berri
a36ba05882 test(proxy): stop monkeypatch.undo re-planting fixture-mocked prisma_client 2026-08-13 20:11:06 -07:00
devin-ai-integration[bot]
59eeae374c
fix(mcp): expose client HTTP headers to logging callbacks and hooks (#36724)
* fix(mcp): expose client HTTP headers to logging callbacks and hooks

MCP protocol tool calls built a synthetic Request with only content-type, so metadata.headers reaching logging callbacks and guardrails was empty while /mcp-rest/tools/call exposed the full set. Rebuild the synthetic request from the connection's raw headers (shared with the sampling path), and pass sanitized headers to the pre-call hook, the MCP to LLM guardrail bridge and the Responses API MCP bridge. Credential headers stay masked and proxy key headers stripped.

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

* fix(mcp): strip custom proxy key and upstream MCP credential headers from logging copies

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

* refactor(mcp): make client side auth header name accessor public

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

* fix(mcp): strip custom proxy key and client redaction opt-out from mcp headers

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

* fix(mcp): drop custom proxy key header in the synthetic request builder

Strips general_settings.litellm_key_header_name in build_synthetic_mcp_request so every caller, including sampling, is covered, and reverts passing general_settings into add_litellm_data_to_request on the tool call path since that also switches on enforced_params.

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: shivam <shivam@berri.ai>
2026-08-13 20:07:16 -07:00
mateo-berri
ea4316b245 fix(ui): resolve provider dropdown enum keys in getPlaceholder 2026-08-13 19:58:06 -07:00
Yassin Kortam
efbdb6901a
fix(access groups): sync assigned_key_ids from the key write paths (#36843)
Some checks failed
Unit Tests: LLM Provider Transformations / Vertex AI (push) Waiting to run
Unit Tests: MCP, Secrets, Containers & Misc / misc (push) Waiting to run
Unit Tests: Proxy Auth & Key Management / proxy-auth (push) Waiting to run
Unit Tests: Proxy DB Operations / assert-shard-coverage (push) Waiting to run
Unit Tests: Proxy DB Operations / auth-checks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / budgets (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / custom-logging (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / db-and-spend (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / endpoints-and-responses (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / guardrails-hooks (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / jwt-and-keys (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / key-generation (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / logging-misc (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-runtime (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-server-core (push) Blocked by required conditions
Unit Tests: Proxy DB Operations / proxy-utils (push) Blocked by required conditions
Unit Tests: Proxy API Endpoints / proxy-endpoints (push) Waiting to run
Unit Tests: Proxy API Endpoints / proxy-server (push) Waiting to run
Unit Tests: Proxy Infrastructure / proxy-infra (push) Waiting to run
Unit Tests: Responses, Caching & Types / responses-caching-types (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
Unit Tests: Proxy Legacy Tests / auth-and-jwt (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / key-generation (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-config (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-response-and-misc (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-server (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-server-extras (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-token-counter (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-user-auth-and-spend (push) Has been cancelled
Unit Tests: Proxy Legacy Tests / proxy-utils (push) Has been cancelled
2026-08-14 02:47:02 +00:00
Yassin Kortam
86f2f16fd4
fix(bedrock): hoist custom.defer_loading before dropping custom on invoke tools (#36855) 2026-08-13 19:28:18 -07:00
Yassin Kortam
d9530bf3d1
fix(proxy): fail config load when a callbacks entry is not dispatchable (#36858) 2026-08-13 19:26:48 -07:00
mateo-berri
60c6c2c703 test: drop redundant explanatory comments from riva provider tests 2026-08-13 19:24:45 -07:00
mateo-berri
3fbe40c9b1 fix(scripts): print the make check verdict on early informational exits 2026-08-13 19:13:44 -07:00
Yassin Kortam
909a2e6232
perf(spend-logs): bound retention cleanup so one run cannot saturate the database (#36594) 2026-08-13 18:56:37 -07:00
mateo-berri
cfbd43172a fix(scripts): end make check with a ran/skipped summary and verdict 2026-08-13 18:49:07 -07:00
Mateo Wang
2b63919f67
Merge pull request #36714 from BerriAI/litellm_check_batch_cost_poll_starvation
fix(batches): stop uncostable batches from starving the cost poll page
2026-08-13 18:41:45 -07:00
yuneng-jiang
89f81919cc
Merge pull request #36832 from BerriAI/litellm_/quizzical-jennings-5df447
refactor(ui): migrate guardrails to shadcn
2026-08-13 18:30:56 -07:00
yuneng-jiang
2913ee811c
Merge pull request #36847 from BerriAI/litellm_/awesome-shirley-6a1a86
refactor(ui): migrate playground to shadcn
2026-08-13 18:30:48 -07:00
yuneng-jiang
6797327dc8
Merge pull request #36838 from BerriAI/litellm_/brave-hermann-3d77ac
refactor(ui): migrate guardrails-monitor to shadcn
2026-08-13 18:30:40 -07:00
yuneng-jiang
ce3a56dce6
Merge pull request #36834 from BerriAI/litellm_/compassionate-jones-9c0d5c
refactor(ui): migrate usage to shadcn
2026-08-13 18:30:30 -07:00
Yassin Kortam
8841cbc10f
fix(mcp): resolve admin OAuth sessions from any worker via DB-backed drafts (#36844)
The Admin UI's Authorize & Fetch Token flow stored its pending server in a
module-level dict, so /register, /authorize and /token only succeeded when
every leg happened to land on the process that served /session. On a proxy
with NUM_WORKERS greater than 1, or more than one replica, each click was an
independent draw and failed with a bare 404, which reads as intermittent.

Persist the pending server as a short-lived draft row instead, so any worker
resolves it. The in-memory cache is kept as the fallback for proxies with no
database configured, which keeps single-process deployments working as before.

A session runs under a caller-supplied id only when that id names a server
that really exists, which is the edit form re-authorizing a saved server.
Anything else gets a fresh id, so two concurrent sessions can never share one
draft and silently adopt each other's URL or client credentials. Drafts past
their lifetime are swept on each write so abandoned sessions do not
accumulate, and a lost create race adopts the winner rather than failing a
caller whose session is ready.

Drafts are excluded from listings and never enter the runtime registry. The
exclusion keeps rows whose approval status is NULL, which both short spellings
of the filter drop, silently hiding every server predating the approval
workflow.

Measured on a two-worker proxy against the live GitHub MCP server, 120
concurrent authorize calls per leg: staging 56/120 failures, this branch
0/120, staging again 65/120 as a positive control.
2026-08-13 18:03:12 -07:00
Yassin Kortam
3615cccfef
fix(team): sweep dangling team references and cache on team delete (#36819)
* fix(team): sweep dangling team references and cache on team delete

delete_team drove all of its cleanup off the team's members_with_roles roster, so any
user row referencing the team by another route kept a dangling team id forever and the
deleted team stayed visible on /user/info. Nothing swept LiteLLM_UserTable.teams or
LiteLLM_TeamMembership by team id, schema.prisma declares no relation between the
membership table and the team table so there is no cascade to fall back on, and the
cached team object was never invalidated on delete.

Adds a sweep that runs before the team rows are dropped: it strips the deleted ids from
every user row that still lists them and removes every membership row for those teams.
Adds _delete_cache_team_object in auth_checks and calls it per deleted team so the
team_id:{team_id} entry cannot outlive the team.

The sweep is targeted, not indiscriminate: only the deleted ids are removed and the
other teams on a user record are left intact.

* fix(team): fail member_add when the team is deleted under the row lock

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

* docs(team): correct the post-delete sweep note for the member_add lock path

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-08-13 18:01:38 -07:00
Yassin Kortam
b344043eaf
fix(ui): stop a deselected MCP server keeping its grant on a virtual key (#36840)
* fix(ui): stop a deselected MCP server keeping its grant on a virtual key

The key editor sent `mcp_tool_permissions` unfiltered, and the MCP resolver
counts a server named only under `mcp_tool_permissions` as entitled, unioning
`tool_perm_servers` into `all_servers` at four sites in
`user_api_key_auth_mcp.py`. Deselecting a server, or removing the access group
that supplied it, therefore left a stale entry that kept the key reaching that
server with its old tool allowlist attached.

Reuse `extractMcpEntitlement`, which already landed for the internal-user
surface, so the key surface drops an entry only once the server is known and no
longer granted, and keeps it whenever a retained access group or toolset could
still supply it. The helper moves to a shared module so the key template does
not import a users page component.

Setting the map unconditionally is part of the same fix: the old
`Object.keys(...).length > 0` guard let the previous map ride through the
`object_permission` spread, which filtering to an empty map would otherwise hit
in exactly the case the fix is for.

* fix(ui): resolve retained MCP groups and toolsets per server when pruning tool permissions

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

* test(ui): mock the MCP toolsets hook in the key update suite

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-08-13 18:00:42 -07:00
Yassin Kortam
e0f388cb5c
feat(ui): render request metrics on the /ui/chat surface (#36845)
/ui/chat never rendered a metrics bar. The Responses helper already parses
usage off the response.completed event, but the chat page passed positional
undefined where onTimingData, onUsageData and onTotalLatency sit, ChatMessage
had nowhere to hold them, and ChatMessages never rendered ResponseMetrics.

Thread the three callbacks through, persist the values on the assistant
message, and reuse the playground's ResponseMetrics to show latency, TTFT,
input/output/total tokens and cost. Also map the cost the proxy reports on the
streamed usage object, which only the chat-completions helper did before.
2026-08-13 17:31:13 -07:00
Yuneng Jiang
62523c1734
fix(ui): restore pattern search and popup layering in the guardrail wizard
Two behaviour differences the port introduced, both found in browser QA

The antd Select matched a prebuilt pattern on its display_name and its
internal name; a Base UI Combobox only searches itemToStringLabel, so
queries like "amex" and "sg" stopped matching. Restore the second field
with a filter predicate on the Root, covered by a regression test that
searches on a token the visible label does not contain

Base UI portals a popup into a positioner whose "isolate z-50" is fixed
in the primitive, so inside an antd Modal at z-index 1000 the options
were visible but not clickable. antd hid this because its own dropdowns
and tooltips already sat above its Modal. The positioner is not reachable
from the call site, so this needs one app-wide rule keyed on an antd
modal being present, and it becomes deletable when the last one goes
2026-08-13 17:27:26 -07:00