Commit graph

43876 commits

Author SHA1 Message Date
mateo-berri
d59135b5ea Merge branch 'litellm_internal_staging' into litellm_remove_types_ruff_exclusion
Import-block conflicts against #35962's unused-import removals resolve
to this branch's side: its modernization already removed every typing
import staging trimmed, plus the usages
2026-08-05 11:10:34 -07:00
mateo-berri
ebc31f7e06 fix(caching): clear strict-lint budget breaches in re-landed closer code 2026-08-05 11:08:19 -07:00
Mateo Wang
c19896029a
Merge pull request #35964 from BerriAI/revert-35929-litellm_zero_dashboard_eslint_headroom
chore(ui): don't zero out stale headroom except no-console
2026-08-05 11:06:16 -07:00
mateo-berri
1a693a3014 fix(types): resolve the four type-discipline additions surfaced by the staging merge 2026-08-05 11:05:53 -07:00
mateo-berri
51c54b56ac Merge branch 'litellm_internal_staging' into litellm_remove_types_ruff_exclusion
Resolve litellm/types/google_genai/main.py and litellm/types/utils.py by
keeping this branch's modernized annotations on top of staging's removal
of inert type: ignore comments. Rebuild ruff-strict-budget.json from
measured merged-tree counts where de-excluding litellm/types adds
violations, keeping the stricter of the two sides' limits everywhere
else so no rule gains headroom. Fix the four type-discipline additions
the merge surfaced: freeze GEMINI_1_5_ACCEPTED_FILE_TYPES, drop a
callback_args parameter rebind in guardrails, and give the two remaining
mutations reasoned suppressions
2026-08-05 11:05:33 -07:00
Mateo Wang
45ed654603
Merge pull request #35962 from BerriAI/litellm_fix_basedpyright_over_limits
fix(lint): bring basedpyright rule counts back under their budget limits
2026-08-05 11:03:53 -07:00
mateo-berri
8b874263e2 fix(passthrough): walk scalar request bodies through managed-id rewrite again
The top-level dispatch in rewrite_body_ids only handled dict and list
bodies, so a truthy scalar JSON body (bare string, number, bool) hit
dict.items() and raised AttributeError where the merge base passed it
through, and a bare managed-ID string body lost resolution. Restore the
base behavior by dispatching through _walk, widen the implementation to
object with a catch-all overload, and pin both paths with regression
tests
2026-08-05 11:02:07 -07:00
Mateo Wang
85aad29885
chore: make no-console max 12 2026-08-05 10:45:56 -07:00
Mateo Wang
64f83a23e1
Revert "chore(ui): zero stale headroom on local dashboard eslint budgets" 2026-08-05 10:44:02 -07:00
mateo-berri
469d5126f6 fix(lint): bring basedpyright rule counts back under their budget limits 2026-08-05 10:23:02 -07:00
mateo-berri
824608c42b Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_reland_evicted_client_closer
# Conflicts:
#	litellm/llms/azure/common_utils.py
2026-08-05 10:16:37 -07:00
Yassin Kortam
0659738b3e
fix(migrations): recover from an interrupted Prisma toolchain install (#35832)
The Prisma CLI is a Node program that installs a private Node runtime on its
first invocation. That one-time install shared the 60s budget that bounds each
migration command, so on a slow or cold machine it was killed before it could
finish. Prisma then decides whether to reinstall by testing the cache
directory for existence alone, and a killed install leaves that directory
behind, so every later attempt skipped the install and failed on a node binary
that was never written. The existing four-attempt retry loop could not help:
each attempt hit the same missing binary, which turned a slow start into a
container that never migrated again.

Migrations now prepare the toolchain as its own step under its own budget, and
a cache directory that exists without a node binary is deleted first so an
interrupted install reinstalls instead of persisting. Both budgets are
overridable, LITELLM_PRISMA_BOOTSTRAP_TIMEOUT for the install and
LITELLM_PRISMA_COMMAND_TIMEOUT for each Prisma command, and every previously
hardcoded timeout now goes through one helper rather than thirteen literals.
The per-command default stays at 60s.

An override is only honoured when it parses as a finite positive number.
Infinity and NaN parse as floats and survive a plain positivity check, and
subprocess treats either as no deadline at all, so a value like `inf` or a
fat-fingered `1e400` would have silently disabled the timeout it was meant to
configure.
2026-08-05 10:14:46 -07:00
Yassin Kortam
54fb717de1
fix(router): redact fallback tracebacks at the call site and cover the sync deferred stream (#35843)
Three follow-ups surfaced while merging current staging into this branch.

`exc_info=True` at both fallback-failure log sites handed a live exception to
the logging machinery. SecretRedactionFilter rewrites `record.exc_text`, but
`record.exc_info` stays an exception object no filter can reach, so a handler
that renders it itself (Datadog and OTel log bridges do) received the
unredacted provider key. Both sites now pass `redact_string(traceback.format_exc())`
as a `%s` arg, keeping staging's lazy-logging form. The existing test only
asserted on `exc_text`, so it passed under the bug; it now renders `exc_info`
the way a bridge handler would and covers every record the call emits.

The eager deferred-stream fetch existed only on the async path. Vertex and
Bedrock build the same `completion_stream=None` plus `make_call` wrapper on
their sync branches, so `Router.completion(stream=True)` still surfaced the
provider error on first iteration, outside `_completion`'s except block, and
never reached the fallback chain. `_completion` now calls `fetch_sync_stream()`
under the same guard `_acompletion` uses.

The first of the three header-strip passes in the proxy error path was dead:
only the custom-header update and the response-headers hook run before the
second pass re-filters everything. Collapsed to one `safe_headers` binding.
2026-08-05 10:06:52 -07:00
Mateo Wang
8fe9809a4b
Merge pull request #35365 from rimysore/fix-managed-files-null-object
fix(managed-files): skip rows without file objects
2026-08-05 10:01:42 -07:00
Mateo Wang
520e38e232
Merge pull request #35929 from BerriAI/litellm_zero_dashboard_eslint_headroom
chore(ui): zero stale headroom on local dashboard eslint budgets
2026-08-05 09:47:16 -07:00
Mateo Wang
0b8c7f29ed
Merge pull request #35927 from BerriAI/litellm_zero_more_local_basedpyright_rules
chore(lint): zero out seven more purely local basedpyright rules
2026-08-05 09:46:21 -07:00
Mateo Wang
551f395dbf
Merge pull request #35928 from BerriAI/litellm_zero_ruff_lit_headroom
chore(lint): zero stale ruff and LIT headroom and strip inert type: ignore comments
2026-08-05 09:46:05 -07:00
Abhimanyu Kapur
cc1c7d6101
feat(complexity_router): let operators rename the four complexity tiers (#35893)
* feat(complexity_router): let operators rename the four complexity tiers

Adds an optional tier_labels map to complexity_router_config so a deployment can
put its own vocabulary on the four tiers, e.g. Cheap / Standard / Premium / Deep,
instead of reading SIMPLE / MEDIUM / COMPLEX / REASONING in its dashboard, its
spend logs, and the rubric the LLM classifier reasons with.

Labels are display-only. Every config key stays canonical, so tiers,
keyword_tier_rules[].tier, and tier_boundaries are written exactly as they are
without labels, and partial maps are fine with unlisted tiers keeping their
default name. A validator rejects blank labels, two tiers sharing a label, and a
label that is another tier's canonical name, since any of those would make a log
row or a rubric line ambiguous. That validator runs on the /model/new and
/model/update write path already, so an ambiguous config gets a 400 rather than
being stored for the router to refuse later.

Under the default heuristic scorer the names are cosmetic: the scorer maps a
weighted score to a rung and never reads a tier name, verified by running the
eval corpus with and without a rename and getting identical tier and identical
score on all 29 cases. Under classifier_type: llm the labels are the names in the
rubric and the values the classifier must return, so the response format's enum
is now built from the configured labels and a reply is resolved back to its tier
against labels first, then canonical names, case-insensitively. An unresolvable
reply degrades to the heuristic on the existing fallback path. A test pins the
generated schema for an unrenamed deployment as equal to the shipped
TierClassification schema, so the wire shape can't drift.

Spend logs keep routing_decision.tier canonical so rows from before and after a
rename stay comparable, and gain routing_decision.tier_label on the tiers that
were renamed.

* refactor(complexity_router): drop added comments and the Counter construction

Review feedback: the repository guide bans new comments, so the explanatory
comments and the appended docstring paragraphs this branch added come back out.
One-line docstrings stay in complexity_router.py, matching that file's own
convention.

The duplicate-label check no longer builds a Counter, which the mutable-collection
budget counts, and the error text drops its list() reprs for joined strings. The
labels are stripped in tier_label() now rather than by rewriting the field in the
validator, so the stored config keeps exactly what the operator wrote.

schema.d.ts is regenerated: ComplexityRouterConfig is exposed in the OpenAPI spec,
so tier_labels surfaces there.

* fix(ui): carry tier_labels through the auto-router preset prefill

buildPresetPrefill maps every payload key onto form state, but the tier_labels
key added by this branch had no line, so a preset shipping labels would apply
its tiers and silently drop its names.
2026-08-05 09:42:57 -07:00
Mateo Wang
7900e1fc79
Merge pull request #35251 from BerriAI/litellm_fix_codecov_oidc_flake 2026-08-05 09:26:43 -07:00
milan
8f1f738b1d merge: litellm_internal_staging into litellm_vertex_batch_embeddings_translation
Some checks failed
Terraform Provider / gofmt, vet, build, test (push) Has been cancelled
Terraform Provider / Provider endpoints vs proxy OpenAPI schema (push) Has been cancelled
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-05 12:59:33 +00:00
mateo-berri
f270b53144 Merge branch 'litellm_internal_staging' into fix-managed-files-null-object 2026-08-05 03:05:32 -07:00
mateo-berri
20d297a151 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_zero_ruff_lit_headroom
# Conflicts:
#	litellm/llms/anthropic/experimental_pass_through/responses_adapters/streaming_iterator.py
2026-08-05 02:53:06 -07:00
Mateo Wang
b735578822
Merge pull request #35367 from rimysore/fix-responses-batch-usage
fix(batches): account for Responses API usage
2026-08-05 02:51:35 -07:00
mateo-berri
66373eb25f fix(types): log AdapterCompletionStreamWrapper errors lazily 2026-08-05 02:49:35 -07:00
mateo-berri
83008a916d Merge remote-tracking branch 'origin/litellm_internal_staging' into fix-responses-batch-usage
# Conflicts:
#	litellm/batches/batch_utils.py
2026-08-05 02:38:02 -07:00
mateo-berri
338e411103 chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
Mateo Wang
64f4bedde1
Merge pull request #34957 from BerriAI/litellm_gpt56_cache_token_pricing
fix(cost): bill gpt-5.6 prompt cache reads at the cache read rate
2026-08-05 02:30:41 -07:00
Mateo Wang
71f7fad16a
Merge pull request #34812 from BerriAI/litellm_fix_openai_cache_token_details_loss
fix(cost_tracking): keep OpenAI prompt cache token details through usage reassembly
2026-08-05 02:21:49 -07:00
mateo-berri
0c50661307 chore(lint): re-tighten reportPrivateUsage and reportDeprecated to post-merge counts 2026-08-05 02:15:42 -07:00
mateo-berri
d4611a1253 Merge origin/litellm_internal_staging 2026-08-05 02:12:38 -07:00
mateo-berri
69a8043667 chore: keep base field ordering for service tier cache write costs 2026-08-05 02:11:05 -07:00
mateo-berri
a9902fcdb5 fix(streaming): carry Anthropic cache-creation TTL split through fallback usage reassembly 2026-08-05 02:06:52 -07:00
mateo-berri
e8a80b9883 docs(anthropic): state why usage-shape detection requires a cache key, pin Responses-shape rejection 2026-08-05 02:01:53 -07:00
mateo-berri
bd04520d98 Merge branch 'litellm_internal_staging' into litellm_gpt56_cache_token_pricing 2026-08-05 01:51:07 -07:00
mateo-berri
b4b5c8f0a1 chore(ui): zero stale headroom on local dashboard eslint budgets 2026-08-05 01:45:02 -07:00
mateo-berri
cdfefd7f41 chore(lint): zero stale headroom on purely local ruff and LIT rules 2026-08-05 01:40:30 -07:00
mateo-berri
021b52527b chore(lint): zero out seven more purely local basedpyright rules 2026-08-05 01:31:09 -07:00
mateo-berri
74f1b934be chore(ui): format CacheLeakageCard with prettier 2026-08-05 01:23:54 -07:00
mateo-berri
7288247682 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_fix_openai_cache_token_details_loss
# Conflicts:
#	litellm/litellm_core_utils/llm_cost_calc/utils.py
#	litellm/litellm_core_utils/streaming_chunk_builder_utils.py
#	litellm/litellm_core_utils/streaming_handler.py
#	tests/test_litellm/litellm_core_utils/test_streaming_chunk_builder_utils.py
2026-08-05 01:23:54 -07:00
mateo-berri
4e32a8bf6a chore(lint): remove litellm/types from the ruff lint exclusion
ruff.toml has excluded litellm/types/* since 2024, so no lint rule ever ran
on the types tree. Remove the exclusion, apply ruff --fix and ruff format
across litellm/types, and hand-fix what autofix cannot reach so the
pyupgrade budgets stay at zero: implicit type aliases converted to PEP 604
unions, RootModel[Union[...]] bases, duplicate imports, and a stray print.

Load-bearing import X as X re-exports deleted by preview-mode F401 are
restored, and the six star-imported hub modules keep their re-export
surface via per-file F401 ignores. Star-import consumers that silently
relied on typing names leaking from those hubs are modernized to builtin
generics and PEP 604 unions.

Runtime annotation introspection that only recognized typing.Union is
taught types.UnionType (guardrail UI field schemas, volcengine response
fill), with regression tests for both. Strict budget limits for the rules
the types tree now trips are raised to exact measured totals, so any
net-new violation still fails the gate
2026-08-05 01:10:15 -07:00
ayaangazali
95bc890fcf fix(azure_ai): strip non-spec message fields on a copy, not the caller's messages 2026-08-05 00:23:54 -07:00
ayaangazali
db061d6e31 fix(azure_ai): strip non-OpenAI-spec message fields before request 2026-08-05 00:23:54 -07:00
Shivi Jain
9dbe61aa6d feat(proxy): add project-level ITPM and OTPM quotas
Add model_itpm_limit and model_otpm_limit to project create and update requests, storing both quota maps in project metadata without a database migration

Reserve input and output tokens independently before provider dispatch, expose separate project rate-limit headers, and reconcile counters across successful calls, failures, retries, fallbacks, streaming, caching, and cancellation

Harden token estimation for pre-tokenized embeddings, multimodal inputs, Responses API requests, native Gemini requests, multiple candidates, and conflicting output-cap aliases

Reject negative output caps, preserve conservative reservations when usage is missing or zero, bind reconciliation and refunds to the reservation window, prevent double refunds or negative counters, update generated API types, and add regression coverage
2026-08-05 12:53:22 +05:30
mateo-berri
e0833c4ba3 fix(cost): bill reasoning tokens at the service tier output rate
A tier request against a model that publishes tier output pricing but no
tier reasoning key (every current Gemini flash entry) billed reasoning
tokens at the standard output_cost_per_reasoning_token, undercounting
priority and fast traffic where thinking tokens dominate completions

generic_cost_per_token now resolves the reasoning rate with explicit
precedence: an explicit output_cost_per_reasoning_token_<tier> key wins,
then the tier-resolved output rate when the model prices that tier, then
the standard reasoning key, then the output base cost. The two tier
reasoning keys are wired through ModelInfo so providers can publish real
tiered reasoning prices when they exist
2026-08-05 00:15:52 -07:00
mateo-berri
629c228b40 fix(pricing): sync flex/priority tier keys to dated OpenAI snapshot variants
Dated snapshots like o4-mini-2025-04-16 were missing the flex and priority cost keys their base alias carries, so service-tier requests against pinned snapshots were billed at standard rates. Sync the tier keys wherever the snapshot's anchor prices match the base alias, and add a drift regression test.
2026-08-04 23:56:52 -07:00
Mateo Wang
732bba00df
Merge pull request #35862 from BerriAI/litellm_self_heal_evicted_httpx_clients
fix(http_handler): self-heal handler clients closed after cache eviction
2026-08-04 23:55:53 -07:00
mateo-berri
5d7bfbc950 refactor(proxy): tighten pass-through credential type annotations 2026-08-04 23:12:31 -07:00
mateo-berri
1fefd80925 fix(proxy): resolve pass-through credentials live from router deployments 2026-08-04 23:01:37 -07:00
mateo-berri
c11ea9694a Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_self_heal_evicted_httpx_clients 2026-08-04 22:52:06 -07:00
mateo-berri
34f87a1a91 fix(async_client_cleanup): stop cleanup from resurrecting healed clients 2026-08-04 22:43:40 -07:00