a2a_protocol_client/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Tom F.
3
4//! A2A protocol v1.0 — HTTP client (hyper-backed).
5//!
6//! This crate provides [`A2aClient`], a full-featured client for communicating
7//! with any A2A-compliant agent over HTTP.
8//!
9//! # Quick start
10//!
11//! ```rust,no_run
12//! use a2a_protocol_client::ClientBuilder;
13//! use a2a_protocol_types::{MessageSendParams, Message, MessageRole, Part, MessageId};
14//!
15//! # async fn example() -> Result<(), a2a_protocol_client::error::ClientError> {
16//! let client = ClientBuilder::new("http://localhost:8080").build()?;
17//!
18//! let params = MessageSendParams {
19//! tenant: None,
20//! message: Message {
21//! id: MessageId::new("msg-1"),
22//! role: MessageRole::User,
23//! parts: vec![Part::text("Hello, agent!")],
24//! task_id: None,
25//! context_id: None,
26//! reference_task_ids: None,
27//! extensions: None,
28//! metadata: None,
29//! },
30//! configuration: None,
31//! metadata: None,
32//! };
33//!
34//! let response = client.send_message(params).await?;
35//! println!("{response:?}");
36//! # Ok(())
37//! # }
38//! ```
39//!
40//! # Streaming
41//!
42//! ```rust,no_run
43//! # use a2a_protocol_client::ClientBuilder;
44//! # use a2a_protocol_types::{MessageSendParams, Message, MessageRole, Part, MessageId, StreamResponse};
45//! # async fn example() -> Result<(), a2a_protocol_client::error::ClientError> {
46//! # let client = ClientBuilder::new("http://localhost:8080").build()?;
47//! # let params = MessageSendParams {
48//! # tenant: None,
49//! # message: Message { id: MessageId::new("m"), role: MessageRole::User,
50//! # parts: vec![], task_id: None, context_id: None,
51//! # reference_task_ids: None, extensions: None, metadata: None },
52//! # configuration: None, metadata: None,
53//! # };
54//! let mut stream = client.stream_message(params).await?;
55//! while let Some(event) = stream.next().await {
56//! match event? {
57//! StreamResponse::StatusUpdate(ev) => {
58//! println!("State: {:?}", ev.status.state);
59//! }
60//! _ => {}
61//! }
62//! }
63//! # Ok(())
64//! # }
65//! ```
66//!
67//! # Authentication
68//!
69//! ```rust,no_run
70//! use a2a_protocol_client::{ClientBuilder, CredentialsStore};
71//! use a2a_protocol_client::auth::{AuthInterceptor, InMemoryCredentialsStore, SessionId};
72//! use std::sync::Arc;
73//!
74//! # fn example() -> Result<(), a2a_protocol_client::error::ClientError> {
75//! let store = Arc::new(InMemoryCredentialsStore::new());
76//! let session = SessionId::new("session-1");
77//! store.set(session.clone(), "bearer", "my-token".into());
78//!
79//! let client = ClientBuilder::new("http://localhost:8080")
80//! .with_interceptor(AuthInterceptor::new(store, session))
81//! .build()?;
82//! # Ok(())
83//! # }
84//! ```
85//!
86//! # Agent card discovery
87//!
88//! ```rust,no_run
89//! use a2a_protocol_client::discovery::resolve_agent_card;
90//! use a2a_protocol_client::A2aClient;
91//!
92//! # async fn example() -> Result<(), a2a_protocol_client::error::ClientError> {
93//! let card = resolve_agent_card("http://localhost:8080").await?;
94//! let client = A2aClient::from_card(&card)?;
95//! # Ok(())
96//! # }
97//! ```
98
99#![deny(missing_docs)]
100#![deny(unsafe_op_in_unsafe_fn)]
101#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
102#![allow(clippy::module_name_repetitions)]
103
104// ── Modules ───────────────────────────────────────────────────────────────────
105
106#[macro_use]
107mod trace;
108
109pub mod auth;
110pub mod builder;
111pub mod client;
112pub mod config;
113pub mod discovery;
114pub mod error;
115pub mod interceptor;
116pub mod methods;
117pub mod streaming;
118#[cfg(feature = "tls-rustls")]
119pub mod tls;
120pub mod transport;
121
122// ── Flat re-exports ───────────────────────────────────────────────────────────
123
124pub use auth::{AuthInterceptor, CredentialsStore, InMemoryCredentialsStore, SessionId};
125pub use builder::ClientBuilder;
126pub use client::A2aClient;
127pub use config::ClientConfig;
128pub use discovery::resolve_agent_card;
129pub use error::{ClientError, ClientResult};
130pub use interceptor::{CallInterceptor, ClientRequest, ClientResponse, InterceptorChain};
131pub use streaming::EventStream;
132pub use transport::{JsonRpcTransport, RestTransport, Transport};