A2AClient discovers and validates one Agent Card lazily. Construction performs no network call. Use the client from trusted code when your application decides exactly which operation to perform.
lib/remote_support.py
send(..., wait=True) is the default. It returns a direct Message immediately when possible. If the server returns a non-terminal Task, it polls that exact Task until it is terminal, interrupted, or the configured timeout expires. Use await client.send(..., return_immediately=True, wait=False) when your application wants to retain the Task ID and decide what happens next.
Choose an explicit client operation
The client never performs background Task listing. Cancelling a local
send or letting it time out triggers a bounded best-effort cancellation only when the remote side already returned an active Task ID.
Outbound discovery selects JSON-RPC or HTTP+JSON interfaces. Harnest does not connect to gRPC or custom A2A bindings.
lib/remote_support.py
Add a remote agent to a graph
RemoteAgent retains only opaque A2A context and Task references in graph state. It can run as a portable graph node:
agent.py
tools/inventory_agent.py
Keep network and credentials explicit
HTTPS is the default. Plain HTTP is accepted automatically for loopback development; another HTTP host requiresallow_insecure=True. A discovered interface may stay on the Agent Card host or one of allowed_hosts, which prevents an Agent Card from silently redirecting authority elsewhere.
For an authenticated remote agent, set audience and scopes on RemoteAgent, or resolve a Credential and pass it to an explicit A2AClient operation. Credentials enter only the final request headers. See Authentication and credentials.
A2AResult normalizes text and structured DataPart content into text and data. Raw protocol messages, Tasks, file parts, and URL parts remain available through result.message or result.task when trusted code needs the official A2A representation.