[Feat]: Add RetryTransport for automatic retry with exponential backoff
还没有人认领这个 Issue。
评估
调研方向
查看现有的传输类(JsonRpcTransport、RestTransport、GrpcTransport)以及 TenantTransportDecorator 模式。新的 RetryTransport 必须能够包装任意 ClientTransport。首先检查 SDK 的异常层次结构(A2AClientError、A2AClientTimeoutError),以及它们如何链接 httpx 和 grpc 错误。为 retry predicate 和 on_retry hook 编写测试。确保该实现适用于全部三种传输,并且不会重试领域错误。
由索引模型根据 Issue 内容生成。
描述
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).A2AClientErrorchained fromhttpx.RequestErrororhttpx.HTTPStatusError(408/429/502/503/504).A2AClientErrorchained fromgrpc.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,GrpcTransportand 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
- 主要语言
- Python
- 星标
- 2.2k
- 派生
- 496
- 平均合并
- 2 天 6 小时
- 30 天内合并 PR
- 19
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
a2aproject/a2a-python 的其他 Issue
-
component: server status:awaiting response
难度 2/5 1-3 小时 新手友好度 75/100
a2aproject/a2a-python#1237 · 2 条评论 · 已指派 1 人 ·
-
component: server status:awaiting response status:stale
难度 2/5 1-3 小时 新手友好度 75/100
a2aproject/a2a-python#1215 · 2 条评论 · 已指派 1 人 ·
-
component: server status:awaiting response status:stale
难度 2/5 1-3 小时 新手友好度 75/100
a2aproject/a2a-python#1205 · 3 条评论 · 已指派 1 人 ·
-
component: server status:awaiting response status:stale
难度 2/5 1-3 小时 新手友好度 75/100
a2aproject/a2a-python#1204 · 2 条评论 · 已指派 1 人 ·
-
component: server
难度 2/5 1-3 小时 新手友好度 70/100
a2aproject/a2a-python#1192 · 3 条评论 · 已指派 1 人 ·
查看 a2aproject/a2a-python 的全部 Issue
相似的 Issue
-
agent-ready documentation needs-triage
难度 1/5 1-3 小时 新手友好度 88/100
-
documentation
难度 1/5 1 小时以内 新手友好度 91/100
-
workflow-status page template still says reusable workflows are "triggered only by workflow_call:" 未关闭
难度 1/5 1 小时以内 新手友好度 92/100
-
instance instance add
难度 1/5 1 小时以内 新手友好度 72/100
searxng/searx-instances#939 · 1 条评论 ·
-
area-deployment area-integrations triage:bot-seen
难度 2/5 半天 新手友好度 86/100