RestrictedPython (ZPL-2.1, a BSD-style permissive license) was added as
a dependency for the custom_code guardrail sandbox, but the license
checker didn't recognize it. Add to authorized packages list.
- vertex_ai_context_caching.py: add explicit Optional[str] annotation on
auth_header so later branches that assign vertex_auth_header (Optional[str])
type-check against the first branch's dict assignment (which already has
type: ignore[assignment]).
- path_utils.py: remove unused pathlib.Path import (F401).
- emulated_handler.py: extract _extract_tool_call_fields,
_resolve_queries_from_args, _execute_file_search_tool_calls, and
_build_follow_up_input helpers to drop aresponses_with_emulated_file_search
below ruff's PLR0915 statement limit. Behavior unchanged.
Add null byte rejection to safe_join and safe_filename. Normalize
backslash separators in safe_filename for cross-platform safety.
Include resolved path in ValueError for debugging. Move imports
to module level per project conventions.
Add safe_join() and safe_filename() in proxy/common_utils/path_utils.py
for constructing filesystem paths from user-controlled inputs. Apply to
guardrail category YAML endpoint and dotprompt file converter.
- factory.py: fix _sort_bedrock_assistant_content_blocks to treat
cachePoint blocks with the same sort key as toolUse so Python's
stable sort keeps each cachePoint paired with its preceding toolUse
block (PR #24368)
- responses/transformation.py: remove cyclic import of OpenAIGPT5Config
inside map_openai_params; add _is_gpt_5_model and
_supports_reasoning_effort_none static methods that replicate the
same logic without the import cycle. _is_gpt_5_model now also
excludes pass-through models from other providers (e.g.
perplexity/openai/gpt-5.2) that contain 'gpt-5' in their name but
should not be subject to OpenAI GPT-5 temperature restrictions
(PR #24371)
- streaming_iterator.py: adopted main's more defensive version of the
tool-arg queueing check (.get() instead of [], isinstance guard) —
same logic, same behavior, lower crash surface
- model_prices_and_context_window.json + backup: combined staging's
search_context_cost_per_query fields (PR #24372) with main's new
supports_service_tier field — both are independent additions to the
same Gemini model entries
- test_streaming_handler.py: kept Azure streaming regression test
(PR #24354) and added main's two new Gemini legacy vertex
finish_reason normalization tests
- test_gemini_batch_embeddings.py: kept staging's unsupported-params
filtering tests (PR #24370) and added main's index/order test
Resolved conflicts:
- streaming_handler.py: combined role check (PR #24354, Azure streaming)
with reasoning_items check (new in main) — both are independent OR
conditions in is_chunk_non_empty()
- CI/CD: accepted main's versions throughout
- Redis tests migrated to CircleCI (PR #25354): removed enable-redis
from GH Actions workflows
- E2E UI tests restructured (PR #25365): simplified CircleCI job
- Coverage via Codecov added to all GH Actions unit test workflows
- Deleted test-litellm-matrix.yml and test-proxy-e2e-azure-batches.yml
(removed in main)
* [Test] Add Azure async chat completion timeout test. WIP
* Capture TTFT for /v1/messages streaming responses
The pass-through streaming path for /v1/messages (Anthropic, Bedrock,
Vertex AI, Azure AI, Minimax) logged completion_start_time only after
the entire stream finished. async_success_handler then fell back to
end_time, making TTFT equal to total duration or null in the UI and
Prometheus.
Record the timestamp of the first chunk in async_sse_wrapper and
propagate it to model_call_details before the logging handler runs,
so gen_ai.response.time_to_first_token reflects the real first-chunk
latency.
Fixes#25598
* [Refactor] Implement timeout resolution logic in completion function
add fetch ``request_timeout`` from litellm_settings
* remove stale test case
* remove extra print statement
* default request timeout value in constants to 600s to match timeout defaults handled in the proxy
* fix request timeout if using default value from constants.py
* update code structure, test cases
* only override if the global timeout sets timeout to 6000s
* update code structure, move hard coded values to const and make the reslve function readable by moving fallback logic to a seperate function
* modify default timeout values, replacing hard coded ones with default values defined
---------
Co-authored-by: harish876 <harishgokul01@gmail.com>
Co-authored-by: Joaquin Hui Gomez <joaquinhuigomez@users.noreply.github.com>
Tighten validation of request body parameters in the proxy routing
layer. Use context variables for internal call state management
instead of passing flags through request kwargs. Clean up metadata
handling at the proxy boundary.
Unit Tests: Proxy DB Operations / proxy-db (auth-checks, tests/proxy_unit_tests/test_auth_checks.py tests/proxy_unit_tests/test_user_api_key_auth.py, 20, 8) (push) Waiting to run
Unit Tests: Proxy DB Operations / proxy-db (remaining, tests/proxy_unit_tests --ignore=tests/proxy_unit_tests/test_key_generate_prisma.py --ignore=tests/proxy_unit_tests/test_auth_checks.py --ignore=tests/proxy_unit_tests/test_user_api_key_auth.py, 30, 8) (push) Waiting to run
* fix: make PodLockManager.release_lock atomic compare-and-delete
Re-lands #21226 (reverted in #21469).
release_lock() previously did GET + compare + DEL in separate calls,
leaving a window where another pod could reacquire the lock between
the GET and DEL, causing a stale owner to delete a live lock.
Fix: use a Redis Lua script for atomic compare-and-delete. Script
registration is cached per PodLockManager instance. Falls back to
the old GET+DEL path for cache backends that don't expose
async_register_script.
Original revert was due to e2e tests running in CI without Redis.
Those tests now carry @pytest.mark.skip(reason="Requires Redis connection.")
so this re-land is safe.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: add Lua fallback on execution error + test coverage gaps
Address Greptile review feedback on #24466:
1. Wrap Lua script execution in try/except — if Redis clears loaded
scripts (restart) or scripting is disabled, fall back to GET+DEL
rather than letting the exception propagate and leave the lock held
until TTL. Reset cached script handle so the next call re-registers.
2. Add test_release_lock_lua_path_emits_released_event — verifies
_emit_released_lock_event is called when Lua path returns 1.
3. Add test_release_lock_falls_back_to_get_del_when_lua_execution_fails
— verifies the fallback path is taken and script handle is reset.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
publish_proxy_extras is superseded by PyPI trusted publishing (OIDC);
the CircleCI project no longer has PYPI_PUBLISH_* credentials configured.
prisma_schema_sync is a leaf smoke test with no dependents, and db push
against the current schema is already exercised by e2e_ui_testing.