Commit graph

14053 commits

Author SHA1 Message Date
Yuneng Jiang
f7cd90f09e
refactor(auth): bind UI/CLI session tokens to their own AES-GCM context
Backport of BerriAI/litellm-private#5 (12981f93d3) onto stable/1.100.x, applied as
the PR's net diff so main-only intermediate refactors stay out.

The dashboard and lite CLI SSO specs under tests/e2e/ui/oidc are left out
because this line has no OIDC e2e harness to run them.
2026-09-29 15:17:24 -07:00
ryan-crabbe-berri
6b103ed064
fix(reset_budget_job): reset end users by budget link, not by user id (#40639)
Adapted for stable/1.100.x: added Final to the test module's typing import; upstream's test file already imported it.

(cherry picked from commit 8a4fae0e17)
2026-09-24 20:39:00 -07:00
amasen02
bc9712f045
fix(proxy): invalidate end-user spend counter and cache on budget reset (#39726)
Adapted for stable/1.100.x: reflowed one generator to this line's ruff format (upstream reformatted it in a later style commit).

Signed-off-by: amasen02 <amasen02@users.noreply.github.com>
(cherry picked from commit daced81f20)
2026-09-24 20:39:00 -07:00
Mateo Wang
b68fcee3ca
fix: treat gpt-6 names as the gpt-5 request family in OpenAI and Azure configs (#39631)
Adapted for stable/1.100.x: import-context conflict only (upstream's neighbouring custom_tools import is not on this line); the added and removed lines are identical to upstream.

(cherry picked from commit 025a3ca42f)
2026-09-24 20:38:59 -07:00
Mateo Wang
9c1216a427
Merge pull request #42597 from BerriAI/litellm_cherrypick_1_100_x
feat(typesafe): backport #41607 to stable/1.100.x for v1.100.2
2026-09-22 20:01:40 -07:00
mateo-berri
1ebc488f07 feat(typesafe): add TypeSafe Jev passthrough with logging and cost tracking
Backport of #41607 to stable/1.100.x.
Cherry-picked from deb9d8aedd (main).

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 21:34:24 +00:00
kerry
4438739b46 fix(test): run the all-beta-headers bedrock cases on Claude Fable 5.1
Backport of #42048 to stable/1.100.x.
Cherry-picked from 7966f50c34 (main). The safeguards backport maps the dangerous-tool-use-2026-09-03 beta for Bedrock, which Claude Opus 4.5 on Bedrock Invoke rejects as an invalid beta flag, so the all-beta-headers Bedrock cases run on Claude Fable 5.1 as they do on main.
2026-09-22 12:55:12 -07:00
mateo-berri
8ccfd6a84e chore(types): keep the backported safeguards annotations within the line's budgets
The picked TypedDict fields use read-only Sequence[Mapping[str, object]] annotations and the picked Vertex test carries a test-quality-ok marker, so stable/1.100.x's LIT001, LIT012 and TQ008 budgets hold. Static typing only, no runtime change.
2026-09-22 11:42:39 -07:00
mateo-berri
eb23cee8ff test: add the local_beta_headers_config fixture the safeguards tests use
Hand-ported to stable/1.100.x from 47b2479c94 on main (fix(bedrock): gate Invoke tool search on the model map's supports_tool_search flag), the one prerequisite the #42288 handler tests need; the rest of that commit stays on main.
2026-09-22 10:38:07 -07:00
mateo-berri
0d95fba73c fix(anthropic): forward Claude Code safeguards and dangerous-tool-use beta to Bedrock Invoke and Vertex on /v1/messages
Backport of #42288 to stable/1.100.x.
Cherry-picked from merge commit fc82f6e8fa (litellm_safeguards_bedrock_vertex_messages).
The line has no bedrock_mantle beta-header mapping and no Mantle /v1/messages route, so the Mantle mapping, its test file, and the bedrock_mantle test parameter are left out.
2026-09-22 10:16:54 -07:00
Yassin Kortam
3469a82da8 fix(anthropic): forward safeguards and anthropic-beta unchanged on native /v1/messages
Backport of #42152 to stable/1.100.x.
Cherry-picked from merge commit e912ebe999 (litellm_claude_code_safeguards_passthrough).
2026-09-22 10:16:25 -07:00
mateo-berri
5545ca9e86 fix(bedrock): match any openai.gpt-<digit> model in the Converse reasoning gate
Backports the Converse part of fbc6fb56ae from main (PR #31884). The gate only matched
openai.gpt-5, so a GPT-6 model fell through to Anthropic's thinking block and Bedrock
rejected the first real turn after a Claude Code /model switch with 400 Unknown
parameter: 'thinking'. The Nova 2 tool_choice registry keys and the invoke json_mode
forwarding in that commit stay on main
2026-09-19 12:43:58 -07:00
mateo-berri
fff43dfc05 fix(bedrock): clamp maxTokens to the 16-token minimum for OpenAI GPT and xAI Grok models on Converse (#41870)
Backport of #41870 to stable/1.100.x. Cherry-picked from a6e3a72ed8 (main) with -m 1.

converse_transformation.py conflicted because this line has no `import re` and no
_is_openai_gpt_reasoning_model helper next to the insertion point. The resolution adds
exactly the four hunks #41870 merged: the import, the 16-token constant,
_requires_min_max_tokens, and the clamped maxTokens assignment. The test file applied clean.
2026-09-19 12:11:50 -07:00
mateo-berri
40f4fa2629 test(responses): import import_module in the error-events tests 2026-09-15 01:41:17 -07:00
mateo-berri
2e3a7f689d fix(responses): keep context-window events out of mid-stream fallback and fix stale exception assertions
(cherry picked from commit fff7a2cecf)
2026-09-15 01:16:38 -07:00
mateo-berri
2e44af6d20 fix(responses): import BaseLLMException lazily and collect stream chunks via anext
Move the BaseLLMException import into _map_error_event_exception so the
module no longer imports it at load time, clearing the module-level cyclic
import CodeQL flagged. The class is used only on the cold error path.

Replace the mutable list-append test collector with aiter/anext so the
regression tests read the stream immutably.

(cherry picked from commit c246372859)
2026-09-15 01:16:38 -07:00
mateo-berri
80b2c803bd fix(responses): route mid-stream error events through exception_type so content_policy_fallbacks fire
Mid-stream error events on the streaming Responses API were all raised as
APIError, so a content_policy_violation event never matched the router's
content-policy fallback dispatch and the client got the raw error instead
of the fallback model's answer. Map each error event's code and status
through the existing exception_type mapping, matching the non-streaming
path, and unwrap the typed ContentPolicyViolationError and
ContextWindowExceededError so the router routes them to the configured
content_policy_fallbacks and context_window_fallbacks.

(cherry picked from commit 073d4fe2b0)
2026-09-15 01:16:38 -07:00
mateo-berri
dec2c2a72a Revert "fix(spend-tracking): keep batch spend keys joinable after v1.99 provenance gate (#39568)"
This reverts commit 803e0f736e.
2026-09-09 16:58:47 -07:00
mateo-berri
d7198f48c0 Revert "fix(spend-tracking): keep internal service-account key names readable in spend logs (#39572)"
This reverts commit c2e18a4320.
2026-09-09 16:58:46 -07:00
mateo-berri
a9ea5713ab test(router): type the breadcrumb test helpers 2026-09-09 14:01:38 -07:00
mateo-berri
76b5fec1c5 fix(router): keep retry breadcrumbs per request and out of the request snapshot
Backport of #39491 to stable/1.100.x. Cherry-picked from 7bc2d0b06e (litellm_internal_staging), with the router hunk of 7c87451ead.
2026-09-09 13:21:09 -07:00
mateo-berri
c2e18a4320 fix(spend-tracking): keep internal service-account key names readable in spend logs (#39572)
Backport of #39572 to stable/1.100.x.
Cherry-picked from merge commit da09976c16 (litellm_internal_staging) with -m 1.
2026-09-07 16:00:13 -07:00
Mateo Wang
803e0f736e fix(spend-tracking): keep batch spend keys joinable after v1.99 provenance gate (#39568)
Backport of #39568 to stable/1.100.x.
Cherry-picked from merge commit 04a198e3e3 (litellm_internal_staging) with -m 1.
2026-09-07 16:00:01 -07:00
yuneng-jiang
6b33d17563
Merge pull request #38850 from BerriAI/litellm_e2e_retry_transient_upstream
test(e2e): retry upstream-saturation failures in the claude CLI driver
2026-08-29 17:48:04 -07:00
yuneng-jiang
df848d85ff
Merge pull request #38833 from BerriAI/litellm_deflake_reliability_fallbacks
test(e2e): stop the reliability fallback tests flaking on gpt-5.5's reasoning budget
2026-08-29 17:44:30 -07:00
yucheng-berri
3c2fa5fafb
fix(otel/v2): detach credential-routed tenant spans into their own trace (#38847)
* fix(otel/v2): detach credential-routed tenant spans into their own trace

Multi-tenant OTel v2 routes a team or key's LLM-call span to that tenant's
own vendor account (New Relic, Arize, Langfuse, Weave) via dynamic OTLP
credential headers, while the request-root, auth, and db spans stay on the
operator's default backend. The span was still parented into the request
trace, so the tenant account received a child whose parent it never got,
and New Relic rendered it as a fragmented trace with a missing parent.

Detach a credential-routed span the same way a project-routed (Phoenix)
span already detaches: root a fresh trace in the tenant account and link
back to the request trace for correlation. Service-name routing keeps
parenting, since it only relabels service.name on the same operator
backend where the parent is present.

Guard the detach on the callback actually owning an OTLP exporter the
credentials can reach: a callback owning only a console or in_memory
exporter has nowhere to stamp them, so the span would export to the
default backend unchanged and detaching would orphan it on the very
backend that holds its parent. In that case warn once and keep the
default tracer.

* fix(otel/v2): derive tenant-route routability from resolved exporter transport

A denylist classified an owned exporter as routable whenever its kind was
not console/in_memory, so a typo'd or unavailable kind (e.g. "otlp",
"grcp") passed the check while _exporter_from_spec falls it back to a
header-ignoring console exporter. Detaching such a span would root a fresh
trace that only ever reaches the operator console, never the tenant
backend, orphaning it on both sides.

Route on a shared exporter_transport() predicate that resolves the kind the
same way _exporter_from_spec builds it (registered factories + otlp_http
aliases -> http, otlp_grpc aliases -> grpc, else headerless), so an
unresolvable kind is headerless and stays parented. Fixes the same latent
gap in project routability.
2026-08-29 17:41:25 -07:00
ryan-crabbe-berri
9da0b30888
Merge pull request #38843 from BerriAI/litellm_mag_budget_ui
feat(ui): set a model access group's shared budget from the dashboard
2026-08-29 17:27:17 -07:00
Mateo Wang
ff2f06e37f
Merge pull request #38444 from BerriAI/litellm_mcp_connector_bulk_import
feat(mcp): bulk-import Anthropic MCP connectors via API and admin UI
2026-08-29 17:21:57 -07:00
Yuneng Jiang
bda2917273
test(e2e): retry upstream-saturation failures in the claude CLI driver
The driver retries rate-limit-shaped failures twice with a 65s backoff, but
RATE_LIMIT_SHAPED_RE only matches 429 / rate limit / too many requests /
throttled / CLI timeout. A saturated provider does not always say any of
those: litellm-e2e-pr build 182 turned a green cell red on

  status 503: litellm.ServiceUnavailableError: BedrockException -
  {"message":"Bedrock is unable to process your request."}

which matched nothing and so was never retried.

Add TRANSIENT_UPSTREAM_SHAPED_RE for 503, 529, "service unavailable",
"overloaded" and Bedrock's "unable to process your request", and have the
retry loop ask is_retryable_shaped (either shape) instead of
is_rate_limit_shaped.

Kept as a second pattern rather than widened into the first on purpose. The
conftest feeds RATE_LIMIT_SHAPED_RE into the rate-limit summary, which the
binary-search helper reads to decide whether to lower a provider's request
rate. A 503 says the provider is out of capacity, not that we are asking too
often, so folding it in there would keep ratcheting our rate down against a
condition our rate never caused.

Retry-loop logging now names which shape fired, so a saturated upstream is
distinguishable from a throttled one in the run output.

Verified against the literal failure text from build 182: is_retryable_shaped
is True while is_rate_limit_shaped stays False.

Note this covers CLI-driven rows only. HTTP-probe rows (tool_search,
count_tokens) have no retry layer at all, so the specific cell that failed in
build 182 is still unprotected -- that is a separate change to http_probe.
2026-08-29 17:13:10 -07:00
yucheng-berri
842c423ccd
fix(guardrails): stop Lakera monitor mode forwarding unmasked PII on Responses-API bodies (#38841)
#34940 widened the mask-in-place safety guard so a Responses-API
`instructions` field (and a combined messages+input body) skips the
PII masking branch. With `on_flagged: "monitor"` that fell straight
through to "allow", so PII that used to be masked now reaches the
model unredacted.

Monitor means "don't block", not "don't redact". Recover the one shape
whose payload is still fully writable: mask it and write the redacted
instructions back into `data["instructions"]` directly, since
apply_redacted_messages_back has no path for that field and would
otherwise fold the instructions text into `data["input"]`.

The combined messages+input and multimodal shapes stay unmasked - both
are unsafe to write back, not merely unwritable - and now log an error
naming the reason instead of passing silently.

No block/allow decision changes: block and inject_system_message keep
the exact outcomes #34940 shipped.
2026-08-29 17:07:39 -07:00
ryan-crabbe-berri
e257383cc6
Merge pull request #38249 from BerriAI/litellm_fix_empty_user_models_visibility
fix(proxy): list all non-team models for users with an empty model list
2026-08-29 17:04:28 -07:00
ryan-crabbe-berri
6f8a3b8661 fix(proxy): scope model listing direct access to the calling key's grant
Direct access on /model/info was read from the user record alone, so an
unrestricted user calling with a key limited to a few models saw every non-team
deployment, including ones the key gets a 403 on. Resolve the key's grant the
same way and intersect the two.

Resolving a grant now also expands access groups, which the key path needs and
the user path was missing.

Claude-Session: https://claude.ai/code/session_01XL7LBFEew4wi8gphVCDq6n
2026-08-29 16:54:02 -07:00
Mateo Wang
2a79a81b46
Merge pull request #38837 from BerriAI/litellm_fix_azure_responses_anyof_tool_schema
fix(azure): flatten top-level tool schema combinators for Azure Responses GPT-4-family deployments
2026-08-29 16:46:22 -07:00
Mateo Wang
1f5e76155b
Merge pull request #38836 from BerriAI/litellm_fix_messages_effort_budget_cap
fix(anthropic): cap reasoning_effort thinking budget below max_tokens on /v1/messages
2026-08-29 16:45:18 -07:00
Mateo Wang
ecd42ea77a
Merge pull request #38792 from BerriAI/litellm_fix_responses_anyof_tool_schema
fix(openai): flatten top-level anyOf/oneOf/allOf in Responses API tool schemas
2026-08-29 16:45:11 -07:00
Mateo Wang
42d8360f29
Merge pull request #38820 from BerriAI/litellm_fix_together_sync_output_ceiling
fix(together_ai): stop writing context_length as max_output_tokens in the serverless sync
2026-08-29 16:44:56 -07:00
ryan-crabbe-berri
2ffd3d0e7d
Merge pull request #35887 from BerriAI/litellm_window_spend_reader
perf(proxy): read budget-window spend from the maintained window table
2026-08-29 16:44:53 -07:00
Mateo Wang
a979c89b88
Merge pull request #38804 from BerriAI/litellm_registry_audit_rolling_38693
fix(models): registry audit: new Together/Fireworks/Gemini/Mistral/xAI models, xai retirement repricing, bedrock grok-4.6 caching, deprecation dates
2026-08-29 16:44:45 -07:00
ryan-crabbe-berri
f82708f41d Merge branch 'litellm_window_spend_writer' into litellm_window_spend_reader 2026-08-29 16:36:09 -07:00
ryan-crabbe-berri
ce96db5a61 test(proxy): pass the window spend args in the access group requeue test 2026-08-29 16:36:04 -07:00
ryan-crabbe-berri
0777e37849 feat(ui): set a model access group's shared budget from the dashboard
Model access group budgets shipped API-only, so the only way to give a group a
budget was a curl. Adds an Access Group Budgets tab under Models & Endpoints
that lists every group with the spend drawn against its shared pool, and a
modal to set, edit or clear the budget.

/access_group/list now carries each group's budget and spend inline, so the
table renders from one read instead of one follow-up request per row.
2026-08-29 16:32:28 -07:00
mateo-berri
36c036cd2d test(reasoning-effort-grid): expect capped thinking on messages-route budget models 2026-08-29 16:28:49 -07:00
ryan-crabbe-berri
3cc2f615da Merge branch 'litellm_window_spend_writer' into litellm_window_spend_reader 2026-08-29 16:24:07 -07:00
yuneng-jiang
e4ae1c1f2e
Merge pull request #38835 from BerriAI/litellm_38816_classifier_cost_savings
fix(proxy): count auto-router classifier cost in savings and benchmarks
2026-08-29 16:23:50 -07:00
ryan-crabbe-berri
140950f52d Merge branch 'litellm_window_spend_schema' into litellm_window_spend_writer 2026-08-29 16:23:45 -07:00
mateo-berri
af186eaaf3 fix(azure): flatten top-level tool schema combinators for Azure Responses GPT-4-family deployments 2026-08-29 16:23:01 -07:00
Mateo Wang
0c8321efc3
Merge pull request #38741 from BerriAI/litellm_fix_anthropic_messages_dict_detail_error
fix(anthropic_endpoints): serialize dict-detail HTTPExceptions on /v1/messages like sibling surfaces
2026-08-29 16:20:08 -07:00
Mateo Wang
6bc8dafa99
Merge pull request #38740 from BerriAI/litellm_vertex_gemini_35_transcribe
feat(vertex_ai): support gemini-3.5-transcribe on /v1/audio/transcriptions
2026-08-29 16:19:56 -07:00
Yuneng Jiang
fd4b540a44
test(e2e): require spent completion tokens before accepting empty fallback content
The first pass accepted any empty completion whose finish_reason was "length",
which also swallowed a fallback that produced nothing at all. Require the
response to have billed completion tokens as well, so empty content is
accepted only when the budget was demonstrably spent on non-visible reasoning.

Asserts on completion_tokens rather than reasoning_tokens because the latter
is provider-optional; with empty content and a refusal of null, consumed
completion tokens are reasoning by elimination, since visible text would be
content. Both counts are reported in the failure message.

Folds the three body accessors onto one _parsed helper instead of re-parsing
per call, and adds completion_tokens_of / reasoning_tokens_of alongside.
2026-08-29 16:19:41 -07:00
Tin Chi Lo
d3db7cebca fix(proxy): count auto-router classifier cost in savings and benchmarks
The LLM classifier's cost was recorded on the routing decision but never
reached any savings surface: per-request autorouter_savings stayed gross
and the session rollup recorded only the served request's spend, so
/auto_router/benchmarks overstated savings and understated routed spend.

Net the classifier cost into the savings figure at its one computation
owner and fold it into the rollup turn's spend, keeping
baseline_spend = spend + saved_spend. The response header's numeric
guard now shares the same reader.

Fixes #38816
2026-08-29 16:09:35 -07:00