Agno's ClaudeAgent and CodexAgent now take retries, delay_between_retries and exponential_backoff with the same defaults as Agent, which are no retries, a one second delay and no backoff. A retry keeps the run id and resumes the Claude SDK session or Codex thread that the failed attempt started, so the model continues the conversation it already had.
Some errors would fail the same way twice, so Agno stops on them. A retry would hand max_turns, max_budget_usd or a Codex budget or usage limit a fresh allowance, and authentication, billing, bad requests, context window and policy errors don't heal on their own. A cancelled run ends right away, even during the backoff. The durable job queue honours the same verdict and fails the job at once, including after a worker restart.
A streaming client has already received the failed attempt's text when the retry starts. Before each new attempt, the stream yields an ExternalRunWarningEvent with type: "retry", so your client can reset the buffered text and keep the tool events. Tool calls from failed attempts stay on the stored run, each one exactly once, and metadata["attempts"] counts the attempts.
from agno.agents.base import ExternalRunWarningEvent
from agno.agents.claude import ClaudeAgent
agent = ClaudeAgent(
id="claude",
db=db,
retries=2,
delay_between_retries=1,
exponential_backoff=True,
)
for event in agent.run("Run echo alpha", session_id="s1", stream=True, yield_run_output=True):
if (
isinstance(event, ExternalRunWarningEvent)
and event.warning
and event.warning.get("type") == "retry"
):
print(event.warning["message"], "Delay:", event.warning["delay"])
run = event # the last item is the RunOutput
print(run.status, (run.metadata or {}).get("attempts", 1))
print([tool.tool_call_id for tool in run.tools])We ran it against the fake Claude SDK from the release's tests, which runs one Bash call and then fails with a 529 on the first two attempts:
Attempt 1 of 3 failed and is being retried; output streamed before this point came from the failed attempt. Delay: 1
Attempt 2 of 3 failed and is being retried; output streamed before this point came from the failed attempt. Delay: 2
RunStatus.completed 3
['call-1', 'call-2']The second and third attempts both resumed SDK session sdk-1. A retried attempt can run a tool again, so make tools with side effects outside the workspace safe to repeat before you turn retries on.
See the cookbook, and learn more about retries and tool effects in the documentation.
Frequently asked questions
Pass retries, delay_between_retries and exponential_backoff to ClaudeAgent or CodexAgent. They use the same defaults as Agent: 0 retries, a 1 second delay and no backoff.
Agno never retries max_turns or max_budget_usd limits, Codex budget and usage limits, authentication, billing, bad requests, context window or policy errors, or a cancelled run. Those would fail the same way again or hand the agent a fresh allowance.
Before each new attempt the stream yields an ExternalRunWarningEvent whose warning has type: "retry", plus attempt, attempts, delay and error. Text received before it came from the failed attempt.
No. The stored run keeps each tool call from every failed attempt once, alongside the final attempt's calls, and metadata["attempts"] records how many attempts the run took.


