|
NeoGraph 0.16.0
A C++20 Graph Agent Engine Library — LangGraph for C++
|
A2A client — call a remote agent over JSON-RPC + HTTP. More...
#include <client.h>
Public Types | |
| using | EventCallback = std::function< bool(const StreamEvent &)> |
SendStreamingMessage / message/stream — send a message and receive SSE-framed status updates as the agent progresses, plus the final Task (assembled from the stream's Task / status / artifact events for 1.0 agents, which have no terminal final frame). | |
Public Member Functions | |
| A2AClient (std::string base_url) | |
| Task | cancel_task (const std::string &task_id) |
tasks/cancel — request cancellation. Returns updated Task. | |
| std::string | endpoint_url () const |
The JSON-RPC endpoint in use: the selected interface URL, or base_url before a selection or when the policy ignores the card URL. | |
| AgentCard | fetch_agent_card (bool force=false) |
| GET /.well-known/agent-card.json. | |
| asio::awaitable< AgentCard > | fetch_agent_card_async (bool force=false) |
| Async variant of fetch_agent_card. | |
| Task | get_task (const std::string &task_id, int history_length=0) |
tasks/get — fetch the latest snapshot of a task. | |
| json | rpc_call (const std::string &method, const json ¶ms, std::optional< WireDialect > dialect=std::nullopt) |
| Lower-level: arbitrary JSON-RPC method, sent verbatim. | |
| asio::awaitable< Task > | send_message_async (const MessageSendParams ¶ms) |
Async variant — server's response payload may be either a Message or a Task; we coerce both into a Task with the message in history so callers have one shape to handle. | |
| Task | send_message_sync (const MessageSendParams ¶ms, graph::CancelToken *cancel=nullptr) |
| Send an arbitrary Message (multipart, file, structured data). | |
| Task | send_message_sync (const std::string &text, const std::string &task_id="", const std::string &context_id="", graph::CancelToken *cancel=nullptr) |
message/send — convenience wrapper around send_message_sync(). | |
| void | set_allow_cross_origin_interfaces (bool allow) |
Allow the AgentCard to direct RPCs to an interface URL on another origin than base_url (default false: such URLs are ignored and RPCs go to base_url). | |
| void | set_authorization_header (std::string authorization_header) |
| Set the explicit Authorization header for subsequent RPC requests. | |
| void | set_connect_timeout (std::chrono::seconds t) |
Bound the time to resolve the host, connect and finish the TLS handshake of each request to t (default 30 s). | |
| void | set_timeout (std::chrono::seconds t) |
Bound the whole exchange of each request (connect, write, and reading the reply or the event stream to its end) to t; an exchange that is not done by then throws. | |
| std::optional< WireDialect > | wire_dialect () const |
| Wire dialect in use: selected from the fetched AgentCard or learned by probing. | |
A2A client — call a remote agent over JSON-RPC + HTTP.
Thread-safe for concurrent use of one instance. base_url is immutable; set_timeout and set_connect_timeout are synchronized and each request snapshots them before network I/O, so an update cannot race or alter an in-flight request. JSON-RPC request IDs are process-local atomic counters. Agent-card cache initialization and force refreshes are single-flight and synchronized; waiting callers receive a copy, and no network I/O occurs under the state lock. Stream callbacks still run on the network thread and must provide their own synchronization for shared application state. Reuses neograph::async::async_post for transport.
Interface selection (spec 8.3.2): before its first RPC the client fetches the AgentCard (unless fetch_agent_card already did) and picks the first supportedInterfaces entry with a JSONRPC binding and a 1.x (-> WireDialect::V1_0) or 0.x (-> V0_3) protocol version, preferring an entry whose URL equals the client's base_url; a 0.3 card without supportedInterfaces selects V0_3 from its protocolVersion / preferredTransport / additionalInterfaces. When the card offers no compatible interface the call throws std::runtime_error naming what the card offers. A selected interface tenant is copied into every request.
Endpoint policy: RPCs go to the selected interface's URL when it has the same origin (scheme, host, port) as base_url, for example an agent whose JSON-RPC endpoint is at /a2a/v1. A card cannot redirect the client to another origin unless set_allow_cross_origin_interfaces opts in; a cross-origin (or unusable) interface URL is otherwise ignored and the RPC goes to base_url.
When no card can be fetched, the client probes: 1.0 first, then 0.3 when the agent answers -32601 (method not found), -32009 (version not supported) or HTTP 400, and remembers the outcome.
| using neograph::a2a::A2AClient::EventCallback = std::function<bool(const StreamEvent&)> |
SendStreamingMessage / message/stream — send a message and receive SSE-framed status updates as the agent progresses, plus the final Task (assembled from the stream's Task / status / artifact events for 1.0 agents, which have no terminal final frame).
on_event is invoked synchronously on the network thread for each parsed StreamEvent. Return true to keep reading or false to abort early: the connection is closed at once and the call returns the task assembled so far. An error frame ends the call the same way and is thrown as A2ARpcError. The final Task (or a status-update with final=true) ends the stream regardless. The stream has no time limit unless set_timeout sets one.
|
explicit |
| base_url | Agent endpoint URL (e.g. "https://agent.example.com"). The well-known card path is appended on discovery. |
| AgentCard neograph::a2a::A2AClient::fetch_agent_card | ( | bool | force = false | ) |
GET /.well-known/agent-card.json.
Exposes the agent's identity, transports, and skills. Caches the result in-instance — repeat calls are no-ops unless force is set.
| json neograph::a2a::A2AClient::rpc_call | ( | const std::string & | method, |
| const json & | params, | ||
| std::optional< WireDialect > | dialect = std::nullopt |
||
| ) |
Lower-level: arbitrary JSON-RPC method, sent verbatim.
When dialect is V1_0 the A2A-Version: 1.0 header is attached. Throws A2ARpcError for a JSON-RPC error reply.
| Task neograph::a2a::A2AClient::send_message_sync | ( | const MessageSendParams & | params, |
| graph::CancelToken * | cancel = nullptr |
||
| ) |
Send an arbitrary Message (multipart, file, structured data).
| cancel | As for the overload above. |
| Task neograph::a2a::A2AClient::send_message_sync | ( | const std::string & | text, |
| const std::string & | task_id = "", |
||
| const std::string & | context_id = "", |
||
| graph::CancelToken * | cancel = nullptr |
||
| ) |
message/send — convenience wrapper around send_message_sync().
| text | Plain text content for a single TextPart. |
| task_id | Optional existing task to continue. |
| context_id | Optional grouping id. |
| cancel | Optional token of the work the call belongs to. Cancelling it ends the call at once: the connection is closed and the call throws graph::CancelledException. The default has no deadline on the exchange (see set_timeout), so a caller that cannot wait without end passes its token or sets a timeout. |
| void neograph::a2a::A2AClient::set_allow_cross_origin_interfaces | ( | bool | allow | ) |
Allow the AgentCard to direct RPCs to an interface URL on another origin than base_url (default false: such URLs are ignored and RPCs go to base_url).
Takes effect at the next interface selection.
| void neograph::a2a::A2AClient::set_authorization_header | ( | std::string | authorization_header | ) |
Set the explicit Authorization header for subsequent RPC requests.
Passing an empty string clears it. The client retains no separate token representation and never copies this value into A2A payload metadata.
| void neograph::a2a::A2AClient::set_connect_timeout | ( | std::chrono::seconds | t | ) |
Bound the time to resolve the host, connect and finish the TLS handshake of each request to t (default 30 s).
Unlike set_timeout it stops counting once the request can be written, so a slow reply or a long stream is not affected. A name lookup that is already running cannot be interrupted, so the bound is then noticed when it returns. Zero removes the bound.
| void neograph::a2a::A2AClient::set_timeout | ( | std::chrono::seconds | t | ) |
Bound the whole exchange of each request (connect, write, and reading the reply or the event stream to its end) to t; an exchange that is not done by then throws.
The default is no bound: a blocking SendMessage runs until the agent answers and a stream until the agent ends it, since a task may take minutes. Zero removes a bound set earlier. Connecting is bounded separately, see set_connect_timeout.
| std::optional< WireDialect > neograph::a2a::A2AClient::wire_dialect | ( | ) | const |
Wire dialect in use: selected from the fetched AgentCard or learned by probing.
nullopt until the first card-selected RPC / successful probe.