Commit graph

11712 commits

Author SHA1 Message Date
Devin AI
1c9c6b61e0 fix(spend_tracking): record the selected deployment on failed request spend logs 2026-08-07 10:32:03 +00:00
Mateo Wang
b66d4e6965
Merge pull request #35137 from BerriAI/litellm_fix_responses_cost_router_35131
fix(proxy): fetch background responses through the router in CheckResponsesCost
2026-08-06 03:26:36 -07:00
Mateo Wang
972c0d0b04
Merge pull request #35140 from BerriAI/litellm_fix_file_content_placeholder_cost
fix(cost): stop token-pricing the placeholder input on file content calls
2026-08-06 03:04:36 -07:00
Mateo Wang
729bec69f5
Merge pull request #36014 from BerriAI/litellm_scan_only_tool_results
feat(guardrails): add scan_only_tool_results to scope unified guardrails to tool results
2026-08-06 02:17:29 -07:00
mateo-berri
14d4897e55 fix(guardrails): refuse scan_only_tool_results combos that scan nothing
Prompt Security drops tool and function rows unless check_tool_results
is on, so it now reports scan-only support from that setting and the
registry refuses the pairing at boot. Pairing scan_only_tool_results
with skip_tool_message_in_guardrail excludes every message, so guardrail
initialization now rejects that combination too.
2026-08-06 01:58:06 -07:00
mateo-berri
28ff7f3f0b fix(guardrails): scan function-role results and dedupe returned tools
Under scan_only_tool_results, legacy OpenAI function-role messages now count as tool results, and duplicate names among guardrail-returned tools keep only the first occurrence. CustomGuardrail.structured_messages_cover_full_request lets CrowdStrike AIDR declare that its writeback already rebuilds the whole conversation, so handlers install it as-is instead of merging it into the full message list a second time and duplicating out-of-scope rows. Lint budget ceilings ratchet down to match the tree
2026-08-06 00:52:16 -07:00
mateo-berri
0b24a9ab05 merge: litellm_internal_staging into litellm_fix_file_content_placeholder_cost 2026-08-06 00:09:27 -07:00
mateo-berri
7d745521bf fix(guardrails): merge synthesized tools under scan_only_tool_results and reject role-filtered no-op combos at init 2026-08-05 23:46:40 -07:00
mateo-berri
e0c4c7cee0 Merge branch 'litellm_internal_staging' into bugfix/managed-batch-cost-not-logged 2026-08-05 23:42:18 -07:00
Devin AI
55c392bda1 merge litellm_internal_staging 2026-08-06 06:15:17 +00:00
mateo-berri
4f7d1fce3a fix(proxy): fall back to the SDK when a queued response's deployment is missing 2026-08-05 23:13:15 -07:00
Mateo Wang
0acca3e86a
Merge pull request #24548 from mpcusack-altos/fix/bedrock-batch-credential-fields
fix(router): include Bedrock batch/S3 fields and model in deployment credentials
2026-08-05 22:39:39 -07:00
tin-berri
86890654c5
fix(proxy): include today's UTC bucket when a daily activity range ends at the caller's current day (#36051)
* fix(proxy): include today's UTC bucket when a daily activity range ends at the caller's current day

* fix(proxy): gate the current-UTC-day extension behind an opt-in param sent by the cost optimization dashboard

* fix(ui): label cost optimization savings dates as UTC days
2026-08-05 22:33:54 -07:00
Michael Cusack
3d275d97fe fix(router): return model and Bedrock batch fields in deployment credentials
get_deployment_credentials_with_provider dropped s3_region_name,
s3_encryption_key_id, and aws_batch_role_arn because
CredentialLiteLLMParams never declared them, and it never returned the
deployment's model, so proxy batch creation against Bedrock failed with
"LiteLLM doesn't support custom_llm_provider=bedrock for 'create_batch'"
or "AWS IAM role ARN is required" (#25104)

Provider-only file and batch calls keep their no-model contract:
get_team_provider_credentials strips the model key so a provider-scoped
request is not pinned to an arbitrary matching deployment
2026-08-05 21:49:31 -07:00
Mateo Wang
ba91768146
Merge pull request #35925 from BerriAI/litellm_tier_aware_reasoning_token_cost
fix(cost): bill reasoning tokens at the service tier output rate
2026-08-05 21:09:55 -07:00
Mateo Wang
b45b4b7300
Merge pull request #35923 from BerriAI/litellm_dated_variant_tier_pricing_sync
fix(pricing): sync flex/priority tier keys to dated OpenAI snapshot variants
2026-08-05 21:09:37 -07:00
tin-berri
7c621b3141
fix(auto-router): accept every reminder marker pair a harness emits (#36029)
* fix(auto-router): accept every reminder marker pair a harness emits

reminder_markers held one (open, close) pair, so a harness that wraps
injected context differently per agent type only got the slice of traffic
using the configured envelope stripped. Every other agent type kept hitting
the original bug: its reminder-only turn never stripped to empty, won
"newest human ask", and the harness blob got classified in place of the
real question, choosing the tier and therefore the spend.

The field now takes a list of ReminderMarkerPair, following the
KeywordTierRule pattern already in this file so each pair validates itself
and errors point at reminder_markers.N.close rather than a bare index.

Blocks from different pairs can nest, which the gap construction could not
handle: resuming the kept text at an inner block's end walks back inside
the enclosing block and leaks its remainder. Running the block ends through
a maximum collapses nested and overlapping spans without a separate merge
pass, and stays linear in block count, which a fold over a growing tuple
of merged spans would not.

A single pair's ends already increase, so the maximum is the identity and
the default path is byte-identical: verified against the shipped function
over 200k generated inputs, and every existing reminder test passes
unchanged. The prior single-pair config shape is rejected loudly at
startup and at /model/new rather than silently stripping nothing.

* docs(auto-router): document reminder_markers in the complexity router README

* chore(ui): regenerate dashboard API types for the reminder_markers shape

---------

Co-authored-by: Abhimanyu Kapur <38531241+akapur99@users.noreply.github.com>
2026-08-05 21:03:36 -07:00
devin-ai-integration[bot]
0bae9708a7
fix(arize_phoenix): lowercase OTLP/gRPC auth metadata key (#34883) 2026-08-05 20:57:50 -07:00
mateo-berri
c2998dea75 fix(guardrails): guard tools write-back under scan_only_tool_results and warn on role-filtered no-op scans 2026-08-05 20:49:15 -07:00
mateo-berri
1b30b1bc20 Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_tier_aware_reasoning_token_cost
# Conflicts:
#	litellm/types/utils.py
2026-08-05 20:45:34 -07:00
Mateo Wang
d26ef670e2
Merge pull request #36031 from BerriAI/litellm_b13_unscoped_files_list
fix(managed_files): return unified ids from unscoped file listing
2026-08-05 20:11:15 -07:00
mateo-berri
4b9872e7e8 fix(managed_files): return unified ids from unscoped file listing 2026-08-05 19:53:44 -07:00
Mateo Wang
b617e672e3
Merge pull request #36024 from BerriAI/litellm_anthropic_sse_keepalive
fix(proxy): send keepalive pings on anthropic messages SSE streams during upstream silence
2026-08-05 19:41:35 -07:00
mateo-berri
2434c1b904 Merge origin/litellm_internal_staging into litellm_deterministic_output_file_ids 2026-08-05 19:04:27 -07:00
mateo-berri
3c808f9c8f Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_scan_only_tool_results 2026-08-05 18:55:43 -07:00
mateo-berri
00cbebf503 fix(managed_files): source the unified input file id from the response so retrieve-time mints converge with the cost job 2026-08-05 18:33:20 -07:00
mateo-berri
d70e10982a fix(guardrails): keep tool-results-only scans off function definitions and merge scoped write-backs
Gate the OpenAI handler's tools forwarding behind scan_only_tool_results,
matching the Anthropic handler, so a tool-results-only scan can no longer
evaluate or rewrite trusted function definitions.

When a guardrail returns a replacement structured_messages list, substitute
the returned messages back into the positions their scoped originals came
from instead of installing the scoped list as the whole conversation, so
out-of-scope messages (system prompt, prior turns) survive redaction on
both the OpenAI and Anthropic paths.
2026-08-05 18:21:58 -07:00
Mateo Wang
60d9e6012c
Merge pull request #35999 from BerriAI/litellm_guardrails_v1_messages_tool_traffic
fix(guardrails): scan /v1/messages tool traffic
2026-08-05 18:08:47 -07:00
Mateo Wang
b9b239b0fb
Merge pull request #35980 from BerriAI/litellm_content_filter_post_mcp_call
fix(guardrails): allow litellm_content_filter to run on post_mcp_call
2026-08-05 18:08:02 -07:00
mateo-berri
f3bfa19ce5 fix(managed_files): resolve model_name identically across all output file registration paths so full unified ids converge 2026-08-05 17:36:22 -07:00
mateo-berri
097c03eebb fix(proxy): tolerate non-scalar sse keepalive interval config shapes 2026-08-05 17:33:09 -07:00
mateo-berri
6ca120a674 fix(proxy): coerce and validate the sse keepalive ping interval from config 2026-08-05 17:23:39 -07:00
Mateo Wang
eabcafc1df
perf(pre-commit): fetch basedpyright base counts from CI artifacts (#35970) 2026-08-05 17:21:16 -07:00
Souravrajvi0
388943ac17
fix(proxy): register managed batch output files on terminal retrieve (#34092)
Terminal batch retrieve could return the raw provider output_file_id, which
skips managed-file ownership checks on /v1/files/{id}/content and lets any key
on the proxy download another user's batch output.

Retrieve now registers the missing managed-file row before responding, and
attributes ownership to the durable batch owner rather than the retrieving
caller, so output and error ids always come back as unified managed ids.

Fixes #33989
2026-08-05 16:38:49 -07:00
Akash Naickar
e6e18d406a
fix(model-prices): correct replicate model key typo (#34800) 2026-08-05 16:37:44 -07:00
tin-berri
55e666a05f
feat(complexity_router): report LLM classifier cost per request via routing_decision and x-litellm-classifier-cost header (#36015) 2026-08-05 16:27:32 -07:00
ryan-crabbe-berri
7e8d0d3130
fix: rebuild models_by_provider in add_known_models so cost map reloads reach wildcard expansion (#36010)
* fix: rebuild models_by_provider in add_known_models so cost map reloads reach wildcard expansion

* fix: refresh models_by_provider in place so captured references survive reloads
2026-08-05 16:24:43 -07:00
yuneng-jiang
c898d341c0
Merge pull request #36011 from BerriAI/litellm_maint_batch_2026_07
fix(proxy)!: apply request-parameter checks consistently across body, path and form inputs
2026-08-05 16:23:16 -07:00
mateo-berri
131339d8e5 fix(proxy): send keepalive pings on anthropic messages SSE streams during upstream silence 2026-08-05 16:15:04 -07:00
mateo-berri
e87b8a098a fix(managed_files): derive unified output file ids deterministically so concurrent registrations converge 2026-08-05 16:08:56 -07:00
Yuneng Jiang
298fb8ce56
fix(health): drop a stored-credential reference along with the credentials it names
A connection test that redirects the destination already leaves the configured
credentials behind. It kept litellm_credential_name, which names the same stored
secrets and is resolved further down the call, so the reference is now dropped
with them. A request that sets no connection fields of its own is unaffected,
which is how the Admin UI tests a configured model.
2026-08-05 16:07:04 -07:00
Yuneng Jiang
59173c3a20
feat(health): let allow_client_side_credentials re-enable configured-credential reuse
The proxy-wide opt-in that already governs callers supplying their own
connection parameters now also governs whether a connection test may pair a
request-supplied endpoint with the configured deployment's credentials. Off by
default, which keeps configured credentials scoped to the endpoint the
configuration names; on, the previous merge behaviour is available unchanged.
2026-08-05 15:58:49 -07:00
Yuneng Jiang
b468acb31c
fix(health): stop inheriting configured credentials when a connection test sets its own
A request that supplies its own connection fields describes a connection of its
own, so the configured deployment's credentials are no longer merged underneath
it. Anything the request leaves unset still comes from the configuration, so
naming a configured model and testing it as configured is unchanged, and adding
a second deployment for an already-configured name works as before.

Replaces the earlier outright rejection, which also refused requests that
supplied a complete connection of their own.
2026-08-05 15:49:41 -07:00
devin-ai-integration[bot]
aa1180c0c9
fix(core_helpers): map generic 'error' finish_reason to 'stop' (#33972)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-05 22:39:12 +00:00
mateo-berri
2ba4e91766 feat(guardrails): add scan_only_tool_results to scope unified guardrails to tool results 2026-08-05 15:38:08 -07:00
Yuneng Jiang
e5effcb861
fix(health)!: let configured deployment parameters win over request overrides
When a connection test names a model that resolves to a configured deployment,
that deployment's routing and credential parameters are authoritative. A request
supplying a complete connection of its own is unaffected.

BREAKING CHANGE: /health/test_connection no longer lets a request replace the
routing or credential parameters of a configured model it names. Supply the full
connection parameters instead of naming a configured model.
2026-08-05 15:17:43 -07:00
Yuneng Jiang
5b2c92d749
fix(proxy)!: parse bracket-notation form metadata the same way its JSON form is parsed
Multipart callers express nested metadata as flat bracket-notation keys, which
reach the request-body check as literal keys rather than as a metadata dict.
The check now rebuilds them with the same helper the endpoints use, so both
encodings are handled identically and cannot drift apart.

BREAKING CHANGE: a multipart field such as `litellm_metadata[api_base]` is now
subject to the same request-body parameter rules as its JSON equivalent. Set
`general_settings.allow_client_side_credentials`, or the deployment's
`configurable_clientside_auth_params`, to keep passing these.
2026-08-05 15:17:43 -07:00
Yuneng Jiang
fc4be70a37
fix(proxy)!: share one destination check between body and path-supplied model
The URL-destination check previously ran over request-body fields only. The
per-field logic moves into reject_url_valued_destination(field, value) so a
deployment name resolved from the request path runs the same check against the
same admin allowlist.

BREAKING CHANGE: a deployment name supplied in the request path that parses as
an http/https destination is now refused. Add the host to
`provider_url_destination_allowed_hosts` in litellm_settings to keep it working.
2026-08-05 15:17:43 -07:00
Mateo Wang
f047124b5a
feat(pre-commit): save full lint output to a per-worktree log file (#36004)
* feat(pre-commit): save full lint output to a per-worktree log file

* docs(claude): point agents at the pre-commit log instead of rerunning

* fix(pre-commit): warn when the log cannot be created or fully written
2026-08-05 15:16:52 -07:00
mateo-berri
f16f3e23cd fix(tool_permission): fail closed on unverifiable SSE streams and end the turn when every tool call is denied
An SSE stream that cannot be positively identified as Anthropic (no
parseable message_start event) now blocks instead of passing through
unscanned, closing the bypass where any raw-SSE backend skipped tool
permission checks entirely. Buffered chunks are joined back into one
stream before parsing, so events split across network chunk boundaries
assemble correctly instead of being silently dropped. Rewrite mode now
resets finish_reason to stop when no tool call survives, so the
re-encoded Anthropic stream reports stop_reason end_turn and clients do
not wait for a tool result that never comes
2026-08-05 15:06:51 -07:00