NVIDIA / NVIDIA/NeMo-Agent-Toolkit
fix: LLM, embedder, and memory framework adapters ignore do_auto_retry=False
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.6k
- Forks
- 762
- Avg merge
- 21h 28m
- Merged PRs (30d)
- 27
Description
Version
develop (and v1.9.0-rc3)
Which installation method(s) does this occur on?
Source
Describe the bug.
RetryMixin provides do_auto_retry: bool = Field(default=True, description="Whether to automatically retry method calls that fail with a retryable error.", exclude=True) and num_retries: int = Field(default=5, gt=0, ...).
Because num_retries validates gt=0, users cannot disable retries by specifying num_retries: 0. Setting do_auto_retry: false in workflow configurations is the documented and tested mechanism to disable retries (as tested in test_retry_mixin.py: test_disabling_retries_uses_do_auto_retry).
While evaluator integrations (langsmith_judge.py, trajectory_evaluator.py, ragas, remote_workflow.py) properly check if config.do_auto_retry:, all runtime framework adapters for LLMs, embedders, and memory editors only check:
if isinstance(llm_config, RetryMixin):
client = patch_with_retry(...)
(or in nvidia_nat_memmachine, call patch_with_retry unconditionally without any check).
Because all provider configs (OpenAIModelConfig, NIMModelConfig, AzureOpenAIModelConfig, AWSBedrockModelConfig, etc.) inherit from RetryMixin, isinstance(..., RetryMixin) is always True. As a result, setting do_auto_retry: false in YAML or configuration is completely ignored across:
nvidia_nat_langchain(LLMs & embedders)nvidia_nat_llama_index(LLMs & embedders)nvidia_nat_agno(LLMs)nvidia_nat_autogen(LLMs)nvidia_nat_crewai(LLMs)nvidia_nat_semantic_kernel(LLMs)nvidia_nat_strands(LLMs)nvidia_nat_mem0ai(memory)nvidia_nat_memmachine(memory)nvidia_nat_zep_cloud(memory)
When a retryable error occurs (e.g., HTTP 429, 500, 503), the client retries 5 times with exponential backoff instead of failing immediately as requested by the user.
Expected Behavior
When do_auto_retry: false is configured, client wrappers should not wrap the instance with patch_with_retry, allowing immediate failure and honoring user configuration.
Minimum reproducible example
import asyncio
from unittest.mock import MagicMock, patch
from nat.llm.openai_llm import OpenAIModelConfig
from nat.plugins.langchain.llm import openai_langchain
class DummyChat:
def __init__(self):
self.attempts = 0
self.model_kwargs = {}
async def ainvoke(self, *args, **kwargs):
self.attempts += 1
print(f"Attempt {self.attempts}")
raise RuntimeError("429 Too Many Requests")
async def main():
cfg = OpenAIModelConfig(model_name="gpt-4o-mini", do_auto_retry=False)
mock_builder = MagicMock()
dummy = DummyChat()
with patch("langchain_openai.ChatOpenAI", return_value=dummy):
async with openai_langchain(cfg, mock_builder) as client:
try:
await client.ainvoke("hello")
except Exception:
print(f"Total attempts made: {dummy.attempts}")
asyncio.run(main())
Relevant log output
Attempt 1
Attempt 2
Attempt 3
Attempt 4
Attempt 5
Total attempts made: 5
(Expected: 1 attempt, but 5 attempts were executed because patch_with_retry was applied despite do_auto_retry=False.)
Other/Misc.
I have verified the fix and will submit a PR linking to this issue.
Code of Conduct
- I agree to follow the NeMo Agent Toolkit Code of Conduct
- I have searched the open bugs and have found no duplicates for this bug report
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with test_retry_mixin.py and trace patch_with_retry through the runtime adapters named in the issue, including the LLM, embedder, and memory integrations. Compare them with the evaluator integrations that already inspect do_auto_retry. Done means each listed adapter honors do_auto_retry: false and retry behavior is covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100