* 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
- Updated benchmarks.md with a section on setting up fake OpenAI endpoints
- Updated load_test.md to mention the self-hosted option
- Updated load_test_advanced.md with a tip box about the example repo
Reference: https://github.com/BerriAI/example_openai_endpoint
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
- Updated create_mcp_server.tsx to show 'Streamable HTTP (Recommended)' label
- Updated mcp_server_edit.tsx to show 'Streamable HTTP (Recommended)' label
- Both Add New MCP Server and Edit MCP Server pages now display the updated label
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Ishaan Jaff <ishaan-jaff@users.noreply.github.com>
* 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>
* 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>
- Add verbose_logger to imports when LITELLM_LOG=DEBUG is set
- Set verbose_logger to DEBUG level alongside verbose_proxy_logger and verbose_router_logger
- Fixes issue where callback integrations (Langsmith, Langfuse, etc.) don't show debug logs with LITELLM_LOG=DEBUG
- Makes LITELLM_LOG=DEBUG behavior consistent with --detailed_debug flag
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
* feat(ui): add license expiration display to usage indicator
- Add getLicenseInfo() function to networking.tsx that calls /health/license
- Display license expiration as human-readable 'X days remaining' or 'Expires in X months'
- Show warning styling (yellow) if license expires in < 30 days
- Show error styling (red) if license is expired
- Fetch license info in parallel with usage data for efficiency
- Include license type display in expanded card view
- Compact UI suitable for sidebar widget
* fix: timezone mismatch in license expiration calculation
Addresses Greptile review feedback - forces UTC midnight for expiration
date and normalizes current date to local midnight to prevent off-by-one
errors in days remaining calculation.
---------
Co-authored-by: Shin <shin@openclaw.dev>
ECS/Fargate supports both RELATIVE_URI and FULL_URI credential delivery.
Only RELATIVE_URI was checked, causing false "missing keys" reports for
FULL_URI setups even though boto3 can authenticate fine.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
1. Cross-account false match: Added _parse_arn_account_and_role_name()
helper that compares partition + account ID + role name (not just
role name) to prevent same-name-different-account false matches.
2. SSL verify: _is_already_running_as_role() now passes ssl_verify to
the STS client via self._get_ssl_verify(), consistent with all other
boto3 client creation in this module.
3. Overbroad AccessDenied fallback: The catch in _auth_with_aws_role now
only falls back to ambient credentials when _is_already_running_as_role
positively confirms the caller is the target role. Genuine trust-policy
or permission misconfigurations are re-raised.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When aws_role_name is configured but the environment (ECS task role, EC2 instance
profile) is already running as that role, AssumeRole is unnecessary and can fail
with AccessDenied. This adds same-role detection for ECS/EC2 (extending existing
IRSA support) and a fallback to ambient credentials when AssumeRole returns
AccessDenied.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Arize Phoenix and Arize loggers now create dedicated TracerProviders
instead of fighting over the global singleton, and the otel callback
dedup check no longer incorrectly matches Arize subclasses.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Allow per-request Phoenix project name via `metadata.phoenix_project_name`, falling back to PHOENIX_PROJECT_NAME env var
- Add missing `post_call_success_hook` to `/images/generations` endpoint so guardrails and OTEL tracing apply to image generation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: Preserved nullable object fields by carrying schema properties
* Fix: _convert_schema_types
* Fix all mypy issues
* Add alert about email notifications
* fixing tests
* extending timeout for long running tests
* Text changes
* [Feat] MCP Oauth2 Fixes - Add support for MCP M2M Oauth2 support (#20788)
* add has_client_credentials
* MCPOAuth2TokenCache
* init MCP Oauth2 constants
* MCPOAuth2TokenCache
* resolve_mcp_auth
* test fixes
* docs fix
* address greptile review: min TTL, env-configurable constants, tests, docs
- Fix zero-TTL edge case: floor at MCP_OAUTH2_TOKEN_CACHE_MIN_TTL (10s)
- Make all MCP OAuth2 constants env-configurable via os.getenv()
- Move test file to follow 1:1 mapping convention (test_oauth2_token_cache.py)
- Add MCP OAuth doc page (mcp_oauth.md) with M2M and PKCE sections
- Update FAQ in mcp.md to reflect M2M support
- Add E2E test script and config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix mypy lint
* fix oauth2
* remove old files
* docs fix
* address greptile comments
* fix: atomic lock creation + validate JSON response shape
- Use dict.setdefault() for atomic per-server lock creation
- Add isinstance(body, dict) check before accessing token response fields
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace asserts with proper guards, wrap HTTP errors with context
- Replace `assert` statements with `if/raise ValueError` (asserts can be
disabled with python -O in production)
- Wrap `httpx.HTTPStatusError` to provide a clear error message with
server_id and status code
- Add tests for HTTP error and non-dict JSON response error paths
- Remove unused imports
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* [UI] M2M OAuth2 UI Flow (#20794)
* add has_client_credentials
* MCPOAuth2TokenCache
* init MCP Oauth2 constants
* MCPOAuth2TokenCache
* resolve_mcp_auth
* test fixes
* docs fix
* address greptile review: min TTL, env-configurable constants, tests, docs
- Fix zero-TTL edge case: floor at MCP_OAUTH2_TOKEN_CACHE_MIN_TTL (10s)
- Make all MCP OAuth2 constants env-configurable via os.getenv()
- Move test file to follow 1:1 mapping convention (test_oauth2_token_cache.py)
- Add MCP OAuth doc page (mcp_oauth.md) with M2M and PKCE sections
- Update FAQ in mcp.md to reflect M2M support
- Add E2E test script and config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix mypy lint
* fix oauth2
* ui feat fixes
* test M2M
* test fix
* ui feats
* ui fixes
* ui fix client ID
* fix: backend endpoints
* docs fix
* fixes greptile
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* [Fix] prevent shared backend model key from being polluted by per-deployment custom pricing (#20679)
* bug: custom price override for models
* added associated test
* fix(mcp): resolve OAuth2 root endpoints returning "MCP server not found" (#20784)
When MCP SDK hits root-level /register, /authorize, /token without
server name prefix, auto-resolve to the single configured OAuth2
server. Also fix WWW-Authenticate header to use correct public URL
behind reverse proxy.
* Add support for langchain_aws via litellm passthrough
* fix(proxy): return early instead of raising ValueError when standard_logging_payload is missing
The `_PROXY_VirtualKeyModelMaxBudgetLimiter.async_log_success_event` hook
raises `ValueError` when `standard_logging_payload` is `None`. This breaks
non-standard call types (e.g. vLLM `/classify`) that do not populate the
payload, and the resulting exception disrupts downstream success callbacks
like Langfuse.
Return early with a debug log instead, matching the existing pattern used
for missing `user_api_key_model_max_budget`.
Fixes#18986
---------
Co-authored-by: Sameer Kankute <sameer@berri.ai>
Co-authored-by: yuneng-jiang <yuneng.jiang@gmail.com>
Co-authored-by: Ishaan Jaff <ishaanjaffer0324@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Shivam Rawat <161387515+shivamrawat1@users.noreply.github.com>
Co-authored-by: michelligabriele <gabriele.michelli@icloud.com>
* fix: redaction headers ignored when sent via proxy
When requests go through the proxy, `litellm_params["litellm_metadata"]`
is always set (even when `None`), so `get_metadata_variable_name_from_kwargs`
always returns "litellm_metadata". The redaction code then reads `None`
instead of the actual metadata dict that contains the headers.
Add a fallback to read from `metadata` when `litellm_metadata` is not a
dict, so `x-litellm-enable-message-redaction` and related headers work
correctly in the proxy flow.
Fixes#20739
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: normalize non-dict metadata after fallback in redact_messages
After falling back from litellm_metadata to metadata, ensure the value
is always a dict so .get("headers") never raises on None/non-dict inputs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix(batch_completion): submit all model futures before waiting
* test: add batch_completion all responses concurrency regression
* fix(batch_completion): continue collecting responses on per-model failures
* fix(batch_completion): handle empty and string models in all responses
* test(batch_completion): avoid blocking wait in concurrency regression
The provider-prefixed entries (deepseek/deepseek-chat, deepseek/deepseek-reasoner)
in the model cost map were missing supports_response_schema, supports_system_messages,
supports_native_streaming, supports_parallel_function_calling, and had stale
max_input_tokens / max_output_tokens values. This caused supports_response_schema()
to return False for DeepSeek models regardless of calling convention.
Changes:
- Sync deepseek/deepseek-chat and deepseek/deepseek-reasoner entries with
their canonical bare-name counterparts in both JSON files
- Add a bare-model-name fallback in _supports_factory so that when a
provider-prefixed entry is missing a capability field, the bare model
entry is consulted before returning False
- Fix pre-existing unused-import lint error (F401) in policy_resolve_endpoints.py
- Add 14 regression tests covering data consistency, API-level correctness,
and the new fallback logic