Skip to content

fix(ci): let the mutation workflow find covered lines so it generates mutants - #38305

Merged
yuneng-berri merged 6 commits into
litellm_internal_stagingfrom
litellm_/testing-strategy-audit-c39e33
Aug 26, 2026
Merged

yuneng-berri merged 6 commits into
litellm_internal_stagingfrom
litellm_/testing-strategy-audit-c39e33

Conversation

@yuneng-berri

@yuneng-berri yuneng-berri commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • The mutation workflow reports nothing, and has for months
  • It burns 26 minutes collecting coverage, then finds 0 mutants
  • A run that overruns its budget publishes no report at all

How it solves it:

  • Point mutation runs at a coverage config that stores absolute paths
  • Give the mutmut step a deadline inside the job's own
  • Upload the per-mutant .meta files, which are what a partial run leaves behind
  • Stop one test from deleting mutmut's own sentinel variable

User Flow

Before: someone who wants a mutation score for the management endpoints clicks the workflow and gets nothing back

  1. They open https://github.com/BerriAI/litellm/actions/workflows/mutation-test.yml and click "Run workflow"
  2. The job spends about 26 minutes running the 2854 tests in scope
  3. It ends on "Stopping early, because we could not find any test case for any mutant"
  4. The run page summary reads "mutmut produced no results, so the report cannot say anything about the suite", and the uploaded report is 221 characters
  5. They learn nothing about the suite, and the last four dispatches all ended this way

After: mutants now exist to be tested, so a scope whose tests all pass comes back with a real score and a list of survivors

  1. They narrow the scope to a module whose tests pass in one process, then click "Run workflow"
  2. The job runs the same tests, then reports mutants generated and starts testing them
  3. The run page summary shows how many mutants were killed and how many survived
  4. The uploaded mutation-report.md names each surviving mutant with its diff, the function it lives in, and the test files that were supposed to catch it
  5. If the run outlasts its budget, the summary and report still cover every mutant it finished rather than being cancelled with nothing

One test in that folder cleared the whole process environment, which took mutmut's MUTANT_UNDER_TEST with it, so the next call through a mutation trampoline raised KeyError. Under -x that ended the run before any mutant was tested. The test now keeps every variable it does not care about, so the click above no longer stops there. See the cases under Proof of Fix.

Relevant issues

Linear ticket

Pre-Submission checklist

  • I have added meaningful tests
  • The handful of test files covering my change pass locally, e.g. uv run pytest tests/test_litellm/<your_test_file>.py -v
  • My PR passes all required CI/CD checks (e.g., lint, schema.d.ts sync check, etc.)
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have received a Greptile Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

The end user here is whoever dispatches the workflow, so the proof is a mutation run: the same scope, scored before and after. Reproduced locally against one module so the whole loop fits in seconds, plus the real CI dispatch on each side.

Shared setup, run from the repo root:

UV_PROJECT_ENVIRONMENT=.venv-mutmut uv sync --frozen --group ci --group proxy-dev --extra google --extra proxy --extra semantic-router --extra saml
UV_PROJECT_ENVIRONMENT=.venv-mutmut uv run --no-sync prisma generate --schema litellm/proxy/schema.prisma
rm -rf .venv-mutmut/lib/python3.*/site-packages/pytest_retry*

Scope narrowed to one module in [tool.mutmut] so a full loop takes seconds instead of hours:

paths_to_mutate = ["litellm/proxy/management_endpoints/sso_helper_utils.py"]
tests_dir = ["tests/local_testing/test_ui_sso_helper_utils.py"]

A second harness builds mutmut's mutants/ sandbox by hand, so the whole folder can be run inside it in ten minutes instead of waiting out a CI dispatch. Mutating every line rather than only the covered ones is deliberate: it is a superset, so more functions carry a trampoline, not fewer.

SB=/tmp/mutmut-sandbox
rm -rf "$SB" && mkdir -p "$SB/mutants/tests" "$SB/harness"
cp -R litellm "$SB/mutants/litellm"
cp -R tests/test_litellm "$SB/mutants/tests/test_litellm"
cp pyproject.toml "$SB/mutants/"
uv pip install --python .venv/bin/python --target "$SB/mmpkgs" mutmut==3.5.0
rm -rf "$SB"/mmpkgs/_pytest "$SB"/mmpkgs/pytest "$SB"/mmpkgs/coverage "$SB"/mmpkgs/pluggy "$SB"/mmpkgs/packaging "$SB"/mmpkgs/iniconfig "$SB"/mmpkgs/typing_extensions.py "$SB"/mmpkgs/a1_coverage.pth
printf 'from mutmut.__main__ import ensure_config_loaded\nensure_config_loaded()\n' > "$SB/harness/mmconfig.py"
PYTHONPATH="$SB/mmpkgs" .venv/bin/python - <<'EOF'
from pathlib import Path
from mutmut.file_mutation import mutate_file_contents
out = Path("/tmp/mutmut-sandbox/mutants")
for f in sorted(Path("litellm/proxy/management_endpoints").rglob("*.py")):
    (out / f).write_text(mutate_file_contents(str(f), f.read_text(), None)[0])
EOF

Running the folder in it is what mutmut's stats phase does (mutmut/__main__.py:574): pytest from inside mutants/, with MUTANT_UNDER_TEST=stats.

REPO=$PWD
cd "$SB/mutants" && MUTANT_UNDER_TEST=stats PY_IGNORE_IMPORTMISMATCH=1 \
  PYTHONPATH="$SB/mutants:$SB/mmpkgs:$SB/harness" \
  "$REPO/.venv/bin/python" -m pytest --rootdir=. --tb=native -q \
  -p mmconfig -p no:retry -p no:rerunfailures -p no:xdist -p no:randomly \
  --ignore=tests/test_litellm/proxy/management_endpoints/test_saml_sso.py \
  tests/test_litellm/proxy/management_endpoints/

Before (ae63786cfb^, the merge base)

Local, one module

  1. Run mutmut the way the workflow does today:
rm -rf mutants && mkdir -p mutants
UV_PROJECT_ENVIRONMENT=.venv-mutmut PYTHONPATH=$PWD/mutants \
  uv run --no-sync --with mutmut==3.5.0 mutmut run
  1. Output:
    done in 17425ms (1 files mutated, 0 ignored, 0 unmodified)
2 passed in 0.06s
Stopping early, because we could not find any test case for any mutant. It seems that the selected tests do not cover any code that we mutated.

Zero mutants tested, exit code 1.

Local, the mutated folder in mutmut's sandbox

  1. Run the folder through the sandbox harness above
  2. Output:
1 failed, 2901 passed, 58 warnings in 573.94s (0:09:33)
FAILED tests/test_litellm/proxy/management_endpoints/test_ui_sso.py::TestCLIKeyRegenerationFlow::test_google_login_only_threads_user_code_when_enabled
  1. Run that one test on its own to see what it actually hit:
  File ".../mutants/litellm/proxy/management_endpoints/ui_sso.py", line 29951, in google_login
    _get_cli_sso_flow_or_raise(login_id=key, cache=cli_sso_session_cache)
  File ".../mutants/litellm/proxy/management_endpoints/ui_sso.py", line 183, in _mutmut_trampoline
    mutant_under_test = os.environ['MUTANT_UNDER_TEST']
KeyError: 'MUTANT_UNDER_TEST'

The test cleared the whole environment, so mutmut's own sentinel went with it. google_login is decorated and mutmut never trampolines a decorated function, which is why the raise lands one frame further in. The bare except Exception: pass around the call then swallowed it, and the assertion read call_args on a mock that was never called, which is the 'NoneType' object has no attribute 'kwargs' everyone saw.

CI, full scope

  1. The most recent dispatch before this PR: https://github.com/BerriAI/litellm/actions/runs/32481213728
  2. Its log:
2854 passed, 58 warnings in 1569.11s (0:26:09)
Stopping early, because we could not find any test case for any mutant.
...
error: mutmut produced no results, so the report cannot say anything about the suite
Wrote /home/runner/work/litellm/litellm/mutation-report.md (0 survivors, 221 chars)
  1. With only the coverage fix in place, mutants exist but the run still ends in the stats phase: https://github.com/BerriAI/litellm/actions/runs/32937470190
1 failed, 1167 passed, 26 warnings in 759.88s (0:12:39)
failed to collect stats. runner returned 1
  1. -x names the first failure and stops, so a throwaway branch added --maxfail=200 to let the whole folder run and count every sandbox failure. mutmut appends pytest_add_cli_args after its own -x (mutmut/__main__.py:563) and a later --maxfail wins: https://github.com/BerriAI/litellm/actions/runs/32959717115
1 failed, 2901 passed, 56 warnings in 1697.46s (0:28:17)
FAILED tests/test_litellm/proxy/management_endpoints/test_ui_sso.py::TestCLIKeyRegenerationFlow::test_google_login_only_threads_user_code_when_enabled - AttributeError: 'NoneType' object has no attribute 'kwargs'
  1. Same folder, same flags, outside the sandbox on the same runner image, as the control:
2902 passed, 56 warnings in 1597.40s (0:26:37)

One test, and it is the same one both locally and on CI. --maxfail is deliberately not shipped: the same args reach the per-mutant runs, where -x is what keeps them fast.

After (3fdeb79737)

Local, one module

  1. Same command, with the workflow's new environment variable:
rm -rf mutants && mkdir -p mutants
UV_PROJECT_ENVIRONMENT=.venv-mutmut PYTHONPATH=$PWD/mutants \
  COVERAGE_RCFILE=$PWD/.github/mutmut-coverage.rc \
  uv run --no-sync --with mutmut==3.5.0 mutmut run
  1. Output:
⠸ 8/8  🎉 8 🫥 0  ⏰ 0  🤔 0  🙁 0  🔇 0  🧙 0
40.87 mutations/second

8 mutants generated, all 8 killed. That module's tests hold up; the point is that the score exists at all.

Local, the mutated folder in mutmut's sandbox

  1. Same harness, same command
  2. Output:
2902 passed, 58 warnings in 580.31s (0:09:40)

Every test in the folder now runs where mutmut needs it to, and the count matches the outside-the-sandbox control above.

CI, full scope

  1. Dispatched at this tip: https://github.com/BerriAI/litellm/actions/runs/32984754749
  2. Still running as of this edit. Generation alone took 57 minutes last time, so the numbers go in here once it clears the stats phase.

Type

🚄 Infrastructure

Caveats (if any)

Medium

  • A whole-folder run has still never finished, so its budget is unmeasured
    • Both known blockers are fixed, but the full run takes hours
    • Generation alone was 57 minutes across 48 files
  • Seven other tests in that file still clear the whole environment
    • None of them calls through a trampoline while cleared, so they pass today
    • A helper moving out of a decorated endpoint would break them the same way

Low

  • COVERAGE_RCFILE replaces the whole coverage config, not just one key
  • That is fine here: mutmut passes source explicitly and writes no data file
  • Local runs need pytest_retry removed from site-packages, same as CI does

… mutants

mutmut's gather_coverage() looks each source file's covered lines up by
absolute path, but [tool.coverage.run] sets relative_files = true, so every
lookup misses. With mutate_only_covered_lines = true that leaves no line
eligible for mutation, and the run ends on "Stopping early, because we could
not find any test case for any mutant" after spending 26 minutes collecting
coverage. The last four dispatches all died that way.

Point COVERAGE_RCFILE at a small rc file for mutation runs only, so the
coverage instance mutmut builds stores absolute paths. Scoped to one module
locally this takes the run from 0 mutants to 8 generated and 8 killed.

Also give the mutmut step a deadline inside the job's own. mutmut records
each mutant's verdict to mutants/mutmut-stats.json as it finishes, so a run
that outlasts its budget still scores what it got through, but a cancelled
job skips the report and upload steps and publishes nothing. That is how the
two runs before these four ended.

Ignore mutants/ and .venv-mutmut, which a local run leaves behind untracked.
@yuneng-berri
yuneng-berri requested a review from a team August 26, 2026 06:18
@greptile-apps

greptile-apps Bot commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR repairs mutation-test coverage discovery and makes long-running mutation jobs retain useful partial output.

  • Adds a mutation-specific coverage configuration that stores absolute file paths.
  • Gives mutmut a deadline before the overall job timeout and uploads per-mutant metadata.
  • Preserves mutmut’s environment sentinel while isolating SSO provider configuration in the affected test.
  • Ignores local mutation-testing environments and generated sandboxes.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
.github/workflows/mutation-test.yml Configures absolute-path coverage collection, a bounded mutmut step, and partial-result artifact uploads without an identified blocking failure.
.github/mutmut-coverage.rc Overrides relative coverage paths so mutmut’s absolute-path covered-line lookup can discover mutants.
tests/test_litellm/proxy/management_endpoints/test_ui_sso.py Retains unrelated environment variables, clears provider-selection variables, and strengthens failure and mock-call assertions.
.gitignore Excludes the local mutation virtual environment and generated mutant sandbox.

Reviews (4): Last reviewed commit: "fix(test): keep the mutmut sentinel out ..." | Re-trigger Greptile

@codecov

codecov Bot commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

The step-timeout comment claimed mutmut streams each mutant's result into
mutants/mutmut-stats.json. It does not. That file holds the pre-run test
timings and coverage map (tests_by_mangled_function_name, duration_by_test,
stats_time) written once by save_stats() before mutation starts.

Per-mutant results live in mutants/<source path>.meta. Verified against
mutmut 3.5.0: SourceFileMutationData.register_result() calls save() after
every single result, and export-cicd-stats walks those .meta files to build
mutmut-cicd-stats.json. So the reason the step deadline exists is still
right, an interrupted run keeps the mutants it already scored, but the
comment pointed at the wrong file.

Also upload the .meta files, since they are the partial results the comment
relies on and the artifact could not otherwise show them.
@yuneng-berri

Copy link
Copy Markdown
Contributor Author

@greptileai the last review scored ab8134c; head is now ac1eb10, which corrects the comment naming where mutmut writes partial results.

With the coverage fix in place the run generates mutants, then dies before
testing any of them: "1 failed ... failed to collect stats. runner returned 1".

The offender is one test. google_login is called inside a bare
`except Exception: pass` and the assertion then reads the mock's call_args, so
an early raise inside mutmut's mutants/ sandbox surfaces as
"'NoneType' object has no attribute 'kwargs'" rather than as the real error.

Deselected rather than ignored, so the other 248 tests in test_ui_sso.py still
contribute to the score.

This is measured rather than guessed. mutmut's stats phase hardcodes -x, so a
failing run only ever names its first offender, which is why deselecting looked
like whack-a-mole before. pytest_add_cli_args is appended after -x, and a later
--maxfail wins, so overriding it once let the whole folder run inside the
sandbox: 1 failed, 2901 passed. That one test is the only one that cannot run
there.

What is still not known is why it raises early in the sandbox. It is not the
suite and not the copied tree: the same folder passes outside mutants/ on the
runner image (2930), passes on a copied tree put first on PYTHONPATH (2902),
and passes with and without the test_saml_sso.py ignore. What is left is
mutmut's trampolines.
@yuneng-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@codspeed

codspeed Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing litellm_/testing-strategy-audit-c39e33 (5bbbbff) with litellm_internal_staging (40423e6)

Open in CodSpeed

test_google_login_only_threads_user_code_when_enabled cleared the whole
process environment for the duration of the call. mutmut's trampoline reads
os.environ['MUTANT_UNDER_TEST'] with a bare subscript, so the first
trampolined callee inside the block, _get_cli_sso_flow_or_raise, raised
KeyError. The bare `except Exception: pass` swallowed it and the assertion
then read call_args on a mock that was never called, which is where
"'NoneType' object has no attribute 'kwargs'" came from.

The test only needs the SSO provider variables unset, so it now preserves the
rest of the environment instead of clearing everything. google_login does not
raise here, so the try/except is gone and any future exception propagates; the
added assert turns a silent early return into a readable failure instead of an
AttributeError.

Root cause measured in a trampolined copy of the mutated folder with
MUTANT_UNDER_TEST=stats: the old test fails there with
KeyError: 'MUTANT_UNDER_TEST' inside _mutmut_trampoline, the new one passes.
That was the only test the mutation run could not execute, so the --deselect
comes back out and it counts toward the score again.
@yuneng-berri

Copy link
Copy Markdown
Contributor Author

@greptileai

@yuneng-berri
yuneng-berri enabled auto-merge August 26, 2026 18:28
@yuneng-berri
yuneng-berri merged commit 7bc8099 into litellm_internal_staging Aug 26, 2026
76 checks passed
@yuneng-berri
yuneng-berri deleted the litellm_/testing-strategy-audit-c39e33 branch August 26, 2026 18:34
doonga pushed a commit to greyrock-labs/home-ops that referenced this pull request Sep 6, 2026
…00.0) (#124)

This PR contains the following updates:

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

---

### Release Notes

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

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

[Compare Source](https://github.com/BerriAI/litellm/compare/v1.99.1...v1.100.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.100.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.100.0/cosign.pub \
  ghcr.io/berriai/litellm:v1.100.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): keep the conversation when chaining previous\_response\_id on the bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;37956](https://github.com/BerriAI/litellm/pull/37956)
- feat(newrelic): per-team New Relic trace routing via team callbacks by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;37603](https://github.com/BerriAI/litellm/pull/37603)
- perf(ci): cache uv dependencies in the lint job by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37783](https://github.com/BerriAI/litellm/pull/37783)
- perf(ci): fan the budget checkers out across cores by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37784](https://github.com/BerriAI/litellm/pull/37784)
- ci: port the Postgres suites off CircleCI onto service containers by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37785](https://github.com/BerriAI/litellm/pull/37785)
- feat(ci): gate patching of SDK internals in tests as TQ008 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37787](https://github.com/BerriAI/litellm/pull/37787)
- ci: measure enterprise/ coverage by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37788](https://github.com/BerriAI/litellm/pull/37788)
- ci: run the keyless caching tests that ran in no job by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37790](https://github.com/BerriAI/litellm/pull/37790)
- fix(ci): run the migration DDL guard, and stop it reading comments as SQL by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37791](https://github.com/BerriAI/litellm/pull/37791)
- ci: run the enterprise package suite in GitHub Actions by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37798](https://github.com/BerriAI/litellm/pull/37798)
- perf(ci): give the two longest unit shards the runner's spare cores by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37804](https://github.com/BerriAI/litellm/pull/37804)
- test(exception-mapping): pin the status and error-shape table every provider maps to by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37807](https://github.com/BerriAI/litellm/pull/37807)
- fix(terraform): add soft\_budget, tags, and soft\_budget\_alerting\_emails to litellm\_team by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37918](https://github.com/BerriAI/litellm/pull/37918)
- fix(ui): theme the created-key box so it follows dark mode by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37985](https://github.com/BerriAI/litellm/pull/37985)
- fix(ui): restore the public model name tooltip layout in the add model flow by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37986](https://github.com/BerriAI/litellm/pull/37986)
- fix(ui): render team and org tpm/rpm limits of 0 as 0 instead of Unlimited by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37916](https://github.com/BerriAI/litellm/pull/37916)
- fix(ui): repoint the key detail URL to the rotated hash after regenerating by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37968](https://github.com/BerriAI/litellm/pull/37968)
- fix(ui): make playground chat bubbles theme-aware by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;37978](https://github.com/BerriAI/litellm/pull/37978)
- fix(UI): correct skill install command and marketplace setup UX by [@&#8203;ozolam](https://github.com/ozolam) in [#&#8203;33514](https://github.com/BerriAI/litellm/pull/33514)
- fix(proxy): skip health checks for strategy routers by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37966](https://github.com/BerriAI/litellm/pull/37966)
- fix(databricks): bill cached tokens at cache rates and add missing Claude pricing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;37975](https://github.com/BerriAI/litellm/pull/37975)
- fix(anthropic): round-trip thinking blocks to OpenAI backends on /v1/messages by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;37953](https://github.com/BerriAI/litellm/pull/37953)
- fix(a2a): normalize agent card protocolBinding casing before transport match by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37917](https://github.com/BerriAI/litellm/pull/37917)
- fix(interactions): track cost and spend for Google Interactions API requests by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;33310](https://github.com/BerriAI/litellm/pull/33310)
- fix(bedrock): stop emitting an empty assistant delta after the finish\_reason chunk by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;36806](https://github.com/BerriAI/litellm/pull/36806)
- fix(anthropic): reconcile enum with declared type in output\_format schema by [@&#8203;dkindlund](https://github.com/dkindlund) in [#&#8203;37882](https://github.com/BerriAI/litellm/pull/37882)
- feat(azure\_ai): support entra id / oauth auth on every azure ai foundry route by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;35415](https://github.com/BerriAI/litellm/pull/35415)
- fix(ui): boot the UI image as an arbitrary uid by anchoring nginx writes under /tmp by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37982](https://github.com/BerriAI/litellm/pull/37982)
- fix(proxy): parse form-encoded video edit/extension bodies after auth by [@&#8203;Souravrajvi0](https://github.com/Souravrajvi0) in [#&#8203;36513](https://github.com/BerriAI/litellm/pull/36513)
- fix(anthropic): keep legacy thinking budget\_tokens on Claude 4.6 models on /v1/messages by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38108](https://github.com/BerriAI/litellm/pull/38108)
- fix(utils): make prompt\_token\_calculator count claude models again by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38130](https://github.com/BerriAI/litellm/pull/38130)
- fix(proxy): keep every value of a repeated form key, and gate the tests that hid it by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;37908](https://github.com/BerriAI/litellm/pull/37908)
- fix(health): apply model\_info.health\_check\_params to health check probes by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38101](https://github.com/BerriAI/litellm/pull/38101)
- fix(runwayml): route every generation endpoint and fix video cost tracking by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38115](https://github.com/BerriAI/litellm/pull/38115)
- fix(passthrough): attribute spend and release budget reservation on router-model /vllm and /azure routes by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38111](https://github.com/BerriAI/litellm/pull/38111)
- fix: match OpenAI SDK wire format on image/video routes by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38104](https://github.com/BerriAI/litellm/pull/38104)
- fix(ci): give three unit shards a job deadline that outlasts their pytest budget by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38139](https://github.com/BerriAI/litellm/pull/38139)
- feat(ui): add Gemini Family auto-router preset by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38138](https://github.com/BerriAI/litellm/pull/38138)
- fix(logging\_worker): carry queued tasks across event-loop change instead of dropping them by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38144](https://github.com/BerriAI/litellm/pull/38144)
- feat(proxy): enforce vector-store upload security controls on /v1/rag/ingest by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38135](https://github.com/BerriAI/litellm/pull/38135)
- test(e2e): pin require\_managed\_files enforcement behind a marker-gated stack phase by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38117](https://github.com/BerriAI/litellm/pull/38117)
- refactor(ui): move the dashboard onto class-variance-authority by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38125](https://github.com/BerriAI/litellm/pull/38125)
- refactor(utils)!: delete prompt\_token\_calculator by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38132](https://github.com/BerriAI/litellm/pull/38132)
- fix(auto-router): list configured auto-routers in the usage picker before they have traffic by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38129](https://github.com/BerriAI/litellm/pull/38129)
- refactor(ui): install the shadcn field primitive by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38126](https://github.com/BerriAI/litellm/pull/38126)
- fix(complexity\_router): keep both ends of a clipped classifier context turn by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38141](https://github.com/BerriAI/litellm/pull/38141)
- fix(ci): ignore-list recursive form-field flatteners in recursive\_detector by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38149](https://github.com/BerriAI/litellm/pull/38149)
- fix(passthrough): stop leaking the caller's virtual key on credential-less Vertex passthrough by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38114](https://github.com/BerriAI/litellm/pull/38114)
- fix(router): stop copying forwarded credentials into retry breadcrumbs by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38133](https://github.com/BerriAI/litellm/pull/38133)
- feat(e2e): record and replay streamed provider responses chunk-for-chunk by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38136](https://github.com/BerriAI/litellm/pull/38136)
- fix: tolerate stream chunks without a choices key in stream\_chunk\_builder by [@&#8203;AkshaySasi](https://github.com/AkshaySasi) in [#&#8203;34382](https://github.com/BerriAI/litellm/pull/34382)
- fix(files): decode x-litellm-model encoded file\_id in chat + responses by [@&#8203;hclsys](https://github.com/hclsys) in [#&#8203;29832](https://github.com/BerriAI/litellm/pull/29832)
- fix(videos): forward uploaded source file on /v1/videos/edits to the provider by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38155](https://github.com/BerriAI/litellm/pull/38155)
- fix(s3\_v2): percent-encode object keys once so signed and sent URLs match by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38005](https://github.com/BerriAI/litellm/pull/38005)
- feat(ui): add error-code drilldown for failed requests on caching page by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38156](https://github.com/BerriAI/litellm/pull/38156)
- feat(search): add Grounding with Bing Search (bing\_grounding) as a search provider by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38119](https://github.com/BerriAI/litellm/pull/38119)
- ci: ban row-rewriting DML from prisma migrations by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;37899](https://github.com/BerriAI/litellm/pull/37899)
- fix(langsmith): keep root-run ids self-consistent so batch ingest stops rejecting header-tagged requests by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38116](https://github.com/BerriAI/litellm/pull/38116)
- ci(e2e): record the e2e suite weekly and replay it on weekdays with zero egress by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38163](https://github.com/BerriAI/litellm/pull/38163)
- chore(codeowners): unown ui container plumbing and generated files by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38124](https://github.com/BerriAI/litellm/pull/38124)
- fix(logging): skip parsing redacted tool call arguments by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38169](https://github.com/BerriAI/litellm/pull/38169)
- feat(complexity\_router): bound the classifier context block, not each turn in it by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38145](https://github.com/BerriAI/litellm/pull/38145)
- fix(http\_handler): dispose aiohttp session when AsyncHTTPHandler is finalized without a running loop by [@&#8203;anmolg1997](https://github.com/anmolg1997) in [#&#8203;36670](https://github.com/BerriAI/litellm/pull/36670)
- fix(proxy): reset a stuck team member's budget by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;37971](https://github.com/BerriAI/litellm/pull/37971)
- fix(anthropic/bedrock): request summarized adaptive thinking for reasoning\_effort and use provider thinking token counts by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37979](https://github.com/BerriAI/litellm/pull/37979)
- fix(completion\_extras): forward reasoning\_effort=max through the Responses API bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38222](https://github.com/BerriAI/litellm/pull/38222)
- feat(vertex\_ai): add native Vertex AI Interactions API support by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38229](https://github.com/BerriAI/litellm/pull/38229)
- test(mcp): drain the logging worker after each test so queued callbacks cannot leak into the next test by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38228](https://github.com/BerriAI/litellm/pull/38228)
- fix(ui): forward OAuth issuer/authorization/token/registration URLs from the MCP server edit form by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;38154](https://github.com/BerriAI/litellm/pull/38154)
- fix(together\_ai): default endpoints to api.together.ai instead of api.together.xyz by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38233](https://github.com/BerriAI/litellm/pull/38233)
- fix(bedrock\_mantle): register a Bedrock runtime passthrough config so /bedrock/model/<deployment>/invoke works by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38231](https://github.com/BerriAI/litellm/pull/38231)
- fix(router): resolve provider from api\_base in deployment validation and acompletion by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38235](https://github.com/BerriAI/litellm/pull/38235)
- fix(model\_prices): raise bedrock\_mantle gpt-5.6 max\_input\_tokens to Mantle's enforced [`1050000`](https://github.com/BerriAI/litellm/commit/1050000) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38225](https://github.com/BerriAI/litellm/pull/38225)
- fix(bedrock\_mantle): normalize Codex input item types Mantle rejects by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38227](https://github.com/BerriAI/litellm/pull/38227)
- fix(proxy): store the actual selected model in spend logs for Azure Model Router by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37770](https://github.com/BerriAI/litellm/pull/37770)
- feat(router): per-group supported reasoning efforts with the max level by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;37897](https://github.com/BerriAI/litellm/pull/37897)
- fix(proxy): stop expected 4xx responses from saturating worker CPU on failure logging by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38102](https://github.com/BerriAI/litellm/pull/38102)
- fix(caching): use upstream RedisCluster on redis-py with per-connection recovery by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38171](https://github.com/BerriAI/litellm/pull/38171)
- perf(auth): drop guaranteed-miss internal-cache Redis read from team object lookup by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38073](https://github.com/BerriAI/litellm/pull/38073)
- fix(together\_ai): route chat completions through a dedicated TogetherAIChatConfig by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38248](https://github.com/BerriAI/litellm/pull/38248)
- fix(ui): read reasoning tokens from Responses API output\_tokens\_details by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;37952](https://github.com/BerriAI/litellm/pull/37952)
- fix(dashboard): don't show a stale provider prompt-cache chip on a response-cache hit by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;37951](https://github.com/BerriAI/litellm/pull/37951)
- fix(ui): render tag-based guardrail mode instead of crashing the guardrails page by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37493](https://github.com/BerriAI/litellm/pull/37493)
- fix(scim): return user\_id as Group members\[].value on transformed group responses by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38161](https://github.com/BerriAI/litellm/pull/38161)
- fix(scim): preserve existing team memberships when POST /Users adoption carries no groups by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38166](https://github.com/BerriAI/litellm/pull/38166)
- fix(router): support mid-stream fallback for anthropic\_messages route type by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;38153](https://github.com/BerriAI/litellm/pull/38153)
- fix(auth): support wildcard prefixes in jwt team\_allowed\_routes by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37756](https://github.com/BerriAI/litellm/pull/37756)
- feat(models): add missing Together AI serverless models to the cost map by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38230](https://github.com/BerriAI/litellm/pull/38230)
- fix(cerebras)!: add max\_retries and extra\_headers to get\_supported\_openai\_params by [@&#8203;deepanshululla](https://github.com/deepanshululla) in [#&#8203;36601](https://github.com/BerriAI/litellm/pull/36601)
- fix(anthropic): translate tool\_result document blocks in the /v1/messages bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38251](https://github.com/BerriAI/litellm/pull/38251)
- fix(team): serialize member\_add, member\_delete, and delete under the team's advisory lock by [@&#8203;yassin-berriai](https://github.com/yassin-berriai) in [#&#8203;37969](https://github.com/BerriAI/litellm/pull/37969)
- docs(pr-template): split Caveats bullets into severity tiers and call for plain engineering language by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38252](https://github.com/BerriAI/litellm/pull/38252)
- fix(anthropic): carry tool\_result document blocks through the /v1/messages responses bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38261](https://github.com/BerriAI/litellm/pull/38261)
- fix(together\_ai): pass tools through for models missing from the registry by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38265](https://github.com/BerriAI/litellm/pull/38265)
- fix(anthropic): carry user-content document blocks through the /v1/messages responses bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38267](https://github.com/BerriAI/litellm/pull/38267)
- fix(rerank): emit latency and cost headers on /rerank by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;35419](https://github.com/BerriAI/litellm/pull/35419)
- perf(streaming): add shared JSONFragmentAccumulator for Vertex and Anthropic by [@&#8203;deepanshululla](https://github.com/deepanshululla) in [#&#8203;36610](https://github.com/BerriAI/litellm/pull/36610)
- fix(together\_ai): strip internal thinking fields from outbound messages, keep reasoning\_content by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38275](https://github.com/BerriAI/litellm/pull/38275)
- fix(router): persist attempted\_fallbacks and original\_model\_group into spend logs metadata by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38107](https://github.com/BerriAI/litellm/pull/38107)
- fix(logging): redact tool call arguments to valid JSON and preserve null content by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38182](https://github.com/BerriAI/litellm/pull/38182)
- fix(ui): stack policy flow builder below the popup layer so guardrail options render by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38273](https://github.com/BerriAI/litellm/pull/38273)
- test: gate the test tree on B003 so a test cannot swap os.environ for a plain dict by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38274](https://github.com/BerriAI/litellm/pull/38274)
- refactor(repositories): type prisma table access with one generic protocol by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38205](https://github.com/BerriAI/litellm/pull/38205)
- fix(anthropic): buffer streamed responses carrying server-fulfilled tools so retrieval tool calls never reach the client by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;36245](https://github.com/BerriAI/litellm/pull/36245)
- test(together\_ai): regression suite across chat, responses, and messages surfaces by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38283](https://github.com/BerriAI/litellm/pull/38283)
- feat(logging): add async\_post\_call\_failure\_deployment\_hook by [@&#8203;deepanshululla](https://github.com/deepanshululla) in [#&#8203;36657](https://github.com/BerriAI/litellm/pull/36657)
- chore: bump litellm-enterprise 0.1.59 -> 0.1.60, litellm 1.99.0 -> 1.100.0 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38243](https://github.com/BerriAI/litellm/pull/38243)
- test(e2e): cover Together AI reasoning, tool calls, template kwargs, and cost through a live proxy by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38286](https://github.com/BerriAI/litellm/pull/38286)
- fix(logging): keep tracebacks for provider-originated 4xx errors by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38296](https://github.com/BerriAI/litellm/pull/38296)
- chore(ci): promote internal staging to main by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38293](https://github.com/BerriAI/litellm/pull/38293)
- refactor(ui): install the shadcn alert primitive by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38300](https://github.com/BerriAI/litellm/pull/38300)
- refactor(ui): re-pull label, textarea, separator and skeleton from the registry by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38302](https://github.com/BerriAI/litellm/pull/38302)
- feat(prometheus): configure deployment caller identity by [@&#8203;mphilippnv](https://github.com/mphilippnv) in [#&#8203;38221](https://github.com/BerriAI/litellm/pull/38221)
- test(e2e): let the Together replayed-reasoning case survive a single provider miss by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38314](https://github.com/BerriAI/litellm/pull/38314)
- fix(otel): map /v1/messages provider errors before failure logging by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38310](https://github.com/BerriAI/litellm/pull/38310)
- fix(exceptions): map upstream status codes for providers with no exception\_type branch by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38318](https://github.com/BerriAI/litellm/pull/38318)
- fix(passthrough): record ownership of streamed responses under managed ids by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38320](https://github.com/BerriAI/litellm/pull/38320)
- fix(proxy): encrypt streamed responses ids on /openai/v1/responses and /responses aliases by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38325](https://github.com/BerriAI/litellm/pull/38325)
- test(cost-calc): pin the rate fallbacks inside a tiered-pricing tier by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38327](https://github.com/BerriAI/litellm/pull/38327)
- test(e2e): cover the Bedrock provider-feature cells customers run by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38232](https://github.com/BerriAI/litellm/pull/38232)
- fix(together\_ai): fail open on response\_format instead of dropping it for unregistered models by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38269](https://github.com/BerriAI/litellm/pull/38269)
- fix(proxy): honor DATABASE\_DISABLE\_PREPARED\_STATEMENTS in componentized entrypoints by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38363](https://github.com/BerriAI/litellm/pull/38363)
- fix(anthropic-responses): preserve structured output strictness by [@&#8203;eugene-yao-zocdoc](https://github.com/eugene-yao-zocdoc) in [#&#8203;38211](https://github.com/BerriAI/litellm/pull/38211)
- chore(typing): roll up the daily tech debt cleanups from Aug 20 to Aug 26 by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37922](https://github.com/BerriAI/litellm/pull/37922)
- fix(router): resolve hidden aliases for explicit lookup by [@&#8203;daniel-meismer-zocdoc](https://github.com/daniel-meismer-zocdoc) in [#&#8203;38272](https://github.com/BerriAI/litellm/pull/38272)
- fix(ui): keep focus in the add model public name input while typing by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38366](https://github.com/BerriAI/litellm/pull/38366)
- fix(model\_prices): price 1-hour cache writes on claude-3-haiku and claude-3-opus at 2x input by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38371](https://github.com/BerriAI/litellm/pull/38371)
- fix(proxy): keep the caller's Google token on credential-less Vertex passthrough under custom auth by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38299](https://github.com/BerriAI/litellm/pull/38299)
- fix(mcp): preserve provider access token lifetime by [@&#8203;daniel-meismer-zocdoc](https://github.com/daniel-meismer-zocdoc) in [#&#8203;38271](https://github.com/BerriAI/litellm/pull/38271)
- chore(ui): remove stale "New" badges from the dashboard by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38374](https://github.com/BerriAI/litellm/pull/38374)
- test(cost-estimate): pin the prices and period totals /cost/estimate returns by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38315](https://github.com/BerriAI/litellm/pull/38315)
- fix(ci): let the mutation workflow find covered lines so it generates mutants by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38305](https://github.com/BerriAI/litellm/pull/38305)
- fix(model\_prices): raise bedrock\_mantle gpt-5.5 and gpt-5.4 max\_input\_tokens to Mantle's enforced [`1050000`](https://github.com/BerriAI/litellm/commit/1050000) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38368](https://github.com/BerriAI/litellm/pull/38368)
- fix(azure/realtime): authenticate realtime websocket with Azure AD token when no api-key by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;34658](https://github.com/BerriAI/litellm/pull/34658)
- fix(bedrock): map reasoning\_effort to reasoning.effort for OpenAI GPT-5.x on Converse by [@&#8203;6matt](https://github.com/6matt) in [#&#8203;38279](https://github.com/BerriAI/litellm/pull/38279)
- test(prometheus): cover caller-identity config failure cases by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38380](https://github.com/BerriAI/litellm/pull/38380)
- fix(redis): support credential providers across clients by [@&#8203;eugene-yao-zocdoc](https://github.com/eugene-yao-zocdoc) in [#&#8203;38094](https://github.com/BerriAI/litellm/pull/38094)
- fix(health): support `mode: image_edit` in health checks by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38291](https://github.com/BerriAI/litellm/pull/38291)
- fix(cost-map): add US data residency uplift to claude-sonnet-4-6 and mythos entries by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38369](https://github.com/BerriAI/litellm/pull/38369)
- fix(anthropic): raise missing-credential error on /v1/messages passthrough by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38240](https://github.com/BerriAI/litellm/pull/38240)
- fix(mcp): complete DCR bridge OAuth challenges by [@&#8203;daniel-meismer-zocdoc](https://github.com/daniel-meismer-zocdoc) in [#&#8203;37384](https://github.com/BerriAI/litellm/pull/37384)
- test(proxy): pin the request-validation contracts in proxy/\_types.py by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38307](https://github.com/BerriAI/litellm/pull/38307)
- docs(CLAUDE.md): add pull-before-work rule by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38386](https://github.com/BerriAI/litellm/pull/38386)
- fix(anthropic): scale cache costs by fast mode and trust served speed by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38378](https://github.com/BerriAI/litellm/pull/38378)
- fix(pricing): add azure gpt-5.6 cache write rates and correct data zone priority by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38370](https://github.com/BerriAI/litellm/pull/38370)
- docs: tighten the pull-before-work rule in CLAUDE.md by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38389](https://github.com/BerriAI/litellm/pull/38389)
- fix(health): strip credential fields from GET /health output by [@&#8203;Siraj637909](https://github.com/Siraj637909) in [#&#8203;37090](https://github.com/BerriAI/litellm/pull/37090)
- fix(minimax): attach MINIMAX\_API\_KEY on anthropic messages requests by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38393](https://github.com/BerriAI/litellm/pull/38393)
- refactor(ui): replace hand-picked z-index values with one named scale and lint it by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38282](https://github.com/BerriAI/litellm/pull/38282)
- fix(health): probe Azure GA realtime path for transcription-only models by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38390](https://github.com/BerriAI/litellm/pull/38390)
- fix(bedrock): parse cacheDetails for Converse 1h/5m cache write cost split by [@&#8203;danielva-monday](https://github.com/danielva-monday) in [#&#8203;36762](https://github.com/BerriAI/litellm/pull/36762)
- fix(caching): flush async cache writes cancelled at event loop shutdown by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38385](https://github.com/BerriAI/litellm/pull/38385)
- fix(router): resolve model\_group\_alias before pre-routing strategy dispatch by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38382](https://github.com/BerriAI/litellm/pull/38382)
- feat(proxy): enforce rpm/tpm on model add + fix validation error title in UI by [@&#8203;kunal2002](https://github.com/kunal2002) in [#&#8203;36518](https://github.com/BerriAI/litellm/pull/36518)
- refactor(ui): move every page header onto the shared PageHeader by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38306](https://github.com/BerriAI/litellm/pull/38306)
- fix(proxy): stop cache eviction errors from failing /key/update by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38308](https://github.com/BerriAI/litellm/pull/38308)
- fix(aiohttp): honor global ssl\_verify on the aiohttp\_openai handler path by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38400](https://github.com/BerriAI/litellm/pull/38400)
- fix(logging\_worker): rescue dequeued logging tasks lost at event loop close by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38394](https://github.com/BerriAI/litellm/pull/38394)
- fix(caching): require the namespace delimiter when checking already-namespaced redis keys by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38403](https://github.com/BerriAI/litellm/pull/38403)
- fix(prompts): reject keyed prompt\_data with prompt\_id and populate prompt version by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38404](https://github.com/BerriAI/litellm/pull/38404)
- fix(cost\_calculator): resolve real cost key when model\_name alias contains '/' by [@&#8203;ksk2023](https://github.com/ksk2023) in [#&#8203;38344](https://github.com/BerriAI/litellm/pull/38344)
- fix(cost-map): correct prompt\_cache\_min\_tokens for Claude Fable 5 and backfill Anthropic re-export entries by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38405](https://github.com/BerriAI/litellm/pull/38405)
- test(azure-ai): pin the 422 retry that drops the field the provider rejected by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38309](https://github.com/BerriAI/litellm/pull/38309)
- refactor(ui): read the auto-router tier set through one row list by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38408](https://github.com/BerriAI/litellm/pull/38408)
- fix(proxy): stop empty DB router\_settings lists from clobbering yaml fallbacks by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38406](https://github.com/BerriAI/litellm/pull/38406)
- fix(team): allow no-reset default budgets for team members by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37708](https://github.com/BerriAI/litellm/pull/37708)
- fix: forward image content lists to DeepSeek vision models by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38397](https://github.com/BerriAI/litellm/pull/38397)
- fix(fireworks\_ai): stop using the trace id as the session affinity key by [@&#8203;Hamjaster](https://github.com/Hamjaster) in [#&#8203;35754](https://github.com/BerriAI/litellm/pull/35754)
- fix(gemini-realtime): keep the client's voice on Vertex AI native-audio Live by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38395](https://github.com/BerriAI/litellm/pull/38395)
- fix(vertex\_ai): bill Gemini grounding per unique web search query by [@&#8203;ousamabenyounes](https://github.com/ousamabenyounes) in [#&#8203;36397](https://github.com/BerriAI/litellm/pull/36397)
- fix(health): make the image\_edit health probe moderation-safe by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38417](https://github.com/BerriAI/litellm/pull/38417)
- test: gate the test tree on fifteen assertion and handler rules it already satisfies by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38361](https://github.com/BerriAI/litellm/pull/38361)
- fix(proxy): key lazy openapi stubs off registered features, not sys.modules by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38416](https://github.com/BerriAI/litellm/pull/38416)
- fix(proxy): derive auto-router health from its underlying models by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38174](https://github.com/BerriAI/litellm/pull/38174)
- fix(responses): let cache-control injection reach the system prompt from instructions by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38120](https://github.com/BerriAI/litellm/pull/38120)
- fix(gemini): bill Google Maps grounding as its own SKU by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38418](https://github.com/BerriAI/litellm/pull/38418)
- fix(speech): keep proxy metadata and completion cost through the TTS completion bridge by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38414](https://github.com/BerriAI/litellm/pull/38414)
- fix: map Gemini ON\_DEMAND\_FLEX traffic type to flex service tier by [@&#8203;bisma-nawaz](https://github.com/bisma-nawaz) in [#&#8203;37724](https://github.com/BerriAI/litellm/pull/37724)
- feat(langfuse): support langfuse\_environment as a per-key dynamic callback param by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38264](https://github.com/BerriAI/litellm/pull/38264)
- feat(proxy): hide unhealthy models from model listings, opt-in by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38313](https://github.com/BerriAI/litellm/pull/38313)
- fix(mcp): honor admin-entered OAuth URLs on authorize after issuer yield by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38379](https://github.com/BerriAI/litellm/pull/38379)
- fix(model\_prices): correct gemini-3.5-flash-lite flex cache-read pricing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38422](https://github.com/BerriAI/litellm/pull/38422)
- fix(cost): price gemini-live-2.5-flash-native-audio realtime sessions by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38419](https://github.com/BerriAI/litellm/pull/38419)
- fix(cost-map): correct Gemini TTS and native-audio rates by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38412](https://github.com/BerriAI/litellm/pull/38412)
- fix(prompts): propagate PATCHed prompt templates to every worker and pod by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38411](https://github.com/BerriAI/litellm/pull/38411)
- fix(model\_prices): bill gemini -latest/preview alias cache reads at 10% of input by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38423](https://github.com/BerriAI/litellm/pull/38423)
- fix(proxy): sync search tools into the router on management writes by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38392](https://github.com/BerriAI/litellm/pull/38392)
- feat(guardrails): track Azure Prompt Shield usage and cost with spend isolation by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38387](https://github.com/BerriAI/litellm/pull/38387)
- fix(prompts): apply prompt templates before routing on /v1/responses and honor ignore\_prompt\_manager\_model by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38407](https://github.com/BerriAI/litellm/pull/38407)
- fix(cost): make cost-breakdown headers respect service tier by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38424](https://github.com/BerriAI/litellm/pull/38424)
- fix(mcp): add litellm\[mcp] extra and actionable error when streamable\_http\_client is missing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38399](https://github.com/BerriAI/litellm/pull/38399)
- revert(proxy): remove router\_model\_name from auto-routed response bodies by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38429](https://github.com/BerriAI/litellm/pull/38429)
- fix(google\_genai): price streamed generateContent with the provider that served it by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;36055](https://github.com/BerriAI/litellm/pull/36055)
- fix(logging): stop billing and logging response reads as LLM calls by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;36890](https://github.com/BerriAI/litellm/pull/36890)
- fix(budget): serialize model\_max\_budget before the /budget/update write by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38430](https://github.com/BerriAI/litellm/pull/38430)
- fix(ui): block the auto-router submit on a missing classifier model and an orphaned keyword rule by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38427](https://github.com/BerriAI/litellm/pull/38427)
- feat(complexity\_router): heuristic-first classifier chaining by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38428](https://github.com/BerriAI/litellm/pull/38428)
- test(e2e): un-skip the per-model budget update case by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38437](https://github.com/BerriAI/litellm/pull/38437)
- fix(cost): stop double-billing cached tokens that overlap a modality by [@&#8203;Srivatsa03](https://github.com/Srivatsa03) in [#&#8203;37407](https://github.com/BerriAI/litellm/pull/37407)
- feat(ui): add Teams list CSV export with budgets, model grants, and rate limits by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38436](https://github.com/BerriAI/litellm/pull/38436)
- fix(mcp): accept raw x-litellm-api-key on streamable HTTP admission by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38364](https://github.com/BerriAI/litellm/pull/38364)
- fix: bound row count on GET /spend/logs to stop unbounded LiteLLM\_SpendLogs scans by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38420](https://github.com/BerriAI/litellm/pull/38420)
- fix(scim): apply default\_team\_params (incl. models) to SCIM-created teams by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38433](https://github.com/BerriAI/litellm/pull/38433)
- fix(prompts): propagate prompt deletes to every worker and pod by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38434](https://github.com/BerriAI/litellm/pull/38434)
- fix(anthropic\_adapter): carry web search cost into /v1/messages breakdown headers by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38439](https://github.com/BerriAI/litellm/pull/38439)
- fix(ui): show custom technical keywords on every router whose scorer runs by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38451](https://github.com/BerriAI/litellm/pull/38451)
- fix(e2e): move the vertex realtime suite off the retired Live preview model by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38454](https://github.com/BerriAI/litellm/pull/38454)
- feat(newrelic): per-team cost and usage metrics via team callbacks by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;37610](https://github.com/BerriAI/litellm/pull/37610)
- fix(ui): carry a preset's per-tier litellm\_params through the prefill by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38453](https://github.com/BerriAI/litellm/pull/38453)
- fix(e2e): size the mid-conversation-system cache prefix above the minimum deterministically by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38468](https://github.com/BerriAI/litellm/pull/38468)
- fix(e2e): disable thinking on the gemini chat cost test instead of racing its budget by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38469](https://github.com/BerriAI/litellm/pull/38469)
- feat(ui): put the auto-router savings hero on a spend rail and a four-tile row by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38470](https://github.com/BerriAI/litellm/pull/38470)
- feat(ui): toggle internal health check visibility in request logs by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38391](https://github.com/BerriAI/litellm/pull/38391)
- fix(mcp): canonicalize bearer scheme on bridge egress by [@&#8203;daniel-meismer-zocdoc](https://github.com/daniel-meismer-zocdoc) in [#&#8203;38398](https://github.com/BerriAI/litellm/pull/38398)
- refactor: clean up fresh tech debt from 2026-08-27 window by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38484](https://github.com/BerriAI/litellm/pull/38484)
- fix(exception\_mapping\_utils): map unmapped exceptions when model and provider are unset by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38496](https://github.com/BerriAI/litellm/pull/38496)
- fix(ui\_sso): resolve highest privilege Entra app role, not first in claim by [@&#8203;imranismail](https://github.com/imranismail) in [#&#8203;36728](https://github.com/BerriAI/litellm/pull/36728)
- fix(proxy): regenerate lazy OpenAPI snapshot and guard it in CI by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38410](https://github.com/BerriAI/litellm/pull/38410)
- feat(ui): add cache hit/miss filter to Request Logs by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38432](https://github.com/BerriAI/litellm/pull/38432)
- fix(bedrock): sign rerank requests with the shared header-filtered SigV4 helper (internal copy of [#&#8203;36462](https://github.com/BerriAI/litellm/issues/36462)) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38093](https://github.com/BerriAI/litellm/pull/38093)
- fix(bedrock): sign rerank requests with the shared, header-filtered SigV4 helper by [@&#8203;noahnistler](https://github.com/noahnistler) in [#&#8203;36462](https://github.com/BerriAI/litellm/pull/36462)
- fix(ui): order the auto-routers table newest first so a new router lands on page one by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38545](https://github.com/BerriAI/litellm/pull/38545)
- feat(ui): run the Anthropic Family preset's reasoning tier on Opus 5 at high thinking by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38490](https://github.com/BerriAI/litellm/pull/38490)
- build(ui): bump nginx to 1.31-alpine by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38541](https://github.com/BerriAI/litellm/pull/38541)
- feat(otel): support per-team/per-key service.name for OTel v2 destinations by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38532](https://github.com/BerriAI/litellm/pull/38532)
- test(e2e): de-flake the cost-header cache read and the router fallback control by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38435](https://github.com/BerriAI/litellm/pull/38435)
- feat(gemini): day-0 support for gemini-3.5-transcribe and transcribe-live by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38540](https://github.com/BerriAI/litellm/pull/38540)
- feat(health): opt-in model-group allowlist for background health checks and health-check routing by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38539](https://github.com/BerriAI/litellm/pull/38539)
- fix(mcp): keep upstream OAuth Authorization when jwt signer hook injects one on tools/call by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38555](https://github.com/BerriAI/litellm/pull/38555)
- fix: suppress misleading register\_model unresolved-cost warnings for entries without custom pricing by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38542](https://github.com/BerriAI/litellm/pull/38542)
- feat(proxy): opt-in budget rollover carrying overage into the next window by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38514](https://github.com/BerriAI/litellm/pull/38514)
- fix(auth): skip guaranteed-miss team lookup for the litellm-dashboard sentinel by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38471](https://github.com/BerriAI/litellm/pull/38471)
- fix(key\_management): allow /key/update to keep or shrink MCP server grants the key already holds by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38463](https://github.com/BerriAI/litellm/pull/38463)
- fix: keep schema reconciliation from fighting a partitioned LiteLLM\_SpendLogs by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38452](https://github.com/BerriAI/litellm/pull/38452)
- fix(ui): open select popups below the trigger instead of over it by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38554](https://github.com/BerriAI/litellm/pull/38554)
- fix(realtime): bill trailing audio when a Gemini transcribe Live session closes by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38563](https://github.com/BerriAI/litellm/pull/38563)
- test(e2e): cover key generate and update on the Admin UI path by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38448](https://github.com/BerriAI/litellm/pull/38448)
- chore: bump litellm-enterprise 0.1.60 -> 0.1.61, litellm-proxy-extras 0.4.89 -> 0.4.90 by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38566](https://github.com/BerriAI/litellm/pull/38566)
- fix(ui): let the paginated search select keep what the user types by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38475](https://github.com/BerriAI/litellm/pull/38475)
- fix(otel): anchor MCP tool-call spans to the gateway's own trace, link the client's context by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38317](https://github.com/BerriAI/litellm/pull/38317)
- fix: roll up the open deflake fixes for the MCP logging queue, PTU rollup, license gate, and pricing test isolation by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;37833](https://github.com/BerriAI/litellm/pull/37833)
- fix(model\_prices): rolling registry audit - verified models and rates for Novita, DeepInfra, W\&B, Bedrock Sol, Gemini, Fireworks, Azure gpt-5.6, Mistral, Together by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38207](https://github.com/BerriAI/litellm/pull/38207)
- test(together\_ai): assert fail-open supported params for models missing from the registry by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38487](https://github.com/BerriAI/litellm/pull/38487)
- test(e2e): let the together tool tests accept parallel calls by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38567](https://github.com/BerriAI/litellm/pull/38567)
- feat(mcp): let a resolved OAuth token target a custom upstream header by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38456](https://github.com/BerriAI/litellm/pull/38456)
- feat(together\_ai): map reasoning\_effort per model class by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38263](https://github.com/BerriAI/litellm/pull/38263)
- feat(dashscope): support qwen-image-3.0 and qwen-image-3.0-pro image generation by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38449](https://github.com/BerriAI/litellm/pull/38449)
- fix(cost): apply Together AI cache read pricing and per-model registry rates by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38280](https://github.com/BerriAI/litellm/pull/38280)
- fix(guardrails): forward aws\_external\_id when the bedrock guardrail assumes a role by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38376](https://github.com/BerriAI/litellm/pull/38376)
- fix(transcription): synthesize srt/vtt output for adapters without native subtitle formats by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38561](https://github.com/BerriAI/litellm/pull/38561)
- fix(streaming): preserve provider service-tier metadata so Vertex flex streams bill at flex rates by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38458](https://github.com/BerriAI/litellm/pull/38458)
- fix(realtime): bill Gemini Live native-audio output tokens at the audio rate by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38457](https://github.com/BerriAI/litellm/pull/38457)
- fix(anthropic): carry tool\_reference tool results through the guardrail translation round trip by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38465](https://github.com/BerriAI/litellm/pull/38465)
- fix(anthropic-adapter): pass provider-native and OpenAI-format tools through on /v1/messages by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38431](https://github.com/BerriAI/litellm/pull/38431)
- test(e2e): serve the vision image from our own fixture by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38575](https://github.com/BerriAI/litellm/pull/38575)
- feat(together\_ai): add zai-org/GLM-5.3-Flash to the model registry by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38486](https://github.com/BerriAI/litellm/pull/38486)
- fix(ui): stop server-searched comboboxes from clobbering picks and queries by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38574](https://github.com/BerriAI/litellm/pull/38574)
- feat(model\_prices): let a map entry declare its exact reasoning\_effort levels by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38481](https://github.com/BerriAI/litellm/pull/38481)
- fix(anthropic): carry the adaptive effort tier to every bridged Claude target by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38533](https://github.com/BerriAI/litellm/pull/38533)
- feat(alerting): add native Microsoft Teams alerting destination by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38367](https://github.com/BerriAI/litellm/pull/38367)
- chore(proxy): resync the generated API artifacts with the current models by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38587](https://github.com/BerriAI/litellm/pull/38587)
- fix(router): reject complexity-router settings written outside complexity\_router\_config by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38570](https://github.com/BerriAI/litellm/pull/38570)
- feat(ui): session-level cache observability in request logs by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38442](https://github.com/BerriAI/litellm/pull/38442)
- fix(ui): link Virtual Keys hint through the migrated /ui route by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38596](https://github.com/BerriAI/litellm/pull/38596)
- fix(anthropic): carry the effort tier only where the target declares reasoning\_effort by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38592](https://github.com/BerriAI/litellm/pull/38592)
- fix(presidio): chunk oversized text before /analyze so large content blocks do not fail by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38483](https://github.com/BerriAI/litellm/pull/38483)
- fix(logging): stop stream-based log collectors classifying INFO logs as errors by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38476](https://github.com/BerriAI/litellm/pull/38476)
- feat(ui): dry-run an auto-router config against the backend before saving it by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38595](https://github.com/BerriAI/litellm/pull/38595)
- fix(guardrails): add fail-open mode to CrowdStrike AIDR guardrail by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38568](https://github.com/BerriAI/litellm/pull/38568)
- fix(router): copy instead of mutating caller metadata when scrubbing fallback stamp keys by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38586](https://github.com/BerriAI/litellm/pull/38586)
- feat(proxy): opt-in enforce\_fallback\_model\_access authorizes router fallbacks against the calling key by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38572](https://github.com/BerriAI/litellm/pull/38572)
- fix(langfuse): warn and drop invalid LANGFUSE\_TRACING\_ENVIRONMENT instead of failing requests by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38582](https://github.com/BerriAI/litellm/pull/38582)
- fix(tencent): route thinking through extra\_body in chat completions by [@&#8203;FelipeRodriguesGare](https://github.com/FelipeRodriguesGare) in [#&#8203;38100](https://github.com/BerriAI/litellm/pull/38100)
- test-check-commits by [@&#8203;nickhac](https://github.com/nickhac) in [#&#8203;36344](https://github.com/BerriAI/litellm/pull/36344)
- feat(proxy): dry-run a real request body on /auto\_router/test\_routing by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38590](https://github.com/BerriAI/litellm/pull/38590)
- fix(shadow\_eval): refuse a judge model that also serves one of the arms it grades by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38589](https://github.com/BerriAI/litellm/pull/38589)
- fix(anthropic): resolve /v1/messages effort tiers through the capability owner by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38492](https://github.com/BerriAI/litellm/pull/38492)
- fix(router): fall over on raised mid-stream errors in /v1/messages streams by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38606](https://github.com/BerriAI/litellm/pull/38606)
- feat(models): add daily Together AI model registry sync script and workflow by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38257](https://github.com/BerriAI/litellm/pull/38257)
- feat(ui): the model and wire layer for operator-defined auto-router tier sets by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38602](https://github.com/BerriAI/litellm/pull/38602)
- fix(moonshot, together\_ai): send the reasoning effort Kimi K3 accepts by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38611](https://github.com/BerriAI/litellm/pull/38611)
- fix(ui): one-click theme toggle and matching Docs/Blog styling in the top bar by [@&#8203;ryan-crabbe-berri](https://github.com/ryan-crabbe-berri) in [#&#8203;38601](https://github.com/BerriAI/litellm/pull/38601)
- feat(proxy): opt-in flags to require rpm/tpm on model and project create by [@&#8203;ansh-agrawal](https://github.com/ansh-agrawal) in [#&#8203;36514](https://github.com/BerriAI/litellm/pull/36514)
- fix(exceptions): keep a refused connection an APIConnectionError by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38624](https://github.com/BerriAI/litellm/pull/38624)
- chore(ci): promote internal staging to main by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38616](https://github.com/BerriAI/litellm/pull/38616)
- fix(anthropic): drop and self-heal empty thinking blocks on /v1/messages by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38625](https://github.com/BerriAI/litellm/pull/38625)
- fix(anthropic): handle per-level reasoning\_effort flags without supports\_reasoning by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38618](https://github.com/BerriAI/litellm/pull/38618)
- fix(complexity\_router): route client housekeeping calls to the cheapest tier by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38598](https://github.com/BerriAI/litellm/pull/38598)
- test: fix staging CI regressions from [#&#8203;38182](https://github.com/BerriAI/litellm/issues/38182), [#&#8203;38144](https://github.com/BerriAI/litellm/issues/38144), [#&#8203;38265](https://github.com/BerriAI/litellm/issues/38265), [#&#8203;37962](https://github.com/BerriAI/litellm/issues/37962), and [#&#8203;37969](https://github.com/BerriAI/litellm/issues/37969) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38304](https://github.com/BerriAI/litellm/pull/38304)
- feat(spend): report prompt caching savings as total and gateway-attributed by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38134](https://github.com/BerriAI/litellm/pull/38134)
- fix(proxy): let llm\_api virtual keys read /model\_group/info by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38662](https://github.com/BerriAI/litellm/pull/38662)
- feat(ui): edit the auto-router tier set with custom classifier-defined tiers by [@&#8203;tin-berri](https://github.com/tin-berri) in [#&#8203;38603](https://github.com/BerriAI/litellm/pull/38603)
- fix(proxy): count tools, system, and Anthropic image and document blocks in the count\_tokens fallback (internal copy of [#&#8203;36671](https://github.com/BerriAI/litellm/issues/36671)) by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38657](https://github.com/BerriAI/litellm/pull/38657)
- test: refresh the suites that drifted from langfuse and OpenAI's retired Assistants API by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38637](https://github.com/BerriAI/litellm/pull/38637)
- test(e2e): unskip four tests whose blockers no longer hold by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38640](https://github.com/BerriAI/litellm/pull/38640)
- feat(proxy): add paginated GET /public/v1/model\_hub by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38636](https://github.com/BerriAI/litellm/pull/38636)
- refactor(ui): type search tool params from the generated schema by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38633](https://github.com/BerriAI/litellm/pull/38633)
- feat(a2a): semantic search over the agent registry via GET /v1/agents?query and an agent\_search MCP tool by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38609](https://github.com/BerriAI/litellm/pull/38609)
- fix(model\_prices): add bedrock\_mantle gpt-5.5/5.4 272K tiers, align sol with AWS invoice by [@&#8203;mateo-berri](https://github.com/mateo-berri) in [#&#8203;38615](https://github.com/BerriAI/litellm/pull/38615)
- fix(ui): keep the usage filter visible when the caller's scope is empty by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38581](https://github.com/BerriAI/litellm/pull/38581)
- fix(registry): add Gemini Omni 1.1 Flash, xAI grok-imagine image models, Mistral cache-read pricing, GLM 5.3 Flash + Kimi K2.7 Code entries by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38560](https://github.com/BerriAI/litellm/pull/38560)
- fix(logging): preserve null end user in callbacks by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38642](https://github.com/BerriAI/litellm/pull/38642)
- test: close mutation-testing gaps in container, skills and openai-like config factories by [@&#8203;yuneng-berri](https://github.com/yuneng-berri) in [#&#8203;38677](https://github.com/BerriAI/litellm/pull/38677)
- fix: enforce MCP toolsets attached to a team, org, or internal user by [@&#8203;yucheng-berri](https://github.com/yucheng-berri) in [#&#8203;38488](https://github.com/BerriAI/litellm/pull/38488)
- fix(tests): drain the global logging worker in RAG aquery billing tests by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38653](https://github.com/BerriAI/litellm/pull/38653)
- chore(techdebt): type new signatures and drop slop comments from the last 24h by [@&#8203;devin-ai-integration](https://github.com/devin-ai-integration)\[bot] in [#&#8203;38644](https://github.com/Be…
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