Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions agentkit/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 11 additions & 2 deletions agentkit/llm/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down Expand Up @@ -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
Expand All @@ -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
24 changes: 22 additions & 2 deletions tests/unit/test_llm_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -47,24 +48,43 @@ def test_create_from_settings_gemini() -> None:
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:
settings = Settings(
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)
Loading