Commit Graph

7264 Commits

Author SHA1 Message Date
hliu-roblox
07ac97aff4
feat(key_management): allow @ in key_alias for email-based aliases (#23003)
Adds @ to the _KEY_ALIAS_PATTERN allowed character set so that
key aliases like user/user@example.com are accepted. Updates tests
to cover email-based alias formats.
2026-03-06 17:24:42 -08:00
Sameer Kankute
11e2bdbaec
Merge pull request #22981 from BerriAI/litellm_reasoning-effort-dict-normalization
feat(openai): normalize reasoning_effort dict to string for chat completion API
2026-03-07 00:37:07 +05:30
ryan-crabbe
7d2681fa36
Merge pull request #22982 from BerriAI/litellm_fix_batch_stale_status
Fix batch list showing stale "validating" status after completion
2026-03-06 09:31:09 -08:00
michelligabriele
5e34fdce77
feat(vertex_ai): support explicit AWS credentials for WIF auth (#21472)
* feat(vertex_ai): support explicit AWS credentials for WIF auth

The current Vertex AI AWS Workload Identity Federation implementation
exclusively uses google.auth.aws.Credentials.from_info(), which requires
EC2 instance metadata access to obtain AWS credentials. In environments
where the metadata service is blocked for security reasons, this makes
WIF unusable.

Add support for explicit AWS credentials by implementing a custom
AwsSecurityCredentialsSupplier (google-auth >= 2.29.0). When aws_* keys
(e.g. aws_role_name, aws_region_name) are present in the WIF credential
JSON, LiteLLM uses BaseAWSLLM.get_credentials() to obtain AWS creds via
STS AssumeRole (or any other supported AWS auth flow), wraps them in the
custom supplier, and passes them to aws.Credentials() — bypassing the
metadata service entirely.

When no aws_* keys are present, the existing from_info() flow is used
unchanged, preserving full backward compatibility.

* refactor(vertex_ai): extract AWS WIF auth to own class + add docs

Address PR review feedback:
- Move _AWS_CREDENTIAL_KEYS, _extract_aws_params(), and
  _credentials_from_aws_with_explicit_auth() from VertexBase into
  new VertexAIAwsWifAuth class in vertex_ai_aws_wif.py
- Add documentation for explicit AWS credentials WIF auth method
  in vertex.md (supported params, JSON example, SDK/Proxy tabs)

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

* fix(vertex_ai): use lazy credentials provider to prevent stale STS tokens

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:27:20 -08:00
Ryan Crabbe
c4db53a98a Address review feedback: remove dead code, add error handling, strengthen test assertions
- Remove unused `completed_jobs` list (dead code after per-job update refactor)
- Wrap DB update in try/except to prevent one failed update from aborting remaining jobs
- Add test assertions verifying batch_processed, status, and file_object are written to DB
2026-03-06 09:25:50 -08:00
Sameer Kankute
d8f139fe4d feat(openai): add 272K tier pricing for GPT-5.4/5.4-pro
Prompts >272K input tokens priced at 2x input, 1.5x output for full session
(standard, batch, flex). Applies to models with 1.05M context window (gpt-5.4,
gpt-5.4-pro).

- Add input/output_cost_per_token_above_272k_tokens to model_prices
- Add above_272k fields to ModelInfoBase and get_model_info extraction
- Add test_generic_cost_per_token_gpt54_above_272k_tokens

Made-with: Cursor
2026-03-06 22:26:14 +05:30
Ryan Crabbe
3d55f7f6ab Fix batch list showing stale "validating" status after completion
CheckBatchCost poller updated the status column but not the file_object
JSON column. The list_batches endpoint reads status from file_object,
so batches appeared stuck in "validating" even after Azure reported
them as completed. Now update file_object alongside status in the
per-job DB write.
2026-03-06 08:54:21 -08:00
Sameer Kankute
14b52b1318 feat(openai): drop reasoning_effort for gpt-5.4 when tools present
Function calls not supported with reasoning_effort != 'none' on gpt-5.4.
Drop reasoning_effort when tools are in the request (small minority of volume).

Made-with: Cursor
2026-03-06 22:20:47 +05:30
Sameer Kankute
b6344c319b feat(openai): normalize reasoning_effort dict to string for chat completion API
The OpenAI chat completion API expects reasoning_effort as a string
('none', 'low', 'medium', 'high', 'xhigh'). Config/deployments may pass
the Responses API format: {'effort': 'high', 'summary': 'detailed'}.

Fix BadRequestError when model config uses dict format by extracting
the 'effort' value before passing to the API.

Made-with: Cursor
2026-03-06 22:17:11 +05:30
Sameer Kankute
8b0375f99c
Merge pull request #22888 from BerriAI/litellm_a2a-custom-headers
[Feat] Add a2a custom headers
2026-03-06 18:24:21 +05:30
Sameer Kankute
e9d797bd8d fix(proxy): do not forward Authorization header to LLM provider when used for LiteLLM proxy auth
When forward_llm_provider_auth_headers=true, Authorization: Bearer <litellm-key> was
being forwarded to Anthropic if it looked like an OAuth key, causing auth failures.

Now checked against authenticated_with_header: if Authorization was used to authenticate
with the proxy, it is always stripped before forwarding to the LLM provider.

Made-with: Cursor
2026-03-06 18:20:48 +05:30
Sameer Kankute
159c477c18 feat(proxy): client-side provider API key precedence for Anthropic /v1/messages
- Add forward_llm_provider_auth_headers support from litellm_settings
- When enabled, client x-api-key takes precedence over deployment keys
- Forward x-api-key when x-litellm-api-key or Authorization used for auth
- Fix duplicate patch lines in test_byok_oauth_endpoints.py
- Add Claude Code BYOK documentation with /login and ANTHROPIC_CUSTOM_HEADERS
- Add unit tests for clean_headers x-api-key forwarding logic
- Sync model_prices backup (pre-commit hook)

Made-with: Cursor
2026-03-06 18:20:46 +05:30
Sameer Kankute
c23eb5afc6 feat(azure_ai): add router flat cost when response contains actual model
- Pass request_model to Azure AI cost calculator to detect router requests
- Add router flat cost ($0.14/M input tokens) even when Azure returns actual model in response
- Add test for router flat cost with response containing actual model
- Update docs with cost calculation flow and configuration requirements

Made-with: Cursor
2026-03-06 18:18:06 +05:30
Sameer Kankute
6ba2e9f10f feat(gpt-5): add supports_none_reasoning_effort and supports_xhigh_reasoning_effort to model cost map
- Shift from hardcoded model checks to dynamic lookup via _supports_factory
- Add supports_none_reasoning_effort for gpt-5.1/5.2/5.4 chat variants
- Add supports_xhigh_reasoning_effort for gpt-5.1-codex-max, gpt-5.2, gpt-5.4+
- Update model_prices_and_context_window.json and backup
- Add ProviderSpecificModelInfo types for new fields
- Fix Azure: use _supports_reasoning_effort_level instead of removed is_model_gpt_5_1_model

Made-with: Cursor
2026-03-06 18:15:32 +05:30
yuneng-jiang
8523bb6b48
Merge pull request #22956 from BerriAI/litellm_key_null_duration
[Fix] Key Expiry Default Duration
2026-03-05 21:06:55 -08:00
yuneng-jiang
e468b0278f [Fix] Key Expiry Default Duration - support null to never expire
Support passing duration=null on /key/update to reset a key's expiry to never expires, alongside the existing "-1" magic string (kept for backward compat).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 20:54:30 -08:00
yuneng-jiang
99c4f3cbea
Merge pull request #22938 from BerriAI/litellm_fix_team_usage_spend
[Fix] Team Usage Spend Truncated Due to Pagination
2026-03-05 20:45:27 -08:00
Sameer Kankute
20ec949cf1
Merge pull request #22734 from vincentkoc/vincentkoc-code/chatgpt-53-oauth-models
feat(models): add ChatGPT 5.3/5.4 aliases + OpenAI gpt-5.4-pro
2026-03-06 08:59:12 +05:30
Sameer Kankute
57596cab1a
Merge pull request #22920 from Varad2001/litellm_gemini_3.1_reasoning_effort
fix(gemini): handle 'minimal' reasoning_effort param for gemini-3.1-f…
2026-03-06 08:55:57 +05:30
yuneng-jiang
d0e480414c Fix team usage spend showing lower than expected values
The /team/daily/activity endpoint used Prisma pagination (page_size=1000)
but the UI only fetched page 1. Teams with many keys/models easily exceed
1000 rows in LiteLLM_DailyTeamSpend, causing truncated totals.

Switches the endpoint to use SQL GROUP BY via get_daily_activity_aggregated
with include_entity_breakdown=True, returning all data in a single response
while preserving per-team breakdown. Also adds timezone parameter support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:00:51 -08:00
Krish Dholakia
53a1e31729
feat(spend-logs): add truncation note when error logs are truncated for DB storage (#22936)
When the messages or response JSON fields in spend logs are truncated
before being written to the database, the truncation marker now includes
a note explaining:
- This is a DB storage safeguard
- Full, untruncated data is still sent to logging callbacks (OTEL, Datadog, etc.)
- The MAX_STRING_LENGTH_PROMPT_IN_DB env var can be used to increase the limit

Also emits a verbose_proxy_logger.info message when truncation occurs in
the request body or response spend log paths.

Adds 3 new tests:
- test_truncation_includes_db_safeguard_note
- test_response_truncation_logs_info_message
- test_request_body_truncation_logs_info_message

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-03-05 16:58:46 -08:00
yuneng-jiang
92b3160206
Merge pull request #22858 from BerriAI/litellm_rbac_vector_agents
[Feature] RBAC for Vector Stores and Agents
2026-03-05 16:40:38 -08:00
Antti Puurula
20ce6ddbef
Fix apac.anthropic.claude-sonnet-4-6 -> au.anthropic.claude-sonnet-4-6 (#21466) 2026-03-05 15:54:26 -08:00
yuneng-jiang
05d2ccdf56 [Fix] PATCH /update/ui_settings now merges with existing record instead of overwriting
Previously, model_dump(exclude_none=True) included all bool fields (since
False != None), causing a partial PATCH to overwrite every other setting to
its default. Fix uses exclude_unset=True and reads the existing DB record
before merging, giving proper PATCH semantics.

This was a pre-existing bug but is fixed here since we're touching this code.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:49:40 -08:00
yuneng-jiang
79817ff796 [Fix] Constrain feature_name to Literal, deduplicate runtime flags, fix silent test swallowing
- rbac_utils.py: change feature_name from str to Literal["agents", "vector_stores"]
  so typos are caught by type checkers at import time
- proxy_setting_endpoints.py: extract _RUNTIME_GENERAL_SETTINGS_FLAGS as a module-level
  constant, replacing duplicated inline lists in get_ui_settings and update_ui_settings
- test_vector_store_rbac.py: remove try/except pattern that silently swallowed non-403
  HTTPExceptions; tests now let any unexpected exception propagate as a test failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:42:17 -08:00
yuneng-jiang
b3c092f489 [Fix] Address code review: delegate team admin check to shared helper, fix sidebar team admin exemption
- rbac_utils.py: remove duplicated _check_if_team_admin/_is_user_team_admin_for_any_team;
  delegate to _user_has_admin_privileges from management_endpoints/common_utils with the
  shared user_api_key_cache (fixes no-op DualCache and missing org admin coverage)
- test_rbac_utils.py: update patch target to match new delegation path
- SidebarProvider.tsx: pass allowAgentsForTeamAdmins and allowVectorStoresForTeamAdmins
  props to Sidebar
- leftnav.tsx: add useTeams hook + isTeamAdmin memo; exempt team admins from sidebar
  filtering when allow_*_for_team_admins is enabled (fixes frontend/backend inconsistency)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 15:04:33 -08:00
Vincent Koc
ba3ce77e29 test(openai): cover gpt-5.4-pro parameter behavior 2026-03-05 17:02:14 -05:00
Vincent Koc
fb935a61ae test(chatgpt): restore gpt-5.2 codex transformation coverage 2026-03-05 17:00:49 -05:00
weiguang li
3d027c0f7a
fix(bedrock): filter out custom field from tools to prevent 400 errors (#22861)
Claude Code v2.1.69+ sends `custom: {defer_loading: true}` on tool
definitions. Anthropic's API accepts this field, but Bedrock rejects it
with "Extra inputs are not permitted", causing ~90% of requests to fail.

Strip the `custom` field from each tool in the request body before
sending to Bedrock, in both the Messages API and Chat API invoke paths.

Fixes #22847

Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
2026-03-05 13:54:23 -08:00
Vincent Koc
9a37fe2821 test(openai): add gpt-5.4 detection and xhigh assertions 2026-03-05 16:50:38 -05:00
Vincent Koc
68ab37cf34 test(chatgpt): add gpt-5.4 alias registration coverage 2026-03-05 16:50:38 -05:00
Vincent Koc
801e2d615b test(chatgpt): cover gpt-5.3 oauth alias registration 2026-03-05 16:50:38 -05:00
Curtis
725c0c158f
Prisma DB Failure Detection and Self-Healing (#21059)
* fix(proxy): readiness check returns 200 when database is unreachable

_db_health_readiness_check() catches health_check() exceptions but
never updates db_health_cache to "disconnected" and never re-raises.
The caller health_readiness() always returns 200 with "db": "connected"
hardcoded, regardless of actual DB state.

In Kubernetes, this means pods with dead database connections stay in
the Service endpoints and continue receiving traffic they cannot serve.

Changes:
- Set db_health_cache to "disconnected" and re-raise the exception on
  health_check failure so health_readiness() returns 503
- Use actual db_health_status["status"] in the response instead of
  hardcoding "db": "connected"
- Reduce cache TTL from 2 minutes to 15 seconds. The 2-minute window
  is too wide for readiness probes (typically 10-15s intervals) and
  means a pod can report healthy for up to 2 minutes after the DB dies
- Only serve cached results when status is "connected". The previous
  condition (status != "unknown") would also cache "disconnected" for
  2 minutes, delaying recovery detection after a DB comes back

* fix(proxy): add DB connection self-healing to readiness check

When the Prisma query engine's internal TCP connection pool holds dead
connections (caused by network blips, Cloud SQL proxy restarts, or
node-level issues), health_check() fails with httpx.ConnectError.
The engine never recovers on its own because nothing triggers a
disconnect/connect cycle to restart the subprocess with fresh
connections.

This leaves pods permanently failing readiness checks until they are
manually restarted, even after the underlying DB becomes reachable
again.

Add a reconnect attempt to _db_health_readiness_check() when
health_check() fails:
1. disconnect() - kills the query engine subprocess and closes all
   connections (has built-in backoff retry: 3 tries, 10s max)
2. connect() - starts a new engine with fresh TCP connections (has
   built-in backoff retry: 3 tries, 10s max)
3. health_check() - verifies the new connection works (has built-in
   backoff retry: 3 tries, 10s max)

If reconnect succeeds, the pod immediately returns to service (200).
If it fails, the original exception is re-raised (503). Reconnect
attempts are rate-limited by probe frequency (~10-15s), so a
permanently unreachable DB gets one attempt per cycle with no retry
loops.

This uses the same disconnect/connect mechanism that
PrismaWrapper.recreate_prisma_client() uses for IAM token refresh,
and aligns with the community-documented pattern for Prisma connection
recovery in long-running processes (prisma/prisma#24718, #27024).

* Add poetry lock and modify test_health_endpoints

* Address allow_requests_on_db_unavailable regression

* Address comments

* resolve greptile issue

* Restore accidentally deleted UI HTML files

These were removed in an earlier commit but still exist on main.
Restoring to keep the PR diff clean.

* Guard reconnect with is_database_transport_error

Only attempt disconnect/connect/health_check cycle for transport-level
failures (unreachable DB, dropped connection). Data-layer errors like
UniqueViolationError indicate the DB is reachable, so reconnecting
would be pointless churn.

* Address greptile's comments

* Fix module alias after rebase and add adversarial test coverage

- Unify module alias to _health_endpoints_module after rebase conflict
- Add test for non-transport error with flag on (exercises is_database_transport_error guard)
- Add test for disconnect() failure during reconnect cycle
- Split non-transport error test into flag-off (re-raises) and flag-on (skips reconnect) variants

* Remove stale UI HTML files reintroduced during rebase
2026-03-05 13:44:49 -08:00
Ishaan Jaff
503eb2fd4c
fix: don't close HTTP/SDK clients on LLMClientCache eviction (#22925)
* fix: don't close HTTP/SDK clients on LLMClientCache eviction

Removing the _remove_key override that eagerly called aclose()/close()
on evicted clients. Evicted clients may still be held by in-flight
streaming requests; closing them causes:

  RuntimeError: Cannot send a request, as the client has been closed.

This is a regression from commit fb72979432. Clients that are no longer
referenced will be garbage-collected naturally. Explicit shutdown cleanup
happens via close_litellm_async_clients().

Fixes production crashes after the 1-hour cache TTL expires.

* test: update LLMClientCache unit tests for no-close-on-eviction behavior

Flip the assertions: evicted clients must NOT be closed. Replace
test_remove_key_closes_async_client → test_remove_key_does_not_close_async_client
and equivalents for sync/eviction paths.

Add test_remove_key_removes_plain_values for non-client cache entries.
Remove test_background_tasks_cleaned_up_after_completion (no more _background_tasks).
Remove test_remove_key_no_event_loop variant that depended on old behavior.

* test: add e2e tests for OpenAI SDK client surviving cache eviction

Add two new e2e tests using real AsyncOpenAI clients:
- test_evicted_openai_sdk_client_stays_usable: verifies size-based eviction
  doesn't close the client
- test_ttl_expired_openai_sdk_client_stays_usable: verifies TTL expiry
  eviction doesn't close the client

Both tests sleep after eviction so any create_task()-based close would
have time to run, making the regression detectable.

Also expand the module docstring to explain why the sleep is required.

* docs(AGENTS.md): add rule — never close HTTP/SDK clients on cache eviction

* docs(CLAUDE.md): add HTTP client cache safety guideline
2026-03-05 12:00:38 -08:00
Sameer Kankute
bf9c96b912
Merge pull request #22679 from giulio-leone/fix/websearch-thinking-constraint
fix: WebSearch interception fails with thinking enabled + SpendLog dedup
2026-03-06 00:49:17 +05:30
Varad Khonde
6d4a281ba0 fix(gemini): handle 'minimal' reasoning_effort param for gemini-3.1-flash-lite-preview 2026-03-06 00:26:45 +05:30
Spencer Burridge
c919031ff0
feat(proxy): include user_email in jwt upsert user creation (#22915)
* Include user_email in new user creation within get_user_object

Enhance the get_user_object function to include user_email in the parameters when creating a new user. This change is accompanied by a new test to verify that user_email is correctly included during the upsert process.

* Improve error handling in test_get_user_object by logging exceptions

Updated the test_get_user_object_upsert_includes_user_email function to log exceptions when they occur, enhancing the visibility of potential issues during testing. This change helps in diagnosing failures related to the mock LiteLLM_UserTable.
2026-03-05 10:55:11 -08:00
Ishaan Jaff
a42132f329
fix(passthrough): propagate Azure 429/5xx errors in async streaming instead of silent HTTP 200 (#22913)
* fix(passthrough): raise_for_status in _async_streaming to propagate Azure 429s

* address greptile review feedback (greploop iteration 1)

Guard data/json args when content is provided to avoid httpx ValueError

* address greptile review feedback (greploop iteration 2)

Use bare raise to preserve original traceback in _async_streaming exception handler

* address greptile review feedback (greploop iteration 3)

Close httpx streaming response on error to prevent connection pool exhaustion

* address greptile review feedback (greploop iteration 4)

Guard aclose() call to prevent masking original exception; add explicit test for content param forwarding

* address greptile review feedback (greploop iteration 5)

Pass content to sign_request so AWS body-hash signing is correct when content is the sole body source

* revert sign_request content change - request_data expects dict, not bytes

Bedrock's sign_request calls json.dumps(request_data) — passing content bytes
would TypeError. sign_request should only receive data/json (dict), not raw bytes.
2026-03-05 10:12:43 -08:00
giulio-leone
7b0ed0ff91 fix: replace sk-fake with safe test key to avoid secret scanner
Replace 'sk-fake' with 'fake-key-for-testing' in websearch interception
tests to prevent false-positive secret scanner triggers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-05 18:29:28 +01:00
Giulio Leone
6b7d767637
feat(anthropic): support top-level cache_control for automatic prompt caching (#22442) 2026-03-05 08:34:56 -08:00
Sameer Kankute
5183a6e850
Merge pull request #22866 from mubashir1osmani/feat/bedrock-mantle-provider-clean
feat: bedrock mantle provider
2026-03-05 18:24:00 +05:30
Sameer Kankute
0620f99fa4
Merge pull request #22867 from BerriAI/litellm_bedrock-azure-cache-control-scope
fix(bedrock,azure_ai): strip scope from cache_control for Anthropic messages
2026-03-05 18:20:59 +05:30
Sameer Kankute
c04c120df2
Merge pull request #22884 from BerriAI/litellm_vertex-output-config-drop
fix(vertex_ai): drop unsupported output_config parameter from all requests
2026-03-05 18:20:47 +05:30
Sameer Kankute
501671aa43 fix(agents): PUT update_agent_in_db clears static_headers and extra_headers when omitted
For full-replace PUT semantics, always include static_headers and extra_headers
in update_data, defaulting to {} and [] when not supplied. Previously,
omitting these fields left stale DB values intact (e.g. auth headers).

Made-with: Cursor
2026-03-05 16:16:21 +05:30
Sameer Kankute
594499e806 Add tests 2026-03-05 15:14:45 +05:30
Julio Quinteros
db8e909ef2 fix(test): add 'realtime' to model mode enum in schema validation
gemini/gemini-live-2.5-flash-preview-native-audio-09-2025 uses mode='realtime'
but the schema in test_aaamodel_prices_and_context_window_json_is_valid did
not include 'realtime' as a valid enum value, causing a ValidationError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 06:41:51 -03:00
Sameer Kankute
9a13c76e2f
Merge pull request #22553 from dsteeley/fix/streaming-multi-tool-call-premature-finish
fix(streaming): output_item.done for function_call must not emit finish_reason
2026-03-05 15:05:43 +05:30
Sameer Kankute
fd53678898 test(agents): add tests for A2A custom header forwarding
Covers:
- Static headers forwarded to backend
- Dynamic headers extracted by name (extra_headers config)
- Convention-based x-a2a-{agent_id/name}-{header} forwarding
- Static headers win over dynamic on conflict
- Unrelated x-a2a- prefixes are not forwarded
- No-header case leaves existing behaviour unchanged
- merge_agent_headers utility unit tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 14:28:48 +05:30
Sameer Kankute
a2c11d431a fix(vertex_ai): drop unsupported output_config parameter from all requests
Vertex AI does not support the output_config parameter in its API.
This parameter is being added by Anthropic/Gemini transformations but needs
to be removed before sending requests to Vertex AI endpoints.

This fix addresses the "Extra inputs are not permitted" error (issue #22312)
when using Claude models with structured outputs on Vertex AI.

Changes:
- Drop output_config in Gemini model transformation
- Drop output_config in Anthropic partner model transformation
- Drop output_config in Anthropic experimental pass-through transformation
- Add comprehensive tests to verify output_config is dropped

Fixes: #22312
Made-with: Cursor
2026-03-05 13:02:17 +05:30
Sameer Kankute
cdf2d67fc8
Merge pull request #22503 from giulio-leone/fix/graceful-tool-args-repair
fix(tools): gracefully repair truncated JSON in tool call arguments
2026-03-05 13:00:07 +05:30