Commit graph

8758 commits

Author SHA1 Message Date
mubashir1osmani
1bc90d2db7
fix guardrail status error (#20972)
* fix guardrail status error

* fix function imports
2026-02-12 20:19:13 -08:00
joaokopernico
da31dd19da
fix(anthropic): use Authorization Bearer for OAuth tokens instead of x-api-key (#21039)
OAuth tokens (sk-ant-oat*) require Authorization: Bearer header per
Anthropic's OAuth specification, but were being sent via x-api-key
which Anthropic rejects with 'invalid x-api-key'.

- optionally_handle_anthropic_oauth: detect OAuth tokens in api_key
  param (standard chat flow), not just Authorization header
- get_anthropic_headers: use Authorization: Bearer + required OAuth
  headers for OAuth tokens, x-api-key for regular API keys
- Passthrough messages: skip x-api-key when Authorization is set
- Add oauth-2025-04-20 to beta headers whitelist config
2026-02-12 20:10:08 -08:00
Emerson Gomes
022846baae
fix(router): remove repeated provider parsing in budget limiter hot path (#21043)
* fix(router): remove budget limiter provider hot-path overhead

- avoid LiteLLM_Params instantiation from dict deployments in provider lookup\n- resolve provider once per deployment and reuse in budget filtering\n- add router unit tests for hot-path behavior\n\nFixes #21042

* fix(router): handle None provider cache entries in budget limiter

- avoid recomputing provider when cached value is None\n- clarify deployment_provider_map uses id(deployment) keys\n- add regression test covering None-provider cache path

* refactor(router): avoid id()-based provider cache coupling

- switch provider cache handoff to index-aligned list between budget-limiter loops\n- remove implicit dependency on object identity stability\n- move hot-path tests to tests/test_litellm/router_strategy per template guidance

* chore(router): make use_litellm_proxy default explicit

Use deployment_litellm_params.get('use_litellm_proxy', False) for clarity and parity with LiteLLM_Params default behavior.

* test(router): add provider-resolution parity guard

- wrap dict litellm_params with lightweight attribute view for get_llm_provider\n- reduce drift risk from manual field extraction vs LiteLLM_Params defaults\n- add parity test matrix comparing optimized path to legacy LiteLLM_Params behavior for dict deployments

* test(router): harden dict view compatibility for provider resolution

- extend _LiteLLMParamsDictView with mapping-like and dump methods\n- add regression test simulating future get_llm_provider method-based access\n- keep hot-path optimization while reducing duck-typing break risk

---------

Co-authored-by: Codex <codex@example.com>
2026-02-12 20:05:55 -08:00
yuneng-jiang
d701cc6588
Merge pull request #21081 from BerriAI/litellm_yj_release_changes_feb12
[Infra] CI/CD Fixes - Nightly Release Feb 12
2026-02-12 18:07:34 -08:00
Ishaan Jaff
9202e67e33
feat: MCP server discovery UI (#21079)
* feat: add curated MCP server registry for discovery UI

Curated list of 31 well-known MCP servers with names, icons,
categories, transport config, and registry URLs. Includes HTTP
endpoints for GitHub, Atlassian, Sentry, Snowflake, and Cloudflare.

* feat: add GET /v1/mcp/discover endpoint for MCP discovery

Admin-only endpoint that serves the curated MCP registry with
optional query and category filters. Used by the UI discovery modal.

* feat: add DiscoverableMCPServer types for MCP discovery

* feat: add fetchDiscoverableMCPServers network function

* feat: add MCP discovery modal component

Compact list-row layout with category filters, search, and
grouped server list. Follows dev-tool aesthetic.

* feat: wire MCP discovery modal into server management page

Add MCP Server button now opens discovery modal. Card click
pre-fills the create form. Custom Server opens blank form.

* feat: add prefill from discovery and back-to-registry link

Create form accepts prefillData from discovery selection and
shows a Browse MCP Registry link to return to discovery modal.

* test: add unit tests for MCP discovery endpoint and registry

Tests for registry JSON structure validation and endpoint
query/category filtering logic. 15 tests total.

* fix: sync registry with official MCP API and fix stdio prefill

- Updated transport types and URLs from registry.modelcontextprotocol.io API
- GitHub: streamable-http at api.githubcopilot.com/mcp/
- GitLab: streamable-http at gitlab.com/api/v4/mcp (remote only)
- Atlassian: SSE at mcp.atlassian.com/v1/sse (remote only)
- Linear: SSE at mcp.linear.app/sse (remote only)
- Notion: SSE at mcp.notion.com/sse (remote only)
- Stripe: streamable-http at mcp.stripe.com (remote only)
- Exa: streamable-http at mcp.exa.ai/mcp (remote only)
- Cloudflare: SSE at bindings.mcp.cloudflare.com/sse (remote only)
- Sentry: stdio via @sentry/mcp-server (npm, correct package)
- Snowflake: stdio via snowflake-labs-mcp (pypi/uvx, not npm)
- Brave Search: stdio via @brave/brave-search-mcp-server (correct package)
- Fixed stdio prefill to generate stdio_config JSON instead of separate fields
- Discovery modal matches create modal width and header style
- Back arrow positioned on left of create modal header

* Update ui/litellm-dashboard/src/components/mcp_tools/mcp_discovery.tsx

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

* Update litellm/proxy/management_endpoints/mcp_management_endpoints.py

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

* fix: address Greptile review feedback

- Move `import json` and `import os` to module top level
- Move mcp_registry.json into litellm/proxy/ for pip distribution
- Fix `Text` component: destructure from antd Typography instead of deprecated Tremor
- Update test fixture path to match new registry location

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-12 17:59:21 -08:00
yuneng-jiang
111593397a fixing core proxy tests 2026-02-12 17:54:32 -08:00
yuneng-jiang
e49d094606 fix openai tests 2026-02-12 17:53:47 -08:00
yuneng-jiang
2864ce73da
Merge pull request #21022 from BerriAI/litellm_unified_ag
[Feature] Access Groups
2026-02-12 15:34:38 -08:00
Harshit Jain
c56bbb9067
Update tests/test_litellm/proxy/management_endpoints/test_ui_sso.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-13 04:48:36 +05:30
Ishaan Jaff
5f40f93846
fix: MCP - inject NPM_CONFIG_CACHE into STDIO MCP subprocess env (#21069)
* fix: inject NPM_CONFIG_CACHE into STDIO MCP subprocess env for Docker

npm/npx needs a writable cache directory. In containers the default
(~/.npm) may not exist or be read-only, causing STDIO MCP servers
launched via npx to fail with ENOENT. Inject NPM_CONFIG_CACHE=/tmp/.npm_mcp_cache
into the subprocess env when not already set.

* test: add unit test for NPM_CONFIG_CACHE injection in STDIO MCP

Verifies that NPM_CONFIG_CACHE is auto-injected when not set, and
preserved when explicitly provided. Also moves the import to module
level per code style rules.

* Update litellm/constants.py

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

* Apply suggestion from @greptile-apps[bot]

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

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-12 15:11:37 -08:00
Harshit Jain
a2b4728e74
Update tests/test_litellm/proxy/management_endpoints/test_ui_sso.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-13 04:40:29 +05:30
Alejandro Tapia
82f6d0fe43 healthcheck-model_id-fix: There was quite a bit of code that needed to be changed since health checks were entirely keyed by model name. This includes, proxy logic, the dashboard, and even networking, because model name was the identifier everywhere. All changed files had tests added to them, which are passing with no regressions. 2026-02-12 14:47:09 -08:00
Harshit Jain
e0846389e9
add modify test to perform async run 2026-02-13 04:04:03 +05:30
yuneng-jiang
a45028f623 Merge remote-tracking branch 'origin' into litellm_unified_ag 2026-02-12 14:32:52 -08:00
Harshit Jain
eb249b2f06
fix: add await in tests 2026-02-13 03:46:31 +05:30
yuneng-jiang
ea8c89ea3f rename file and add tests 2026-02-12 14:05:51 -08:00
Harshit Jain
1792b3c8e5
fix: add async call to avoid server pauses 2026-02-13 03:28:51 +05:30
yuneng-jiang
c34cdb29cd remove double auth and add alias 2026-02-12 13:40:58 -08:00
yuneng-jiang
e6df587bfb adding tests and fixing prisma lookup table 2026-02-12 12:48:05 -08:00
Ishaan Jaff
3d9b145b04
[Feat] Adds support for server-side compaction on the OpenAI Responses API context_management (#21058)
* test_responses_api_context_management_server_side_compaction

* Server-side compaction

* docs fix

* test_responses_api_shell_tool
2026-02-12 10:00:30 -08:00
Sameer Kankute
e68b970953
Merge branch 'main' into litellm_oss_staging_02_11_2026 2026-02-12 21:14:08 +05:30
Sameer Kankute
59d6ab8a00
Merge branch 'main' into litellm_oss_staging_02_11_2026 2026-02-12 20:04:46 +05:30
shin-bot-litellm
7b6b97cc10 fix: mask API keys in error responses for invalid/malformed keys (#20289)
Fixes AT&T customer issue where API keys are returned in plain text
in error responses.

Changes:
1. user_api_key_auth.py: Mask the API key in the AssertionError when a
   key doesn't start with 'sk-' (e.g. key with leading space). Shows
   first 4 + last 4 chars with **** in between instead of the full key.

2. key_management_endpoints.py: Same masking for the key format
   validation error when creating keys with invalid prefix.

3. presidio.py: Sanitize exceptions from Presidio analyze/anonymize
   calls to prevent leaking original request text (which may contain
   API keys) in error responses. Error messages now show only the
   exception type, not the full payload.
2026-02-12 19:58:05 +05:30
shin-bot-litellm
7ee36c2a3a fix(http_handler): bypass cache when shared_session is provided for aiohttp tracing (#20630)
* Add http support to custom code guardrails + Unified guardrails for MCP + Agent guardrail support (#20619)

* fix: fix styling

* fix(custom_code_guardrail.py): add http support for custom code guardrails

allows users to call external guardrails on litellm with minimal code changes (no custom handlers)

Test guardrail integrations more easily

* feat(a2a/): add guardrails for agent interactions

allows the same guardrails for llm's to be applied to agents as well

* fix(a2a/): support passing guardrails to a2a from the UI

* style(code-editor): allow editing custom code guardrails on ui + add examples of pre/post calls for custom code guardrails

* feat(mcp/): support custom code guardrails for mcp calls

allows custom code guardrails to work on mcp input

* feat(chatui.tsx): support guardrails on mcp tool calls on playground

* fix(mypy): resolve missing return statements and type casting issues (#20618)

* fix(mypy): resolve missing return statements and type casting issues

* fix(pangea): use elif to prevent UnboundLocalError and handle None messages

Address Greptile review feedback:
- Make branches mutually exclusive using elif to prevent input_messages from being overwritten
- Handle case where data.get('messages') returns None to avoid passing invalid payload to Pangea API

---------

Co-authored-by: Shin <shin@openclaw.ai>

* [Feat] MCP Gateway - Allow setting MCP Servers as Private/Public available on Internet (#20607)

* update MCPAuthenticatedUser

* add available_on_public_internet for MCPs

* update claude.md

* init IPAddressUtils

* init available_on_public_internet

* add on REST endpoints

* filter with IP

* TestIsInternalIp

* _extract_mcp_headers_from_request

* init get_mcp_client_ip

* _get_general_settings

* allowed_server_ids

* address PR comments

* get_mcp_server_by_name fix

* fix server

* fix review comments

* get_public_mcp_servers

* address _get_allowed_mcp_servers

* fixing user_id

* [Feat] IP-Based Access Control for MCP Servers (#20620)

* update MCPAuthenticatedUser

* add available_on_public_internet for MCPs

* update claude.md

* init IPAddressUtils

* init available_on_public_internet

* add on REST endpoints

* filter with IP

* TestIsInternalIp

* _extract_mcp_headers_from_request

* init get_mcp_client_ip

* _get_general_settings

* allowed_server_ids

* address PR comments

* get_mcp_server_by_name fix

* fix server

* fix review comments

* get_public_mcp_servers

* address _get_allowed_mcp_servers

* test fix

* fix linting

* inint ui types

* add ui for managing MCP private/public

* add ui

* fixes

* add to schema

* add types

* fix endpoint

* add endpoint

* update manager

* test mcp

* dont use external party for ip address

* Add OpenAI/Azure release test suite with HTTP client lifecycle regression detection (#20622)

* docs (#20626)

* docs

* fix(mypy): resolve type checking errors in 5 files (#20627)

- a2a_protocol/exception_mapping_utils.py: Fix type ignore comment for None assignment
- caching/redis_cache.py: Add type ignore for async ping return type
- caching/redis_cluster_cache.py: Add type ignore for async ping return type
- llms/deprecated_providers/palm.py: Add type ignore for palm.generate_text
- proxy/auth/handle_jwt.py: Add type ignore for jwt.decode options argument

All changes add appropriate type: ignore comments to handle library typing inconsistencies.

* fix(test): update deprecated gemini embedding model (#20621)

Replace text-embedding-004 with gemini-embedding-001.

The old model was deprecated and returns 404:
'models/text-embedding-004 is not found for API version v1beta'

Co-authored-by: Shin <shin@openclaw.ai>

* ui new buil

* fix(http_handler): bypass cache when shared_session is provided for aiohttp tracing

When users pass a shared_session with trace_configs to acompletion(),
the get_async_httpx_client() function was ignoring it and returning
a cached client without the user's tracing configuration.

This fix bypasses the cache when shared_session is provided, ensuring
the user's ClientSession (with its trace_configs, connector settings, etc.)
is actually used for the request.

Fixes #20174

---------

Co-authored-by: Krish Dholakia <krrishdholakia@gmail.com>
Co-authored-by: Shin <shin@openclaw.ai>
Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: yuneng-jiang <yuneng.jiang@gmail.com>
Co-authored-by: Alexsander Hamir <alexsanderhamirgomesbaptista@gmail.com>
Co-authored-by: shin-bot-litellm <shin-bot-litellm@users.noreply.github.com>
2026-02-12 19:57:57 +05:30
Varun Chawla
e587370f67 fix(proxy): add regression tests for #20441 - <script> tags in messages (#20573)
* fix: empty guardrails/policies arrays should not trigger enterprise license check (#20304)

The UI sends empty arrays for enterprise-only fields (guardrails, policies,
logging) even when the user has not configured these features. The backend
`is not None` check treated `[]` as a truthy intent to use the feature,
falsely requiring an enterprise license for basic team operations.

Backend: Add `and updated_kv[field] != [] and updated_kv[field] != {}`
guards in `_update_metadata_fields` so empty collections are skipped.

UI: Conditionally omit guardrails, logging, and policies from the
payload when empty instead of defaulting to `[]`.

Fixes #20304

* fix: allow clearing fields with empty collections while skipping enterprise check

Address PR review feedback:

1. Move the empty-collection guard into _update_metadata_field (singular)
   so that empty lists/dicts skip only the premium license check but still
   get written into metadata. This lets users intentionally clear a
   previously-set field (e.g. guardrails: []) without being blocked, while
   the UI's default empty arrays still don't trigger a false enterprise
   error.

2. Remove sys.path hack from test file; use standard imports that work
   with pytest discovery.

3. Add tests verifying that empty collections are moved into metadata
   (field clearing works) even though they bypass the premium check.

Fixes #20304

* fix(proxy): add regression tests for #20441 - ensure <script> tags in LLM messages are not blocked

The 403 Forbidden error when sending messages containing `<script>` is caused
by external WAF/reverse proxy infrastructure (confirmed by the standard nginx
HTML 403 response format), not by LiteLLM's own content filtering. However,
these regression tests ensure that:

1. The content filter guardrail's built-in patterns do not match HTML tags
2. Messages containing <script> and other HTML tags pass through the content
   filter unchanged when no explicit HTML-blocking rules are configured
3. The HTTP request body parser correctly handles JSON payloads containing
   HTML content without modification

These tests guard against accidentally introducing HTML/XSS filtering that
would break legitimate LLM API usage (e.g., discussing HTML/JavaScript code).

Closes #20441

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 19:57:40 +05:30
Varun Chawla
6fc335030a fix(responses): handle Pydantic ValidationError when provider omits required fields in streaming events (#20580)
When an OpenAI-compatible upstream provider emits minimal streaming event
payloads that omit required fields (e.g. created_at, output, output_index,
content_index), Pydantic raises a ValidationError crashing the SSE stream
and returning HTTP 500.

Fall back to model_construct() on ValidationError, consistent with the
existing pattern in transform_response_api_response for non-streaming.

Fixes https://github.com/BerriAI/litellm/issues/20570

Signed-off-by: Varun Chawla <varun_6april@hotmail.com>
2026-02-12 19:55:58 +05:30
Zero Clover
7044512407 Fix responses bridge metadata isolation (#20484) 2026-02-12 19:39:05 +05:30
Dennis Zheleznyak
19d290a988 fix(sagemaker): Support TEI raw array response format for embeddings (#20487)
HuggingFace Text Embeddings Inference (TEI) returns embeddings as raw
arrays [[0.1, 0.2, ...]] instead of wrapped format {"embedding": [...]}.

This change handles both formats:
- Raw array: [[...]] (TEI, some HF models)
- Wrapped: {"embedding": [[...]]} (standard HF format)

Fixes SagemakerError: "HF response missing 'embedding' field" when using
TEI containers on SageMaker.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-12 19:39:05 +05:30
Sameer Kankute
e8f97bbfca Return 200 response for stale dlete requests from client 2026-02-12 19:21:14 +05:30
Harshit Jain
c867740d5e
Merge pull request #20481 from Harshit28j/litellm_aws_rotation_fix
Fix authorization issues, same alias; verified working
2026-02-12 09:36:10 +05:30
Harshit Jain
af8dabb4ce
Merge branch 'main' into litellm_fix_tts_metrics 2026-02-12 09:33:55 +05:30
Harshit Jain
7e958bbf67
Apply suggestion from @greptile-apps[bot]
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-12 09:03:43 +05:30
Harshit Jain
931e9ff88d
Update tests/test_litellm/proxy/test_docker_no_network_on_deploy.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-12 09:01:13 +05:30
Harshit Jain
095fa517e0
fix lint and format errors 2026-02-12 08:09:20 +05:30
Krish Dholakia
af3acdda18
Guardrails - add toxic/abusive content filter guardrails 2026-02-11 18:08:16 -08:00
Krish Dholakia
5736fd32d9
MCP fixes
* fix(oldteams.tsx): show policies when creating

* fix(proxy/_types.py): ensure mcp rest endpoints can be called by virtual key

ensures UI works with virtual key testing mcp endpoints

* refactor: migrate get object permissions table logic to happen in user api key auth - allows functions to trust user api key object they receive has what they need

* fix(rest_endpoints.py): filter for allowed tools based on what key has access to

* fix(mcp_server_manager.py): ensure only allowed MCP's are returned to the user, via rest endpoints
2026-02-11 18:07:24 -08:00
Harshit Jain
8249cce157 add tests for hotpath & docker container 2026-02-12 01:26:22 +00:00
yuneng-jiang
5fa5657476
Merge pull request #20991 from BerriAI/litellm_spend_logs_sort_03
[Feature] Allow Sorting on /spend/logs/ui
2026-02-11 14:11:11 -08:00
yuneng-jiang
55225a09cf Allow sorting on /spend/logs/ui 2026-02-11 12:48:33 -08:00
Ishaan Jaff
2b00466d3a
fix: support prompt_cache_key for OpenAI and Azure chat completions (#20989)
* fix:fix: prompt_cache_key OAI + Azure OpenAI

* test_prompt_cache_key_supported

* test_azure_openai_with_prompt_cache_key

* fix: remove unnecessary async from test_azure_openai_with_prompt_cache_key

Addresses Greptile feedback: litellm.completion() is synchronous, so
async def is unnecessary and would silently pass without running.

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

* fix: remove unused filter_and_transform_beta_headers imports

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

* test_azure_openai_with_prompt_cache_key

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 12:25:29 -08:00
yuneng-jiang
b88b2520c0
Merge pull request #20987 from BerriAI/litellm_inv_user_org
[Feature] Allow Organization and Team Admins to call /invitation/new
2026-02-11 11:38:15 -08:00
yuneng-jiang
40295595c7 allow team and org admins to call invitation/new 2026-02-11 11:23:27 -08:00
Ishaan Jaff
9975a9e3d4
fix: support Azure AD token auth for non-Claude azure_ai models (#20981)
* fix: _should_use_api_key_header

* test_azure_ai_validate_environment_with_api_key

* fix: remove unused top-level RouteChecks import

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

* docs: add missing env keys to config_settings reference

Add MODEL_COST_MAP_MIN_MODEL_COUNT, MODEL_COST_MAP_MAX_SHRINK_RATIO,
and MAX_POLICY_ESTIMATE_IMPACT_ROWS to the environment variables
reference table.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 10:48:44 -08:00
michelligabriele
81a1cb1318
fix(mcp): merge query params when authorization_url already contains them (#20968) 2026-02-11 08:43:19 -08:00
Sameer Kankute
c27650c4cf
Merge pull request #20935 from BerriAI/litellm_anthropic_filter_bedrock_headers
[Feat]Managing Anthropic Beta Headers
2026-02-11 18:19:01 +05:30
Cas Steigstra
2ef0d9e80a fix: export PermissionDeniedError from litellm.__init__
PermissionDeniedError (403) is defined in litellm/exceptions.py but was
never added to the import block in litellm/__init__.py. This makes it
the only standard HTTP error exception not accessible as
litellm.PermissionDeniedError, forcing users to import from
litellm.exceptions directly.

Fixes #20959
2026-02-11 13:39:19 +01:00
Sameer Kankute
a9255349b6
Merge pull request #20938 from skylarkoo7/fix-20885-deepseek-model-metadata
fix(model-info): sync DeepSeek model metadata and add bare-name fallback
2026-02-11 17:15:03 +05:30
Sameer Kankute
a7b63d3895
Merge pull request #20958 from gotsysdba/main
Fix OCI Cohere system messages by populating preambleOverride
2026-02-11 17:07:34 +05:30
Sameer Kankute
b962b2cc85 Fix beta header old tests 2026-02-11 16:57:52 +05:30
Sameer Kankute
64355e6da4 Fix test_vertex_ai_partner_models_anthropic_remove_prompt_caching_scope_beta_header 2026-02-11 16:55:54 +05:30