From 3647875abaa74623e2c64cf59e07b711dbc93cc2 Mon Sep 17 00:00:00 2001 From: "Arthur K." Date: Thu, 16 Jul 2026 21:53:12 +0300 Subject: [PATCH] fix: add one second to retry after delays --- nanobot/providers/base.py | 4 +++- tests/providers/test_provider_retry.py | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/nanobot/providers/base.py b/nanobot/providers/base.py index 84610878..2b0ef332 100644 --- a/nanobot/providers/base.py +++ b/nanobot/providers/base.py @@ -20,6 +20,7 @@ from nanobot.utils.helpers import sanitize_surrogates_deep STREAM_IDLE_TIMEOUT_ENV = "NANOBOT_STREAM_IDLE_TIMEOUT_S" DEFAULT_STREAM_IDLE_TIMEOUT_S = 90.0 MAX_STREAM_IDLE_TIMEOUT_S = 3600.0 +RETRY_AFTER_BUFFER = 1 def resolve_stream_idle_timeout_s( @@ -965,8 +966,9 @@ class LLMProvider(ABC): ) break + retry_after = self._extract_retry_after_from_response(response) base_delay = delays[min(attempt - 1, len(delays) - 1)] - delay = self._extract_retry_after_from_response(response) or base_delay + delay = retry_after + RETRY_AFTER_BUFFER if retry_after else base_delay if persistent: delay = min(delay, self._PERSISTENT_MAX_DELAY) diff --git a/tests/providers/test_provider_retry.py b/tests/providers/test_provider_retry.py index e9b599cd..a00ad7ee 100644 --- a/tests/providers/test_provider_retry.py +++ b/tests/providers/test_provider_retry.py @@ -3,7 +3,7 @@ import copy import pytest -from nanobot.providers.base import GenerationSettings, LLMProvider, LLMResponse +from nanobot.providers.base import RETRY_AFTER_BUFFER, GenerationSettings, LLMProvider, LLMResponse class ScriptedProvider(LLMProvider): @@ -402,8 +402,8 @@ async def test_chat_with_retry_uses_retry_after_and_emits_wait_progress(monkeypa ) assert response.content == "ok" - assert delays == [7.0] - assert progress and "7s" in progress[0] + assert delays == [7.0 + RETRY_AFTER_BUFFER] + assert progress and f"{int(7 + RETRY_AFTER_BUFFER)}s" in progress[0] def test_extract_retry_after_supports_common_provider_formats() -> None: @@ -444,7 +444,7 @@ async def test_chat_with_retry_prefers_structured_retry_after_when_present(monke response = await provider.chat_with_retry(messages=[{"role": "user", "content": "hello"}]) assert response.content == "ok" - assert delays == [9.0] + assert delays == [9.0 + RETRY_AFTER_BUFFER] @pytest.mark.asyncio @@ -521,7 +521,7 @@ async def test_chat_with_retry_retries_429_transient_rate_limit(monkeypatch) -> assert response.content == "ok" assert provider.calls == 2 - assert delays == [0.2] + assert delays == [0.2 + RETRY_AFTER_BUFFER] @pytest.mark.asyncio @@ -591,7 +591,7 @@ async def test_chat_with_retry_prefers_structured_retry_after(monkeypatch) -> No response = await provider.chat_with_retry(messages=[{"role": "user", "content": "hello"}]) assert response.content == "ok" - assert delays == [0.2] + assert delays == [0.2 + RETRY_AFTER_BUFFER] @pytest.mark.asyncio