* Fix MCP health check CancelledError handling for parallel test execution
Add asyncio.CancelledError handler in health_check_server() and missing
@pytest.mark.asyncio decorator on test_mcp_server_manager_config_integration_with_database.
In Python 3.8+, CancelledError inherits from BaseException, not Exception,
so it bypassed the generic exception handler when pytest-xdist cancels
running tasks after a failure.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Regenerate poetry.lock to resolve merge conflict markers
The lock file had unresolved conflict markers from a previous merge,
causing poetry to fail with "Invalid statement (at line 8534, column 1)".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Split tests/test_litellm into 10 parallel CI jobs using GitHub Actions
matrix strategy to reduce PR feedback time from ~25 min to ~8-10 min.
Changes:
- Add new test-litellm-matrix.yml workflow with 10 matrix jobs:
- llms (~225 files, 4 workers)
- proxy-guardrails (~51 files, 4 workers)
- proxy-core (~52 files, 4 workers)
- proxy-misc (~77 files, 4 workers)
- integrations (~60 files, 4 workers)
- core-utils (~32 files, 2 workers)
- other (~69 files, 4 workers) - includes all previously uncovered dirs
- root (~34 files, 4 workers)
- proxy-unit-a (~20 files, 2 workers)
- proxy-unit-b (~28 files, 2 workers)
- Deprecate test-litellm.yml (moved to workflow_dispatch for manual use)
- Add matching Makefile targets for local testing:
- make test-unit-llms
- make test-unit-proxy-guardrails
- make test-unit-proxy-core
- make test-unit-proxy-misc
- make test-unit-integrations
- make test-unit-core-utils
- make test-unit-other
- make test-unit-root
- make test-proxy-unit-a
- make test-proxy-unit-b
Benefits:
- ~3x faster wall-clock time through parallelization
- Dependency caching for faster subsequent runs
- Concurrency control to cancel stale runs
- Better failure isolation per test group
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
- Fix skip condition to detect claude models (was only checking for
"anthropic" in model name, missing "claude-haiku-4-5")
- Add missing skip for OpenAI tests when OPENAI_API_KEY is not set
- Fix TypeError in utils.py when metadata is explicitly None instead
of missing (use `or {}` fallback)
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>
* 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>