Conversation
…ardization, and utilities
Core infrastructure improvements:
- Smart 'latest' model alias resolution with cost-based tiebreaking
- Standardized error responses with proper HTTP status codes and error.code field
- ProxyExhaustionError for structured credential exhaustion reporting
- TerminalRequestError for non-rotatable errors (404, model not found)
- Per-provider retry count override via MAX_RETRIES_{PROVIDER} env var
- Retry 429 rate_limit errors with backoff instead of rotating
- Cached token pricing in streaming cost calculation
- Split quota stats into current_period and global/lifetime views
- Log rotation for proxy.log and proxy_debug.log (RotatingFileHandler)
- Include latest virtual models in /v1/models endpoint
- Resolve singleton cache pollution for dynamic providers
- Fork-specific README and .gitignore updates
…ased model filtering, and enhanced X-Initiator heuristic
Test suite designed to catch breakage from branch re-organization without sending queries to real LLM providers. Covers all critical integration points that previously broke silently during deployment. Coverage: - Anthropic↔OpenAI format translation & streaming - Error classification (determines retry/rotation behavior) - Request sanitization (prevents 400s from invalid params) - Provider-specific request transforms - Model alias & latest registry parsing - Usage tracking (windows, quota groups, custom caps) - Credential discovery, deduplication, env:// URI - Provider plugin registration & singleton pattern - Proxy endpoint routing & auth All tests use synthetic credentials and mocked HTTP. Runs in ~2.3s. Zero API cost.
…flow Replaces the old manifest-driven multi-branch replay system with a simpler linear commit stack. Changes are made via fixup!/autosquash. Upstream syncs are a single git rebase. Includes: - AGENTS.md: entry point for all AI coding agents - .agent/rules/claude.md: Claude-specific SSH/deployment notes - .agent/rules/llm-proxy.md: container layout and deployment pipeline - .agent/skills/upstream-sync/SKILL.md: sync workflow reference
Custom provider for Google Vertex AI Express Mode API keys that uses x-goog-api-key header authentication against the Vertex AI OpenAI-compatible endpoint. Supports non-streaming and streaming chat completions with automatic model discovery. Models are prefixed as vertex/ (e.g. vertex/gemini-3.1-flash-lite-preview). Env vars: VERTEX_PROJECT, VERTEX_LOCATION, VERTEX_API_KEY_N
Added tests for get_provider_route in litellm_providers.py covering different trailing slash configurations and edge cases.
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Code Review
This pull request introduces a new test suite for the get_provider_route function in tests/rotator_library/test_litellm_providers.py, covering scenarios such as trailing slashes, empty routes, and missing keys. The reviewer suggested refactoring these tests using pytest.mark.parametrize to eliminate repetitive code and improve maintainability.
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | ||
| def test_get_provider_route_with_trailing_slash(): | ||
| assert get_provider_route("provider_with_slash") == "myroute" | ||
|
|
||
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | ||
| def test_get_provider_route_without_trailing_slash(): | ||
| assert get_provider_route("provider_without_slash") == "myroute" | ||
|
|
||
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | ||
| def test_get_provider_route_empty(): | ||
| assert get_provider_route("provider_empty_route") is None | ||
|
|
||
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | ||
| def test_get_provider_route_missing_key(): | ||
| assert get_provider_route("provider_no_route") is None | ||
|
|
||
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | ||
| def test_get_provider_route_unknown_provider(): | ||
| assert get_provider_route("unknown_provider") is None |
There was a problem hiding this comment.
The test suite for get_provider_route can be significantly simplified and made more maintainable by using pytest.mark.parametrize. This avoids repeating the @patch decorator and the function structure for each test case, making it easier to add new scenarios in the future.
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| def test_get_provider_route_with_trailing_slash(): | |
| assert get_provider_route("provider_with_slash") == "myroute" | |
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| def test_get_provider_route_without_trailing_slash(): | |
| assert get_provider_route("provider_without_slash") == "myroute" | |
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| def test_get_provider_route_empty(): | |
| assert get_provider_route("provider_empty_route") is None | |
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| def test_get_provider_route_missing_key(): | |
| assert get_provider_route("provider_no_route") is None | |
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| def test_get_provider_route_unknown_provider(): | |
| assert get_provider_route("unknown_provider") is None | |
| @patch("rotator_library.litellm_providers.SCRAPED_PROVIDERS", MOCK_PROVIDERS) | |
| @pytest.mark.parametrize( | |
| "provider_key, expected_route", | |
| [ | |
| ("provider_with_slash", "myroute"), | |
| ("provider_without_slash", "myroute"), | |
| ("provider_empty_route", None), | |
| ("provider_no_route", None), | |
| ("unknown_provider", None), | |
| ], | |
| ) | |
| def test_get_provider_route(provider_key, expected_route): | |
| assert get_provider_route(provider_key) == expected_route |
|
[Gemini-CLI Review Skill] @jules Reviewing this PR against the checklist and Gemini Code Assist feedback:
|
I have updated the test file to use |
Refactored tests for get_provider_route to use parametrization, added test cases for non-string config routes, and updated the original logic to gracefully handle non-string routes.
Refactored tests for get_provider_route to use parametrization, added test cases for non-string config routes, and updated the original logic to gracefully handle non-string routes.
|
[Gemini-CLI Review Skill] @jules Great work on the |
I have removed the |
Refactored tests for get_provider_route to use parametrization, added test cases for non-string config routes, and updated the original logic to gracefully handle non-string routes.
Refactored tests for get_provider_route to use parametrization, added test cases for non-string config routes, and updated the original logic to gracefully handle non-string routes.
|
[Gemini-CLI Review Skill] Consolidated into the linear commit stack on dev. |
Acknowledged. This issue is resolved. |
🎯 What: The testing gap addressed for
get_provider_routewhich was missing tests.📊 Coverage: Scenarios covered: providers with trailing slash, without trailing slash, empty route, missing route key, and unknown provider.
✨ Result: The improvement in test coverage allows for confident refactoring of
get_provider_routeand litellm providers code.PR created automatically by Jules for task 17306181585139002901 started by @b3nw