From 8afdac55fd8d8c8eb5389d846965c8e8896a5519 Mon Sep 17 00:00:00 2001 From: Amar K P Date: Thu, 1 Oct 2026 20:30:54 +0530 Subject: [PATCH 1/2] test(llm): test that create_llm_client_from_settings wraps live providers with retry --- tests/unit/test_llm_factory.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_llm_factory.py b/tests/unit/test_llm_factory.py index f0d6cc0..5f748ba 100644 --- a/tests/unit/test_llm_factory.py +++ b/tests/unit/test_llm_factory.py @@ -42,15 +42,21 @@ def test_create_unknown_provider_raises() -> None: create_llm_client(provider="claude") +from agentkit.llm.retry import RetryingLLMClient + + def test_create_from_settings_gemini() -> None: settings = Settings( LLM_PROVIDER="gemini", LLM_MODEL="gemini-2.0-flash", GEMINI_API_KEY="test-gemini-key", + MAX_RETRIES=3, ) client = create_llm_client_from_settings(settings) - assert isinstance(client, GeminiClient) + assert isinstance(client, RetryingLLMClient) + assert isinstance(client._client, GeminiClient) assert client.model == "gemini-2.0-flash" + assert client._max_retries == 3 def test_create_from_settings_openai() -> None: @@ -58,13 +64,30 @@ def test_create_from_settings_openai() -> None: LLM_PROVIDER="openai", LLM_MODEL="gpt-4o", OPENAI_API_KEY="test-openai-key", + MAX_RETRIES=2, ) client = create_llm_client_from_settings(settings) - assert isinstance(client, OpenAIClient) + assert isinstance(client, RetryingLLMClient) + assert isinstance(client._client, OpenAIClient) assert client.model == "gpt-4o" + assert client._max_retries == 2 + + +def test_create_from_settings_zero_retries() -> None: + settings = Settings( + LLM_PROVIDER="gemini", + LLM_MODEL="gemini-2.0-flash", + GEMINI_API_KEY="test-gemini-key", + MAX_RETRIES=0, + ) + client = create_llm_client_from_settings(settings) + assert isinstance(client, GeminiClient) + assert not isinstance(client, RetryingLLMClient) def test_create_from_settings_fake() -> None: settings = Settings(LLM_PROVIDER="fake") client = create_llm_client_from_settings(settings) assert isinstance(client, FakeLLMClient) + assert not isinstance(client, RetryingLLMClient) + From e244f09512bbe47c1dd848a231d668894d7d94bd Mon Sep 17 00:00:00 2001 From: Amar K P Date: Thu, 1 Oct 2026 20:32:42 +0530 Subject: [PATCH 2/2] feat(llm): wire RetryingLLMClient with MAX_RETRIES in LLM factory --- agentkit/config.py | 5 +++++ agentkit/llm/factory.py | 13 +++++++++++-- tests/unit/test_llm_factory.py | 5 +---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/agentkit/config.py b/agentkit/config.py index 3fc702f..1121ada 100644 --- a/agentkit/config.py +++ b/agentkit/config.py @@ -71,6 +71,11 @@ class Settings(BaseSettings): gt=0, description="Maximum execution steps allowed per agent run.", ) + MAX_RETRIES: int = Field( + default=3, + ge=0, + description="Maximum retries on transient LLM errors.", + ) RUN_TIMEOUT_S: int = Field( default=60, gt=0, diff --git a/agentkit/llm/factory.py b/agentkit/llm/factory.py index e840cf0..56168d5 100644 --- a/agentkit/llm/factory.py +++ b/agentkit/llm/factory.py @@ -8,6 +8,7 @@ from agentkit.llm.fake import FakeLLMClient from agentkit.llm.gemini import GeminiClient from agentkit.llm.openai import OpenAIClient +from agentkit.llm.retry import RetryingLLMClient logger = logging.getLogger(__name__) @@ -59,7 +60,7 @@ def create_llm_client_from_settings(settings: Settings) -> LLMClient: settings: Application Settings instance. Returns: - Configured LLMClient instance. + Configured LLMClient instance (wrapped with RetryingLLMClient for live providers). """ provider = settings.LLM_PROVIDER.strip().lower() api_key: str | None = None @@ -69,8 +70,16 @@ def create_llm_client_from_settings(settings: Settings) -> LLMClient: elif provider == "openai": api_key = settings.OPENAI_API_KEY - return create_llm_client( + client = create_llm_client( provider=provider, api_key=api_key, model=settings.LLM_MODEL, ) + + if provider in ("gemini", "openai") and settings.MAX_RETRIES > 0: + return RetryingLLMClient( + client=client, + max_retries=settings.MAX_RETRIES, + ) + + return client diff --git a/tests/unit/test_llm_factory.py b/tests/unit/test_llm_factory.py index 5f748ba..2f4afc9 100644 --- a/tests/unit/test_llm_factory.py +++ b/tests/unit/test_llm_factory.py @@ -5,6 +5,7 @@ from agentkit.llm.fake import FakeLLMClient from agentkit.llm.gemini import GeminiClient from agentkit.llm.openai import OpenAIClient +from agentkit.llm.retry import RetryingLLMClient def test_create_fake_client() -> None: @@ -42,9 +43,6 @@ def test_create_unknown_provider_raises() -> None: create_llm_client(provider="claude") -from agentkit.llm.retry import RetryingLLMClient - - def test_create_from_settings_gemini() -> None: settings = Settings( LLM_PROVIDER="gemini", @@ -90,4 +88,3 @@ def test_create_from_settings_fake() -> None: client = create_llm_client_from_settings(settings) assert isinstance(client, FakeLLMClient) assert not isinstance(client, RetryingLLMClient) -