apomesh-a2a-client
The outbound half of the A2A integration — the HTTP client the
orchestrator drives when a session delegates to a configured remote
peer as a tool. The orchestrator resolves the peer row and its
credential, constructs one client per call, and reads the remote task
state back through the inverse state table (delegation_outcome).
Deliberately orchestrator-free: only the orchestrator depends on this
crate, never the reverse.
Position in the workspace
Section titled “Position in the workspace”- Layer: protocol-adjacent client leaf, beside the substrate. See Agent federation for where it sits in the delegation spine.
- Depends on: exactly three substrate leaves — apomesh-a2a-types (the wire vocabulary), apomesh-substrate-net (the webpki-roots HTTP egress client), and apomesh-substrate-sse (the shared SSE parser).
- Consumed by:
apomesh-orchestrator —
the delegation-execution module that admits peers at session start
and runs each
a2a:<peer-id>tool call.
What it owns
Section titled “What it owns”A2aClient— one peer, one client: card URL + RPC URL +PeerAuth+ the resolved credential + per-call timeout. Methods:fetch_card,send_message,send_streaming_message,subscribe_to_task,get_task,cancel_task. The streaming continuation is atomic: resuming a paused remote task rides oneSendStreamingMessagerequest carrying the task id, so resume + attach cannot race the remote task’s completion.PeerAuth— the auth-header discriminator, chosen from the typed kind of the resolved credential, never by sniffing the secret’s bytes:Bearer(Authorization: Bearer …) orApiKey { header }(DEFAULT_API_KEY_HEADER=X-API-Keyfor foreign peers unless the peer row names another;X-Apomesh-Api-Keyfor apomesh peers). Credentials the client cannot represent are rejected with a typed error at admission — never silently sent.EgressPolicy— the SSRF posture:DenySsrfRanges(default) rejects loopback / RFC1918 / link-local (including the cloud metadata address) / CGNAT / ULA / mapped-IPv6 / multicast / special-use targets before any request is issued;AllowPrivateis the deliberate, named knob for loopback stubs and the full-circle e2e — never the production posture.DelegationOutcome+delegation_outcome— the pure, wildcard-free inverse of the inbound adapter’s substrate→TaskStateprojection:Pending,Completed,Failed,Canceled,Rejected, andInputRequired(the typed input-required tool result carrying the peer’s prompt + task id for continuation).DEFAULT_CALL_TIMEOUT— the 300-second wall clock bounding one whole remote interaction (per-peer override via the peer row’scall_timeout_secs).A2aClientError— the typed error vocabulary; no variant ever carries credential material (the auth header value is marked sensitive, and redaction is part of the constructor’s contract).
The client is substrate plumbing — operators configure peers in
[[a2a_peers]] and sessions call the projected a2a:<peer-id> tool;
see Delegate to A2A peers
for the operator-facing path. Direct construction is for the
orchestrator’s delegation module and tests.
Related
Section titled “Related”- Build: A2A federation — serving agents inbound and delegating outbound.
- Reference: apomesh-a2a-types — the shared wire vocabulary.
- Reference: apomesh-substrate-sse — the SSE parser the streaming path decodes with.