mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-10 08:28:25 +00:00
Merge 6c97c678ab into 3b8ad37296
This commit is contained in:
commit
f55167a317
2 changed files with 50 additions and 24 deletions
|
|
@ -2098,18 +2098,7 @@ def client(original_function):
|
|||
return result
|
||||
except Exception as e:
|
||||
if call_type == CallTypes.completion.value:
|
||||
num_retries = kwargs.get("num_retries", None) or litellm.num_retries or None
|
||||
if kwargs.get("retry_policy", None):
|
||||
get_num_retries_from_retry_policy: Callable[..., int | None] = (
|
||||
litellm_utils.get_num_retries_from_retry_policy
|
||||
)
|
||||
reset_retry_policy = litellm_utils.reset_retry_policy
|
||||
num_retries = get_num_retries_from_retry_policy(
|
||||
exception=e,
|
||||
retry_policy=kwargs.get("retry_policy"),
|
||||
)
|
||||
kwargs["retry_policy"] = reset_retry_policy() # prevent infinite loops
|
||||
litellm.num_retries = None # set retries to None to prevent infinite loops
|
||||
num_retries, kwargs = _get_wrapper_num_retries(kwargs=kwargs, exception=e)
|
||||
context_window_fallback_dict: Final = kwargs.get("context_window_fallback_dict", {})
|
||||
|
||||
is_completion_litellm_router_call: Final = _is_litellm_router_call(kwargs, is_async=False)
|
||||
|
|
@ -2135,16 +2124,7 @@ def client(original_function):
|
|||
kwargs["model"] = context_window_fallback_dict[model]
|
||||
return original_function(*args, **kwargs)
|
||||
elif call_type == CallTypes.responses.value:
|
||||
num_retries = kwargs.get("num_retries", None) or litellm.num_retries or None
|
||||
if kwargs.get("retry_policy", None):
|
||||
get_num_retries_from_retry_policy = litellm_utils.get_num_retries_from_retry_policy
|
||||
reset_retry_policy = litellm_utils.reset_retry_policy
|
||||
num_retries = get_num_retries_from_retry_policy(
|
||||
exception=e,
|
||||
retry_policy=kwargs.get("retry_policy"),
|
||||
)
|
||||
kwargs["retry_policy"] = reset_retry_policy() # prevent infinite loops
|
||||
litellm.num_retries = None # set retries to None to prevent infinite loops
|
||||
num_retries, kwargs = _get_wrapper_num_retries(kwargs=kwargs, exception=e)
|
||||
|
||||
is_responses_litellm_router_call: Final = _is_litellm_router_call(kwargs, is_async=False)
|
||||
if (
|
||||
|
|
@ -2436,7 +2416,6 @@ def client(original_function):
|
|||
num_retries and not is_acompletion_litellm_router_call and not isinstance(e, ImportError)
|
||||
): # only enter this if call is not from litellm router/proxy. router has it's own logic for retrying
|
||||
try:
|
||||
litellm.num_retries = None # set retries to None to prevent infinite loops
|
||||
kwargs["num_retries"] = num_retries
|
||||
kwargs["original_function"] = original_function
|
||||
if isinstance(e, openai.RateLimitError): # rate limiting specific error
|
||||
|
|
@ -2467,7 +2446,6 @@ def client(original_function):
|
|||
num_retries and not is_aresponses_litellm_router_call and not isinstance(e, ImportError)
|
||||
): # only enter this if call is not from litellm router/proxy. router has it's own logic for retrying
|
||||
try:
|
||||
litellm.num_retries = None # set retries to None to prevent infinite loops
|
||||
kwargs["num_retries"] = num_retries
|
||||
kwargs["original_function"] = original_function
|
||||
if isinstance(e, openai.RateLimitError): # rate limiting specific error
|
||||
|
|
|
|||
|
|
@ -10880,3 +10880,51 @@ def test_get_optional_params_forwards_a_tool_config_cache_point_to_a_downstream_
|
|||
)
|
||||
|
||||
assert optional_params["extra_body"] == {"kept": True, "cache_control_injection_points": [point]}
|
||||
|
||||
|
||||
_FAILING_CALL_CASES: Final = (
|
||||
pytest.param("completion", "chat/completions", {"messages": [{"role": "user", "content": "hi"}]}, id="completion"),
|
||||
pytest.param("responses", "responses", {"input": "hi"}, id="responses"),
|
||||
)
|
||||
_FAILING_ASYNC_CALL_CASES: Final = (
|
||||
pytest.param(
|
||||
"acompletion", "chat/completions", {"messages": [{"role": "user", "content": "hi"}]}, id="acompletion"
|
||||
),
|
||||
pytest.param("aresponses", "responses", {"input": "hi"}, id="aresponses"),
|
||||
)
|
||||
|
||||
|
||||
@respx.mock
|
||||
@pytest.mark.parametrize("call_name, path, payload", _FAILING_CALL_CASES)
|
||||
def test_failed_call_keeps_global_num_retries_for_later_calls(
|
||||
monkeypatch: pytest.MonkeyPatch, call_name: str, path: str, payload: dict[str, object]
|
||||
) -> None:
|
||||
monkeypatch.setattr(litellm, "num_retries", 3)
|
||||
route: Final = respx.post(f"https://api.openai.com/v1/{path}").respond(500, json={"error": {"message": "boom"}})
|
||||
call: Final = getattr(litellm, call_name)
|
||||
|
||||
for _ in range(2):
|
||||
with pytest.raises(litellm.InternalServerError):
|
||||
call(model="openai/gpt-5.6", api_key="sk-test", max_retries=0, **payload)
|
||||
|
||||
assert route.call_count == 8
|
||||
assert litellm.num_retries == 3
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
@pytest.mark.parametrize("call_name, path, payload", _FAILING_ASYNC_CALL_CASES)
|
||||
async def test_failed_async_call_keeps_global_num_retries_for_later_calls(
|
||||
monkeypatch: pytest.MonkeyPatch, call_name: str, path: str, payload: dict[str, object]
|
||||
) -> None:
|
||||
monkeypatch.setattr(litellm, "num_retries", 3)
|
||||
monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
|
||||
route: Final = respx.post(f"https://api.openai.com/v1/{path}").respond(500, json={"error": {"message": "boom"}})
|
||||
call: Final = getattr(litellm, call_name)
|
||||
|
||||
for _ in range(2):
|
||||
with pytest.raises(litellm.InternalServerError):
|
||||
await call(model="openai/gpt-5.6", api_key="sk-test", max_retries=0, **payload)
|
||||
|
||||
assert route.call_count == 8
|
||||
assert litellm.num_retries == 3
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue