mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-12 08:42:18 +00:00
19 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5088b0cea6
|
feat(ui): replace deployment warning banners with a health icon, alert banner and panel (#46498)
* feat(ui): replace deployment warning banners with a health icon, critical row and panel The debug, no Redis, env credential login and license expiry banners are gone. Proxy admins and proxy admin viewers now get a shield icon in the header with an active warning count, one row under the header for the top critical warning, and a side panel where proxy admins snooze, ignore or restore each warning for every admin of the proxy * test(ui): cover deployment health wiring and warning content, drop unused license tier helper Both dashboard shells are checked end to end for the icon, critical row and panel, and the warning catalog is checked for its license wording, fix text and links. getLicenseExpiryTier and its thresholds lost their last caller with the license banner, and the proxy now decides severity * fix(ui): wrap long setting names in deployment warning fix text on narrow screens * style(ui): restyle deployment health to the dashboard design system The critical row now follows the deployment alert banner: tone tint, bold lead, Review as a link and +N more on the right. The panel drops nested cards for ruled rows with severity icons, row actions move into a ⋯ menu, ignored rows show only who snoozed them and until when, and loading uses skeleton rows. The header shield matches the bell and carries a small count pill * style(ui): rebuild deployment health on shadcn primitives with the reviewed design The banner shows the most severe active alert by title with a Review link, the header shield carries a count badge, and the panel groups issues into collapsible Critical, Warnings, and Ignored and snoozed sections. Each issue is a tinted Alert with a docs link and a Snooze menu, snoozed issues keep the full layout with a status badge and Restore, and the empty state uses the shadcn Empty primitive * chore(ui): exempt shadcn primitives from the PascalCase filename rule The shadcn CLI writes kebab-case files under components/ui, so every primitive needed a suppression entry and each new one failed lint. Exempt the folder and drop the 34 entries it replaces * fix(ui): let long setting names in deployment warnings wrap inside the alert on phones The shadcn Alert lays out its text in a 1fr grid column, whose minimum width is the longest unbreakable run. overflow-wrap break-word does not lower that minimum, so a long setting name pushed the panel wider than a 390px screen. overflow-wrap anywhere does |
||
|
|
05f1c73a3c
|
refactor(ui): move TraceView into components/lens/traces (#44501)
Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
5ddcc45b3a
|
feat(ui): share trace drawer as a closable SidePanel and polish Lens (#44473)
Some checks failed
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 / caching-local (push) Waiting to run
Unit Tests / core-utils (push) Waiting to run
Unit Tests / enterprise-package (push) Waiting to run
Unit Tests / enterprise-routing (push) Waiting to run
Unit Tests / integrations (push) Waiting to run
Unit Tests / All Other Providers (push) Waiting to run
Unit Tests / Vertex AI (push) Waiting to run
Unit Tests / mcp-integration (push) Waiting to run
Unit Tests / misc (push) Waiting to run
Unit Tests / proxy-auth (push) Waiting to run
Unit Tests / proxy-endpoints (push) Waiting to run
Unit Tests / proxy-extras (push) Waiting to run
Unit Tests / proxy-infra (push) Waiting to run
Unit Tests / proxy-infra-root (push) Waiting to run
Unit Tests / proxy-server (push) Waiting to run
Unit Tests / responses-caching-types (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
* feat(ui): extract trace drawer into a shared SidePanel that closes on outside press
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(ui): center Lens mode switch in a notch joined to the content card
Larger Traces/Investigations switch, a subtle dot when an investigation is running or queued, and a bigger Lens title with a docs link.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ui): stronger Lens frame border and header spacing
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ui): align Lens notch fillet with the notch border
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ui): centered Lens loading/error states and proxy JSON calls in dev
The dev server answered GET /lens with the Lens page HTML because the UI route shadowed the proxy fallback rewrite. JSON API requests now go to the proxy before page routes, and a non-JSON success body raises a readable ApiError.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(ui): theme-scale type and shape in trace views, aligned pane bars
Add local/no-arbitrary-design-value, scoped to TraceView and Lens, banning
arbitrary font size, tracking, leading, radius, border and CSS property
values. Map the Figma-export values onto the theme scale and replace hex
colors with info/destructive tokens.
Add PaneBar, a fixed-height bordered row, and build the step tree and span
detail headers from it so their borders line up across the split.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ui): restore AgentTracesSection emptied in
|
||
|
|
0c86d6bfc9
|
refactor(dashboard): migrate to zod 4 and openai 6 (#44345)
* refactor(dashboard): migrate to zod 4 and openai 6 Bump the dashboard to real zod 4.6.5 and openai 6.49.0 so every module imports from bare "zod" instead of "zod/v4". Ports the ten files that still used the zod 3 API (error params, record, passthrough, strict, email/date validators, union discriminator codes) and adapts the LiteAdmin tool schemas and form plumbing where openai 6 and zod 4 changed behaviour. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * style(dashboard): prettier format zod 4 schema files Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(dashboard): restore system one missing state message under zod 4 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Yujong Lee <yujong@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
847d737b8e
|
test(ui): budget DOM-structure assertions in dashboard tests
Turn on testing-library/no-node-access, no-container and prefer-screen-queries as warnings and baseline them in eslint-budgets.json so the counts can only go down. These three rules catch tests that assert on DOM structure rather than on what a user can observe: reaching through parentElement chains, querying the container by CSS selector, and destructuring queries off render instead of going through screen. Those assertions break on refactors that change nothing a user sees, and stay green when the behaviour underneath is broken. Baselines are the current counts, so nothing fails today. |
||
|
|
6385b6d801 |
refactor(ui): replace hand-picked z-index values with one named scale and lint it
Regression LIT-6143 (the policy Flow Builder painting its guardrail dropdown underneath a position: fixed shell at z-index 1000) was one instance of a class of bug: pages picking their own z-index numbers above the portalled popup layer. This removes the class. - globals.css defines the only z-index values in the dashboard as Tailwind utilities: z-raised, z-chrome, z-sticky, z-sticky-pinned, z-floating, z-overlay, z-popup; every numeric, arbitrary and inline z-index across src is migrated onto them and tailwind-merge learns the tokens - new local/no-ad-hoc-z-index ESLint rule bans z-<n>, z-[...], z-(...) and inline zIndex everywhere, and reserves z-popup for the portalled primitives in components/ui (and the DataTable menus) - the Flow Builder renders in the dashboard content area instead of as a fixed full-screen overlay, so it has no stacking level at all - the guardrail content-filter Add keyword / Add pattern / Custom pattern dialogs drop the leftover z-[1100] (renamed from ABOVE_ANTD_MODAL when antd was removed) that hid their own Action select and pattern combobox behind the dialog, the same bug as LIT-6143 |
||
|
|
93c1461074
|
fix(ui): restore hover feedback and dark-mode variants lost in the token migration (#37579)
* fix(ui): restore hover feedback and dark-mode variants lost in the token migration PR #37576 mapped hardcoded Tailwind palette classes onto semantic tokens. Two-tone hover pairs collapsed onto a single token, so 116 hover utilities across 49 files became identical to their base class and produced no visible feedback, and in seven files a dark: variant was dropped while its hardcoded light partner survived, leaving those elements stuck light in dark mode. Hover states now follow the alpha-step idiom the shadcn primitives already use (hover:bg-primary/80, hover:bg-success/20): a duplicated hover:text-X or hover:bg-X becomes /80, hover:border-border becomes hover:border-ring, and a duplicate is dropped where another hover utility on the element already carries the change. One transition-colors that no longer animated anything is removed. For the dark-mode gaps, indigo maps onto info and amber onto warning. There is no purple token in globals.css, so the purple sites keep their palette classes and get their dark: partner back. * fix(ui): add an eslint rule that fails a hover: utility identical to its base The token migration collapsed two-tone hover pairs by hand, so nothing catches the next one. `local/no-noop-hover-variant` reads every string literal and template chunk and errors when a `hover:X` sits alongside a bare `X`, which is exactly the shape that renders no hover feedback. It ships at error with no suppression baseline, so the eleven sites that already carried a dead hover before the migration are fixed here too. The rule reads one class string at a time, so a base class supplied by a different ternary branch than its hover partner is left alone: a selected row whose resting colour already matches its hover colour is deliberate, not a bug. |
||
|
|
7b574b9df6
|
chore(ui): drop the antd dependency and its leftovers (#37574)
Some checks failed
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
CodSpeed Benchmarks / benchmarks (push) Waiting to run
Publish basedpyright base counts / publish (push) Waiting to run
Code Quality Checks / code-quality (push) Waiting to run
UI Unit Tests / ui-unit-tests (push) Waiting to run
Unit Tests: Documentation Validation / documentation (push) Waiting to run
GitHub Actions Security Analysis / zizmor (push) Waiting to run
Unit Tests: Core Utilities / core-utils (push) Has been cancelled
Unit Tests: Enterprise, Google GenAI & Routing / enterprise-routing (push) Has been cancelled
Unit Tests: Integrations (Callbacks & Logging) / integrations (push) Has been cancelled
Unit Tests: LLM Provider Transformations / Vertex AI (push) Has been cancelled
Unit Tests: LLM Provider Transformations / All Other Providers (push) Has been cancelled
Unit Tests: MCP, Secrets, Containers & Misc / misc (push) Has been cancelled
Unit Tests: Proxy Auth & Key Management / proxy-auth (push) Has been cancelled
Unit Tests: Proxy Infrastructure / proxy-infra (push) Has been cancelled
Unit Tests: Responses, Caching & Types / responses-caching-types (push) Has been cancelled
Unit Tests: Proxy API Endpoints / proxy-endpoints (push) Has been cancelled
Unit Tests: Proxy API Endpoints / proxy-server (push) Has been cancelled
Nothing in the dashboard renders antd any more, so the package and the
scaffolding around it can go. This removes `antd` and
`@ant-design/cssinjs` from package.json, deletes the global StyleProvider
the root layout wrapped every page in, drops the `antd` cascade layer and
the z-index override that lifted Base UI popups over an antd Modal, and
retires the lint rules that policed antd imports and antd class selectors
in tests.
Fifteen test files still carried `vi.mock("antd", ...)` factories for
components that stopped importing antd during the migration. They were
inert, and they resolve the real module, so they would have broken the
moment the package left node_modules.
The compatibility shims keep their behaviour and lose the antd name:
`antdRules`/`antdRequired` become `validatorRules`/`requiredRule`,
`isAntdUrl` becomes `isValidUrl`, and `ABOVE_ANTD_MODAL` becomes
`NESTED_DIALOG_LAYER`. Comments that explain why a contract looks the way
it does still name antd, because that history is the reason.
|
||
|
|
629d7683f2
|
refactor(ui): swap @ant-design/icons for lucide-react (#37553)
The dashboard drew its icons from two libraries at once: lucide-react, which shadcn/ui ships with, and @ant-design/icons, left over from antd. This moves the last 39 files onto lucide and drops the dependency, so the icon set matches the component library everywhere. antd icons sized themselves from the inherited font-size and rendered as role="img" with an aria-label, neither of which a lucide svg does, so the swap carries explicit size classes and gives the two icon-only plugin buttons real accessible names. |
||
|
|
41d6dbb50c |
build(ui): gate dashboard test assertions with testing-library and jest-dom
Enables 14 rules at error with zero violations, so the vacuous-assertion class
the previous commit fixed cannot come back. No budget file and no suppressions
baseline: a rule is on only if it is already at zero.
prefer-to-have-value stays off. It matches any attribute whose name contains
"value", so it rewrites toHaveAttribute("aria-valuenow", n) into toHaveValue(n),
and jest-dom's toHaveValue supports only form controls, which breaks every
role="meter" element the dashboard renders.
Records the enabled set, the rules left off with their measured counts, and the
seven ways these plugins' autofixers produce broken output.
|
||
|
|
7d15c5b6da
|
test(ui): query antd controls accessibly instead of by internal CSS class
Dashboard tests located controls through antd's own class names (.ant-form-item, .ant-select-selector, .ant-select-item-option). Those break when a page moves to shadcn without any behaviour changing, and they miss regressions a user would notice. Replace them with role, label, title and accessible icon-name queries where antd exposes one, and add local/no-antd-class-selectors to keep them out. The rule is enabled as an error at zero violations, so there is no budget file and no suppressions baseline. It found eight more sites a '.ant-' search missed, written as bare class names. Eleven couplings remain and carry an inline suppression naming why: antd puts role="option" only on a hidden mirror list, so the visible options have no role, no aria-disabled and a tooltip in title; Skeleton and the modal mask expose nothing at all; and one assertion's whole purpose is that no antd modal renders. 7231 tests passed before, 7233 pass after: one conflated ModelSelector case became three focused ones. |
||
|
|
67fce87b16
|
chore(ui): add filename, size, JSX-handler, prefer-const, and antd lint rules (#34341)
* chore(ui): add filename, size, JSX-handler, prefer-const, and antd lint rules Wires up five error-level ESLint rules on the dashboard, grandfathering every current offender into eslint-suppressions.json so the gate only bites new code and ratchets down as files are fixed - local/filename-pascal-case: new local rule requiring PascalCase .tsx names, exempting Next.js reserved files (page, layout, route, ...) and test/spec files (239 grandfathered) - max-lines: 800 lines over src/**, excluding tests, src/data, and generated schema.d.ts (20 grandfathered) - local/no-complex-jsx-arrow: new local rule flagging inline JSX arrow handlers with block bodies over two statements; each failure is a small extract-to-named -handler refactor (65 grandfathered) - prefer-const: flipped from off to error (103 grandfathered) - no-restricted-imports: added antd to the phase-out ban alongside tremor, and pointed both messages at shadcn/ui primitives (405 antd import sites grandfathered) Both new local rules ship with RuleTester coverage * fix(ui): preserve secondary extensions in filename-pascal-case suggestion The suggestion text built the rename from only the head segment, so a multi-dot file like my-component.utils.tsx was told to become MyComponent.tsx instead of MyComponent.utils.tsx. Rebuild it from the PascalCased head plus the untouched remaining segments, and add tests covering multi-dot filenames and the hyphenated Next.js reserved names (global-error, apple-icon, opengraph-image, twitter-image) |
||
|
|
5973d9fd2b
|
feat(ui): add eslint rules for nested ternaries, large inline object args, and long condition chains (#32415)
* feat(ui): add eslint rules for nested ternaries, large inline object args, and long condition chains Adds three dashboard lint rules to keep new code readable. Nested ternaries are banned outright via the built-in no-nested-ternary, with the 265 existing occurrences grandfathered in eslint-suppressions.json so only new ones fail. Two custom rules ship as a small local plugin under scripts/eslint-rules: no-large-inline-object-arg flags object literals with 4+ properties passed straight into a call, nudging toward a named variable, and no-long-condition-chain flags boolean expressions that combine 4+ conditions, nudging toward a named boolean. Both are warnings tracked on the existing budget ratchet (eslint-budgets.json + eslint-metrics.json) with headroom above the current counts, so they ratchet down over time rather than freezing a baseline. Both thresholds are configurable rule options and covered by RuleTester unit tests. * fix(ui): scope no-long-condition-chain to boolean operators, not nullish Greptile flagged that the rule counted nullish-coalescing chains the same as &&/|| chains, so a 4-part `a ?? b ?? c ?? d` fallback surfaced "Boolean expression combines 4 conditions", which is inaccurate since a `??` fallback is value defaulting, not a condition. Restrict the visitor to && / || nodes so `??` chains are treated as leaves, while a boolean chain nested inside a `??` is still caught. Drops 6 miscounted occurrences (240 -> 234). * chore(ui): sync lint metrics and suppressions with staging Merge advanced the base branch, adding one no-large-inline-object-arg occurrence (508 -> 509) and making one grandfathered react-hooks suppression stale. Regenerate eslint-metrics.json and prune the suppression so the budget/drift gate passes. * chore(ui): sync lint metrics with staging Merge advanced the base, adding four no-large-inline-object-arg occurrences (509 -> 513). Regenerate eslint-metrics.json so the drift gate passes. |
||
|
|
76a9f7b5f3
|
chore(ui): add no-console lint ratchet and strip console from prod builds
Introduce a gradual ratchet to remove raw console.* calls from the dashboard, mirroring the existing no-explicit-any budget. The no-console eslint rule is set to warn with allow: [warn, error] so the 486 console.log/debug/info calls are tracked without force-deleting the legitimate console.error/warn error reporting in catch blocks. The count is grandfathered via eslint-budgets.json (max 486, target 0) and eslint-metrics.json, so any newly added console.log fails the budget check and follow-up PRs grind the max down toward zero. Independently, next.config strips console output from production builds via SWC removeConsole (exclude: [error]), gated on NODE_ENV=production so dev keeps full console output. This gives an immediate prod-hygiene net regardless of how long the source cleanup takes. Verified against a real production build: app-code console.log dropped from 675 to 14 in the bundle (remainder is node_modules, which the transform leaves alone), console.warn app calls stripped, console.error preserved 906 to 906. |
||
|
|
e53bd7cbd1
|
feat(ui): generate dashboard API types from the proxy OpenAPI spec (#29816)
* feat(ui): generate dashboard API types from the proxy OpenAPI spec Introduces the shared type foundation for the dashboard without touching any runtime code. The proxy's FastAPI app is the source of truth; app.openapi() emits the spec and openapi-typescript turns it into src/lib/http/schema.d.ts. Adds an npm run gen:api script (a Python spec dump piped into openapi-typescript) and a Check UI API Types Sync CI job that regenerates the file from the live spec and fails if it drifts, so the committed types can never silently fall out of step with the backend. The generated file is pinned to openapi-typescript 7.13.0 and excluded from prettier, eslint, and knip, and marked linguist-generated so it collapses in diffs. No openapi-fetch and no call-site changes yet; this only makes the types exist. * chore(ui): tidy gen-api-types script per review Write the spec dump inside a with-block and clean up the temp dir in a finally, so repeated local runs don't leave stray ~MB JSON files behind. |
||
|
|
f3811ce63b
|
refactor(ui): shared HTTP client + location-pinned fetch() lint rule (#29723)
* refactor(ui): add shared HTTP client and pin raw fetch() to one file Introduce src/lib/http/client.ts, a single typed wrapper that owns the only fetch() in the dashboard. It centralizes the base URL, the auth header, error parsing (deriveErrorMessage), non-2xx -> thrown ApiError, and JSON parsing, and is framework-agnostic (no React) so it can run from client and, later, server components. The base URL, auth header name and the logout side effect are injected through createApiClient. networking.tsx builds one configured apiClient and the 29 functions whose boilerplate maps exactly to the client's default behavior (canonical deriveErrorMessage + handleError + res.json() template) now call it instead of hand-rolling fetch. Names, signatures, return types and error behavior are unchanged; this is a pure refactor that drops ~440 lines. The no-restricted-syntax fetch rule now points at the client and a files: ["src/lib/http/**"] override makes that the only place fetch() is allowed. Re-baselined eslint-suppressions.json: networking.tsx fetch suppressions drop 270 -> 241; no other rule's counts change. The remaining networking.tsx fetches and the ~61 scattered component/hook fetches diverge from the default client behavior (text() error bodies, no res.ok check, no handleError side effect) and stay grandfathered for a follow-up burndown. * fix(ui): make the HTTP client tolerate non-JSON error bodies The non-2xx branch parsed the error body with response.json(), so a gateway returning HTML (502/503 from a reverse proxy) threw a SyntaxError before onError fired or ApiError was built, dropping the user-facing notification. This matched the old per-function behavior, but the client is now the single error path so it is the right place to harden. Read the body as text once, try JSON.parse for the existing deriveErrorMessage path, and fall back to the raw text (or the HTTP status) otherwise. The success path stays strict json() so return types are unchanged. * fix(ui): await the returned apiClient promise in 6 migrated functions The codemod rendered the `return response.json()` tail as `return apiClient.x()` without `await`. Inside the surrounding try/catch that returns an unawaited promise, so the catch never runs and its console.error log is dropped on failure; 4 of the 6 were `return await response.json()` originally, so this restores their exact behavior. Use `return await apiClient.x()` in all six. * refactor(ui): widen onError type and handle empty success bodies Address review notes on the shared client. Type onError as (message: string) => void | Promise<void> so the fire-and-forget async contract (networking passes the async handleError) is explicit rather than silently discarded by void. On the success path, read the body as text and return undefined for an empty body (e.g. a 204 No Content) instead of throwing a SyntaxError, while still parsing non-empty bodies strictly so a malformed JSON response surfaces rather than being masked. Add tests for the 204 case. |
||
|
|
41e90a6ada
|
chore(ui): remove the bare-fetch lint rule (#29712)
* fix(ui): only flag bare fetch() outside React Query queryFn/mutationFn The frontend lint rule banned every fetch() call by static AST name match, so a fetch wrapped in a React Query queryFn/mutationFn tripped it just like a loose fetch in a component. esquery (no-restricted-syntax) can't express "has ancestor", so this replaces that selector with a small custom rule (local/no-bare-fetch) that exempts a fetch lexically inside a queryFn or mutationFn and reports everything else. Re-baselined eslint-suppressions.json under the new rule id (same 44 files / 331 violations) so existing code keeps its grandfathered suppressions. Adds a RuleTester suite covering wrapped (valid) vs unwrapped, the standalone *Api.ts function pattern, queryKey, and computed-key cases. * chore(ui): remove the bare-fetch lint rule Drop the fetch lint gate (and its 331 grandfathered suppressions) ahead of the networking refactor. The plan is to centralize all fetching in a single shared http client and enforce that with a location-based rule, so keeping a fetch rule in place now would only block CI while functions are routed through the new client. Removing it unblocks that work; the location-based rule lands with the client in a follow-up. |
||
|
|
443f0ca4cd
|
ci(ui): frontend-lint job enforcing prettier + eslint on changed files (#29633)
* ci(ui): add frontend-lint job enforcing prettier and eslint on changed files
Lints only the files a PR adds or modifies under ui/litellm-dashboard,
so new and touched code must be prettier-clean and eslint-clean while the
existing tree is grandfathered. Skips cleanly when a PR touches no
lintable UI files. This lets us adopt the formatters incrementally
without a repo-wide reformat
* ci(ui): write frontend-lint file lists to $RUNNER_TEMP
Keep the prettier/eslint changed-file lists out of the checkout dir so
they cannot collide with a future source file of the same name
* lint(ui): baseline existing eslint findings so only new ones block
Capture the current error-level eslint findings (318 across 183 files)
in a committed suppressions baseline via eslint --suppress-all. Every
rule stays at its error severity, so any newly introduced violation
fails the frontend-lint gate, while the existing tree is grandfathered;
touching a legacy file never forces fixing its pre-existing issues. CI
runs eslint with --pass-on-unpruned-suppressions so that fixing a
baselined issue does not fail on a now-stale suppression, and the
generated baseline is prettier-ignored since eslint owns its format.
Burn the baseline down over time with eslint --prune-suppressions
* lint(ui): enforce a count budget for explicit any
Make @typescript-eslint/no-explicit-any a warning and cap the total
instead of hard-blocking each new one. A frontend-lint step counts the
repo-wide explicit any and fails only when it exceeds the committed
budget in eslint-any-budget.json. max starts at 2031, ten above the
current 2021, so the next ten land as warnings and the build fails once
that headroom is gone. Lower max over time toward target to ratchet the
count down. New anys still surface as warnings on changed files via the
normal eslint step
* lint(ui): enable zero-cost rules no-var, no-self-assign, react/no-danger
These have no existing violations, so they need no baseline; turning them
on purely blocks new instances. react/no-danger guards against new
dangerouslySetInnerHTML (XSS), no-var enforces let/const, and
no-self-assign catches self-assignment typos. no-debugger is already
enforced by the recommended preset
* lint(ui): add baselined complexity rules
Enable complexity:20, max-depth:4, max-params:4, max-nested-callbacks:4,
with thresholds set near the codebase p99 so only genuine outliers are
flagged. The 272 existing over-threshold functions are grandfathered in
the suppressions baseline; new over-threshold functions block. Lower the
thresholds over time to ratchet complexity down. max-lines-per-function
is intentionally left off since React components are legitimately long
* lint(ui): ban new raw fetch, standardize on React Query
Add a no-restricted-syntax rule flagging bare fetch() calls, pointing
contributors at React Query (@tanstack/react-query). The rule is not
exempted anywhere, including the already-bloated networking.tsx, so all
331 existing fetch calls are grandfathered but no new ones can be added
there or elsewhere. New data access goes through React Query, and the
networking layer can be migrated out and pruned from the baseline over
time
* lint(ui): ban new @tremor/react imports
Add a no-restricted-imports rule flagging imports from @tremor/react so
tremor is phased out rather than spread further. The 232 existing tremor
imports are grandfathered in the baseline; new ones block and point at
antd. Migrate components off tremor and prune the baseline over time
* lint(ui): widen explicit-any budget headroom to 2040
Raise max from 2031 to 2040, giving ~19 of slack over the current 2021
instead of 10
* style(ui): prettier-format eslint.config.mjs
The frontend-lint gate flagged its own config file. Format it so the
prettier check on this PR's changed files passes
* lint(ui): soften complexity and max-depth to warnings
These two are smell metrics with arbitrary thresholds where a legit new
function can trip them, so make them advisory rather than hard-blocking.
They drop out of the baseline (now 963). max-params, max-nested-callbacks,
and the react-hooks rules stay strict since those are clear-cut
* lint(ui): move complexity and max-depth to the count-budget pattern
Generalize the explicit-any budget into a shared lint-budget mechanism:
eslint-budgets.json maps a rule to {max, target} and check-lint-budgets.mjs
counts each across the repo and fails when a count exceeds its max.
complexity (129, max 140) and max-depth (61, max 70) now use the same
slack-plus-counter model as explicit-any (2021, max 2040): they warn
per-file and the build only fails if the repo-wide total crosses the
ceiling. Lower each max toward its target over time
* docs(ui): note pruning the eslint suppressions baseline when fixing lint debt
|
||
|
|
c7f1bcfd0d
|
build(ui): migrate eslint to flat config and bump eslint-config-next to 16 (#29626)
ESLint 9 defaults to flat config and eslint-config-next was pinned at 15 while Next is on 16, so eslint only ran with ESLINT_USE_FLAT_CONFIG=false and next lint is gone on Next 16. Replace .eslintrc.json with a native flat eslint.config.mjs (config-next 16 ships flat configs, so no FlatCompat shim is needed), bump eslint-config-next to 16.2.6, add @eslint/js and typescript-eslint as explicit devDeps for the recommended rule sets, and point the lint script at eslint directly. This only makes eslint runnable on modern tooling; it does not wire it into CI. The same rules carry over (next/core-web-vitals, eslint and typescript-eslint recommended, prettier, unused-imports) |