mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-06 07:48:06 +00:00
11 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
8efb99b4ac
|
feat(ui): shareable URL state for usage views and users-to-usage deeplinks (#43425)
* feat(ui): shareable URL state for usage views and users-to-usage deeplinks The Usage page now keeps the view, global view tab, date range and entity filters in the URL, so links can be bookmarked and shared. Relative presets are stored as range=7d and keep rolling, custom ranges as UTC from/to. Invalid params are dropped, and a link to a view or user the viewer cannot access shows a toast and falls back to the default view. Internal Users rows get a "View usage" action that opens usage filtered to that user, and the per-user usage views link back to the user's record. A "Copy Share Link" button sits next to "Ask AI" * fix(ui): clean usage links for sessions without the organizations query The organizations query only runs for premium sessions, and a disabled query stays pending forever, so the URL cleanup never ran for other sessions. Gate on isLoading instead, and give the access denied toast an id so a re-run effect shows it once * fix(ui): type-check usage entity filters and address review findings Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): keep team usage available to internal users Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * style(ui): format users table usage action Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): sync date picker preset with the current usage range Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): restore dashboard AGENTS.md from main and drop unused usage state Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): share custom usage date ranges as calendar days Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ui): keep per-user agent usage page across rerenders 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> |
||
|
|
9a5e828310
|
feat(ui): inline Lens settings tab and investigation editor (#44479)
* feat(ui): move worker status into the Lens notch and New investigation into the list toolbar Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): make the Lens notch entry a settings gear that houses the worker section Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): replace the Lens worker modal with an inline Settings tab Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): section the Lens settings tab with tracing status and worker cards Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): let Lens settings sections span the full card width Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): replace the investigation setup modal with an inline side-by-side editor New, edit, and duplicate now take over the Investigations tab body: matching activity on the left, every setting on the right, with no wizard steps or modal Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): step the inline investigation setup vertically with traces alongside Setup now sits on the left as three progressive steps (activity, criteria, run) that collapse to a summary once done and reopen on click. Matching activity stays on the right for every step. The editor gets a back control and the Investigations notch shows a New, Editing, or Duplicate badge while the editor is open Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): page the matching activity preview with useInfiniteQuery as it scrolls Replace the Previous/Next offset buttons with the same infinite query and near-tail prefetch the traces list uses, so the preview keeps loaded runs and its title while the next page arrives Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): make the investigation step field map exhaustive over the form schema Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): always show the Settings tab label in the Lens mode switch Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): collapse Lens worker cards into compact status rows Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): keep the Lens Settings tab icon-only in every state Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * wip * fix(ui): tick the Lens worker health dot so an expired heartbeat goes stale Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): regroup Lens settings, model and api layers Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): dedupe Lens formatting helpers Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): poll Lens once, drive the interval from data, settle mutations before invalidating Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): let Lens leaves fetch their own data Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): bind drawer and trace shortcuts through react-hotkeys-hook One useShortcut hook replaces the three hand-rolled keydown listeners in SidePanel, the trace step tree and the log drawer, with a layer option deciding which keys a pane claims from the panel around it. The span tree footer now renders ShortcutHints from what is actually bound instead of hand-typed kbd text. * refactor(ui): extract Inspector from SidePanel Inspector.Root owns the open item, J/K stepping, Escape and full screen; Inspector.Row marks a list entry with aria-selected and data-state and toggles it on click or Enter/Space; Inspector.Panel is the resizable side panel with the exit animation and click-outside rules. The runs table and section compose these parts directly, so RunDrawer and the SidePanel prop bag go away. * refactor(ui): model the Lens worker screen as a tagged union and slot in its ready action workerScreen() decides between list, form and install from the worker rows, the registration result and the edit target, so WorkerSettings switches on one value and each card owns its own copy. The post-install CTA is now a ReactNode slot that LensWorkspace fills instead of an onReady callback threaded through LensSettings and WorkerSettings. Clipboard copy state lives in WorkerInstall as mutations, and the styled settings leaves export Props types, set data-slot and accept native element props. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): compose the Lens setup stepper from SetupStep children Each step's heading, summary and fields now live together in one SetupStep instead of four parallel structures keyed by index, and the last-step spacing comes from CSS rather than a passed index. The mode prop is now required since InvestigationsView always passes it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): keep the Lens Settings panel mounted so a pending worker install survives tab switches The settings TabsContent unmounted WorkerSettings whenever another tab was active, dropping the one-time worker token shown during install. The panel now uses keepMounted, and the workspace test registers a worker, switches tabs and back, then follows the connected worker into the first investigation through the slotted CTA. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(ui): cover the Lens worker install waiting-to-connected transition Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): give the Lens activity preview a grouped contract and a structural debounce useMatchingActivity now owns its return types (scope options, preview status, page and optional manual selection) instead of borrowing them from the components it feeds, and the preview takes those groups plus the section attributes. The clear-selection action moves into the preview footer, RunList becomes a RunRow leaf, and ScopeFields drops the unused nameField and id props now that MetadataFilters calls useId itself. The preview scope settles through a hashKey-based useDebouncedValue instead of JSON round-tripping into state, and the loading title follows isPlaceholderData since the query keeps previous data. RunFields and AnalysisModelField take the analysis models and the model gate as two objects instead of seven flat props. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): select the Lens investigations screen with a pure tagged union investigationScreen maps the list query and the route to one of loading, failed, welcome, list, detail, setup or missing, so the view can switch instead of juggling mutually exclusive booleans. The status model gains activeJob, carries connected inside Readiness and folds the activity probe into one ActivityCheck value for the welcome page Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(ui): cover the Lens preview footer clear action and the preview debounce Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): let Lens investigation leaves own their URL slice and express intent InvestigationsView renders the screen union and owns every write through useInvestigationActions, so leaves receive on* handlers instead of the API writer. useInvestigationResults becomes useRunSnapshot; FindingsTab, HistoryTab, RunPicker and RequestEvidenceSheet read their own nuqs slice and run their own queries. The finding sheet becomes an Inspector side panel (FindingDetails) keyed per finding, with the trace and request evidence sheets grouped in EvidenceSheets. WatchAllBanner owns its mutation, the welcome page takes the readiness and activity values, the progress sampler records on the wall clock outside render, and run history invalidates when the list reports a scheduler-started job Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(ui): cover Lens investigation intents, pause, cancel, history refresh and the finding panel Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): keep the inspector open behind sheet overlays and mount HotkeysProvider from a client wrapper * feat(ui): open Lens runs and evidence in the inspector panel A quote's original trace step or logged request now stacks inside the finding panel behind a back link, keeping the finding and its feedback draft mounted. The detail Runs tab and the setup activity preview open runs in the same panel with J/K stepping, so the TraceSheet and RequestEvidenceSheet modals are gone. Picking a different finding or run clears any stacked evidence from the URL. * feat(ui): open Lens investigations in the inspector panel beside the list The investigations list stays on screen and a row opens its investigation in the side panel, so J/K walk investigations and their open findings in display order and the selected row carries the same highlight as runs. The panel body is the former detail page; findings and runs opened inside it nest their own inspector, which claims the keys from the one around it while open. Opening an investigation and peeking at a finding now replace each other in the URL. * fix(ui): run the Lens notch border along the tab pill and flag only a disconnected worker Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): show the shortcut hints in every inspector panel Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): extract the Lens dot field into composable DotFieldRoot and DotFieldCanvas Move the dot grid model and canvas painter out of TracesTimeline into components/lens/dotField so other Lens surfaces can reuse it. The root owns layout and context; overlays compose as children. agoLabel moves to lens/model/format and the unused columnTop helper is dropped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): drop the manual refresh button from the runs time controls Live polls and range changes refetch, so the button only cleared the zoom, which Escape already does Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): extract the Lens run search into a composable SearchBox primitive Move the query parser, glob matcher and autocomplete out of runSearch into components/lens/search, generic over a QueryLanguage (field specs plus what free text searches). SearchBox.Root owns the ProseMirror state, menu and keyboard; SearchBox.Input and SearchBox.Suggestions compose under it. Clause highlighting becomes a ProseMirror plugin built from the language. RunSearch now only declares the run fields and composes the parts, so the investigations tab can define its own language and reuse the same box. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): label the runs range by preset while Live and pin it once paused Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): split the Lens search language from where its data lives QueryLanguage is now pure vocabulary (keys, groups, icons). Reading fields off loaded items moves to a ClientIndex consumed by a separate evaluator, and value suggestions come from an injectable ValueSource, so a server-backed runs list can plug in a facet lookup while the investigations tab keeps filtering in memory. The parsed query serializes to a typed SearchQuery (text terms plus eq/neq/glob/nglob filters) that the client evaluator consumes today and a server can consume later. The suggestion menu shows a loading row while a source is still answering. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * style(ui): format the Lens SearchBox and its test with the project prettier config Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): mirror the Lens run filters as trace SQL with a copyable curl in the search footer The suggestions footer gains a slot, and SearchBox.ApiHint fills it with the API equivalent of the typed query: a dialect chip, a one-line preview and a Copy as curl button. The runs box translates each filter to a predicate over the agent_traces_by_key rollup, bounded to the range the list shows, and copies a POST to /v1/traces/query. Any other list can plug its own translate into the same part. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): show the Lens introduction as a first-visit dialog with a typed don't-show-again The guided setup no longer replaces the Lens tabs. It opens in a dialog on the first visit of a session or from ?setup=lens, with a close and a "Don't show this again" checkbox in its top-right corner. The header "Set up Lens" button is gone. Dismissal state lives in a new schema-validated web storage helper (src/lib/storage.ts) that reads through useSyncExternalStore, so server renders see the fallback and other tabs stay in sync; only Lens uses it for now. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): keep only Copy as curl in the Lens run search footer Drop the SQL chip and predicate preview; SearchBox.ApiHint becomes SearchBox.CopyCommand, which takes the command for the current query. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(ui): align the Lens investigations list with the traces list Use the shared query SearchBox with investigation fields (name, agent, status, schedule), match the traces toolbar, and drop the count footer and inner padding. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(ui): let Lens settings bring back the introduction after don't show again Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): share one InspectorTable between the traces list and the Lens investigations tree Compose TanStack Table, react-virtual and the shadcn table cells into InspectorTable parts (Root, Grid, Header, Body, Row, Indent). Investigations get findings as real sub-rows with TanStack expansion instead of a hand-rolled flattener. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): break Lens import cycles and move shared pieces out of lens Search and the dot field go to components/shared, run search and the preview button go to view_logs where they are consumed. Lens api, services and demo live under data/, all URL state in route.ts, storage keys in storage.ts, and the session frame styles become cva variants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): one Lens readiness source and one onboarding flow Readiness is computed once in model/readiness and read through useLensReadiness, replacing useLensSetup, status.readiness and the welcome screen's own checks. The Investigations welcome now renders the same onboarding steps as the introduction dialog, with permissions and actions coming from an OnboardingProvider instead of props passed down four levels. StepIndicator and StateMessage are shared lens components, and the step panels are labelled accordion regions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): read the Lens token from services and use semantic status colors Lens services carry the access token they were built for, so trace evidence, readiness and onboarding read it from context instead of a prop threaded through six components. List and history invalidation lives in one data hook. Status colors use the success, warning and destructive tokens, and template-literal class names go through cn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(ui): split Lens demo fixtures from the fake demo APIs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(ui): show Lens check history as a dot timeline Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chores * fix(ui): clear stale Lens evidence on run change and keep read-only users off Settings Also names inline option objects to bring local/no-large-inline-object-arg back under budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
529ac12ba5
|
test(ui): drop the helper docblock
The repo does not take explanatory comments. The reason the helper queries by role lives in the commit that introduced it and in the PR description. |
||
|
|
eb53639ecb
|
test(ui): pick select options by role instead of by text
Clicking a Base UI select entry found by text or by a title attribute is a race. The text node exists one render before the popup finishes entering, and until then the positioner still carries pointer-events: none, so user-event refuses the click and the test throws. Querying by role only matches once the popup is exposed to the accessibility tree, which is after that window closes. Route the 37 remaining select interactions through chooseSelectOption, which does the role query. Instrumenting the converted files shows the text query resolving while the popup was still pointer-blocked on 6 of 41 samples; the role query was never blocked. Seven files kept their text queries because their popup entries carry no accessible role, so there is nothing to query by. |
||
|
|
a5f9410681
|
test(ui): wait for the select popup before clicking its option
key_edit_view opened a select and then clicked the option it found by title text or by raw text. Both queries match the moment the option enters the DOM, which is one render before the popup finishes entering. Until then the positioner still carries an inline pointer-events: none, and user-event refuses to click through it. That is a race, and a fast machine loses it. Five of the file's 84 tests failed on every local run while CI stayed green, which is the worst shape for a test to have: it is only ever red on the machine of whoever is trying to change the code. tests/test-utils.tsx already ships chooseSelectOption for exactly this. It finds the option by role and waits for the positioner to release pointer events before clicking. The five call sites now use it, and the helper takes the direct user-event API as well as a setup() instance so callers do not have to restructure to use it. Five consecutive full-file runs pass where every previous run failed. Also finishes this file's screen queries, which brings prefer-screen-queries to its target of 18. |
||
|
|
f1e143a87c
|
chore(ui): upgrade the dashboard to React 19 (#37411)
* chore(ui): upgrade the dashboard to React 19 Bumps react and react-dom from 18.3.1 to 19.2.8 with matching @types. Next 16 already required a React 19 peer, so this aligns the dashboard with what the framework expects and unblocks Base UI and shadcn work that assumes the React 19 ref model. React 19 passes ref through as a regular prop, so the setup file's forwardRef tripwire and the ref-forwarding test's forwardRef case no longer describe real behavior; both now assert the React 19 contract instead. useRef<T>(null) now yields RefObject<T | null>, which is the one prop type MessageList had to widen. * test(ui): wait for a Base UI select popup to open before clicking an option The option lands in the DOM one render before the popup finishes entering, while its positioner still carries pointer-events: none, so clicking it throws. Waiting on the option's text alone was a race that React 19's flush timing loses, which is why four ToolPolicies cases went red on the bump. chooseSelectOption in test-utils opens the trigger, finds the option by role, waits for it to stop being pointer-blocked, then clicks. It also replaces the last-match-by-text hack, which only worked because the popup happens to portal after the table. |
||
|
|
2dc49a913c
|
refactor(ui): replace hand-rolled query-param routing with nuqs (#35871)
* refactor(ui): replace hand-rolled query-param routing with nuqs The dashboard carried five copies of the same pushState-based detail routing hook plus a shared navigateWithParams helper, each with its own plumbing test and a copy-pasted reactive useSearchParams mock in component tests. nuqs provides the same shallow history-API routing behind useQueryState/useQueryStates, so the key, team and org hooks are deleted in favor of inline useQueryState at their single consumers, while the models and logs hooks keep their interfaces but drop their hand-rolled internals. Component tests now mount NuqsTestingAdapter (via renderWithProviders or locally) instead of patching window.history, and URL assertions go through onUrlUpdate spies that can additionally distinguish push from replace, which the old window.location checks could not * test(ui): assert browser back closes the log drawer after in-drawer selection Greptile flagged that the nuqs port of the switching-logs test stopped at asserting emitted push and replace modes. The test now replays those recorded modes against a history stack and performs the back step, so a regression to push-on-select or broken URL-derived drawer state fails the test instead of passing silently |
||
|
|
2e492f5cb7
|
fix(ui): hide guardrail group headers when only one group has entries
The team settings guardrails dropdown always rendered the Global and Other headers, so a proxy with no global guardrails showed an empty Global heading above the list. |
||
|
|
dc3bdffaee | Migrate MCP servers to react query | ||
|
|
5197268a58 | added and ran prettier autoformatter | ||
|
|
f80660acd9 | vitests for GuardrailViewer components |