Skip to content

feat: ruff strict-rule suppressions baseline gate - #30303

Merged
ryan-crabbe-berri merged 11 commits into
litellm_internal_stagingfrom
litellm_ruff_strict_suppressions
Jun 13, 2026
Merged

feat: ruff strict-rule suppressions baseline gate#30303
ryan-crabbe-berri merged 11 commits into
litellm_internal_stagingfrom
litellm_ruff_strict_suppressions

Conversation

@ryan-crabbe-berri

@ryan-crabbe-berri ryan-crabbe-berri commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

None

Linear ticket

None

Pre-Submission checklist

  • I have added meaningful tests
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

What this adds

This gives the backend a stricter ruff rule set in the same spirit as the dashboard's eslint gate, without forcing a repo-wide cleanup first. Each of ten rules gets a hard ceiling on how many times it may appear across the whole codebase. Today's count sits under the ceiling, so existing violations are grandfathered; a change only fails CI when it pushes a rule's total above its ceiling. As violations get fixed and a count drops, you lower that ceiling, so the number can only ratchet down

The new rules are kept in ruff-strict.toml, a config separate from ruff.toml. The existing ruff check gate is untouched, so nothing about today's linting changes

The rules and their ceilings

The ceiling for each rule is baseline + slack, stored in ruff-strict-budget.json, where the baseline is today's count. The annotation-completeness rules (ANN001, ANN401, TID251, ANN003) get a slack of 10 to 25 so they nudge rather than block; the correctness and structural rules get a small cushion of 3 to be liberal to start

Rule Enforces Today Slack Ceiling
ANN001 function arguments must be typed 2,865 10 2,875
ANN401 no Any in annotations 1,885 10 1,895
PLR0913 at most 5 function arguments 1,813 3 1,816
TID251 no importing the listed typing collection aliases 2,404 10 2,414
ANN003 **kwargs must be typed 759 10 784
C901 cyclomatic complexity at most 15 301 3 304
PLW0603 no rebinding module globals via global 183 3 186
B006 no mutable values as argument defaults 180 3 183
RUF012 mutable class attributes must be ClassVar 158 3 161
ANN002 *args must be typed 64 3 67

TID251 is import-level, so it counts about one violation per file; it bans typing.Any, Dict, List, Set, MutableSequence, and MutableMapping, steering new code toward structured and immutable types (tuple, Sequence, Mapping, frozenset, AbstractSet, frozen dataclasses, NamedTuples, TypedDicts). Tune any rule by editing its slack, and ratchet by lowering the baseline with make lint-strict-budget-update after fixes

Some rules are intentionally partial. "No lists or dicts unless frozen" is covered for argument defaults (B006), class attributes (RUF012), and new imports of the mutable typing collection aliases such as Dict, List, and Set (TID251), but ruff cannot ban every literal. "Globals must be frozen" is covered only as a ban on global rebinding (PLW0603), since ruff has no rule forcing module constants to be Final. Mutation of function arguments has no ruff rule at all and is left out

How the gate works

A first cut compared the whole tree against a committed baseline count, and it broke immediately. CI lints the PR merged with the current base tip, so when other PRs merged new violations into litellm_internal_staging, those counted against this PR's frozen baseline even though this PR never touched those files. A committed snapshot goes stale the moment the base moves

scripts/ruff_strict_gate.py is drift-safe instead. It counts each rule on the head, counts the same rule on the base it merges into (a throwaway git worktree of the merge-base), and fails a rule only when its head total is both over the ceiling and higher than the base. So if the base already drifted over a ceiling, a change that does not add to that rule still passes, and a change that reduces an over-ceiling rule passes too; only a change that pushes the total up is blamed. Existing violations are grandfathered because they already sit in the base count

The escape hatch for a genuinely justified violation is an inline # noqa on that line, which stays visible and greppable

CI (LiteLLM team)

  • Branch creation CI run
    Link:
  • CI run for the last commit
    Link:
  • Merge / cherry-pick CI run
    Links:

Proof of fix

The gate is dev tooling, so the proof is its behavior. A clean change passes; a change that pushes a rule over its ceiling fails and names what it added; a change within the slack passes

$ python scripts/ruff_strict_gate.py
OK: every strict rule is within its codebase ceiling (base origin/litellm_internal_staging)

# add 3 mutable defaults (B006 ceiling is 183 = 180 baseline + 3 slack)
$ python scripts/ruff_strict_gate.py ; echo "exit=$?"
OK: every strict rule is within its codebase ceiling (base origin/litellm_internal_staging)
exit=0

# add a 4th, now over the ceiling
$ python scripts/ruff_strict_gate.py ; echo "exit=$?"
FAIL: strict-rule totals exceed their ceiling (base origin/litellm_internal_staging):
  B006: total 184 over cap 183 (this change added 4)
    litellm/_tmp_probe.py:1
    litellm/_tmp_probe.py:5
    litellm/_tmp_probe.py:9
    litellm/_tmp_probe.py:13
Reduce the new violations or remove an equal number elsewhere; the ceiling is baseline + slack in ruff-strict-budget.json.
exit=1

The gate logic is unit tested in tests/test_litellm/test_ruff_strict_gate.py: the ceiling boundary, drift safety (a base already over the ceiling does not blame a change that adds nothing, and a change that reduces an over-ceiling rule passes), per-rule independence, a missing rule defaulting to zero, and the diff parsing used to point at what a change added

Type

Infrastructure

Changes

ruff-strict.toml (new) defines the ten strict rules by extending ruff.toml and configures the TID251 banned-api list. ruff-strict-budget.json (new) holds each rule's baseline and slack. scripts/ruff_strict_gate.py (new) is the drift-safe total-count gate, with --update to re-capture baselines after fixes. .github/workflows/test-linting.yml gains one step that runs the gate against the PR base. The Makefile gains lint-strict-budget and lint-strict-budget-update, with the check wired into make lint. ruff.toml is untouched. CLAUDE.md documents how to ratchet the baselines down and how to avoid spending the Any budget

@ryan-crabbe-berri
ryan-crabbe-berri requested a review from a team June 12, 2026 18:08
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces a ratcheting ruff strict-rule gate that enforces ten additional lint rules across the codebase without requiring an upfront mass cleanup. A drift-safe script compares head violation counts against the merge-base rather than a frozen snapshot, so only changes that push a rule's total above its ceiling are blocked.

  • ruff-strict.toml + ruff-strict-budget.json define ten rules with per-rule baselines and slack; scripts/ruff_strict_gate.py implements the ceiling check using git worktree for the base snapshot and a diff parser to pinpoint which lines in the PR introduced breaches.
  • The CI workflow gains one PR-only step passing BASE_SHA from the PR event, and make lint is wired to run the budget check locally via origin/litellm_internal_staging as the default base.
  • Unit tests cover the ceiling boundary, drift-safety, per-rule independence, and diff-line parsing, though the parametrised hunk test uses a weak truthiness assertion.

Confidence Score: 5/5

Safe to merge; the gate is additive dev tooling that leaves the existing ruff check untouched and only affects PR CI on violations exceeding a generous per-rule budget.

All findings are quality-of-life issues in the gate script itself (exception masking in the worktree cleanup, exit-code conflation, and a weak test assertion). None affect whether the gate correctly passes or fails a PR in normal operation, and the core evaluate/drift-safety logic is well-exercised by the new unit tests.

scripts/ruff_strict_gate.py — the finally block in base_counts and the shared _run exit-code handling are worth a second look for robustness when git worktree add fails.

Important Files Changed

Filename Overview
scripts/ruff_strict_gate.py New drift-safe gate script; correct core logic but finally block can mask the original git error when worktree add fails, and _run conflates ruff/git exit-code 1 semantics
tests/test_litellm/test_ruff_strict_gate.py Good unit coverage of evaluate, drift-safety, and diff parsing; parametrised hunk test uses weak truthiness assertion instead of explicit line-set comparison
.github/workflows/test-linting.yml Adds one PR-only CI step that passes BASE_SHA from the PR event; workflow is pull_request-scoped so BASE_SHA is always populated, fetch-depth=0 satisfies git worktree requirements
Makefile Adds lint-strict-budget and lint-strict-budget-update targets and wires the budget check into make lint; local execution requires origin/litellm_internal_staging to be up to date
ruff-strict.toml New ruff config extending the existing one with ten strict rules; TID251 banned-api messages are clear and actionable
ruff-strict-budget.json New file recording today's baseline counts and per-rule slack; values match the PR description table

Reviews (3): Last reviewed commit: "chore: give the structural strict rules ..." | Re-trigger Greptile

Comment thread scripts/ruff_suppressions.py Outdated
@ryan-crabbe-berri

Copy link
Copy Markdown
Contributor Author

@greptileai re review

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes
Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged
…aseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script
@ryan-crabbe-berri
ryan-crabbe-berri force-pushed the litellm_ruff_strict_suppressions branch from dcce19f to a1264a7 Compare June 12, 2026 18:46
Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0
Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0
Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines
To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later
@ryan-crabbe-berri

Copy link
Copy Markdown
Contributor Author

@greptileai re review

ryan-crabbe-berri and others added 4 commits June 12, 2026 17:40
… to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10
Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

@mateo-berri mateo-berri left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this. LGTM 🏆

@ryan-crabbe-berri
ryan-crabbe-berri enabled auto-merge (squash) June 13, 2026 03:03
@ryan-crabbe-berri
ryan-crabbe-berri merged commit c90eb7e into litellm_internal_staging Jun 13, 2026
120 checks passed
@ryan-crabbe-berri
ryan-crabbe-berri deleted the litellm_ruff_strict_suppressions branch June 13, 2026 03:14
michaelxer pushed a commit to michaelxer/litellm that referenced this pull request Jun 17, 2026
* feat: add ruff strict-rule suppressions baseline gate

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes

* fix: surface per-file drift as a warning on a passing suppressions check

Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged

* refactor: gate strict ruff rules on the delta vs base, not a frozen baseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script

* chore: allow 5 new ANN001/ANN003/ANN401 per change

Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0

* feat: add TID251 typing.Any/Dict import ban and widen annotation budgets

Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0

* refactor: make the strict gate a drift-safe per-rule total ceiling

Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines

* chore: give the structural strict rules a cushion of 3

To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later

* feat: ban more typing collection aliases and tighten annotation slack to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10

* docs: document the strict-gate ratchet and Any-avoidance in CLAUDE.md

Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

* feat: make it a bit more strict

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
michaelxer pushed a commit to michaelxer/litellm that referenced this pull request Jun 17, 2026
* feat: add ruff strict-rule suppressions baseline gate

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes

* fix: surface per-file drift as a warning on a passing suppressions check

Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged

* refactor: gate strict ruff rules on the delta vs base, not a frozen baseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script

* chore: allow 5 new ANN001/ANN003/ANN401 per change

Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0

* feat: add TID251 typing.Any/Dict import ban and widen annotation budgets

Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0

* refactor: make the strict gate a drift-safe per-rule total ceiling

Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines

* chore: give the structural strict rules a cushion of 3

To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later

* feat: ban more typing collection aliases and tighten annotation slack to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10

* docs: document the strict-gate ratchet and Any-avoidance in CLAUDE.md

Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

* feat: make it a bit more strict

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
koladefaj pushed a commit to koladefaj/litellm that referenced this pull request Jun 17, 2026
* feat: add ruff strict-rule suppressions baseline gate

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes

* fix: surface per-file drift as a warning on a passing suppressions check

Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged

* refactor: gate strict ruff rules on the delta vs base, not a frozen baseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script

* chore: allow 5 new ANN001/ANN003/ANN401 per change

Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0

* feat: add TID251 typing.Any/Dict import ban and widen annotation budgets

Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0

* refactor: make the strict gate a drift-safe per-rule total ceiling

Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines

* chore: give the structural strict rules a cushion of 3

To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later

* feat: ban more typing collection aliases and tighten annotation slack to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10

* docs: document the strict-gate ratchet and Any-avoidance in CLAUDE.md

Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

* feat: make it a bit more strict

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
factnn pushed a commit to factnn/litellm that referenced this pull request Jun 18, 2026
* feat: add ruff strict-rule suppressions baseline gate

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes

* fix: surface per-file drift as a warning on a passing suppressions check

Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged

* refactor: gate strict ruff rules on the delta vs base, not a frozen baseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script

* chore: allow 5 new ANN001/ANN003/ANN401 per change

Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0

* feat: add TID251 typing.Any/Dict import ban and widen annotation budgets

Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0

* refactor: make the strict gate a drift-safe per-rule total ceiling

Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines

* chore: give the structural strict rules a cushion of 3

To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later

* feat: ban more typing collection aliases and tighten annotation slack to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10

* docs: document the strict-gate ratchet and Any-avoidance in CLAUDE.md

Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

* feat: make it a bit more strict

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
* feat: add ruff strict-rule suppressions baseline gate

Introduce a stricter ruff rule set (typed params, no Any, complexity and
arg-count caps, mutable-default and global-rebinding checks) grandfathered
against the current tree and enforced as a budget rather than zero-tolerance

ruff-strict.toml defines the 9 rules separately from ruff.toml so the existing
ruff check stays green. scripts/ruff_suppressions.py builds the per-file,
per-rule baseline in ruff-suppressions.json and gates CI by failing when the
total grows past the baseline plus a 0.5% slack margin. The baseline ratchets
down via `make lint-suppressions-update` after fixes

* fix: surface per-file drift as a warning on a passing suppressions check

Greptile flagged that cmd_check computed per-file regressions but only printed
them on failure, so violations shifted between files (or a brand-new file under
the slack) passed with a silent OK. Print them as a non-fatal warning on the
pass path too; pass/fail behavior is unchanged

* refactor: gate strict ruff rules on the delta vs base, not a frozen baseline

The committed total-count baseline went stale against a moving base. CI lints the
PR merged with the current staging tip, so violations merged by other PRs counted
against this PR and tripped the budget even though nothing here touched them

Replace it with a drift-proof gate. scripts/ruff_strict_gate.py runs ruff on the
head, keeps only violations on lines this change adds relative to the merge-base,
and fails when a rule exceeds its per-rule allowance in ruff-strict-budget.json
(all 0 today). Because the base is measured live, base drift cancels out and only
what the change introduces is gated. Drops ruff-suppressions.json and the old
suppressions script

* chore: allow 5 new ANN001/ANN003/ANN401 per change

Give the three annotation-completeness rules a small per-change allowance so a
large new module is not blocked over a few untyped params or kwargs, while the
correctness and structural rules (B006, C901, PLR0913, PLW0603, RUF012, ANN002)
stay at 0

* feat: add TID251 typing.Any/Dict import ban and widen annotation budgets

Add TID251 (flake8-tidy-imports banned-api) to ruff-strict.toml, banning new
imports of typing.Any and typing.Dict and steering new code toward structured
types. It counts the import site, about one per file, so it is set non-blocking
at 50 as a forward-looking signal

Widen the annotation-completeness budgets so they nudge rather than block:
ANN001 50, ANN401 50, ANN003 25. Correctness and structural rules stay at 0

* refactor: make the strict gate a drift-safe per-rule total ceiling

Switch the gate from a per-change allowance to a hard ceiling on each rule's
total count across the codebase. The ceiling is baseline + slack in
ruff-strict-budget.json, with baseline captured from today's tree

To stay drift-safe, the gate counts each rule on the head and on the merge-base
(via a throwaway git worktree) and fails a rule only when its head total is over
the ceiling and higher than the base, so base drift never blames a change that
did not add to that rule. Annotation rules keep generous slack (ANN001 and
ANN401 50, ANN003 25, TID251 50); structural and correctness rules are frozen at
today's count. Add make lint-strict-budget-update to re-capture baselines

* chore: give the structural strict rules a cushion of 3

To be liberal to start, B006, C901, PLR0913, PLW0603, RUF012, and ANN002 each get
a slack of 3 instead of 0, so an occasional legitimate case is not hard-blocked.
The annotation budgets are unchanged, and these ratchet down later

* feat: ban more typing collection aliases and tighten annotation slack to 10

Add typing.List, typing.Set, typing.MutableSequence, and typing.MutableMapping to
the TID251 banned-api list, steering new code toward tuple, Sequence, Mapping,
frozenset, and frozen dataclasses. This raises TID251's baseline to 2404

Bring the three rules that were at slack 50 (ANN001, ANN401, TID251) down to 10

* docs: document the strict-gate ratchet and Any-avoidance in CLAUDE.md

Add a line on running make lint-strict-budget-update to knock baselines down
after fixes, and a line on validating untyped inputs in the caller rather than
spending the Any budget

* feat: make it a bit more strict

---------

Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
blake-hamm added a commit to blake-hamm/bhamm-lab that referenced this pull request Jun 28, 2026
…to v1.90.0 (#232)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [https://github.com/BerriAI/litellm.git](https://github.com/BerriAI/litellm) | minor | `v1.89.4` → `v1.90.0` |

---

### Release Notes

<details>
<summary>BerriAI/litellm (https://github.com/BerriAI/litellm.git)</summary>

### [`v1.90.0`](https://github.com/BerriAI/litellm/releases/tag/v1.90.0)

[Compare Source](BerriAI/litellm@v1.89.4...v1.90.0-rc.1)

#### Verify Docker Image Signature

All LiteLLM Docker images are signed with [cosign](https://docs.sigstore.dev/cosign/overview/). Every release is signed with the same key introduced in [commit `0112e53`](BerriAI/litellm@0112e53).

**Verify using the pinned commit hash (recommended):**

A commit hash is cryptographically immutable, so this is the strongest way to ensure you are using the original signing key:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

**Verify using the release tag (convenience):**

Tags are protected in this repository and resolve to the same key. This option is easier to read but relies on tag protection rules:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/v1.90.0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

Expected output:

```
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
```

***

#### What's Changed

- fix(responses-bridge): map system-only chat request to system input item by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29817](BerriAI/litellm#29817)
- feat(bedrock): forward strict and additionalProperties to Converse toolSpec by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29814](BerriAI/litellm#29814)
- fix(mcp): highlight MCP cards red when the logged-in user is missing per-user env vars by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29856](BerriAI/litellm#29856)
- feat(ui): add budget duration to edit team member form by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29717](BerriAI/litellm#29717)
- fix(ui): make workflow runs page fill full width by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29868](BerriAI/litellm#29868)
- feat: standardize rate limit errors with category, rate\_limit\_type, model, and llm\_provider fields by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;27687](BerriAI/litellm#27687)
- fix(ui): default guardrails page to the Guardrails tab by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29872](BerriAI/litellm#29872)
- docs(readme): add Deploy on AWS/GCP Terraform section and fix deploy button rendering by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29879](BerriAI/litellm#29879)
- refactor(bedrock): build Converse toolSpec via a BedrockToolSpec dict subclass by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29869](BerriAI/litellm#29869)
- feat(litellm): add models and repository layers by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29686](BerriAI/litellm#29686)
- feat(ui): include internal routes in the dashboard's generated OpenAPI types by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29885](BerriAI/litellm#29885)
- feat(proxy): publish /v2/model/info in Swagger OpenAPI spec by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29900](BerriAI/litellm#29900)
- refactor(ui): single source of truth for migrated-page routing by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29949](BerriAI/litellm#29949)
- fix(ui/model-hub): render provider icons on the public model hub by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29958](BerriAI/litellm#29958)
- fix(ui): keep create guardrail modal open on outside click by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29871](BerriAI/litellm#29871)
- fix(ui): label default key type as "Full Access" on key edit page by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29870](BerriAI/litellm#29870)
- fix(ui): unify migrated-route URLs and migrate the API Reference page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29953](BerriAI/litellm#29953)
- fix(mcp): let non-creator users OAuth into OBO-mode MCP servers from the Tools page by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29867](BerriAI/litellm#29867)
- Litellm oss staging 080626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29932](BerriAI/litellm#29932)
- feat(galileo): add health check support for UI callback test by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29908](BerriAI/litellm#29908)
- fix(model-management): allow deleting a BYOK model after its team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29875](BerriAI/litellm#29875)
- feat(jwt-auth): opt-in fallback to DB team on unresolved JWT claim by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28913](BerriAI/litellm#28913)
- fix(team\_endpoints): don't block /team/update on unchanged team budget by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29525](BerriAI/litellm#29525)
- fix(fireworks): enable tool calling for glm-5p1 in model cost map by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29697](BerriAI/litellm#29697)
- fix(vertex): propagate Vertex AI metadata in streaming success callbacks by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29899](BerriAI/litellm#29899)
- fix(ui): show team projects to internal users on key creation by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28855](BerriAI/litellm#28855)
- build(deps): bump pyjwt to 2.13.0 and ws override to 8.20.1 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29982](BerriAI/litellm#29982)
- fix(team-management): delete a team's BYOK models when the team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29977](BerriAI/litellm#29977)
- feat(vantage): include organization metadata in FOCUS Tags export by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28184](BerriAI/litellm#28184)
- fix(guardrails): read CrowdStrike AIDR identity from both metadata bags by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29991](BerriAI/litellm#29991)
- fix(mcp): mirror upstream token lifetime instead of forcing a 1h OBO expiry by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29951](BerriAI/litellm#29951)
- feat(azure\_ai): add MAI-Image-2.5 image generation support by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29688](BerriAI/litellm#29688)
- fix(mcp): load MCP tool configuration tools via the OBO/passthrough-aware GET path by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29960](BerriAI/litellm#29960)
- fix(team): reserve team budget raises for proxy admins on /team/update by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;30030](BerriAI/litellm#30030)
- test(ui): data-driven App Router migration E2E smoke (default + server-root-path) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29974](BerriAI/litellm#29974)
- fix(proxy): extend response headers hook to streaming, TTS, image gen, and pass-through by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;24232](BerriAI/litellm#24232)
- chore(ui): remove dead App Router route stubs under (dashboard) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30045](BerriAI/litellm#30045)
- fix(ui/mcp): reset OAuth state on create-server modal close so a prior server's token no longer leaks into the next add-server session by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30000](BerriAI/litellm#30000)
- fix(mcp): allow team access-group grants in OAuth authorize/token access check by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30041](BerriAI/litellm#30041)
- docs(security): require a reproduction video for vulnerability reports by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30063](BerriAI/litellm#30063)
- feat(ui): add admin flag to disable in-product UI nudges for everyone by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29796](BerriAI/litellm#29796)
- chore(ui): remove dead dashboard files and unused dependencies by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30047](BerriAI/litellm#30047)
- fix(proxy): authorize batch files using upload target\_model\_names (LIT-3593) by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30009](BerriAI/litellm#30009)
- Add Claude Fable 5 across Anthropic, Bedrock, Vertex AI, and Azure AI by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30064](BerriAI/litellm#30064)
- Add Claude Fable 5 cost map entries (data-only hotfix for the hosted map) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30076](BerriAI/litellm#30076)
- fix(caching): restore stored prompt\_tokens on embedding cache hits instead of recomputing by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30046](BerriAI/litellm#30046)
- Litellm oss 090626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30021](BerriAI/litellm#30021)
- fix(proxy): self-heal startup/reload prisma reads on engine disconnect by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;28803](BerriAI/litellm#28803)
- chore(ui): make knip recognize .mjs scripts and openapi-typescript by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30052](BerriAI/litellm#30052)
- fix(register\_model): preserve built-in cache pricing when registering custom overrides under unmapped keys by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30044](BerriAI/litellm#30044)
- \[internal copy of [#&#8203;28007](BerriAI/litellm#28007)] Fix/gcp model garden streaming by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28363](BerriAI/litellm#28363)
- feat(cli): per-agent `lite claude` / `codex` / `opencode` commands that wrap coding agents through the proxy by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29850](BerriAI/litellm#29850)
- fix(callbacks): forward callback\_settings to callback initializers and guard consumers against non-dict values by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30161](BerriAI/litellm#30161)
- fix(mcp): drop orphaned per-user credential rows when an MCP server is deleted by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30141](BerriAI/litellm#30141)
- fix(proxy): recover from cached-plan errors by reconnecting the Prisma client by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29983](BerriAI/litellm#29983)
- feat(proxy): add option to disable server-side prepared statements for DB lookups by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29984](BerriAI/litellm#29984)
- fix(release): stop backport releases from overwriting the latest badge by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30005](BerriAI/litellm#30005)
- feat: add conventional commits and coding guidelines by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30159](BerriAI/litellm#30159)
- fix(proxy): return 5xx on DB infra errors during auth; reserve 401 for genuine auth failures by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29986](BerriAI/litellm#29986)
- fix(ui): dev server 404s on migrated-page links because uiBase hardcodes /ui by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30169](BerriAI/litellm#30169)
- refactor(ui): consolidate dashboard to one shell in the (dashboard) layout by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30166](BerriAI/litellm#30166)
- fix(proxy): align /v1/model/info with router deployments by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30025](BerriAI/litellm#30025)
- fix: completion\_cost AttributeError on streaming Anthropic web\_search responses ([#&#8203;26153](BerriAI/litellm#26153)) by [@&#8203;ishaan-berri](https://github.com/ishaan-berri) in [#&#8203;27346](BerriAI/litellm#27346)
- \[internal copy of [#&#8203;30137](BerriAI/litellm#30137)] perf(realtime): eliminate redundant per-frame JSON work on OpenAI realtime relay by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30142](BerriAI/litellm#30142)
- feat(bedrock): aws\_bedrock\_project\_id for bedrock-mantle project / workspace association by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30163](BerriAI/litellm#30163)
- chore(hooks): enforce Conventional Commits and Conventional Branches by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30174](BerriAI/litellm#30174)
- feat(rate-limiter): allow opting out of v3 TPM reservation and Redis circuit breaker by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30211](BerriAI/litellm#30211)
- feat(spend\_logs): opt-in native Postgres partitioning for SpendLogs retention by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29466](BerriAI/litellm#29466)
- feat(ui): migrate playground to path routing and colocate its files by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30185](BerriAI/litellm#30185)
- feat(ui): migrate projects and access-groups to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30226](BerriAI/litellm#30226)
- fix(proxy): coalesce NULL rollup metrics in aggregated daily-activity by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30151](BerriAI/litellm#30151)
- fix(anthropic\_passthrough): resolve costing model from message\_start chunk, litellm\_params and model\_group instead of 'unknown' by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30160](BerriAI/litellm#30160)
- feat(ui): migrate budgets, workflows, and guardrails-monitor to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30236](BerriAI/litellm#30236)
- feat(ui): migrate mcp-servers, search-tools, tag-management, vector-stores, and memory to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30261](BerriAI/litellm#30261)
- fix(a2a): forward agent\_extra\_headers through completion bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28277](BerriAI/litellm#28277)
- fix(gemini-live): forward audio buffer commit and correct Vertex PCM rate by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29946](BerriAI/litellm#29946)
- fix(proxy): skip double-wrapping unified batch output file ids on retrieve by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30011](BerriAI/litellm#30011)
- feat: litellm oss 110626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30202](BerriAI/litellm#30202)
- fix(docker): copy only runtime artifacts into the final image by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30243](BerriAI/litellm#30243)
- feat(proxy): enforce key/team guardrails on bedrock passthrough routes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30194](BerriAI/litellm#30194)
- feat(gemini): forward web search tools in image generation by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30119](BerriAI/litellm#30119)
- fix: bedrock mantle fixes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30083](BerriAI/litellm#30083)
- feat(proxy): add require\_managed\_files setting for file uploads by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30186](BerriAI/litellm#30186)
- fix(mcp): honor server\_id for REST tool calls with shared upstream URLs by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30184](BerriAI/litellm#30184)
- fix(responses): presidio PII masking for Azure WebSocket and streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30003](BerriAI/litellm#30003)
- feat(passthrough): add configurable pass-through request timeouts by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30266](BerriAI/litellm#30266)
- fix(google\_genai): preserve complete SSE events in Vertex/Gemini image streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30270](BerriAI/litellm#30270)
- fix(proxy): populate access\_via\_team\_ids on /v1/model/info by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30274](BerriAI/litellm#30274)
- chore(oss): litellm oss staging 120626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30292](BerriAI/litellm#30292)
- feat(ui): migrate policies, guardrails, prompts, tool-policies, and skills to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30263](BerriAI/litellm#30263)
- feat(ui): migrate caching, cost-tracking, transform-request, ui-theme, and logs to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30267](BerriAI/litellm#30267)
- fix(ui): gate dashboard layout on ui config load so deep links work under SERVER\_ROOT\_PATH by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30312](BerriAI/litellm#30312)
- feat(ui): migrate admin-panel, logging-and-alerts, model-hub-table, and usage to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30268](BerriAI/litellm#30268)
- fix(otel): cap metric attribute cardinality with include/exclude lists by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30257](BerriAI/litellm#30257)
- fix(proxy): grace-period key rotation 401s; return deprecated-key lookup result directly by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30327](BerriAI/litellm#30327)
- chore(deps): bump vitest, brace-expansion, pypdf and tornado by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30220](BerriAI/litellm#30220)
- refactor(ui): remove unreachable /chat page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30178](BerriAI/litellm#30178)
- feat(ui): migrate agents and router-settings to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30323](BerriAI/litellm#30323)
- feat: strengthen coding conventions in CLAUDE.md by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30333](BerriAI/litellm#30333)
- feat(ui): cut the users page over to the /ui/users path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30334](BerriAI/litellm#30334)
- feat: ruff strict-rule suppressions baseline gate by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30303](BerriAI/litellm#30303)
- feat(guardrails): add Cisco AI Defense integration ([#&#8203;28249](BerriAI/litellm#28249)) by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30338](BerriAI/litellm#30338)
- chore(ui): remove dead UI components unreferenced by any page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30340](BerriAI/litellm#30340)
- ci: add osv-scanner lockfile scan workflow by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30222](BerriAI/litellm#30222)
- fix(otel): record full error message on standard exception event in otel v2 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30380](BerriAI/litellm#30380)
- test(fireworks): mock whisper transcription tests instead of live calls by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30391](BerriAI/litellm#30391)
- build(ui): pin esbuild to 0.28.1 via overrides by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30390](BerriAI/litellm#30390)
- feat(ui): cut the organizations page over to the /ui/organizations path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30336](BerriAI/litellm#30336)
- fix(proxy): support SMTP implicit SSL (port 465) by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30395](BerriAI/litellm#30395)
- fix(mcp): default Linear MCP registry entry to streamable HTTP by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30396](BerriAI/litellm#30396)
- fix(ui): stop Virtual Keys page from infinite render loop by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30397](BerriAI/litellm#30397)
- fix(streaming): guard raise\_on\_model\_repetition against empty choices by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30485](BerriAI/litellm#30485)
- feat(otel-v2): emit the 6 gen\_ai.client.\* metrics at parity with v1 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30326](BerriAI/litellm#30326)
- fix(mcp): drop phantom 401 span on delegated OAuth2 tool calls by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30494](BerriAI/litellm#30494)
- feat(ui): cut the teams page over to the /ui/teams path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30343](BerriAI/litellm#30343)
- fix(integrations): cap Anthropic cache\_control injection at 4 blocks by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30480](BerriAI/litellm#30480)
- chore(codecov): add Batches, Videos, and Realtime components by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30517](BerriAI/litellm#30517)
- test(batches): move orphan tests into tests/test\_litellm for CI coverage by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30510](BerriAI/litellm#30510)
- fix(guardrails): run pre\_call hook once for model-level guardrails by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30543](BerriAI/litellm#30543)
- fix(guardrails): stop re-initializing DB guardrails on every poll by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30542](BerriAI/litellm#30542)
- chore(oss): litellm oss staging 150626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30463](BerriAI/litellm#30463)
- ci(lint): add blanket-noqa, dataclass-default, and unused-noqa Ruff rules by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30516](BerriAI/litellm#30516)
- ci: ratchet lint and type-check gates (ruff preview, ANN, mypy, basedpyright) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30379](BerriAI/litellm#30379)
- fix(proxy): allow internal roles to access vector store CRUD routes by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30503](BerriAI/litellm#30503)
- fix(otel): stamp gen\_ai.input/output.messages on v2 spans by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30548](BerriAI/litellm#30548)
- fix(otel): export v2 gen\_ai client metrics to the configured meter provider by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30549](BerriAI/litellm#30549)
- fix(bedrock): preserve cache\_control for ARN models in /v1/messages adapter by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29823](BerriAI/litellm#29823)
- fix: greatly increase basedpyright slack by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30563](BerriAI/litellm#30563)
- fix(budget): recompute budget\_reset\_at when budget\_duration changes on /budget/update by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30555](BerriAI/litellm#30555)
- fix(otel): accept UPPER\_SNAKE\_CASE OTEL\_INSTRUMENTATION\_GENAI\_CAPTURE\_MESSAGE\_CONTENT in v2 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30562](BerriAI/litellm#30562)
- chore(lint): remove PLR0915 too-many-statements ruff rule by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30574](BerriAI/litellm#30574)
- ci(lint): ratcheted type-discipline gate (mutable collections, casts, guards, kwargs, suppressions) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30500](BerriAI/litellm#30500)
- feat(proxy): add verification\_uri\_complete to CLI SSO device flow by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30571](BerriAI/litellm#30571)
- chore: litellm oss staging160626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30527](BerriAI/litellm#30527)
- fix(guardrails): return 400 not 500 when AIM blocks a request by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30573](BerriAI/litellm#30573)
- ci(lint): grandfather any-discipline with a per-file ratchet budget (50% headroom) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30582](BerriAI/litellm#30582)
- fix(audio): don't override explicit response\_format with verbose\_json by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30599](BerriAI/litellm#30599)
- fix(anthropic): price and surface response service\_tier in cost tracking by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30558](BerriAI/litellm#30558)
- feat: add dev and wildcard proxy configs for local testing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30556](BerriAI/litellm#30556)
- fix(proxy): list public team model name in /v1/models by [@&#8203;ishaan-berri](https://github.com/ishaan-berri) in [#&#8203;30588](BerriAI/litellm#30588)
- ci: drop mypy entirely, standardize type checking on basedpyright by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30648](BerriAI/litellm#30648)
- feat(guardrails): surface OpenAI moderation violation\_categories on guardrail traces by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30659](BerriAI/litellm#30659)
- fix(proxy): resolve list files credentials from team BYOK deployments by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30495](BerriAI/litellm#30495)
- feat(proxy): add --max\_requests\_before\_restart\_jitter to stagger worker restarts by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30601](BerriAI/litellm#30601)
- fix(health): correct bedrock embedding health checks by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30583](BerriAI/litellm#30583)
- test: harden remaining pass-through CI flakes (image-gen spend poll, ruby assistants timeout) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30685](BerriAI/litellm#30685)
- test(pass\_through): harden vertex spendlog poll against transient empty reads by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30683](BerriAI/litellm#30683)
- fix(cost): stop non-string service\_tier from silently dropping cost tracking by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30690](BerriAI/litellm#30690)
- feat(proxy): warn at startup when custom\_auth skips common\_checks enforcement by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30665](BerriAI/litellm#30665)
- fix(pod\_lock): release cron lock by matching async\_set\_cache JSON encoding by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30600](BerriAI/litellm#30600)
- ci: run a local fake OpenAI endpoint instead of the shared Railway mock by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30695](BerriAI/litellm#30695)
- ci(windows): pin uv to Python 3.11 so it ignores the preinstalled 3.14 by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30704](BerriAI/litellm#30704)
- feat(ui): migrate models page to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30677](BerriAI/litellm#30677)
- refactor(ui): remove orphaned pass-through-settings route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30692](BerriAI/litellm#30692)
- fix(cost): stop non-string response service\_tier from dropping cost tracking by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30706](BerriAI/litellm#30706)
- feat(agent-shin): automated PR/issue triage, low-quality auto-close, and review-gate label lifecycle by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30433](BerriAI/litellm#30433)
- chore: litellm oss 170626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30637](BerriAI/litellm#30637)
- fix(bedrock\_mantle): add SigV4 fallback to chat completions auth by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30714](BerriAI/litellm#30714)
- feat(search): add TinyFish as search provider by [@&#8203;simantak-dabhade](https://github.com/simantak-dabhade) in [#&#8203;30634](BerriAI/litellm#30634)
- feat(ui): migrate old usage report to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30694](BerriAI/litellm#30694)
- fix(proxy): enforce budgets against authoritative DB spend when the cross-pod counter is stale by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30684](BerriAI/litellm#30684)
- chore(ci): remove Agent Shin pull\_request\_target workflows by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30784](BerriAI/litellm#30784)
- chore: litellm oss staging by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30745](BerriAI/litellm#30745)
- ci(zizmor): also run on litellm\_internal\_staging by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30789](BerriAI/litellm#30789)
- fix(test): drop references to removed Agent Shin workflows by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30791](https://github.com/BerriAI/litellm/pull/30791)
- chore: remove in-product survey and Claude Code feedback nudges by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30773](https://github.com/BerriAI/litellm/pull/30773)
- feat(ui): migrate api-keys landing to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30699](https://github.com/BerriAI/litellm/pull/30699)
- feat(proxy): configurable response headers and login-page hint by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;30792](https://github.com/BerriAI/litellm/pull/30792)
- ci(zizmor): gate PRs on medium+ findings and clear existing ones by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30797](https://github.com/BerriAI/litellm/pull/30797)
- fix(proxy): use e.request\_data for logging\_obj in ModifyResponseException streaming passthrough by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30800](https://github.com/BerriAI/litellm/pull/30800)
- chore: make pr template linear portion clearer by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30766](https://github.com/BerriAI/litellm/pull/30766)
- chore(typing): add boto3/botocore stubs so basedpyright resolves the AWS SDK by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30815](https://github.com/BerriAI/litellm/pull/30815)
- fix(otel): one v2 logger owns the global provider; scope tenant OTLP creds per exporter by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;30590](https://github.com/BerriAI/litellm/pull/30590)
- fix(passthrough): recover output tokens for interrupted anthropic streams by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30787](https://github.com/BerriAI/litellm/pull/30787)
- fix(proxy): record partial spend on the failure row for interrupted streams by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30788](https://github.com/BerriAI/litellm/pull/30788)
- fix(ui): repoint dead usage guide link to cost tracking docs by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30859](https://github.com/BerriAI/litellm/pull/30859)
- fix(ui): warn that team models are deleted in the delete-team modal by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29990](https://github.com/BerriAI/litellm/pull/29990)
- feat(caching): add valkey-semantic cache backend and fix semantic cache scope keys by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30675](https://github.com/BerriAI/litellm/pull/30675)
- test(ui): isolate OldTeams delete-warning tests from leaked mock by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30871](https://github.com/BerriAI/litellm/pull/30871)
- feat: add lint-gate target and truncation-proof summary to the strict ruff gate by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30877](https://github.com/BerriAI/litellm/pull/30877)
- chore(ui): rebuild ui for release by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30894](https://github.com/BerriAI/litellm/pull/30894)
- chore(ci): bump deps by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30899](https://github.com/BerriAI/litellm/pull/30899)
- fix(watsonx): wrap string embedding input in array for WatsonX API by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30897](https://github.com/BerriAI/litellm/pull/30897)
- test: point router/completion/triton tests at the local fake OpenAI endpoint by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30900](https://github.com/BerriAI/litellm/pull/30900)
- feat(sandbox): e2b code execution primitive by [@&#8203;krrish-berri-2](https://github.com/krrish-berri-2) in [#&#8203;30898](https://github.com/BerriAI/litellm/pull/30898)
- fix(ui): source api-keys identity from useAuthorized to stop "User ID is not set" by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30903](https://github.com/BerriAI/litellm/pull/30903)
- chore(ui): rebuild ui by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30906](https://github.com/BerriAI/litellm/pull/30906)
- chore(ci): promote internal staging to main by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30907](https://github.com/BerriAI/litellm/pull/30907)
- fix(redis): prevent forcing SSLConnection when ssl=False in connection pool by [@&#8203;Jacopos311](https://github.com/Jacopos311) in [#&#8203;30770](https://github.com/BerriAI/litellm/pull/30770)
- fix(proxy): log UI setup failures instead of silently swallowing by [@&#8203;sarvesh1327](https://github.com/sarvesh1327) in [#&#8203;30819](https://github.com/BerriAI/litellm/pull/30819)

#### New Contributors

- [@&#8203;simantak-dabhade](https://github.com/simantak-dabhade) made their first contribution in [#&#8203;30634](BerriAI/litellm#30634)
- [@&#8203;Jacopos311](https://github.com/Jacopos311) made their first contribution in [#&#8203;30770](https://github.com/BerriAI/litellm/pull/30770)
- [@&#8203;sarvesh1327](https://github.com/sarvesh1327) made their first contribution in [#&#8203;30819](https://github.com/BerriAI/litellm/pull/30819)

**Full Changelog**: <BerriAI/litellm@v1.89.0...v1.90.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMjAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIyMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: Renovate Bot <renovate@bhamm-lab.com>
Reviewed-on: https://codeberg.org/blake-hamm/bhamm-lab/pulls/232
blake-hamm added a commit to blake-hamm/bhamm-lab that referenced this pull request Jun 28, 2026
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [ghcr.io/berriai/litellm](https://images.chainguard.dev/directory/image/wolfi-base/overview) ([source](https://github.com/BerriAI/litellm)) | final | minor | `v1.85.1` → `v1.90.0` |

---

### Release Notes

<details>
<summary>BerriAI/litellm (ghcr.io/berriai/litellm)</summary>

### [`v1.90.0`](https://github.com/BerriAI/litellm/releases/tag/v1.90.0)

[Compare Source](https://github.com/BerriAI/litellm/compare/v1.90.0...v1.90.0)

##### Verify Docker Image Signature

All LiteLLM Docker images are signed with [cosign](https://docs.sigstore.dev/cosign/overview/). Every release is signed with the same key introduced in [commit `0112e53`](https://github.com/BerriAI/litellm/commit/0112e53046018d726492c814b3644b7d376029d0).

**Verify using the pinned commit hash (recommended):**

A commit hash is cryptographically immutable, so this is the strongest way to ensure you are using the original signing key:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

**Verify using the release tag (convenience):**

Tags are protected in this repository and resolve to the same key. This option is easier to read but relies on tag protection rules:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/v1.90.0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

Expected output:

```
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
```

***

##### What's Changed

- fix(responses-bridge): map system-only chat request to system input item by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29817](https://github.com/BerriAI/litellm/pull/29817)
- feat(bedrock): forward strict and additionalProperties to Converse toolSpec by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29814](https://github.com/BerriAI/litellm/pull/29814)
- fix(mcp): highlight MCP cards red when the logged-in user is missing per-user env vars by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29856](https://github.com/BerriAI/litellm/pull/29856)
- feat(ui): add budget duration to edit team member form by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29717](https://github.com/BerriAI/litellm/pull/29717)
- fix(ui): make workflow runs page fill full width by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29868](https://github.com/BerriAI/litellm/pull/29868)
- feat: standardize rate limit errors with category, rate\_limit\_type, model, and llm\_provider fields by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;27687](https://github.com/BerriAI/litellm/pull/27687)
- fix(ui): default guardrails page to the Guardrails tab by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29872](https://github.com/BerriAI/litellm/pull/29872)
- docs(readme): add Deploy on AWS/GCP Terraform section and fix deploy button rendering by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29879](https://github.com/BerriAI/litellm/pull/29879)
- refactor(bedrock): build Converse toolSpec via a BedrockToolSpec dict subclass by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29869](https://github.com/BerriAI/litellm/pull/29869)
- feat(litellm): add models and repository layers by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29686](https://github.com/BerriAI/litellm/pull/29686)
- feat(ui): include internal routes in the dashboard's generated OpenAPI types by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29885](https://github.com/BerriAI/litellm/pull/29885)
- feat(proxy): publish /v2/model/info in Swagger OpenAPI spec by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29900](https://github.com/BerriAI/litellm/pull/29900)
- refactor(ui): single source of truth for migrated-page routing by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29949](https://github.com/BerriAI/litellm/pull/29949)
- fix(ui/model-hub): render provider icons on the public model hub by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29958](https://github.com/BerriAI/litellm/pull/29958)
- fix(ui): keep create guardrail modal open on outside click by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29871](https://github.com/BerriAI/litellm/pull/29871)
- fix(ui): label default key type as "Full Access" on key edit page by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29870](https://github.com/BerriAI/litellm/pull/29870)
- fix(ui): unify migrated-route URLs and migrate the API Reference page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29953](https://github.com/BerriAI/litellm/pull/29953)
- fix(mcp): let non-creator users OAuth into OBO-mode MCP servers from the Tools page by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29867](https://github.com/BerriAI/litellm/pull/29867)
- Litellm oss staging 080626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29932](https://github.com/BerriAI/litellm/pull/29932)
- feat(galileo): add health check support for UI callback test by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29908](https://github.com/BerriAI/litellm/pull/29908)
- fix(model-management): allow deleting a BYOK model after its team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29875](https://github.com/BerriAI/litellm/pull/29875)
- feat(jwt-auth): opt-in fallback to DB team on unresolved JWT claim by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28913](https://github.com/BerriAI/litellm/pull/28913)
- fix(team\_endpoints): don't block /team/update on unchanged team budget by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29525](https://github.com/BerriAI/litellm/pull/29525)
- fix(fireworks): enable tool calling for glm-5p1 in model cost map by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29697](https://github.com/BerriAI/litellm/pull/29697)
- fix(vertex): propagate Vertex AI metadata in streaming success callbacks by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29899](https://github.com/BerriAI/litellm/pull/29899)
- fix(ui): show team projects to internal users on key creation by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28855](https://github.com/BerriAI/litellm/pull/28855)
- build(deps): bump pyjwt to 2.13.0 and ws override to 8.20.1 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29982](https://github.com/BerriAI/litellm/pull/29982)
- fix(team-management): delete a team's BYOK models when the team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29977](https://github.com/BerriAI/litellm/pull/29977)
- feat(vantage): include organization metadata in FOCUS Tags export by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28184](https://github.com/BerriAI/litellm/pull/28184)
- fix(guardrails): read CrowdStrike AIDR identity from both metadata bags by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29991](https://github.com/BerriAI/litellm/pull/29991)
- fix(mcp): mirror upstream token lifetime instead of forcing a 1h OBO expiry by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29951](https://github.com/BerriAI/litellm/pull/29951)
- feat(azure\_ai): add MAI-Image-2.5 image generation support by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29688](https://github.com/BerriAI/litellm/pull/29688)
- fix(mcp): load MCP tool configuration tools via the OBO/passthrough-aware GET path by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29960](https://github.com/BerriAI/litellm/pull/29960)
- fix(team): reserve team budget raises for proxy admins on /team/update by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;30030](https://github.com/BerriAI/litellm/pull/30030)
- test(ui): data-driven App Router migration E2E smoke (default + server-root-path) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29974](https://github.com/BerriAI/litellm/pull/29974)
- fix(proxy): extend response headers hook to streaming, TTS, image gen, and pass-through by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;24232](https://github.com/BerriAI/litellm/pull/24232)
- chore(ui): remove dead App Router route stubs under (dashboard) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30045](https://github.com/BerriAI/litellm/pull/30045)
- fix(ui/mcp): reset OAuth state on create-server modal close so a prior server's token no longer leaks into the next add-server session by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30000](https://github.com/BerriAI/litellm/pull/30000)
- fix(mcp): allow team access-group grants in OAuth authorize/token access check by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30041](https://github.com/BerriAI/litellm/pull/30041)
- docs(security): require a reproduction video for vulnerability reports by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30063](https://github.com/BerriAI/litellm/pull/30063)
- feat(ui): add admin flag to disable in-product UI nudges for everyone by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29796](https://github.com/BerriAI/litellm/pull/29796)
- chore(ui): remove dead dashboard files and unused dependencies by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30047](https://github.com/BerriAI/litellm/pull/30047)
- fix(proxy): authorize batch files using upload target\_model\_names (LIT-3593) by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30009](https://github.com/BerriAI/litellm/pull/30009)
- Add Claude Fable 5 across Anthropic, Bedrock, Vertex AI, and Azure AI by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30064](https://github.com/BerriAI/litellm/pull/30064)
- Add Claude Fable 5 cost map entries (data-only hotfix for the hosted map) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30076](https://github.com/BerriAI/litellm/pull/30076)
- fix(caching): restore stored prompt\_tokens on embedding cache hits instead of recomputing by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30046](https://github.com/BerriAI/litellm/pull/30046)
- Litellm oss 090626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30021](https://github.com/BerriAI/litellm/pull/30021)
- fix(proxy): self-heal startup/reload prisma reads on engine disconnect by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;28803](https://github.com/BerriAI/litellm/pull/28803)
- chore(ui): make knip recognize .mjs scripts and openapi-typescript by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30052](https://github.com/BerriAI/litellm/pull/30052)
- fix(register\_model): preserve built-in cache pricing when registering custom overrides under unmapped keys by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30044](https://github.com/BerriAI/litellm/pull/30044)
- \[internal copy of [#&#8203;28007](https://github.com/BerriAI/litellm/issues/28007)] Fix/gcp model garden streaming by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28363](https://github.com/BerriAI/litellm/pull/28363)
- feat(cli): per-agent `lite claude` / `codex` / `opencode` commands that wrap coding agents through the proxy by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29850](https://github.com/BerriAI/litellm/pull/29850)
- fix(callbacks): forward callback\_settings to callback initializers and guard consumers against non-dict values by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30161](https://github.com/BerriAI/litellm/pull/30161)
- fix(mcp): drop orphaned per-user credential rows when an MCP server is deleted by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30141](https://github.com/BerriAI/litellm/pull/30141)
- fix(proxy): recover from cached-plan errors by reconnecting the Prisma client by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29983](https://github.com/BerriAI/litellm/pull/29983)
- feat(proxy): add option to disable server-side prepared statements for DB lookups by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29984](https://github.com/BerriAI/litellm/pull/29984)
- fix(release): stop backport releases from overwriting the latest badge by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30005](https://github.com/BerriAI/litellm/pull/30005)
- feat: add conventional commits and coding guidelines by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30159](https://github.com/BerriAI/litellm/pull/30159)
- fix(proxy): return 5xx on DB infra errors during auth; reserve 401 for genuine auth failures by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29986](https://github.com/BerriAI/litellm/pull/29986)
- fix(ui): dev server 404s on migrated-page links because uiBase hardcodes /ui by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30169](https://github.com/BerriAI/litellm/pull/30169)
- refactor(ui): consolidate dashboard to one shell in the (dashboard) layout by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30166](https://github.com/BerriAI/litellm/pull/30166)
- fix(proxy): align /v1/model/info with router deployments by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30025](https://github.com/BerriAI/litellm/pull/30025)
- fix: completion\_cost AttributeError on streaming Anthropic web\_search responses ([#&#8203;26153](https://github.com/BerriAI/litellm/issues/26153)) by [@&#8203;ishaan-berri](https://github.com/ishaan-berri) in [#&#8203;27346](https://github.com/BerriAI/litellm/pull/27346)
- \[internal copy of [#&#8203;30137](https://github.com/BerriAI/litellm/issues/30137)] perf(realtime): eliminate redundant per-frame JSON work on OpenAI realtime relay by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30142](https://github.com/BerriAI/litellm/pull/30142)
- feat(bedrock): aws\_bedrock\_project\_id for bedrock-mantle project / workspace association by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30163](https://github.com/BerriAI/litellm/pull/30163)
- chore(hooks): enforce Conventional Commits and Conventional Branches by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30174](https://github.com/BerriAI/litellm/pull/30174)
- feat(rate-limiter): allow opting out of v3 TPM reservation and Redis circuit breaker by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30211](https://github.com/BerriAI/litellm/pull/30211)
- feat(spend\_logs): opt-in native Postgres partitioning for SpendLogs retention by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29466](https://github.com/BerriAI/litellm/pull/29466)
- feat(ui): migrate playground to path routing and colocate its files by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30185](https://github.com/BerriAI/litellm/pull/30185)
- feat(ui): migrate projects and access-groups to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30226](https://github.com/BerriAI/litellm/pull/30226)
- fix(proxy): coalesce NULL rollup metrics in aggregated daily-activity by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30151](https://github.com/BerriAI/litellm/pull/30151)
- fix(anthropic\_passthrough): resolve costing model from message\_start chunk, litellm\_params and model\_group instead of 'unknown' by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30160](https://github.com/BerriAI/litellm/pull/30160)
- feat(ui): migrate budgets, workflows, and guardrails-monitor to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30236](https://github.com/BerriAI/litellm/pull/30236)
- feat(ui): migrate mcp-servers, search-tools, tag-management, vector-stores, and memory to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30261](https://github.com/BerriAI/litellm/pull/30261)
- fix(a2a): forward agent\_extra\_headers through completion bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28277](https://github.com/BerriAI/litellm/pull/28277)
- fix(gemini-live): forward audio buffer commit and correct Vertex PCM rate by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29946](https://github.com/BerriAI/litellm/pull/29946)
- fix(proxy): skip double-wrapping unified batch output file ids on retrieve by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30011](https://github.com/BerriAI/litellm/pull/30011)
- feat: litellm oss 110626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30202](https://github.com/BerriAI/litellm/pull/30202)
- fix(docker): copy only runtime artifacts into the final image by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30243](https://github.com/BerriAI/litellm/pull/30243)
- feat(proxy): enforce key/team guardrails on bedrock passthrough routes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30194](https://github.com/BerriAI/litellm/pull/30194)
- feat(gemini): forward web search tools in image generation by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30119](https://github.com/BerriAI/litellm/pull/30119)
- fix: bedrock mantle fixes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30083](https://github.com/BerriAI/litellm/pull/30083)
- feat(proxy): add require\_managed\_files setting for file uploads by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30186](https://github.com/BerriAI/litellm/pull/30186)
- fix(mcp): honor server\_id for REST tool calls with shared upstream URLs by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30184](https://github.com/BerriAI/litellm/pull/30184)
- fix(responses): presidio PII masking for Azure WebSocket and streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30003](https://github.com/BerriAI/litellm/pull/30003)
- feat(passthrough): add configurable pass-through request timeouts by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30266](https://github.com/BerriAI/litellm/pull/30266)
- fix(google\_genai): preserve complete SSE events in Vertex/Gemini image streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30270](https://github.com/BerriAI/litellm/pull/30270)
- fix(proxy): populate access\_via\_team\_ids on /v1/model/info by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30274](https://github.com/BerriAI/litellm/pull/30274)
- chore(oss): litellm oss staging 120626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30292](https://github.com/BerriAI/litellm/pull/30292)
- feat(ui): migrate policies, guardrails, prompts, tool-policies, and skills to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30263](https://github.com/BerriAI/litellm/pull/30263)
- feat(ui): migrate caching, cost-tracking, transform-request, ui-theme, and logs to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30267](https://github.com/BerriAI/litellm/pull/30267)
- fix(ui): gate dashboard layout on ui config load so deep links work under SERVER\_ROOT\_PATH by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30312](https://github.com/BerriAI/litellm/pull/30312)
- feat(ui): migrate admin-panel, logging-and-alerts, model-hub-table, and usage to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30268](https://github.com/BerriAI/litellm/pull/30268)
- fix(otel): cap metric attribute cardinality with include/exclude lists by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30257](https://github.com/BerriAI/litellm/pull/30257)
- fix(proxy): grace-period key rotation 401s; return deprecated-key lookup result directly by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30327](https://github.com/BerriAI/litellm/pull/30327)
- chore(deps): bump vitest, brace-expansion, pypdf and tornado by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30220](https://github.com/BerriAI/litellm/pull/30220)
- refactor(ui): remove unreachable /chat page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30178](https://github.com/BerriAI/litellm/pull/30178)
- feat(ui): migrate agents and router-settings to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30323](https://github.com/BerriAI/litellm/pull/30323)
- feat: strengthen coding conventions in CLAUDE.md by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30333](https://github.com/BerriAI/litellm/pull/30333)
- feat(ui): cut the users page over to the /ui/users path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30334](https://github.com/BerriAI/litellm/pull/30334)
- feat: ruff strict-rule suppressions baseline gate by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30303](https://github.com/BerriAI/litellm/pull/30303)
- feat(guardrails): add Cisco AI Defense integration ([#&#8203;28249](https://github.com/BerriAI/litellm/issues/28249)) by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30338](https://github.com/BerriAI/litellm/pull/30338)
- chore(ui): remove dead UI components unreferenced by any page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30340](https://github.com/BerriAI/litellm/pull/30340)
- ci: add osv-scanner lockfile scan workflow by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30222](https://github.com/BerriAI/litellm/pull/30222)
- fix(otel): record full error message on standard exception event in otel v2 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30380](https://github.com/BerriAI/litellm/pull/30380)
- test(fireworks): mock whisper transcription tests instead of live calls by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30391](https://github.com/BerriAI/litellm/pull/30391)
- build(ui): pin esbuild to 0.28.1 via overrides by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30390](https://github.com/BerriAI/litellm/pull/30390)
- feat(ui): cut the organizations page over to the /ui/organizations path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30336](https://github.com/BerriAI/litellm/pull/30336)
- fix(proxy): support SMTP implicit SSL (port 465) by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30395](https://github.com/BerriAI/litellm/pull/30395)
- fix(mcp): default Linear MCP registry entry to streamable HTTP by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30396](https://github.com/BerriAI/litellm/pull/30396)
- fix(ui): stop Virtual Keys page from infinite render loop by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30397](https://github.com/BerriAI/litellm/pull/30397)
- fix(streaming): guard raise\_on\_model\_repetition against empty choices by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30485](https://github.com/BerriAI/litellm/pull/30485)
- feat(otel-v2): emit the 6 gen\_ai.client.\* metrics at parity with v1 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30326](https://github.com/BerriAI/litellm/pull/30326)
- fix(mcp): drop phantom 401 span on delegated OAuth2 tool calls by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30494](https://github.com/BerriAI/litellm/pull/30494)
- feat(ui): cut the teams page over to the /ui/teams path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30343](https://github.com/BerriAI/litellm/pull/30343)
- fix(integrations): cap Anthropic cache\_control injection at 4 blocks by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30480](https://github.com/BerriAI/litellm/pull/30480)
- chore(codecov): add Batches, Videos, and Realtime components by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30517](https://github.com/BerriAI/litellm/pull/30517)
- test(batches): move orphan tests into tests/test\_litellm for CI coverage by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30510](https://github.com/BerriAI/litellm/pull/30510)
- fix(guardrails): run pre\_call hook once for model-level guardrails by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30543](https://github.com/BerriAI/litellm/pull/30543)
- fix(guardrails): stop re-initializing DB guardrails on every poll by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30542](https://github.com/BerriAI/litellm/pull/30542)
- chore(oss): litellm oss staging 150626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30463](https://github.com/BerriAI/litellm/pull/30463)
- ci(lint): add blanket-noqa, dataclass-default, and unused-noqa Ruff rules by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30516](https://github.com/BerriAI/litellm/pull/30516)
- ci: ratchet lint and type-check gates (ruff preview, ANN, mypy, basedpyright) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30379](https://github.com/BerriAI/litellm/pull/30379)
- fix(proxy): allow internal roles to access vector store CRUD routes by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30503](https://github.com/BerriAI/litellm/pull/30503)
- fix(otel): stamp gen\_ai.input/output.messages on v2 spans by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30548](https://github.com/BerriAI/litellm/pull/30548)
- fix(otel): export v2 gen\_ai client metrics to the configured meter provider by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30549](https://github.com/BerriAI/litellm/pull/30549)
- fix(bedrock): preserve cache\_control for ARN models in /v1/messages adapter by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29823](https://github.com/BerriAI/litellm/pull/29823)
- fix: greatly increase basedpyright slack by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30563](https://github.com/BerriAI/litellm/pull/30563)
- fix(budget): recompute budget\_reset\_at when budget\_duration changes on /budget/update by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30555](https://github.com/BerriAI/litellm/pull/30555)
- fix(otel): accept UPPER\_SNAKE\_CASE OTEL\_INSTRUMENTATION\_GENAI\_CAPTURE\_MESSAGE\_CONTENT in v2 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30562](https://github.com/BerriAI/litellm/pull/30562)
- chore(lint): remove PLR0915 too-many-statements ruff rule by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30574](https://github.com/BerriAI/litellm/pull/30574)
- ci(lint): ratcheted type-discipline gate (mutable collections, casts, guards, kwargs, suppressions) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30500](https://github.com/BerriAI/litellm/pull/30500)
- feat(proxy): add verification\_uri\_complete to CLI SSO device flow by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30571](https://github.com/BerriAI/litellm/pull/30571)
- chore: litellm oss staging160626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30527](https://github.com/BerriAI/litellm/pull/30527)
- fix(guardrails): return 400 not 500 when AIM blocks a request by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30573](https://github.com/BerriAI/litellm/pull/30573)
- ci(lint): grandfather any-discipline with a per-file ratchet budget (50% headroom) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30582](https://github.com/BerriAI/litellm/pull/30582)
- fix(audio): don't override explicit response\_format with verbose\_json by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30599](https://github.com/BerriAI/litellm/pull/30599)
- fix(anthropic): price and surface response service\_tier in cost tracking by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30558](https://github.com/BerriAI/litellm/pull/30558)
- feat: add dev and wildcard proxy configs for local testing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30556](https://github.com/BerriAI/litellm/pull/30556)
- fix(proxy): list public team model name in /v1/models by [@&#8203;ishaan-berri](https://github.com/ishaan-berri) in [#&#8203;30588](https://github.com/BerriAI/litellm/pull/30588)
- ci: drop mypy entirely, standardize type checking on basedpyright by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30648](https://github.com/BerriAI/litellm/pull/30648)
- feat(guardrails): surface OpenAI moderation violation\_categories on guardrail traces by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30659](https://github.com/BerriAI/litellm/pull/30659)
- fix(proxy): resolve list files credentials from team BYOK deployments by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30495](https://github.com/BerriAI/litellm/pull/30495)
- feat(proxy): add --max\_requests\_before\_restart\_jitter to stagger worker restarts by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30601](https://github.com/BerriAI/litellm/pull/30601)
- fix(health): correct bedrock embedding health checks by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30583](https://github.com/BerriAI/litellm/pull/30583)
- test: harden remaining pass-through CI flakes (image-gen spend poll, ruby assistants timeout) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30685](https://github.com/BerriAI/litellm/pull/30685)
- test(pass\_through): harden vertex spendlog poll against transient empty reads by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30683](https://github.com/BerriAI/litellm/pull/30683)
- fix(cost): stop non-string service\_tier from silently dropping cost tracking by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30690](https://github.com/BerriAI/litellm/pull/30690)
- feat(proxy): warn at startup when custom\_auth skips common\_checks enforcement by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30665](https://github.com/BerriAI/litellm/pull/30665)
- fix(pod\_lock): release cron lock by matching async\_set\_cache JSON encoding by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30600](https://github.com/BerriAI/litellm/pull/30600)
- ci: run a local fake OpenAI endpoint instead of the shared Railway mock by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30695](https://github.com/BerriAI/litellm/pull/30695)
- ci(windows): pin uv to Python 3.11 so it ignores the preinstalled 3.14 by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30704](https://github.com/BerriAI/litellm/pull/30704)
- feat(ui): migrate models page to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30677](https://github.com/BerriAI/litellm/pull/30677)
- refactor(ui): remove orphaned pass-through-settings route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30692](https://github.com/BerriAI/litellm/pull/30692)
- fix(cost): stop non-string response service\_tier from dropping cost tracking by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30706](https://github.com/BerriAI/litellm/pull/30706)
- feat(agent-shin): automated PR/issue triage, low-quality auto-close, and review-gate label lifecycle by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30433](https://github.com/BerriAI/litellm/pull/30433)
- chore: litellm oss 170626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30637](https://github.com/BerriAI/litellm/pull/30637)
- fix(bedrock\_mantle): add SigV4 fallback to chat completions auth by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30714](https://github.com/BerriAI/litellm/pull/30714)
- feat(search): add TinyFish as search provider by [@&#8203;simantak-dabhade](https://github.com/simantak-dabhade) in [#&#8203;30634](https://github.com/BerriAI/litellm/pull/30634)
- feat(ui): migrate old usage report to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30694](https://github.com/BerriAI/litellm/pull/30694)
- fix(proxy): enforce budgets against authoritative DB spend when the cross-pod counter is stale by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30684](https://github.com/BerriAI/litellm/pull/30684)
- chore(ci): remove Agent Shin pull\_request\_target workflows by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30784](https://github.com/BerriAI/litellm/pull/30784)
- chore: litellm oss staging by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30745](https://github.com/BerriAI/litellm/pull/30745)
- ci(zizmor): also run on litellm\_internal\_staging by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30789](https://github.com/BerriAI/litellm/pull/30789)
- fix(test): drop references to removed Agent Shin workflows by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30791](https://github.com/BerriAI/litellm/pull/30791)
- chore: remove in-product survey and Claude Code feedback nudges by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30773](https://github.com/BerriAI/litellm/pull/30773)
- feat(ui): migrate api-keys landing to App Router path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30699](https://github.com/BerriAI/litellm/pull/30699)
- feat(proxy): configurable response headers and login-page hint by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;30792](https://github.com/BerriAI/litellm/pull/30792)
- ci(zizmor): gate PRs on medium+ findings and clear existing ones by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30797](https://github.com/BerriAI/litellm/pull/30797)
- fix(proxy): use e.request\_data for logging\_obj in ModifyResponseException streaming passthrough by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30800](https://github.com/BerriAI/litellm/pull/30800)
- chore: make pr template linear portion clearer by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30766](https://github.com/BerriAI/litellm/pull/30766)
- chore(typing): add boto3/botocore stubs so basedpyright resolves the AWS SDK by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30815](https://github.com/BerriAI/litellm/pull/30815)
- fix(otel): one v2 logger owns the global provider; scope tenant OTLP creds per exporter by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;30590](https://github.com/BerriAI/litellm/pull/30590)
- fix(passthrough): recover output tokens for interrupted anthropic streams by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30787](https://github.com/BerriAI/litellm/pull/30787)
- fix(proxy): record partial spend on the failure row for interrupted streams by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30788](https://github.com/BerriAI/litellm/pull/30788)
- fix(ui): repoint dead usage guide link to cost tracking docs by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30859](https://github.com/BerriAI/litellm/pull/30859)
- fix(ui): warn that team models are deleted in the delete-team modal by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29990](https://github.com/BerriAI/litellm/pull/29990)
- feat(caching): add valkey-semantic cache backend and fix semantic cache scope keys by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30675](https://github.com/BerriAI/litellm/pull/30675)
- test(ui): isolate OldTeams delete-warning tests from leaked mock by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30871](https://github.com/BerriAI/litellm/pull/30871)
- feat: add lint-gate target and truncation-proof summary to the strict ruff gate by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30877](https://github.com/BerriAI/litellm/pull/30877)
- chore(ui): rebuild ui for release by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30894](https://github.com/BerriAI/litellm/pull/30894)
- chore(ci): bump deps by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30899](https://github.com/BerriAI/litellm/pull/30899)
- fix(watsonx): wrap string embedding input in array for WatsonX API by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30897](https://github.com/BerriAI/litellm/pull/30897)
- test: point router/completion/triton tests at the local fake OpenAI endpoint by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30900](https://github.com/BerriAI/litellm/pull/30900)
- feat(sandbox): e2b code execution primitive by [@&#8203;krrish-berri-2](https://github.com/krrish-berri-2) in [#&#8203;30898](https://github.com/BerriAI/litellm/pull/30898)
- fix(ui): source api-keys identity from useAuthorized to stop "User ID is not set" by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30903](https://github.com/BerriAI/litellm/pull/30903)
- chore(ui): rebuild ui by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30906](https://github.com/BerriAI/litellm/pull/30906)
- chore(ci): promote internal staging to main by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30907](https://github.com/BerriAI/litellm/pull/30907)
- fix(redis): prevent forcing SSLConnection when ssl=False in connection pool by [@&#8203;Jacopos311](https://github.com/Jacopos311) in [#&#8203;30770](https://github.com/BerriAI/litellm/pull/30770)
- fix(proxy): log UI setup failures instead of silently swallowing by [@&#8203;sarvesh1327](https://github.com/sarvesh1327) in [#&#8203;30819](https://github.com/BerriAI/litellm/pull/30819)

##### New Contributors

- [@&#8203;simantak-dabhade](https://github.com/simantak-dabhade) made their first contribution in [#&#8203;30634](https://github.com/BerriAI/litellm/pull/30634)
- [@&#8203;Jacopos311](https://github.com/Jacopos311) made their first contribution in [#&#8203;30770](https://github.com/BerriAI/litellm/pull/30770)
- [@&#8203;sarvesh1327](https://github.com/sarvesh1327) made their first contribution in [#&#8203;30819](https://github.com/BerriAI/litellm/pull/30819)

**Full Changelog**: <https://github.com/BerriAI/litellm/compare/v1.89.0...v1.90.0>

### [`v1.90.0`](https://github.com/BerriAI/litellm/releases/tag/v1.90.0)

[Compare Source](https://github.com/BerriAI/litellm/compare/v1.89.4...v1.90.0)

##### Verify Docker Image Signature

All LiteLLM Docker images are signed with [cosign](https://docs.sigstore.dev/cosign/overview/). Every release is signed with the same key introduced in [commit `0112e53`](https://github.com/BerriAI/litellm/commit/0112e53046018d726492c814b3644b7d376029d0).

**Verify using the pinned commit hash (recommended):**

A commit hash is cryptographically immutable, so this is the strongest way to ensure you are using the original signing key:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/0112e53046018d726492c814b3644b7d376029d0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

**Verify using the release tag (convenience):**

Tags are protected in this repository and resolve to the same key. This option is easier to read but relies on tag protection rules:

```bash
cosign verify \
  --key https://raw.githubusercontent.com/BerriAI/litellm/v1.90.0/cosign.pub \
  ghcr.io/berriai/litellm:v1.90.0
```

Expected output:

```
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
```

***

##### What's Changed

- fix(responses-bridge): map system-only chat request to system input item by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29817](https://github.com/BerriAI/litellm/pull/29817)
- feat(bedrock): forward strict and additionalProperties to Converse toolSpec by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29814](https://github.com/BerriAI/litellm/pull/29814)
- fix(mcp): highlight MCP cards red when the logged-in user is missing per-user env vars by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29856](https://github.com/BerriAI/litellm/pull/29856)
- feat(ui): add budget duration to edit team member form by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29717](https://github.com/BerriAI/litellm/pull/29717)
- fix(ui): make workflow runs page fill full width by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29868](https://github.com/BerriAI/litellm/pull/29868)
- feat: standardize rate limit errors with category, rate\_limit\_type, model, and llm\_provider fields by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;27687](https://github.com/BerriAI/litellm/pull/27687)
- fix(ui): default guardrails page to the Guardrails tab by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29872](https://github.com/BerriAI/litellm/pull/29872)
- docs(readme): add Deploy on AWS/GCP Terraform section and fix deploy button rendering by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29879](https://github.com/BerriAI/litellm/pull/29879)
- refactor(bedrock): build Converse toolSpec via a BedrockToolSpec dict subclass by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29869](https://github.com/BerriAI/litellm/pull/29869)
- feat(litellm): add models and repository layers by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29686](https://github.com/BerriAI/litellm/pull/29686)
- feat(ui): include internal routes in the dashboard's generated OpenAPI types by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29885](https://github.com/BerriAI/litellm/pull/29885)
- feat(proxy): publish /v2/model/info in Swagger OpenAPI spec by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29900](https://github.com/BerriAI/litellm/pull/29900)
- refactor(ui): single source of truth for migrated-page routing by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29949](https://github.com/BerriAI/litellm/pull/29949)
- fix(ui/model-hub): render provider icons on the public model hub by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29958](https://github.com/BerriAI/litellm/pull/29958)
- fix(ui): keep create guardrail modal open on outside click by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29871](https://github.com/BerriAI/litellm/pull/29871)
- fix(ui): label default key type as "Full Access" on key edit page by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29870](https://github.com/BerriAI/litellm/pull/29870)
- fix(ui): unify migrated-route URLs and migrate the API Reference page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29953](https://github.com/BerriAI/litellm/pull/29953)
- fix(mcp): let non-creator users OAuth into OBO-mode MCP servers from the Tools page by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29867](https://github.com/BerriAI/litellm/pull/29867)
- Litellm oss staging 080626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29932](https://github.com/BerriAI/litellm/pull/29932)
- feat(galileo): add health check support for UI callback test by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29908](https://github.com/BerriAI/litellm/pull/29908)
- fix(model-management): allow deleting a BYOK model after its team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29875](https://github.com/BerriAI/litellm/pull/29875)
- feat(jwt-auth): opt-in fallback to DB team on unresolved JWT claim by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28913](https://github.com/BerriAI/litellm/pull/28913)
- fix(team\_endpoints): don't block /team/update on unchanged team budget by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29525](https://github.com/BerriAI/litellm/pull/29525)
- fix(fireworks): enable tool calling for glm-5p1 in model cost map by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;29697](https://github.com/BerriAI/litellm/pull/29697)
- fix(vertex): propagate Vertex AI metadata in streaming success callbacks by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29899](https://github.com/BerriAI/litellm/pull/29899)
- fix(ui): show team projects to internal users on key creation by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28855](https://github.com/BerriAI/litellm/pull/28855)
- build(deps): bump pyjwt to 2.13.0 and ws override to 8.20.1 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29982](https://github.com/BerriAI/litellm/pull/29982)
- fix(team-management): delete a team's BYOK models when the team is deleted by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29977](https://github.com/BerriAI/litellm/pull/29977)
- feat(vantage): include organization metadata in FOCUS Tags export by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;28184](https://github.com/BerriAI/litellm/pull/28184)
- fix(guardrails): read CrowdStrike AIDR identity from both metadata bags by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;29991](https://github.com/BerriAI/litellm/pull/29991)
- fix(mcp): mirror upstream token lifetime instead of forcing a 1h OBO expiry by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29951](https://github.com/BerriAI/litellm/pull/29951)
- feat(azure\_ai): add MAI-Image-2.5 image generation support by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29688](https://github.com/BerriAI/litellm/pull/29688)
- fix(mcp): load MCP tool configuration tools via the OBO/passthrough-aware GET path by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;29960](https://github.com/BerriAI/litellm/pull/29960)
- fix(team): reserve team budget raises for proxy admins on /team/update by [@&#8203;milan-berri](https://github.com/milan-berri) in [#&#8203;30030](https://github.com/BerriAI/litellm/pull/30030)
- test(ui): data-driven App Router migration E2E smoke (default + server-root-path) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29974](https://github.com/BerriAI/litellm/pull/29974)
- fix(proxy): extend response headers hook to streaming, TTS, image gen, and pass-through by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;24232](https://github.com/BerriAI/litellm/pull/24232)
- chore(ui): remove dead App Router route stubs under (dashboard) by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30045](https://github.com/BerriAI/litellm/pull/30045)
- fix(ui/mcp): reset OAuth state on create-server modal close so a prior server's token no longer leaks into the next add-server session by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30000](https://github.com/BerriAI/litellm/pull/30000)
- fix(mcp): allow team access-group grants in OAuth authorize/token access check by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30041](https://github.com/BerriAI/litellm/pull/30041)
- docs(security): require a reproduction video for vulnerability reports by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30063](https://github.com/BerriAI/litellm/pull/30063)
- feat(ui): add admin flag to disable in-product UI nudges for everyone by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;29796](https://github.com/BerriAI/litellm/pull/29796)
- chore(ui): remove dead dashboard files and unused dependencies by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30047](https://github.com/BerriAI/litellm/pull/30047)
- fix(proxy): authorize batch files using upload target\_model\_names (LIT-3593) by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30009](https://github.com/BerriAI/litellm/pull/30009)
- Add Claude Fable 5 across Anthropic, Bedrock, Vertex AI, and Azure AI by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30064](https://github.com/BerriAI/litellm/pull/30064)
- Add Claude Fable 5 cost map entries (data-only hotfix for the hosted map) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30076](https://github.com/BerriAI/litellm/pull/30076)
- fix(caching): restore stored prompt\_tokens on embedding cache hits instead of recomputing by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30046](https://github.com/BerriAI/litellm/pull/30046)
- Litellm oss 090626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30021](https://github.com/BerriAI/litellm/pull/30021)
- fix(proxy): self-heal startup/reload prisma reads on engine disconnect by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;28803](https://github.com/BerriAI/litellm/pull/28803)
- chore(ui): make knip recognize .mjs scripts and openapi-typescript by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30052](https://github.com/BerriAI/litellm/pull/30052)
- fix(register\_model): preserve built-in cache pricing when registering custom overrides under unmapped keys by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30044](https://github.com/BerriAI/litellm/pull/30044)
- \[internal copy of [#&#8203;28007](https://github.com/BerriAI/litellm/issues/28007)] Fix/gcp model garden streaming by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28363](https://github.com/BerriAI/litellm/pull/28363)
- feat(cli): per-agent `lite claude` / `codex` / `opencode` commands that wrap coding agents through the proxy by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;29850](https://github.com/BerriAI/litellm/pull/29850)
- fix(callbacks): forward callback\_settings to callback initializers and guard consumers against non-dict values by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30161](https://github.com/BerriAI/litellm/pull/30161)
- fix(mcp): drop orphaned per-user credential rows when an MCP server is deleted by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;30141](https://github.com/BerriAI/litellm/pull/30141)
- fix(proxy): recover from cached-plan errors by reconnecting the Prisma client by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29983](https://github.com/BerriAI/litellm/pull/29983)
- feat(proxy): add option to disable server-side prepared statements for DB lookups by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29984](https://github.com/BerriAI/litellm/pull/29984)
- fix(release): stop backport releases from overwriting the latest badge by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30005](https://github.com/BerriAI/litellm/pull/30005)
- feat: add conventional commits and coding guidelines by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30159](https://github.com/BerriAI/litellm/pull/30159)
- fix(proxy): return 5xx on DB infra errors during auth; reserve 401 for genuine auth failures by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29986](https://github.com/BerriAI/litellm/pull/29986)
- fix(ui): dev server 404s on migrated-page links because uiBase hardcodes /ui by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30169](https://github.com/BerriAI/litellm/pull/30169)
- refactor(ui): consolidate dashboard to one shell in the (dashboard) layout by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30166](https://github.com/BerriAI/litellm/pull/30166)
- fix(proxy): align /v1/model/info with router deployments by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30025](https://github.com/BerriAI/litellm/pull/30025)
- fix: completion\_cost AttributeError on streaming Anthropic web\_search responses ([#&#8203;26153](https://github.com/BerriAI/litellm/issues/26153)) by [@&#8203;ishaan-berri](https://github.com/ishaan-berri) in [#&#8203;27346](https://github.com/BerriAI/litellm/pull/27346)
- \[internal copy of [#&#8203;30137](https://github.com/BerriAI/litellm/issues/30137)] perf(realtime): eliminate redundant per-frame JSON work on OpenAI realtime relay by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30142](https://github.com/BerriAI/litellm/pull/30142)
- feat(bedrock): aws\_bedrock\_project\_id for bedrock-mantle project / workspace association by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30163](https://github.com/BerriAI/litellm/pull/30163)
- chore(hooks): enforce Conventional Commits and Conventional Branches by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30174](https://github.com/BerriAI/litellm/pull/30174)
- feat(rate-limiter): allow opting out of v3 TPM reservation and Redis circuit breaker by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30211](https://github.com/BerriAI/litellm/pull/30211)
- feat(spend\_logs): opt-in native Postgres partitioning for SpendLogs retention by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;29466](https://github.com/BerriAI/litellm/pull/29466)
- feat(ui): migrate playground to path routing and colocate its files by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30185](https://github.com/BerriAI/litellm/pull/30185)
- feat(ui): migrate projects and access-groups to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30226](https://github.com/BerriAI/litellm/pull/30226)
- fix(proxy): coalesce NULL rollup metrics in aggregated daily-activity by [@&#8203;michelligabriele](https://github.com/michelligabriele) in [#&#8203;30151](https://github.com/BerriAI/litellm/pull/30151)
- fix(anthropic\_passthrough): resolve costing model from message\_start chunk, litellm\_params and model\_group instead of 'unknown' by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30160](https://github.com/BerriAI/litellm/pull/30160)
- feat(ui): migrate budgets, workflows, and guardrails-monitor to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30236](https://github.com/BerriAI/litellm/pull/30236)
- feat(ui): migrate mcp-servers, search-tools, tag-management, vector-stores, and memory to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30261](https://github.com/BerriAI/litellm/pull/30261)
- fix(a2a): forward agent\_extra\_headers through completion bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;28277](https://github.com/BerriAI/litellm/pull/28277)
- fix(gemini-live): forward audio buffer commit and correct Vertex PCM rate by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;29946](https://github.com/BerriAI/litellm/pull/29946)
- fix(proxy): skip double-wrapping unified batch output file ids on retrieve by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30011](https://github.com/BerriAI/litellm/pull/30011)
- feat: litellm oss 110626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30202](https://github.com/BerriAI/litellm/pull/30202)
- fix(docker): copy only runtime artifacts into the final image by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30243](https://github.com/BerriAI/litellm/pull/30243)
- feat(proxy): enforce key/team guardrails on bedrock passthrough routes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30194](https://github.com/BerriAI/litellm/pull/30194)
- feat(gemini): forward web search tools in image generation by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30119](https://github.com/BerriAI/litellm/pull/30119)
- fix: bedrock mantle fixes by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30083](https://github.com/BerriAI/litellm/pull/30083)
- feat(proxy): add require\_managed\_files setting for file uploads by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30186](https://github.com/BerriAI/litellm/pull/30186)
- fix(mcp): honor server\_id for REST tool calls with shared upstream URLs by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30184](https://github.com/BerriAI/litellm/pull/30184)
- fix(responses): presidio PII masking for Azure WebSocket and streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30003](https://github.com/BerriAI/litellm/pull/30003)
- feat(passthrough): add configurable pass-through request timeouts by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30266](https://github.com/BerriAI/litellm/pull/30266)
- fix(google\_genai): preserve complete SSE events in Vertex/Gemini image streaming by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30270](https://github.com/BerriAI/litellm/pull/30270)
- fix(proxy): populate access\_via\_team\_ids on /v1/model/info by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30274](https://github.com/BerriAI/litellm/pull/30274)
- chore(oss): litellm oss staging 120626 by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30292](https://github.com/BerriAI/litellm/pull/30292)
- feat(ui): migrate policies, guardrails, prompts, tool-policies, and skills to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30263](https://github.com/BerriAI/litellm/pull/30263)
- feat(ui): migrate caching, cost-tracking, transform-request, ui-theme, and logs to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30267](https://github.com/BerriAI/litellm/pull/30267)
- fix(ui): gate dashboard layout on ui config load so deep links work under SERVER\_ROOT\_PATH by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30312](https://github.com/BerriAI/litellm/pull/30312)
- feat(ui): migrate admin-panel, logging-and-alerts, model-hub-table, and usage to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30268](https://github.com/BerriAI/litellm/pull/30268)
- fix(otel): cap metric attribute cardinality with include/exclude lists by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30257](https://github.com/BerriAI/litellm/pull/30257)
- fix(proxy): grace-period key rotation 401s; return deprecated-key lookup result directly by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30327](https://github.com/BerriAI/litellm/pull/30327)
- chore(deps): bump vitest, brace-expansion, pypdf and tornado by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30220](https://github.com/BerriAI/litellm/pull/30220)
- refactor(ui): remove unreachable /chat page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30178](https://github.com/BerriAI/litellm/pull/30178)
- feat(ui): migrate agents and router-settings to path routes by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30323](https://github.com/BerriAI/litellm/pull/30323)
- feat: strengthen coding conventions in CLAUDE.md by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;30333](https://github.com/BerriAI/litellm/pull/30333)
- feat(ui): cut the users page over to the /ui/users path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30334](https://github.com/BerriAI/litellm/pull/30334)
- feat: ruff strict-rule suppressions baseline gate by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30303](https://github.com/BerriAI/litellm/pull/30303)
- feat(guardrails): add Cisco AI Defense integration ([#&#8203;28249](https://github.com/BerriAI/litellm/issues/28249)) by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30338](https://github.com/BerriAI/litellm/pull/30338)
- chore(ui): remove dead UI components unreferenced by any page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30340](https://github.com/BerriAI/litellm/pull/30340)
- ci: add osv-scanner lockfile scan workflow by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30222](https://github.com/BerriAI/litellm/pull/30222)
- fix(otel): record full error message on standard exception event in otel v2 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30380](https://github.com/BerriAI/litellm/pull/30380)
- test(fireworks): mock whisper transcription tests instead of live calls by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30391](https://github.com/BerriAI/litellm/pull/30391)
- build(ui): pin esbuild to 0.28.1 via overrides by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30390](https://github.com/BerriAI/litellm/pull/30390)
- feat(ui): cut the organizations page over to the /ui/organizations path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30336](https://github.com/BerriAI/litellm/pull/30336)
- fix(proxy): support SMTP implicit SSL (port 465) by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;30395](https://github.com/BerriAI/litellm/pull/30395)
- fix(mcp): default Linear MCP registry entry to streamable HTTP by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30396](https://github.com/BerriAI/litellm/pull/30396)
- fix(ui): stop Virtual Keys page from infinite render loop by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30397](https://github.com/BerriAI/litellm/pull/30397)
- fix(streaming): guard raise\_on\_model\_repetition against empty choices by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30485](https://github.com/BerriAI/litellm/pull/30485)
- feat(otel-v2): emit the 6 gen\_ai.client.\* metrics at parity with v1 by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30326](https://github.com/BerriAI/litellm/pull/30326)
- fix(mcp): drop phantom 401 span on delegated OAuth2 tool calls by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30494](https://github.com/BerriAI/litellm/pull/30494)
- feat(ui): cut the teams page over to the /ui/teams path route by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;30343](https://github.com/BerriAI/litellm/pull/30343)
- fix(integrations): cap Anthropic cache\_control injection at 4 blocks by [@&#8203;shivamrawat1](https://github.com/shivamrawat1) in [#&#8203;30480](https://github.com/BerriAI/litellm/pull/30480)
- chore(codecov): add Batches, Videos, and Realtime components by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30517](https://github.com/BerriAI/litellm/pull/30517)
- test(batches): move orphan tests into tests/test\_litellm for CI coverage by [@&#8203;Sameerlite](https://github.com/Sameerlite) in [#&#8203;30510](https://github.com/BerriAI/litellm/pull/30510)
- fix(guardrails): run pre\_call hook once for model-level guardrails by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;30543](http…
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants