Commit graph

10107 commits

Author SHA1 Message Date
user
815a2bed1a
test: add regression tests for cross-org admin escalation
Verify that an org admin of org-A cannot operate on org-B, and that
an admin of both orgs can operate on both.
2026-04-16 21:06:56 +00:00
user
91bfbe6efe
fix(proxy): enforce organization boundaries in admin operations
Validate org admin role against all requested organizations instead
of returning on first match. Scope team list queries to the caller's
permitted organizations when filtering by user_id.
2026-04-16 21:06:56 +00:00
ishaan-berri
6fab790a6e
Merge pull request #25867 from BerriAI/litellm_day_0_opus_4.7_support
Litellm day 0 opus 4.7 support
2026-04-16 22:49:51 +05:30
yuneng-jiang
21c0718850
Merge pull request #25871 from BerriAI/litellm_yj_apr15
[Infra] Merge dev branch
2026-04-16 10:11:48 -07:00
ishaan-berri
44c992416c
Merge pull request #25867 from BerriAI/litellm_day_0_opus_4.7_support
Litellm day 0 opus 4.7 support
2026-04-16 09:42:11 -07:00
Yuneng Jiang
b26f858ab0
fix(ci): authorize langgraph-prebuilt in liccheck.ini
langgraph-prebuilt was previously pulled in as a transitive of langgraph
so PyPI license metadata was reported as unknown. Now that it is
explicitly pinned (==1.0.8) to avoid the broken 1.0.9 release, the
license checker flags it. It is published under MIT by the same
langchain-ai/langgraph repository as langgraph itself.
2026-04-16 09:41:51 -07:00
Yuneng Jiang
dafa1bf97c
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_yj_apr15
# Conflicts:
#	litellm/litellm_core_utils/litellm_logging.py
#	uv.lock
2026-04-16 09:17:20 -07:00
Sameer Kankute
b3d5ff5774
Fix tests + add docs 2026-04-16 21:45:31 +05:30
Sameer Kankute
607412defb
feat(bedrock): inject thinking for clear_thinking context_management on Messages API
Bedrock rejects clear_thinking_20251015 unless thinking is enabled or adaptive.
Inject minimal extended thinking and interleaved-thinking beta when Claude Code
sends context_management without thinking. Adds unit tests.

Made-with: Cursor
2026-04-16 21:11:09 +05:30
Sameer Kankute
4b5c86b8a1
Fix code qa 2026-04-16 19:29:08 +05:30
Sameer Kankute
89767a6e43
litellm_staging_03_22_2026
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Caching (Redis) / caching-redis (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
2026-04-16 19:24:08 +05:30
Tim Ren
dd4a41951f
fix(utils): allowed_openai_params must not forward unset params as None (#25777)
* feat(proxy): add NO_OPENAPI env var to disable /openapi.json endpoint (#25696)

* feat(proxy): add NO_OPENAPI env var to disable /openapi.json endpoint - Fixes #25538

* test(proxy): add tests for _get_openapi_url

---------

Co-authored-by: Progressive-engg <lov.kumari55@gmail.com>

* feat(prometheus): add api_provider label to spend metric (#25693)

* feat(prometheus): add api_provider label to spend metric

Add `api_provider` to `litellm_spend_metric` labels so users can
build Grafana dashboards that break down spend by cloud provider
(e.g. bedrock, anthropic, openai, azure, vertex_ai).

The `api_provider` label already exists in UserAPIKeyLabelValues and
is populated from `standard_logging_payload["custom_llm_provider"]`,
but was not included in the spend metric's label list.

* add api_provider to requests metric + add test

Address review feedback:
- Add api_provider to litellm_requests_metric too (same call-site as
  spend metric, keeps label sets in sync)
- Add test_api_provider_in_spend_and_requests_metrics following the
  existing pattern in test_prometheus_labels.py

* fix: ensure `litellm_metadata` is attached to `pre_call` guardrail to align with `post_call` guardrail (#25641)

* fix: ensure `litellm_metadata` is attached to pre_call to align with post_call

* refactor: remove unused BaseTranslation._ensure_litellm_metadata

* refactor: module level imports for ensure_litellm_metadata and CodeQL

* fix: update based off of Codex comment

* revert: undo usage of `_guardrail_litellm_metadata`

* feat: add pricing entry for openrouter/google/gemini-3.1-flash-lite-preview (#25610)

* fix(bedrock): skip synthetic tool injection for json_object with no schema (#25740)

When response_format={"type": "json_object"} is sent without a JSON
schema, _create_json_tool_call_for_response_format builds a tool with an
empty schema (properties: {}). The model follows the empty schema and
returns {} instead of the actual JSON the caller asked for.

This patch:
- Skips synthetic json_tool_call injection when no schema is provided.
  The model already returns JSON when the prompt asks for it.
- Fixes finish_reason: after _filter_json_mode_tools strips all
  synthetic tool calls, finish_reason stays "tool_calls" instead of
  "stop". Callers (like the OpenAI SDK) misinterpret this as a pending
  tool invocation.

json_schema requests with an explicit schema are unchanged.

Co-authored-by: Claude <noreply@anthropic.com>

* fix(utils): allowed_openai_params must not forward unset params as None

`_apply_openai_param_overrides` iterated `allowed_openai_params` and
unconditionally wrote `optional_params[param] = non_default_params.pop(param, None)`
for each entry. If the caller listed a param name but did not actually
send that param in the request, the pop returned `None` and `None` was
still written to `optional_params`. The openai SDK then rejected it as
a top-level kwarg:

    AsyncCompletions.create() got an unexpected keyword argument 'enable_thinking'

Reproducer (from #25697):

    allowed_openai_params = ["chat_template_kwargs", "enable_thinking"]
    body = {"chat_template_kwargs": {"enable_thinking": False}}

Here `enable_thinking` is only present nested inside
`chat_template_kwargs`, so the helper should forward
`chat_template_kwargs` and leave `enable_thinking` alone. Instead it
wrote `optional_params["enable_thinking"] = None`.

Fix: only forward a param if it was actually present in
`non_default_params`. Behavior is unchanged for the happy path (param
sent → still forwarded), and the explicit `None` leakage is gone.

Adds a regression test exercising the helper in isolation so the test
does not depend on any provider-specific `map_openai_params` plumbing.

Fixes #25697

---------

Co-authored-by: lovek629 <59618812+lovek629@users.noreply.github.com>
Co-authored-by: Progressive-engg <lov.kumari55@gmail.com>
Co-authored-by: Ori Kotek <ori.k@codium.ai>
Co-authored-by: Alexander Grattan <51346343+agrattan0820@users.noreply.github.com>
Co-authored-by: Mohana Siddhartha Chivukula <103447836+iamsiddhu3007@users.noreply.github.com>
Co-authored-by: Amiram Mizne <amiramm@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-16 19:04:26 +05:30
Brendan Smith-Elion
265a960472
fix(noma-v2): fall back to key_alias for application_id in Noma dashboard (#25795)
Noma v1 resolved application_id from user_api_key_alias when no explicit
value was set (PR #16832). Noma v2 (PR #21400) was rewritten from scratch
and this fallback was not ported, causing all requests from shared LiteLLM
instances to appear as a single generic "litellm" application in the Noma
dashboard — breaking per-user traceability.

Fix: after checking dynamic_params and self.application_id, fall back to
user_api_key_alias from litellm_metadata or metadata. This matches the
pattern used by PromptSecurityGuardrail._resolve_key_alias_from_request_data()
and restores the v1 behavior where each API key gets its own application
entry in the Noma dashboard.

Fixes #25794

Co-authored-by: Brendan Smith-Elion <brendan.smith-elion@arcadia.io>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 19:04:24 +05:30
Jared Everett
3cbb36aa13
fix(ollama): propagate done_reason='length' as finish_reason for max_tokens truncation (#25824)
* fix(ollama): propagate done_reason='length' as finish_reason for max_tokens truncation

Ollama returns done_reason='length' when a response is cut off by num_predict
(the max_tokens limit). Previously, non-streaming responses hardcoded
finish_reason='stop', and streaming used chunk.get('done_reason', 'stop')
which also defaulted to 'stop' when done_reason was absent.

This meant callers (e.g. the Anthropic pass-through adapter, which maps
OpenAI 'length' -> Anthropic 'max_tokens') could never detect truncation,
making stop_reason always appear as 'end_turn' even for cut-off responses.

Fix: read done_reason from the response JSON in the non-streaming path and
use `chunk.get('done_reason') or 'stop'` in the streaming path, so Ollama's
actual done_reason passes through to the caller unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Update test_ollama_chat_transformation.py

* Update litellm/llms/ollama/chat/transformation.py

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-04-16 19:03:41 +05:30
Darien Kindlund
6b2973b29a
fix(vertex): strip version suffix from model name in count_tokens requests (#25800)
The Vertex AI count-tokens endpoint rejects model names that include
version suffixes (@default, @20251001, etc.) with:
"claude-sonnet-4-6@default is not supported for token counting"

The same model without the suffix ("claude-sonnet-4-6") works correctly.

Strip @suffix from both the model parameter and request_data["model"]
in handle_count_tokens_request before sending to the API.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 19:03:40 +05:30
Sameer Kankute
83d0f28aa8
Fix tests 2026-04-16 19:02:29 +05:30
Sameer Kankute
3c9bf32611
fix(bedrock): prevent negative streaming costs with start-only cache usage
Bedrock /v1/messages streams can report cache tokens only on message_start while message_delta carries only uncached input tokens. Merge cache fields onto the final delta usage and clamp negative text-token remainders in cost calc to keep usage/cost consistent.

Made-with: Cursor
2026-04-16 13:08:31 +05:30
Yuneng Jiang
c8cfc5de21
fix(httpx): set response.request and strip content-encoding in MaskedHTTPStatusError
MaskedHTTPStatusError constructs a new httpx.Response from the original
error. Two bugs surfaced under real HTTP error responses:

1. The new Response was created without request=, so response.request
   raised RuntimeError("The .request property has not been set.") for
   any downstream caller (e.g. exception_mapping_utils) that inspected it.

2. The decoded response bytes were passed together with the original
   Content-Encoding header. On construction httpx tried to decompress
   the already-decoded bytes and raised httpx.DecodingError
   ("Error -3 while decompressing data: incorrect header check").

Set response.request to the masked Request and strip Content-Encoding
(and the now-stale Content-Length) before rebuilding the Response.
URL/message masking is unchanged; the new request carries the already
masked URL.

Also update test_logging_key_masking_gemini: the security commit
25f93bed91 moved Gemini API keys from ?key=... URL params to the
x-goog-api-key header, so api_base no longer contains the key.
2026-04-15 22:03:48 -07:00
Yuneng Jiang
070374d03a
fix(ci): authorize RestrictedPython in liccheck.ini
RestrictedPython (ZPL-2.1, a BSD-style permissive license) was added as
a dependency for the custom_code guardrail sandbox, but the license
checker didn't recognize it. Add to authorized packages list.
2026-04-15 21:20:40 -07:00
yuneng-jiang
be1b802501
Merge pull request #25834 from stuxf/fix/path-traversal-guardrail-yaml
fix(proxy): add shared path utilities, prevent directory traversal
2026-04-15 21:01:48 -07:00
user
c2b3b62996
test: add unit tests for path_utils safe_join and safe_filename 2026-04-16 03:25:42 +00:00
Chesars
f82ba6ca6b Resolve remaining merge conflicts with upstream/main
- streaming_iterator.py: adopted main's more defensive version of the
  tool-arg queueing check (.get() instead of [], isinstance guard) —
  same logic, same behavior, lower crash surface
- model_prices_and_context_window.json + backup: combined staging's
  search_context_cost_per_query fields (PR #24372) with main's new
  supports_service_tier field — both are independent additions to the
  same Gemini model entries
- test_streaming_handler.py: kept Azure streaming regression test
  (PR #24354) and added main's two new Gemini legacy vertex
  finish_reason normalization tests
- test_gemini_batch_embeddings.py: kept staging's unsupported-params
  filtering tests (PR #24370) and added main's index/order test
2026-04-15 23:05:03 -03:00
Chesars
67e4604284 Merge upstream/main into litellm_staging_03_22_2026
Resolved conflicts:
- streaming_handler.py: combined role check (PR #24354, Azure streaming)
  with reasoning_items check (new in main) — both are independent OR
  conditions in is_chunk_non_empty()
- CI/CD: accepted main's versions throughout
  - Redis tests migrated to CircleCI (PR #25354): removed enable-redis
    from GH Actions workflows
  - E2E UI tests restructured (PR #25365): simplified CircleCI job
  - Coverage via Codecov added to all GH Actions unit test workflows
  - Deleted test-litellm-matrix.yml and test-proxy-e2e-azure-batches.yml
    (removed in main)
2026-04-15 22:54:53 -03:00
Ishaan Jaffer
def9c4ec47
chore: merge litellm_internal_staging, resolve uv.lock conflict 2026-04-15 18:51:19 -07:00
ishaan-berri
a588f76789
Litellm ishaan april15 2 (#25828)
* [Test] Add Azure async chat completion timeout test. WIP

* Capture TTFT for /v1/messages streaming responses

The pass-through streaming path for /v1/messages (Anthropic, Bedrock,
Vertex AI, Azure AI, Minimax) logged completion_start_time only after
the entire stream finished. async_success_handler then fell back to
end_time, making TTFT equal to total duration or null in the UI and
Prometheus.

Record the timestamp of the first chunk in async_sse_wrapper and
propagate it to model_call_details before the logging handler runs,
so gen_ai.response.time_to_first_token reflects the real first-chunk
latency.

Fixes #25598

* [Refactor] Implement timeout resolution logic in completion function

add fetch ``request_timeout`` from litellm_settings

* remove stale test case

* remove extra print statement

* default request timeout value in constants to 600s to match timeout defaults handled in the proxy

* fix request timeout if using default value from constants.py

* update code structure, test cases

* only override if the global timeout sets timeout to 6000s

* update code structure, move hard coded values to const and make the reslve function readable by moving fallback logic to a seperate function

* modify default timeout values, replacing hard coded ones with default values defined

---------

Co-authored-by: harish876 <harishgokul01@gmail.com>
Co-authored-by: Joaquin Hui Gomez <joaquinhuigomez@users.noreply.github.com>
2026-04-15 18:42:23 -07:00
user
47214be317
fix(proxy): harden request parameter handling
Tighten validation of request body parameters in the proxy routing
layer. Use context variables for internal call state management
instead of passing flags through request kwargs. Clean up metadata
handling at the proxy boundary.
2026-04-16 01:38:12 +00:00
Ishaan Jaffer
9977e63e3c
Merge remote-tracking branch 'origin/main' into worktree-foamy-jumping-coral 2026-04-15 18:29:55 -07:00
ishaan-berri
10131374ee
Merge pull request #25813 from BerriAI/litellm_ishaan_april15
Litellm ishaan april15
2026-04-15 18:29:22 -07:00
ishaan-berri
7a6b7ade03
Merge pull request #25807 from BerriAI/litellm_fix_provider_headers_in_logging
fix(logging): preserve provider response headers in StandardLoggingPayload
2026-04-15 18:29:03 -07:00
Ishaan Jaffer
537e72c742
style: black format test_mcp_server.py 2026-04-15 18:19:21 -07:00
Ishaan Jaffer
fcd71e0026
style: black format test_mcp_server_manager.py 2026-04-15 18:19:17 -07:00
Ishaan Jaffer
f768946549
style: black format test_anthropic_common_utils.py 2026-04-15 18:19:12 -07:00
Ishaan Jaffer
9a154a3be7
style: black format test_mcp_sigv4_auth.py 2026-04-15 18:19:08 -07:00
Ishaan Jaffer
c8a0fe193f
style: black format test_unit_test_caching.py 2026-04-15 18:19:04 -07:00
Ishaan Jaffer
93a90a53be
style: black format test_mcp_client.py 2026-04-15 18:19:01 -07:00
Ishaan Jaffer
f2a1dbe7c9
style: black format test_health_check_max_tokens.py 2026-04-15 18:18:56 -07:00
Ishaan Jaffer
3847a59d79
style: black format test_model_param_helper.py 2026-04-15 18:18:52 -07:00
ishaan-berri
cb8fc480e6
Merge pull request #25732 from harish876/health-check-oom
Optimize database query to prevent OOM errors during health checks
2026-04-15 18:13:11 -07:00
Joe Reyna
f92490c308
fix: make PodLockManager.release_lock atomic compare-and-delete (re-land #21226) (#24466)
Some checks are pending
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Waiting to run
Unit Tests: Security / security (push) Waiting to run
* fix: make PodLockManager.release_lock atomic compare-and-delete

Re-lands #21226 (reverted in #21469).

release_lock() previously did GET + compare + DEL in separate calls,
leaving a window where another pod could reacquire the lock between
the GET and DEL, causing a stale owner to delete a live lock.

Fix: use a Redis Lua script for atomic compare-and-delete. Script
registration is cached per PodLockManager instance. Falls back to
the old GET+DEL path for cache backends that don't expose
async_register_script.

Original revert was due to e2e tests running in CI without Redis.
Those tests now carry @pytest.mark.skip(reason="Requires Redis connection.")
so this re-land is safe.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add Lua fallback on execution error + test coverage gaps

Address Greptile review feedback on #24466:

1. Wrap Lua script execution in try/except — if Redis clears loaded
   scripts (restart) or scripting is disabled, fall back to GET+DEL
   rather than letting the exception propagate and leave the lock held
   until TTL. Reset cached script handle so the next call re-registers.

2. Add test_release_lock_lua_path_emits_released_event — verifies
   _emit_released_lock_event is called when Lua path returns 1.

3. Add test_release_lock_falls_back_to_get_del_when_lua_execution_fails
   — verifies the fallback path is taken and script handle is reset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 17:33:21 -07:00
yuneng-jiang
93faf321df
Merge pull request #25818 from jaydns/fix/custom-code-guardrail-restrictedpython
fix(guardrails): replace custom_code sandbox with RestrictedPython
2026-04-15 16:50:10 -07:00
yuneng-jiang
3f3bfdbe33
Merge pull request #25117 from stuxf/fix/credential-leak-prevention
security: prevent API key leaks in error tracebacks, logs, and alerts
2026-04-15 16:49:44 -07:00
jayden
469045ba91
fix(guardrails): provide _inplacevar_ to sandbox 2026-04-15 15:45:25 -07:00
jayden
fc9852cea2
fix(guardrails): move test_custom_code_security.py to correct location 2026-04-15 15:27:32 -07:00
jayden
0a1b4427a6
fix(guardrails): replace custom_code sandbox with RestrictedPython 2026-04-15 15:13:52 -07:00
Ishaan Jaffer
aaf169c91b
resolve merge conflicts: keep null-safety tests + add L3 regression tests from base 2026-04-15 12:34:39 -07:00
Ishaan Jaffer
98c2d90f5c
fix(logging): update test_get_additional_headers to reflect provider header passthrough 2026-04-15 12:23:33 -07:00
Ishaan Jaffer
cc6a33cce4
test(logging): add tests for get_additional_headers header preservation 2026-04-15 11:32:09 -07:00
Yuneng Jiang
eba43b5c04
Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_migration_projects
Some checks failed
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (key-generation, tests/proxy_unit_tests/test_key_generate_prisma.py, 30, 0) (push) Has been cancelled
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Has been cancelled
Unit Tests: Security / security (push) Has been cancelled
2026-04-15 10:14:06 -07:00
Sameer Kankute
9ed90d53cd
fix(router): enable order fallback for wildcard model groups
Use wildcard-aware deployment lookup when building order-based fallback levels so requests like openai/gpt-4.1-mini can advance from order=1 to order=2, and add a regression test for wildcard routing.

Made-with: Cursor
2026-04-15 17:48:25 +05:30
Vinh Pham Huu
61aee29b41 feat: Update video metadata handling and media resolution checks for Gemini models 2026-04-15 17:56:15 +07:00