Skip to content

[Feat]: Add RetryTransport for automatic retry with exponential backoff #871

Description

@cchinchilla-dev

Is your feature request related to a problem? Please describe.

The SDK's transports (JsonRpcTransport, RestTransport, GrpcTransport) raise immediately on transient failures (network errors, timeouts, rate limits, 5xx responses, gRPC UNAVAILABLE/RESOURCE_EXHAUSTED) with no built-in retry mechanism. Every caller has to reimplement the same retry/backoff loop, and to do it correctly they have to inspect __cause__ chains because A2AClientError doesn't expose HTTP status codes or gRPC codes directly.

Describe the solution you'd like

A RetryTransport decorator wrapping any ClientTransport, mirroring the existing TenantTransportDecorator pattern:

inner = JsonRpcTransport(httpx_client=client, agent_card=card)
transport = RetryTransport(base=inner, max_retries=3)

The default predicate retries on:

  • A2AClientTimeoutError (always).
  • A2AClientError chained from httpx.RequestError or httpx.HTTPStatusError(408/429/502/503/504).
  • A2AClientError chained from grpc.aio.AioRpcError(UNAVAILABLE/RESOURCE_EXHAUSTED).
  • Domain errors (TaskNotFoundError, etc.) are never retried.

retry_predicate is configurable for custom logic, and on_retry is exposed as a hook for logging/metrics. Streaming methods (send_message_streaming, subscribe) only retry before the first event is yielded.

Describe alternatives you've considered

  • Retry via ClientCallInterceptor — not feasible; after() only fires on successful results, so interceptors never see exceptions.
  • Transport-specific retry (httpx custom transport, gRPC retryPolicy / UnaryUnaryClientInterceptor) — operates below the SDK's exception layer, requires two separate configurations, and doesn't cover all three transports uniformly.
  • Retry inside each transport implementation — triples the logic across JsonRpcTransport, RestTransport, GrpcTransport and forces every future transport to reimplement it.

Additional context

Purely additive: new RetryTransport class, tests, and one export change. No new dependencies — the grpc import is conditional, matching the SDK's existing pattern. ClientFactory integration is left as a follow-up.

Code of Conduct

  • I agree to follow this project's Code of Conduct

Activity

  1. cchinchilla-dev commented on Mar 19, 2026

    @cchinchilla-dev
    ContributorAuthor

    Note: the corrections below are now folded into the issue description above; full implementation details live in PR, as requested in review.

  2. self-assigned this
    on Mar 25, 2026
  3. added
    component: clientIssues related to transport logic and configuration for external apps connecting to A2A agents.
    on Mar 25, 2026
  4. rohityan commented on Mar 25, 2026

    @rohityan

    Hi @cchinchilla-dev , thanks for the detailed approach. Please submit a PR when you are ready.

  5. cchinchilla-dev commented on Mar 25, 2026

    @cchinchilla-dev
    ContributorAuthor

    @rohityan Thanks for the confirmation. I’m finalizing the implementation and will submit the PR shortly.

  6. cchinchilla-dev commented on Apr 22, 2026

    @cchinchilla-dev
    ContributorAuthor

    Hi @ishymko — congrats on the v1 release! I see this PR was closed when 1.0-dev was deleted as part of the cleanup. Is this feature still of interest for a future release? Happy to rebase onto whichever branch is the right target now. Thanks!

  7. ishymko commented on Apr 24, 2026

    @ishymko
    Member

    Hi @cchinchilla-dev, thank you!

    Yeah the PR got auto-closed due to branch removal, this branch was merged to main now after 1.0 stable release.

    It makes sense conceptually but details require careful review, would you mind consolidating PR description, issue description and 1.0-dev notes comment (and update this issue description)? Lower level details can be discussed in the PR, let's focus on the most important aspects to make it more compact.

    Thank you!

  8. cchinchilla-dev commented on Apr 25, 2026

    @cchinchilla-dev
    ContributorAuthor

    Hi @ishymko, thanks for the quick reply!

    Consolidated as suggested: issue trimmed to rationale + alternatives, and implementation details + validation are in #1018.

    Fully agree this needs careful review. No rush — happy to iterate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

component: clientIssues related to transport logic and configuration for external apps connecting to A2A agents.

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions