Replaces the antd Button, Row, Col, Spin and Typography usage in
GuardrailsOverview with the shadcn button, a CSS grid and the house
loading wrapper, and swaps the ant-design icons for lucide equivalents
that the already-migrated GuardrailDetail sibling uses. The busy state
keeps the aria-busy attribute the antd Spin exposed, so the loading
contract is unchanged for assistive tech.
The route's other analyzer-listed file, GuardrailsMonitorView, keeps its
DateRangePickerValue type import because the shared AdvancedDatePicker
prop contract requires it, so there is nothing to migrate there.
Retires the file's now unused no-restricted-imports suppression
Ports the 21 route-owned guardrails components off antd and Tremor onto the
installed shadcn base-vega primitives. Forms, tables and shared components stay
where they are: the route analyzer buckets add_guardrail_form, guardrail_info
and six others as DEFERRED, and eleven components under src/components as
SHARED, so none of them are touched here.
Three behaviours needed explicit handling because Base UI does not match antd by
default. Base UI Tabs mounts only the active panel, so the playground draft and
every panel's local state would reset on a tab switch; TabsContent now carries
keepMounted. ComboboxList takes a function child to render the filtered items,
and mapping over the array instead renders everything and silently disables the
type to filter behaviour antd gave for free. SelectContent gets
alignItemWithTrigger={false} so popups anchor below the trigger the way antd's
did, which also removes a focus race that made the template picker
intermittently unclickable.
The three dialogs reached from inside the still-antd wizard need a layer above
its z-index of 1000 to be visible at all.
Adds three tests rather than editing the characterisation tests from the
previous commit: a guard that every tab panel stays mounted, and one filtering
regression each for the pattern and mode dropdowns.
Prunes the guardrails entries from eslint-suppressions.json.
Replaces antd and Tremor markup on the usage route with the installed shadcn
base-vega primitives. Behaviour is unchanged: the route's characterisation
tests were rewritten to role and text queries in the previous commit, proven
green against the antd components, and pass through this commit unedited.
Tremor tab panels stayed mounted once rendered, so every migrated TabsContent
and the collapsible model sections in activity_metrics carry keepMounted to
keep view-mode and expansion state alive across tab switches.
* chore(ui): remove Agent Platform announcement bell from navbar
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(ui): highlight Auto Router in the navbar announcement
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): open Auto Router docs link in a new tab
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Revert "fix(ui): open Auto Router docs link in a new tab"
This reverts commit 3be861bafe.
* chore(ui): title the navbar announcement LiteLLM Auto Router
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Mubashir Osmani <mubashir@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Covers the header and export action, all five summary metric cards, the
table toolbar heading, the evaluation settings modal wiring, the busy
state and the request failure message. Every assertion is role, title or
text based so it holds against both the antd markup and its shadcn
replacement, letting the migration commit land without editing this file
create_view_tolerating_race took the module's _db = Any. It now takes a
Protocol naming the single operation it calls, so the contract is checkable
at its call sites without retyping the rest of the module.
Kept free of Any deliberately: an earlier version typed the Protocol's
parameters as Any and pushed create_views.py from 26 basedpyright errors to
30 by adding reportExplicitAny. This version measures identical to the
baseline on both create_views.py (26) and utils.py (1355).
Against a real Postgres the previous commit still died on MonthlyGlobalSpend:
only 2 of the 8 creation sites went through the tolerant helper, so the losing
replica re-raised on the first unguarded one and skipped the rest.
The regression test now makes every CREATE lose the race and asserts all 8 are
still attempted, which fails on the partial fix.
Rewrites the usage route's library-coupled assertions to role and text
queries so they characterise behaviour rather than the widget library that
happens to render it. Every test here is green against the current antd and
Tremor components and is meant to survive a migration unedited.
Drops the wholesale vi.mock of antd, @ant-design/icons and @tremor/react in
UsagePageView, UsageViewSelect and activity_metrics, and drives the real
controls instead. Two of those mocks were hiding behaviour: activity_metrics
asserted panel order through a heading role that only existed because the
mock faked an h2, and the Tremor tab stubs flattened panel selection away
entirely.
Replaces DOM-shape lookups with anchors that do not move: a chart is found
from its own heading rather than a fixed wrapper depth, an active panel is
identified by the inactive markers both tab libraries set, and select options
are matched by text since antd's real options carry no option role.
Adds the missing characterisation test for team_multi_select, and covers the
mount contracts the route depends on: Tremor keeps every tab panel mounted,
and antd Collapse keeps a section mounted once it has been expanded, which is
what preserves the view-mode state a model section owns.
Rewrite the PatternModal test off antd class selectors onto role and text
queries, and add characterisation tests for the guardrails components that
had none: the keyword modal, the content filter display and configuration,
the guardrail garden and the custom code modal.
Also covers two behaviours the migration must preserve: the action and
severity dropdowns in the content filter tables, and test playground state
surviving a tab switch away and back.
Every assertion here passes against the current antd and Tremor components
so the same file can prove the shadcn versions unedited.
Every replica booting against the same fresh database sees each view as
absent and issues the CREATE. Postgres fails all but one with a
duplicate-object error, and that exception propagated out of
create_missing_views, so every view after the first was never created and
/global/spend* 500'd for the life of the deployment.
Losing that race reaches the desired end state, so treat it as success.
Genuine DDL errors still propagate.
Every case in TestAccessControl asserted that something was refused. A gateway
that denied the allow-listed model too would have passed all of them, so the
suite could not tell "denied correctly" from "broken outright".
Adds the positive half: a key allow-listed for gemini-2.5-flash can call it and
gets back a real completion rather than a 200-wrapped error.
Also tightens the unknown-model case. It accepted any valid JSON, so a bare
"{}" or even "null" satisfied it. It now requires the OpenAI-shaped error
envelope with a message a client can actually surface, parsed through a typed
model instead of json.loads.
Completed batches that contain only failed requests do not generate an
output file, leaving output_file_id unset while the failures are recorded
through error_file_id instead.
The completion handler attempted to read the output payload regardless of
whether an output file actually existed. During retrieve polling this caused
the logging pipeline to fail with "Output file id is None cannot retrieve
file content", preventing normal completion bookkeeping from running.
Skip output retrieval when no output file is available and return an empty
batch summary (zero usage, zero cost, no model entries). The lower-level
file retrieval helper still reports an error if it is called directly with
an invalid or missing file identifier.
Closes#33987
Prettier flagged the two test files added while fixing review findings.
Migrating these components off Ant Design also retired the lint suppressions
they carried, so prune those 15 entries and leave the unrelated ones for the
PRs that made them stale.
antd's Collapse kept the panel mounted once opened, so a tool a user had
expanded stayed expanded after closing and reopening Tools. Base UI renders
only the open branch, so the migration silently reset every ToolItem.
The regression test passes against the antd original, fails against the
migration without keepMounted, and passes with it.
* fix(proxy/batches): stop forwarding custom_llm_provider twice in list and cancel
The model-routing branches of list_batches and cancel_batch passed
custom_llm_provider as an explicit kwarg while also leaving it inside the dict
they splat, so every such call raised "got multiple values for keyword argument
'custom_llm_provider'" and returned a 500.
list_batches SCENARIO 2 called data.update(credentials) but never removed
custom_llm_provider before litellm.alist_batches(custom_llm_provider=..., **data);
it now uses prepare_data_with_credentials, the same helper the create and
retrieve branches already use, which pops it out.
cancel_batch SCENARIO 3 resolved the provider with
`provider or data.pop("custom_llm_provider", None) or ...`, so when the path
param provider was set the pop short-circuited and a body custom_llm_provider
stayed in data and collided with the explicit kwarg. The body value is now
popped unconditionally before the fallback chain, so the path param wins cleanly
and data no longer carries a duplicate.
Both paths already had strict-xfail regression tests documented "remove when
fixed"; those markers are dropped so the tests now guard the fix.
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
* fix(proxy/files): avoid duplicate custom_llm_provider in list
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
---------
Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
InputCard and OutputCard located SectionHeader's copy button by querying for a
descendant with aria-label="copy", which is the antd CopyOutlined icon. That
selector reaches into SectionHeader's internals, so migrating it off antd left
copyButton undefined and failed four tests.
getByRole("button", { name: /copy/i }) is green against both the antd and the
shadcn SectionHeader, verified by running these two files against each.
The key source trigger rendered the stored value, so the playground showed
session and custom instead of Current UI Session and Virtual Key. Name the
selected option on the trigger.
Clearing the key while models were loading left the selector disabled for
good: the in-flight load skips its reset once cancelled, and the branch that
handles an empty key returned without clearing the loading flag, so nothing
put it back. Clear it on that path too.
* fix(ui): restore playground model filtering by endpoint
Bring back the prior Chat model dropdown filter (including chat models
on responses/anthropic/interactions and image models on image_edits), and
map mode realtime so the realtime endpoint only lists compatible models
* fix(ui): exclude unknown model modes from playground endpoint filters
Modes outside ModelMode (batch, rerank, ocr, etc.) must not collapse to
chat-compatible, or conversational endpoints surface unusable models
* feat(ui): add shared vercel-style playground chat composer (#36131)
* feat(ui): adopt vercel-style chat composer for playground
Replace the compact single-line input with a PromptInput-style composer:
taller auto-growing textarea, rounded card shell, footer tools, and
stop button while a request is in flight
* style(ui): strengthen playground chat composer border and shadow
Make the shared chat input stand out with a fuller border, layered
shadow, and a slightly stronger focus ring
* fix(ui): size chat composer textarea with CSS field-sizing
Drop direct el.style.height mutation in favor of field-sizing:content
* fix(ui): keep the chat composer out of a nested form and focus its textarea
The composer wrapped everything in a native form, so MCP mode nested Ant
Design's tool-arguments form inside it, which is invalid HTML and let Enter
hit either form. The footer also relied on InputGroupAddon focusing the first
input in the group, which is the hidden file input from the attach controls
rather than the message textarea.
Drop the outer form and submit from the send button directly, and have the
addon focus the element marked as the group's control.
* refactor(ui): reuse the endpoint compatibility check when a model is picked
The endpoint guard added upstream duplicated the compatibility families this
PR introduces, so point it at isModelCompatibleWithEndpoint instead. Filtering
also means an incompatible model is no longer offered for an endpoint, so the
test that picked one now asserts it is absent.
* fix(ui): match the image-edit model mode the backend actually sends
model_prices_and_context_window.json labels these models image_edit, but the
mode enum spelled it image_edits, so once unknown modes started being filtered
out every image-edit model vanished from the playground, /v1/images/edits
included. The endpoint key keeps its own spelling.
The compatibility tests stubbed getEndpointType with a hand-written map that
repeated the same wrong spelling, which is how this stayed hidden, so they now
run against the real mapping.
Picking a model reset the endpoint from its mode unconditionally, so choosing
a chat model while on /v1/responses, /v1/messages or interactions bounced the
playground to /v1/chat/completions. Only switch when the current endpoint
cannot serve the picked model.
The temperature and max-token boxes parsed and clamped on every keystroke, so
a decimal lost its point and clearing the field snapped to a bound. They are
now text fields with a numeric input mode that hold what was typed and clamp
on blur; the sliders beside them still give the stepped control.
The image-edit and transcription areas invited a drag but had no drop
handlers after the Ant Design Dragger came out, so drops did nothing. Wire
drop through the same validation the file picker uses.