Commit graph

43050 commits

Author SHA1 Message Date
Yuneng Jiang
61334ec94a
fix(ui): match the MCP servers count badge to its sibling permission badges
The Object Permissions section rendered the MCP Servers badge with shadcn's
default variant (solid bg-primary), so a plain count showed up as a black pill
next to the light Vector Stores and Agents counts. Counts now use secondary
everywhere, and destructive stays reserved for the blocked state.
2026-08-14 16:32:27 -07:00
yuneng-jiang
652f4cb8e4
Merge pull request #36982 from BerriAI/litellm_/revert-36837-ui-regression
Revert "fix(auth): stop the team fallback from widening model access" (#36837)
2026-08-14 16:19:17 -07:00
yucheng-berri
2fc39cde18
fix(langfuse): gate update_trace_keys behind an operator setting (#36862)
update_trace_keys lets a caller name which request metadata entries get copied
onto an existing trace, and the name is unrestricted. Sending
update_trace_keys: ["user_api_key_auth"] with existing_trace_id serializes the
resolved auth object, including the team callback credentials it carries, onto
the trace through Langfuse.trace(**trace_params). TraceBody is Extra.allow, so
an unexpected key ships rather than being dropped.

Any holder of a team key can do this and read the result in the destination the
team already logs to, so the feature is now inert unless an operator turns it on
with langfuse_enable_update_trace_keys.
2026-08-14 16:05:28 -07:00
Yuneng Jiang
9592a5447f
Revert "fix(auth): stop the team fallback from widening model access (#36837)"
This reverts commit ab2333b6c4.

Every Admin UI login mints its session key against the sentinel team_id
`litellm-dashboard`, and no LiteLLM_TeamTable row is ever created for it.
That lookup is therefore a provably-absent row on every UI request, which
#36837 turned into a hard refusal with no override, so the whole dashboard
404s.

Reverting restores the token-derived fallback. The model-access widening
#36837 closed is reopened and needs a re-land that exempts the UI sentinel
team.
2026-08-14 16:03:51 -07:00
Ahmed N
29fe342ead
fix(transcription): stop a zero output rate from zeroing transcription cost (#36914)
cost_per_second treated a declared-but-zero output_cost_per_second as a real
rate, so the output branch claimed the call and the elif locked out
input_cost_per_second. Every transcription model shipping
output_cost_per_second 0.0 next to a real input rate billed $0, which covers
43 of the 55 per-second entries in the cost map: all 36 deepgram models, both
assemblyai, both elevenlabs scribe, both groq whisper and azure-stt. Custom
deployments pairing the two fields the same way billed $0 as well

Take the output branch only when that rate is actually billable, so a zero
falls through to the input rate. Entries that duplicate one rate into both
fields, whisper-1 among them, keep billing exactly what they bill today
2026-08-14 15:12:37 -07:00
devin-ai-integration[bot]
865ed96765
fix(proxy): force prisma recreate on postgres cached-plan error (#36428)
`_query_first_with_cached_plan_fallback` recovers from Postgres's "cached
plan must not change result type" by recreating the Prisma client, which
drops both the server-side plans and the engine's client-side statement-name
cache. Since #30183 the shared reconnect path probes the writer with
`SELECT 1` first and skips the recreate when it answers, which is right for
the IAM token refresh it was added for and wrong here: the connection is
healthy, it is the session's prepared statements that are stale, so the probe
always passes and always vetoes the recreate. Callers now pass
`force_recreate` to skip that probe, and only the cached-plan fallback does.

Getting past the probe is not enough on its own. Both cooldown checks would
still skip the recreate for 15 seconds after any earlier reconnect, which
outlives the 10 second auth retry window, so a migration landing in that
window kept 503ing. `force=True` would fix that but would also let every
concurrent caller of the same burst kill the engine the first one just built.
The caller instead names the engine it observed before the query, and the
cooldown is waived only while that engine is still the live one, so the first
caller repairs the pool and the rest fall back to the normal cooldown.

That engine has to be the one the query actually ran on. `query_first` is a
top-level read, so with a read replica configured it is dispatched to the
reader and it is the reader's prepared statements that go stale, while
`writer_db` names a different engine with its own counter. The observation
and the cooldown comparison both go through `read_db`, added alongside
`writer_db` and backed by a `read_target` property on the routing wrapper
that `__getattr__` now dispatches through so the two cannot drift.

The observation carries the wrapper, not just its generation. `read_db`
resolves to the reader while it is available and to the writer once it is
not, and those counters are independent and both start at zero, so comparing
a bare number across that switch pits one engine's counter against another's.
Equal by coincidence waives the cooldown for an engine already replaced;
unequal gates a caller that needs the recreate. Identity settles it, and is
sound because the engine object is never re-pointed without the generation
also moving.

Three smaller holes on the way out. The waiver is withdrawn once a repair of
that same engine has been tried and failed, so a burst collapses onto one
attempt instead of each caller running its own recreate serially; the record
is keyed per engine rather than counted globally, so an unrelated reconnect
failure cannot suppress a stale reader's recovery and a writer failure cannot
evict the reader's record. And a forced recreate that the optimistic-lock
guard declines is no longer reported as a success on either the direct or the
heavy path, since the routing wrapper leaves the reader untouched in that
case; a decline is deliberately not counted as a failure, so the caller's own
backoff still gets its waiver on the next attempt.

A decline on the heavy path clears the dead-engine flag before raising. The
clear after the cycle is skipped by any raise, which is right for a failure
and wrong here, and the non-forced path already clears it on a decline, so
this restores that policy rather than inventing one. Stranding the flag would
route the next cycle back down the probe-free heavy branch, where the
refreshed generation matches and the recreate kills the healthy engine a
refresh just spawned, which is #29176.

Clearing that flag is necessary and not sufficient. The escalation check
re-arms it whenever the consecutive-failure count sits at the threshold, so a
decline that left the count alone sent the very next attempt back down the
same path. A decline is raised only at the generation guard, and the
generation moves only after a replacement connects, so a decline is proof
that a replacement succeeded and the count is reset on it.

Fixes #36418

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-14 15:04:01 -07:00
yuneng-jiang
f03df1bb42
Merge pull request #36966 from BerriAI/litellm_shadcn_smallfiles_0814
refactor(ui): migrate ten small dashboard files off antd and tremor
2026-08-14 11:50:56 -07:00
yuneng-jiang
e659147aee
Merge pull request #36964 from BerriAI/litellm_/cranky-jepsen-f831e1
refactor(ui): move MCP permission panels onto shadcn primitives
2026-08-14 11:50:42 -07:00
Fahima Mokhtari
b9d2fd0ee9
fix(exception_mapping): bare 429 in an error body no longer outranks the status code (#36705)
is_error_str_rate_limit treats any standalone 429 in the stringified exception as
a rate limit, and for openai-compatible providers that check runs before the
status-code branch. Providers echo the request back in validation errors, so a
400 whose body happens to contain a 429 comes out as RateLimitError.

Tokenised prompts hit this routinely, since 429 is an ordinary token id (" that"
in several tokenisers) and an echoed prompt_token_ids array is enough:

  {"error":{"message":"`tools` must not be an empty array",
            "type":"invalid_request_error","code":400},
   "prompt_token_ids":[9906,429,1234]}

The mislabel is not cosmetic. RateLimitError tells callers and routers to retry,
so a request that cannot succeed gets replayed, and the failure is booked against
provider throttling rather than the caller. Against DeepInfra, one recurring 400
("`tools` must not be an empty array") came back as a rate limit in 77 of 198
occurrences, the split depending only on whether the echoed prompt contained 429.

16482 narrowed '"429" in error_str' to \b429\b after a false positive on
'asbjdad429addad'. Word boundaries cannot separate a real 429 from a token id, so
the same class of false positive survives.

is_error_str_rate_limit now takes an optional status_code, and the bare-number
branch fires only when no explicit status contradicts it. The status is read off
an arbitrary exception, so a non-integer is treated as unknown and left to the
existing behaviour. The repo has a single call site.

The phrase branches are untouched, so a provider reporting a real rate limit in
the message text under a non-429 status still maps to RateLimitError (11455).
This is not "status code wins".

Tests cover the matcher (suppressed under a 400; still detected with no status,
None, 429, or a non-integer status; phrase honoured under a 400) and
exception_type end to end (400 with 429 in the echoed body -> BadRequestError,
real 429 -> RateLimitError). Reverting the source change fails the latter.
2026-08-14 11:39:35 -07:00
Fahima Mokhtari
e1ef7775bd
fix(main): an explicit provider outranks a known OpenAI model name (#36800)
* fix(main): an explicit provider outranks a known OpenAI model name

completion() picks the OpenAI handler whenever `model in
litellm.open_ai_chat_completion_models`, and that clause is evaluated before the
gemini and vertex_ai branches. get_llm_provider() already resolves those names
to "openai", so the clause only adds anything when the provider is something
else, and then it silently overrides it: the config built for the requested
provider is handed to the OpenAI handler.

For gemini that is fatal. VertexGeminiConfig.transform_request raises
NotImplementedError by design, since Vertex builds its request in its own
handler, so `gemini/gpt-4o` dies in async_transform_request before anything is
sent. register_model() reaches the same state without an odd model id: an entry
claiming litellm_provider "openai" adds its name to
open_ai_chat_completion_models, so one mislabelled pricing entry reroutes every
later call to that model in the process.

The name clause now applies only when no other provider was resolved.

* test(main): move the routing regression into the mapped test file

CLAUDE.md asks bug fixes to extend the mapped test file, so these belong in
tests/test_litellm/test_main.py rather than a module of their own.

They also no longer swap out the provider handler objects. Both Gemini cases
inject an HTTPHandler whose post() answers like generativelanguage does, then
assert the URL the request went to and read the reply back; the OpenAI case
injects an OpenAI client and patches its own raw-response create. That asserts
the endpoint the call reaches instead of which attribute the test replaced, and
matches the neighbouring tests in the file.
2026-08-14 11:39:02 -07:00
Yuneng Jiang
c51c5f1821
refactor(ui): drop narration comments from the MCP permission panels 2026-08-14 11:24:47 -07:00
Yuneng Jiang
538f5b3e84
refactor(ui): drop explanatory comments from the migration tests 2026-08-14 11:21:01 -07:00
yuneng-jiang
2bc9bb4a9d
Merge pull request #36962 from BerriAI/litellm_shadcn_daterange_type_0814
refactor(ui): declare DateRangePickerValue locally instead of importing it from tremor
2026-08-14 11:16:08 -07:00
yuneng-jiang
387ad0bb4f
Merge pull request #36960 from BerriAI/litellm_cost_tracking_removal_pending_state
fix(ui): keep the cost tracking removal confirmation open until it settles
2026-08-14 11:15:53 -07:00
Yuneng Jiang
aa093980b1
refactor(ui): migrate ten small dashboard files off antd and tremor
Moves the onboarding views, router settings inputs, tag rate limit editor,
fallback buttons, created-key display and the shared numerical input onto the
in-repo shadcn layer. Each control has a direct equivalent, so this is a
like-for-like swap with no layout changes and no new styling.

Router settings saves by reading input values straight off the DOM with
document.querySelector('input[name="..."]'), a path no test covered. Adds a
regression test that types into a field and asserts the typed value reaches
the payload, so the name attribute contract stays enforced.

Also adds tests for TagRateLimitEditor, which had none and whose RPM cell
switched from antd InputNumber to a native number input.
2026-08-14 11:15:30 -07:00
Yuneng Jiang
caf305f732
refactor(ui): move MCP permission panels onto shadcn primitives
Replaces antd Radio, Checkbox and Tooltip, plus Tremor Text and Badge,
with the in-repo shadcn equivalents across the three MCP permission
panels, and drops the no-restricted-imports suppressions they no longer
need. Also removes the stale suppression on settings.test.tsx, which
imports neither library.

The tool rows keep their existing click-to-toggle behaviour: the row
owns the toggle and the checkbox no longer carries its own change
handler, since Base UI replays the click through a hidden input that
reaches the row on its own.

Adds payload-level tests for the risk-group view covering group clear,
mixed-state re-arm, single-tool toggles from both the box and the row,
and a controlled round trip proving each control re-renders from the
permissions it emitted.
2026-08-14 11:08:09 -07:00
Yuneng Jiang
fe61fa12e4
refactor(ui): declare DateRangePickerValue locally instead of importing it from tremor
DateRangePickerValue is a plain object shape, not a component, so the
twelve files that used it were each carrying a no-restricted-imports
suppression for a type that tremor declares as
{ from?: Date; to?: Date; selectValue?: string }.

Declare that shape in components/shared/date_picker_types.ts and point
every consumer at it, which drops ten suppressions from the baseline.
advanced_date_picker and usage_date_picker keep their tremor imports:
they still render tremor Button, Text and DateRangePicker, and moving
DateRangePicker itself needs react-day-picker.
2026-08-14 11:01:43 -07:00
Yuneng Jiang
7da8a3bef5
test(ui): build the deferred removal with Promise.withResolvers
The pending-state test seeded its deferred promise by declaring the resolver
with let and reassigning it inside the executor. Promise.withResolvers is the
standard way to get the same handle without the reassignment, and the
assertions are unchanged.
2026-08-14 10:43:15 -07:00
Yuneng Jiang
62b072dcf7
Merge branch 'litellm_internal_staging' into litellm_cost_tracking_removal_pending_state 2026-08-14 10:33:53 -07:00
Yuneng Jiang
4974290d3f
fix(ui): keep the cost tracking removal confirmation open until it settles
The discount and margin removal confirmation used AlertDialogAction, which
renders AlertDialogPrimitive.Close and dismisses the dialog on click. The
dialog therefore disappeared while the removal request was still in flight,
leaving the admin with no sign that anything happened and free to fire a
duplicate removal.

Swap the confirm control for a plain destructive Button, track an isRemoving
pending state that disables Cancel and relabels Remove to "Removing...", and
clear the pending removal in a finally block once the request settles.
2026-08-14 10:33:27 -07:00
yuneng-jiang
c9917cbf99
Merge pull request #36918 from BerriAI/litellm_shadcn_modelhub_0814
refactor(ui): move the model hub and model select onto shadcn primitives
2026-08-14 10:33:24 -07:00
yuneng-jiang
5156bf04b6
Merge pull request #36915 from BerriAI/litellm_shadcn_settings_0814
refactor(ui): migrate router settings and shared badges off antd and tremor
2026-08-14 10:28:02 -07:00
Armaan Sandhu
e1f3d6e158
feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery (#35455)
* feat(proxy): serve Anthropic-native /v1/models for Claude Code gateway discovery

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

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

* style: apply ruff format to changed lines

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

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

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

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

* ci: trigger buildkite status report

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

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

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

---------

Co-authored-by: yuneng-jiang <yuneng@berri.ai>
Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-08-14 10:22:58 -07:00
yuneng-jiang
3d35cff9f5
Merge pull request #36913 from BerriAI/litellm_shadcn_permissions_0814
refactor(ui): migrate key info and permissions views off antd and tremor
2026-08-14 10:15:28 -07:00
yuneng-jiang
10df18be66
Merge pull request #36910 from BerriAI/litellm_shadcn_common_0814
refactor(ui): migrate shared common_components off antd and tremor
2026-08-14 10:11:52 -07:00
yuneng-jiang
609ecf06c2
Merge pull request #36866 from BerriAI/litellm_/remove-test-migrate-gha-d1eae8
ci: drop the duplicate proxy_unit_tests letter-shard workflow
2026-08-14 10:11:08 -07:00
Yuneng Jiang
693683c013
Merge branch 'litellm_internal_staging' into litellm_shadcn_modelhub_0814 2026-08-14 09:59:57 -07:00
Yuneng Jiang
30c1b972d4
Merge branch 'litellm_internal_staging' into litellm_shadcn_settings_0814 2026-08-14 09:59:20 -07:00
Yuneng Jiang
e897e2b0aa
Merge branch 'litellm_internal_staging' into litellm_shadcn_permissions_0814 2026-08-14 09:59:12 -07:00
Yuneng Jiang
da339a7e8a
Merge branch 'litellm_internal_staging' into litellm_shadcn_common_0814 2026-08-14 09:57:34 -07:00
Yuneng Jiang
7e375ed6e8 chore: retrigger e2e gate 2026-08-14 09:48:49 -07:00
yuneng-jiang
b77923fc87
Merge pull request #36955 from BerriAI/litellm_shadcn_next_0814
refactor(ui): move the cost tracking components onto shadcn primitives
2026-08-14 09:46:30 -07:00
yuneng-jiang
48a3423aed
Merge pull request #36936 from BerriAI/litellm_shadcn_rootbig_0814
refactor(ui): move the settings page and bulk user invite onto shadcn primitives
2026-08-14 09:41:07 -07:00
yuneng-jiang
8c168177ec
Merge pull request #36927 from BerriAI/litellm_shadcn_rootcomponents_0814
refactor(ui): move the root-level dashboard components onto shadcn primitives
2026-08-14 09:40:54 -07:00
yuneng-jiang
cb33d204f4
Merge pull request #36924 from BerriAI/litellm_shadcn_dropdowns_0814
refactor(ui): move the shared dropdowns and selectors onto shadcn primitives
2026-08-14 09:40:49 -07:00
yuneng-jiang
de57ebbad9
Merge pull request #36908 from BerriAI/litellm_shadcn_aihub_0814
refactor(ui): migrate AI Hub off antd and tremor to shadcn
2026-08-14 09:39:00 -07:00
yuneng-jiang
5ab91b3f07
Merge pull request #36904 from BerriAI/litellm_shadcn_viewlogs_0814
refactor(ui): migrate log details drawer off antd to shadcn
2026-08-14 09:38:51 -07:00
yuneng-jiang
5374e0b0c7
Merge pull request #36902 from BerriAI/litellm_shadcn_navbar_0814
refactor(ui): migrate Navbar off antd to shadcn
2026-08-14 09:36:38 -07:00
Yuneng Jiang
035f8d5f8a
refactor(ui): move the cost tracking components onto shadcn primitives
Rebuilds the provider discount and margin tables, the pricing calculator and
its multi-cost results on the in-repo shadcn layer, and swaps the imperative
antd modal.confirm removals for AlertDialog. Row actions gained accessible
names, which replace the Tremor stub mocks the tests used to drive.
cost_tracking_settings keeps its two antd Modals and Forms, since they wrap
the two add forms that stay on antd for now.
2026-08-14 09:36:16 -07:00
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
0ee47a0028
test(ui): cover appending a second model in ModelSelect
The rewritten suite only ever picked one ordinary model, so a
regression that replaced the selection instead of appending to it
would have gone unnoticed. The case passes against the antd version
too, so it pins behavior the migration preserves rather than adds.
2026-08-14 06:12:28 -07:00
Yuneng Jiang
afff1b08fa
refactor(ui): move the shared dropdowns and selectors onto shadcn primitives
Rebuilds the thirteen form-free components under common_components on
the in-repo shadcn layer, so they inherit the dashboard's design tokens
instead of styling themselves through Ant Design and Tremor.

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

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

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

- antd Popover, Dropdown and Modal become HoverCard, DropdownMenu and Dialog,
  and Tremor TabGroup becomes Tabs with keepMounted so panel state survives
  a tab switch the way Tremor's did
- the key id copy control moves to the shared CopyButton, which also fixes an
  icon that rendered at 24px because it inherited the heading font size
- antd Checkbox onChange becomes onCheckedChange
- every public prop signature is unchanged, since these are shared views
- three member permission tests were passing vacuously: they searched for an
  unchecked box by reading .checked, which is undefined on a Base UI checkbox,
  so the assertions sat inside an if that never ran. They now scope the
  checkbox to its own row and assert the toggle, the save and the revert
- drops the eslint suppressions these files no longer need
2026-08-14 03:30:31 -07:00