Pre-alpha 文档
调用 A2A Agent,不猜测执行结果。
冻结 A2A 1.0 Agent Card 与 Egress Interface,使用完整 HTTP+JSON 或 JSON-RPC/SSE Operation,并将 Outbound Send 绑定到 PostgreSQL Durability。
一套 Operation Surface,两种 Binding
| 领域 | Operation | Transport Result |
|---|---|---|
| Message | Send、Streaming Send | Task/Message 或有界 SSE |
| Task | Get、List、Cancel、Subscribe | 有界 Snapshot/Page 或 SSE |
| Push Config | Create、Get、List、Delete | Secret-redacted 有界 Contract |
| Card | Authenticated Extended Card | 重新校验的 Agent Card |
每个请求发送 A2A-Version: 1.0。Client 校验 Response Media、
JSON-RPC Version/ID、Result/Error 互斥存在、精确 Response Union、Duplicate
JSON Key、Resource Identity、Blocking-send Lifecycle、Task-page
Filter/Order、 SSE Event Lifecycle、Artifact Append 连续性、Idle
Time、Event Count 与 Byte Ceiling;不会跟随 Redirect,也不会自动 Retry
Request。
在执行前冻结 Discovery
- 使用已验证 HTTPS;Literal Loopback HTTP 只属于显式 Test/Sidecar Boundary。
- 读取一个有界 Public Agent Card,并可校验 RFC 8785 Digest。
- 按 Server Preference 选择首个受支持的 1.0 Interface。
- 要求其 Binding 和 URL 与本地 Egress Pin 精确一致。
- 校验 Extension、Tenant,以及完整的 Anonymous 或单 Scheme Bearer-compatible Security 选择。
let client = A2aClient::discover(
A2aAgentCardEndpoint::https(
"https://partner.example/.well-known/agent-card.json",
)?,
vec![A2aClientInterfacePin::https(
"https://partner.example/a2a",
A2aBinding::HttpJson,
)?],
A2aAgentCardTrust::TlsServerIdentity,
A2aClientSecurity::bearer("oidc", Arc::new(token_provider))?,
vec![],
A2aClientOptions::default(),
).await?; 生产 Bearer Provider 针对每个精确 Operation、Remote Routing Tenant、Task 与 Scope 解析短期 Credential。Durable Send 还会传递本地 Tenant、Run、Invocation 与 Physical Attempt Identity。当前 Profile 支持 HTTP Bearer、OAuth 2.0 与 OpenID Connect Token;不支持或 Multi-scheme Requirement 会 Fail Closed。 Token、Response Body 与 Remote Text 都不会进入 Public Error 或 Debug Output。
Extended Card 必须经过认证并重新校验,但只作为数据返回;它不会修改 Immutable Client,也不会静默改变 Egress/Security Pin。采用它必须经过审核并新建 Binding。
让 PostgreSQL 独占 Dispatch 决策权
Agent Card 不携带 Skill Argument/Result JSON Schema,A2A 1.0 也没有把 Send
路由到 Skill 的字段。所选 Skill 只固定 Media 和 Security 证据;可信本地
Registry 校验 Input,以及标准单 Key {"message": ...} 或 {"task": ...} Output。
let recovery = A2aRemoteAgentRecovery::operator_attested_context_task_history(
4,
64,
DurationMillis::new(1_000)?,
)?;
let remote = A2aRemoteAgent::bind_with_recovery(
descriptor,
client,
"answer",
A2aRemoteAgentDelivery::AtMostOnce,
recovery,
schemas,
)?;
let mut tools = ToolProviderRegistryBuilder::new();
tools.register(Arc::new(remote))?;
let tools = tools.build();
Invocation Ledger 在唯一一次 Network Send 前提交 executing;合法 Response 经过 Schema 校验后才 Commit。可能 Dispatch
后的任何不确定结果都会 变为 Unknown + ReconcileFirst,普通
Recovery 不会再次发送。
Adapter 显式设置 returnImmediately: true。返回 Task 只提交
Message Submission
与持久化句柄,不代表远端已经进入终态。等待完成属于应用自有、独立授权的
get_task 或 subscribe_to_task Workflow。
不要虚构 Message-ID Idempotency
| Mode | Descriptor Truth | Message Identity |
|---|---|---|
AtMostOnce | Non-idempotent Write;不支持 Key | Physical Attempt ID |
MessageIdDeduplicated | Idempotent Write;Key 必填 | Stable Invocation Key |
A2A 本身不要求接收端对 messageId 去重。只有 Operator 证明远端在
本地 Ledger Retention 与灾备窗口内都能基于持久化记录去重时,第二种 Mode 才安全。Lost
Send Response 不一定返回 Task ID。
只根据经过证明的远端事实恢复
| Mode | 必需的部署证据 | 行为 |
|---|---|---|
Disabled | 无 | 保持 Fail Closed,等待人工 Reconciliation |
ContextTaskHistory | 保留 Client Context、完整稳定的 Task Pagination、保留原始 Message ID | 有界 ListTasks 扫描;绝不重发 |
MessageIdReplay | 在完整 Recovery Window 内基于持久化记录去重 Message ID | 重放精确 Request Identity;只允许 Deduplicated Delivery |
Enabled Mode 要求 Descriptor Status-query 声明一致,并配置有界 Poll
Interval。 Context Recovery 会给原始 Message 增加单向 Opaque ID,最多扫描
16 页、每页 100 个 Task、每个 Task 最多 256 条 History,并且只接受唯一
Match,且 Role、Context 与 Payload 必须等于原始 Message。没有 Match 变为
Pending;重复 Identity、歧义 Match、同 ID Payload
Substitution 或扫描上限耗尽都会 Fail Closed。
Provider-native Agent 会原子提交权威 Evidence。Pending Probe 会变成后续
Lease 下的 持久化 SafeAfter Node Retry,原 Physical Attempt 与
Business-call Count 保持不变。
对每次 Exchange 设上限
- 默认 Discovery 15 秒、Unary/Stream-establishment 60 秒、Stream Idle 60 秒。
- 默认 Request 16 MiB、Unary Response 2 MiB。
- 默认 SSE Line 512 KiB、Event 2 MiB、Total 64 MiB、4,096 个 Event。
- Task Page 遵循 A2A 的 100 条上限、包含等号的 Timestamp Filter 与最新优先排序; Push-config Page 本地上限 256。
上生产前还要独立限制 DNS/Proxy Egress、审核每次 Card 变化、使用 Attempt-scoped Workload Credential、对齐本地 Ledger 与远端 Dedup Retention、 对 Unknown Outcome 告警,并验证 Accepted-request/Lost-response、Cancellation Race、Malformed Stream、Database Failover 与 Restore。
先看证据,再看边界
真实 Loopback Test 在两种 Binding 上执行全部 11 个 Operation,并覆盖严格
Discovery、Authorization、Error、Stream 与 Lost Response;还证明无需重发的
Context/History Recovery、同 ID Payload Substitution 拒绝,以及显式 Dedup
Attestation 下的精确 Replay。另一项 Provider-neutral 真实 PostgreSQL Test
证明 Unknown → Pending → 持久化 Retry → Committed,两次 Probe
期间只有一次 Business Call。
请阅读完整生产指南与复现命令。官方 TCK 证据只适用于独立 Server Profile;Client Live-peer 与 Recovery-attestation Qualification、gRPC、 Stable API Review 与完整生产 Release 仍是独立门禁。