Commit graph

36177 commits

Author SHA1 Message Date
Ishaan Jaff
9f2453712e
perf: streaming latency improvements — 4 targeted hot-path fixes (#22346)
* perf: raise aiohttp connection pool limits (300→1000, 50/host→500)

* perf: skip model_copy() on every chunk — only copy usage-bearing chunks

* perf: replace list+join O(n²) with str+= O(n) in async_data_generator

* perf: cache model-level guardrail lookup per request, not per chunk
2026-02-27 20:45:53 -08:00
Ishaan Jaff
ee703cea99
fix(jwt): OIDC discovery URLs, roles array handling, dot-notation error hints (#22336)
* fix(jwt): support OIDC discovery URLs, handle roles array, improve error hints

Three fixes for Azure AD JWT auth:

1. OIDC discovery URL support - JWT_PUBLIC_KEY_URL can now be set to
   .well-known/openid-configuration endpoints. The proxy fetches the
   discovery doc, extracts jwks_uri, and caches it.

2. Handle roles claim as array - when team_id_jwt_field points to a list
   (e.g. AAD's "roles": ["team1"]), auto-unwrap the first element instead
   of crashing with 'unhashable type: list'.

3. Better error hint for dot-notation indexing - when team_id_jwt_field is
   set to "roles.0" or "roles[0]", the 401 error now explains to use
   "roles" instead and that LiteLLM auto-unwraps lists.

* Add integration demo script for JWT auth fixes (OIDC discovery, array roles, dot-notation hints)

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Add demo_servers.py for manual JWT auth testing with mock JWKS/OIDC endpoints

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Add demo screenshots for PR comment

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* Add integration test results with screenshots for PR review

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* address greptile review feedback (greploop iteration 1)

- fix: add HTTP status code check in _resolve_jwks_url before parsing JSON
- fix: remove misleading bracket-notation hint from debug log (get_nested_value does not support it)

* Update tests/test_litellm/proxy/auth/test_handle_jwt.py

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

* remove demo scripts and assets

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-27 20:30:47 -08:00
Julio Quinteros Pro
8ab542875c
Merge pull request #21107 from BerriAI/fix/bedrock-filter-json-tool-call-scoped
fix(bedrock): filter internal json_tool_call when mixed with real tools
2026-02-28 01:17:09 -03:00
Ishaan Jaff
eea083fa4b
fix(mcp): default available_on_public_internet to true (#22331)
* fix(mcp): default available_on_public_internet to true

MCPs were defaulting to private (available_on_public_internet=false) which
was a breaking change. This reverts the default to public (true) across:
- Pydantic models (AddMCPServerRequest, UpdateMCPServerRequest, LiteLLM_MCPServerTable)
- Prisma schema @default
- mcp_server_manager.py YAML config + DB loading fallbacks
- UI form initialValue and setFieldValue defaults

* fix(ui): add forceRender to Collapse.Panel so toggle defaults render correctly

Ant Design's Collapse.Panel lazy-renders children by default. Without
forceRender, the Form.Item for 'Available on Public Internet' isn't
mounted when the useEffect fires form.setFieldValue, causing the Switch
to visually show OFF even though the intended default is true.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix(mcp): update remaining schema copies and MCPServer type default to true

Missed in previous commit per Greptile review:
- schema.prisma (root)
- litellm-proxy-extras/litellm_proxy_extras/schema.prisma
- litellm/types/mcp_server/mcp_server_manager.py MCPServer class

* ui(mcp): reframe network access as 'Internal network only' restriction

Replace scary 'Available on Public Internet' toggle with 'Internal network only'
opt-in restriction. Toggle OFF (default) = all networks allowed. Toggle ON =
restricted to internal network only. Auth is always required either way.

- MCPPermissionManagement: new label/tooltip/description, invert display via
  getValueProps/getValueFromEvent so underlying available_on_public_internet
  value is unchanged
- mcp_server_view: 'Public' → 'All networks', 'Internal' → 'Internal only' (orange)
- mcp_server_columns: same badge updates

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-02-27 20:06:07 -08:00
rasmi
bffce842a1
Remove Apache 2 license from SKILL.md (#22322) 2026-02-27 19:33:55 -08:00
Julio Quinteros Pro
9db4ab1188
Merge pull request #22039 from demoray/bcaswell/fix-long-path-filenames
fix: shorten guardrail benchmark result filenames for Windows long path support
2026-02-28 00:28:34 -03:00
Brian Caswell
bcf9acf5ea Update litellm/proxy/guardrails/guardrail_hooks/litellm_content_filter/guardrail_benchmarks/test_eval.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-28 00:27:39 -03:00
Brian Caswell
37ec9f8995 fix: shorten guardrail benchmark result filenames for Windows long path support
Fixes #21941

The generated result filenames from _save_confusion_results contained
parentheses, dots, and full yaml filenames, producing paths that exceed
the Windows 260-char MAX_PATH limit. Rework the safe_label logic to
produce short {topic}_{method_abbrev} filenames (e.g. insults_cf.json)
while preserving the full label inside the JSON content.

Rename existing tracked result files to match the new naming convention.
2026-02-28 00:27:39 -03:00
Julio Quinteros Pro
fdf4c9dbdc fix: use correct class name AmazonConverseConfig in helper method calls
Fixed MyPy errors where BedrockConverseConfig was used instead of
AmazonConverseConfig in the _unwrap_bedrock_properties() calls.

Errors:
- Line 1619: BedrockConverseConfig -> AmazonConverseConfig
- Line 1631: BedrockConverseConfig -> AmazonConverseConfig

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 00:18:56 -03:00
Julio Quinteros Pro
b983352d11 refactor: extract duplicated JSON unwrapping into helper method
Addresses review comment from greptile-apps:
https://github.com/BerriAI/litellm/pull/21107#pullrequestreview-3796085353

Changes:
- Added `_unwrap_bedrock_properties()` helper method to eliminate code duplication
- Replaced two identical JSON unwrapping blocks (lines 1592-1601 and 1612-1620)
  with calls to the new helper method
- Improves maintainability - single source of truth for Bedrock properties unwrapping logic

The helper method:
- Parses JSON string
- Checks for single "properties" key structure
- Unwraps and returns the properties value
- Returns original string if unwrapping not needed or parsing fails

No functional changes - pure refactoring.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 00:18:56 -03:00
Julio Quinteros Pro
fcabf9b602 fix(bedrock): filter internal json_tool_call when mixed with real tools
Fixes #18381: When using both tools and response_format with Bedrock
Converse API, LiteLLM internally adds json_tool_call to handle structured
output. Bedrock may return both this internal tool AND real user-defined
tools, breaking consumers like OpenAI Agents SDK.

Changes:
- Non-streaming: Added _filter_json_mode_tools() to handle 3 scenarios:
  only json_tool_call (convert to content), mixed (filter it out), or
  no json_tool_call (pass through)
- Streaming: Added json_mode tracking to AWSEventStreamDecoder to suppress
  json_tool_call chunks and convert to text content
- Fixed optional_params.pop() mutation issue

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-28 00:18:56 -03:00
Julio Quinteros Pro
5a28ca985c
Update .github/workflows/scan_duplicate_issues.yml
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-28 00:17:31 -03:00
Julio Quinteros Pro
94b7342da8
Update .github/workflows/check_duplicate_issues.yml
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-28 00:17:22 -03:00
Julio Quinteros Pro
1ac3c230cb
Update .github/scripts/close_duplicate_issues.py
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-02-28 00:17:12 -03:00
Shivam Rawat
d49abf8577
[Fix] Pass MCP auth headers from request into tool fetch for /v1/responses and chat completions (#22291)
* fixed dynamic auth for /responses with mcp

* fixed greptile concern
2026-02-27 19:15:51 -08:00
Julio Quinteros Pro
2d649f239f
Merge pull request #22026 from ZeroClover/fix/img-extra-headers
fix(image_generation): propagate extra_headers to Upstream
2026-02-28 00:14:43 -03:00
Julio Quinteros Pro
98bc247618
Merge pull request #22143 from shivaaang/fix/llm-client-cache-unawaited-coroutine
fix(caching): store task references in LLMClientCache._remove_key
2026-02-28 00:13:52 -03:00
milan-berri
3e60ca3682
fix: populate user_id and user_info for admin users in /user/info (#22239)
* fix: populate user_id and user_info for admin users in /user/info endpoint

Fixes #22179

When admin users call /user/info without a user_id parameter, the endpoint
was returning null for both user_id and user_info fields. This broke
budgeting tooling that relies on /user/info to look up current budget and spend.

Changes:
- Modified _get_user_info_for_proxy_admin() to accept user_api_key_dict parameter
- Added logic to fetch admin's own user info from database
- Updated function to return admin's user_id and user_info instead of null
- Updated unit test to verify admin user_id is populated

The fix ensures admin users get their own user information just like regular users.

* test: make mock get_data signature match real method

- Updated MockPrismaClientDB.get_data() to accept all parameters that the real method accepts
- Makes mock more robust against future refactors
- Added datetime and Union imports
- Mock now returns None when user_id is not provided
2026-02-27 19:12:16 -08:00
milan-berri
594600dcb5
fix: Add PROXY_ADMIN role to system user for key rotation (#21896)
* fix: Add PROXY_ADMIN role to system user for key rotation

The key rotation worker was failing with 'You are not authorized to regenerate this key'
when rotating team keys. This was because the system user created by
get_litellm_internal_jobs_user_api_key_auth() was missing the user_role field.

Without user_role=PROXY_ADMIN, the system user couldn't bypass team permission checks
in can_team_member_execute_key_management_endpoint(), causing authorization failures
for team key rotation.

This fix adds user_role=LitellmUserRoles.PROXY_ADMIN to the system user, allowing
it to bypass team permission checks and successfully rotate keys for all teams.

* test: Add unit test for system user PROXY_ADMIN role

- Verify internal jobs system user has PROXY_ADMIN role
- Critical for key rotation to bypass team permission checks
- Regression test for PR #21896
2026-02-27 19:11:29 -08:00
Julio Quinteros Pro
8b50703f74
Merge pull request #22327 from BerriAI/fix/mcp-test-mock-filter-method-name
fix(mcp): update test mocks for renamed filter_server_ids_by_ip_with_info
2026-02-27 23:52:39 -03:00
Ishaan Jaff
8ce358e303
[Feat] Agent RBAC Permission Fix - Ensure Internal Users cannot create agents (#22329)
* fix: enforce RBAC on agent endpoints — block non-admin create/update/delete

- Add /v1/agents/{agent_id} to agent_routes so internal users can
  access GET-by-ID (previously returned 403 due to missing route pattern)
- Add _check_agent_management_permission() guard to POST, PUT, PATCH,
  DELETE agent endpoints — only PROXY_ADMIN may mutate agents
- Add user_api_key_dict param to delete_agent so the role check works
- Add comprehensive unit tests for RBAC enforcement across all roles

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* fix: mock prisma_client in internal user get-agent-by-id test

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

* feat(ui): hide agent create/delete controls for non-admin users

Match MCP servers pattern: wrap '+ Add New Agent' button in
isAdmin conditional so internal users see a read-only agents view.
Delete buttons in card and table were already gated.
Update empty-state copy for non-admin users.
Add 7 Vitest tests covering role-based visibility.

Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
2026-02-27 18:32:39 -08:00
Shivaang
fb72979432 fix(caching): store background task references in LLMClientCache._remove_key to prevent unawaited coroutine warnings
Fixes #22128
2026-02-27 21:23:56 -05:00
Julio Quinteros Pro
e3779a8fb3 fix(lint): suppress PLR0915 too-many-statements in complex transform methods
These three methods legitimately need many statements for their
event/message transformation logic. Suppress the lint warning rather
than artificially splitting the methods.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:18:06 -03:00
Julio Quinteros Pro
9278a311ca
Merge pull request #22333 from BerriAI/fix/bedrock-parallel-tool-calls-map-params
fix(bedrock): restore parallel_tool_calls mapping in map_openai_params
2026-02-27 23:17:05 -03:00
Julio Quinteros Pro
b192ba797e
Merge pull request #22335 from BerriAI/fix/claude-code-plugin-migration
fix(db): add missing migration for LiteLLM_ClaudeCodePluginTable
2026-02-27 23:14:20 -03:00
Julio Quinteros Pro
332dc32299
Merge pull request #22334 from BerriAI/fix/anthropic-passthrough-azure-test
fix(test): update Azure pass-through test after Responses API routing change
2026-02-27 23:09:04 -03:00
Julio Quinteros Pro
9b20a050ec
Merge pull request #22332 from BerriAI/fix/realtime-guardrail-test-assertions
fix(test): update realtime guardrail test assertions for voice violation behavior
2026-02-27 23:08:04 -03:00
Julio Quinteros Pro
2ac5365e06 fix: update stale docstring to match guardrail voicing behavior
Addresses Greptile review feedback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:04:43 -03:00
Julio Quinteros Pro
d292ed7702 fix(db): add missing migration for LiteLLM_ClaudeCodePluginTable
PR #22271 added the LiteLLM_ClaudeCodePluginTable model to
schema.prisma but did not include a corresponding migration file,
causing test_aaaasschema_migration_check to fail.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:02:17 -03:00
Ishaan Jaff
15fcd90b9c
feat: add in_flight_requests metric to /health/backlog + prometheus (#22319)
* feat: add in_flight_requests metric to /health/backlog + prometheus

* refactor: clean class with static methods, add tests, fix sentinel pattern

* docs: add in_flight_requests to prometheus metrics and latency troubleshooting
2026-02-27 18:00:50 -08:00
Julio Quinteros Pro
273994b996 fix(test): update Azure pass-through test to mock litellm.completion
Commit 99c62ca40e removed "azure" from _RESPONSES_API_PROVIDERS,
routing Azure models through litellm.completion instead of
litellm.responses. The test was not updated to match, causing it
to assert against the wrong mock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:59:38 -03:00
Julio Quinteros Pro
aa899b504f fix(bedrock): restore parallel_tool_calls mapping in map_openai_params
The revert in 8565c70e53 removed the parallel_tool_calls handling from
map_openai_params, and the subsequent fix d0445e1e33 only re-added the
transform_request consumption but forgot to re-add the map_openai_params
producer that sets _parallel_tool_use_config. This meant parallel_tool_calls
was silently ignored for all Bedrock models.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:56:38 -03:00
Julio Quinteros Pro
9a48c8e36a fix(test): update realtime guardrail test assertions for voice violation behavior
Tests were asserting no response.create/conversation.item.create sent to
backend when guardrail blocks, but the implementation intentionally sends
these to have the LLM voice the guardrail violation message to the user.

Updated assertions to verify the correct guardrail flow:
- response.cancel is sent to stop any in-progress response
- conversation.item.create with violation message is injected
- response.create is sent to voice the violation
- original blocked content is NOT forwarded

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:53:09 -03:00
Harshit28j
50ecfbc614 Merge branch 'main' of https://github.com/BerriAI/litellm 2026-02-28 07:12:06 +05:30
Julio Quinteros Pro
cb4cfa1db4 fix(mcp): update test mocks to use renamed filter_server_ids_by_ip_with_info
Tests were mocking the old method name `filter_server_ids_by_ip` but production
code at server.py:774 calls `filter_server_ids_by_ip_with_info` which returns
a (server_ids, blocked_count) tuple. The unmocked method on AsyncMock returned
a coroutine, causing "cannot unpack non-iterable coroutine object" errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:37:05 -03:00
Dylan Duan
af6fe184fb
docs: update AssemblyAI docs with Universal-3 Pro, Speech Understanding, and LLM Gateway (#21130)
* docs: update AssemblyAI docs with Universal-3 Pro, Speech Understanding, and LLM Gateway provider config

* feat: add AssemblyAI LLM Gateway as OpenAI-compatible provider
2026-02-27 17:24:48 -08:00
ryan-crabbe
e445a32c4c
Merge pull request #22324 from BerriAI/litellm_prometheus_child_exit_cleanup
Add Prometheus child_exit cleanup for gunicorn workers
2026-02-27 16:51:19 -08:00
Ryan Crabbe
4fa6742b01 Add Prometheus child_exit cleanup for gunicorn workers
When a gunicorn worker exits (e.g. from max_requests recycling), its
per-process prometheus .db files remain on disk. For gauges using
livesum/liveall mode, this means the dead worker's last-known values
persist as if the process were still alive. Wire gunicorn's child_exit
hook to call mark_process_dead() so live-tracking gauges accurately
reflect only running workers.
2026-02-27 16:11:15 -08:00
Rahul Dhanawade
64c85dbc9f
Fix/claude code plugin schema (#22271)
* fix: add missing LiteLLM_ClaudeCodePluginTable to schema.prisma

- Claude Code Plugin Marketplace endpoints (/claude-code/marketplace.json,
  /claude-code/plugins) were returning 500 errors because
  LiteLLM_ClaudeCodePluginTable model was missing from both schema.prisma files
- Prisma client was generated without this table causing AttributeError:
  'Prisma' object has no attribute 'litellm_claudecodeplugintable'
- Added missing model definition to root schema.prisma and
  litellm/proxy/schema.prisma

Fixes #21310

* test: add regression test for LiteLLM_ClaudeCodePluginTable schema

* fix: address greptile review - add @updatedAt, clean up test imports
2026-02-27 15:59:37 -08:00
yuneng-jiang
03720ec08c
Merge pull request #22315 from BerriAI/litellm_projects_page
[Feature] UI - Projects: Add Projects page with list and create flows
2026-02-27 15:45:01 -08:00
yuneng-jiang
7cffd77d68
Merge pull request #22323 from BerriAI/litellm_project_list_timestamps
[Fix] Include timestamps in /project/list response
2026-02-27 15:44:02 -08:00
yuneng-jiang
8bb6457471 [Fix] Include created_at and updated_at in /project/list response
The /project/list endpoint was not returning created_at and updated_at timestamps because these fields were not defined in LiteLLM_ProjectTable. Added these fields to the model so FastAPI includes them in the response (values come from the database). This allows the UI to display project creation and last-updated times.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-02-27 15:41:03 -08:00
Alejandro Tapia
f1c563d2b2 org-exclusive-add-member 2026-02-27 14:58:17 -08:00
tombii
d292da2c14 fix(openrouter): pattern-based fix for native OpenRouter model double-stripping
Replace the hardcoded NATIVE_OPENROUTER_MODELS set approach with a
pattern-based check in _get_openai_compatible_provider_info: after
stripping the outer "openrouter/" provider prefix, if the remaining
model name still starts with "openrouter/", return immediately without
further stripping.

This fixes openrouter/openrouter/aurora-alpha, openrouter/openrouter/polaris-alpha,
and any future native OpenRouter models — not just the three hard-coded
ones (auto, free, bodybuilder) from the previous approach.

Fixes #16353

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 23:14:53 +01:00
Cesar Garcia
7d084dfb9d
Merge pull request #20525 from Chesars/docs/opus-4-6-openrouter-and-1m-context
docs: add OpenRouter Opus 4.6 to model map and update Claude Opus 4.6 docs
2026-02-27 19:07:31 -03:00
Chesars
5628ba0831 docs: remove openrouter/anthropic/claude-opus-4.6 from backup JSON
Model should only be in the main cost map, not the backup.
2026-02-27 19:05:33 -03:00
Chesars
c47d219806 docs: add openrouter/anthropic/claude-opus-4.6 to main model cost map 2026-02-27 19:04:49 -03:00
Chesars
ab8ffb0573 Merge upstream/main into fix-model-management-ui 2026-02-27 19:01:58 -03:00
Cesar Garcia
6430173bde
Merge pull request #20516 from Chesars/fix/openrouter-native-model-double-strip
fix(adapter): double-stripping of model names with provider-matching prefixes
2026-02-27 18:58:37 -03:00
Cesar Garcia
e05865fc1f
Merge pull request #20520 from Chesars/feat/add-openrouter-native-models
feat(model_prices): add OpenRouter native models to model cost map
2026-02-27 18:54:24 -03:00