| Crates.io | tower-a2a |
| lib.rs | tower-a2a |
| version | 1.0.0 |
| created_at | 2026-01-12 19:52:41.890569+00 |
| updated_at | 2026-01-13 11:17:54.232951+00 |
| description | A Tower middleware layer for the A2A Protocol |
| homepage | |
| repository | https://github.com/datathreads/tower-a2a.git |
| max_upload_size | |
| id | 2038729 |
| size | 925,789 |
tower middleware layer for the A2A ProtocolThis library provides a composable, transport-agnostic implementation of the A2A protocol as Tower middleware. It enables Rust applications to communicate with AI agents using standardized protocol operations, task management, and authentication schemes.
By leveraging the tower::Service abstraction, this library separates the protocol logic from the transport layer. This allows you to swap HTTP for WebSockets or add standard middleware like tower-http (for tracing or compression) directly into your agent communication pipeline.
Easily inject Retry, RateLimit, or Timeout layers using the standard Tower ecosystem. We have a production-ready HTTP client, but allow you to build custom Connector implementations for gRPC or proprietary backends.
[ Your App ] -> [ tower-a2a ] -> [ Layer: Auth ] -> [ Layer: Log ] -> [ Transport: HTTP | gRPC | WebSocket ] ( -> [ TCP ])
Service and Layer traits for composable middlewareAdd this to your Cargo.toml:
[dependencies]
tower-a2a = "0.1.0"
use tower_a2a::prelude::*;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Build client with HTTP transport and authentication
let mut client = A2AClientBuilder::new("https://agent.example.com")
.with_http()
.with_bearer_auth("your-token".to_string())
.with_timeout(Duration::from_secs(30))
.build()?;
// Discover agent capabilities
let agent_card = client.discover().await?;
println!("Connected to: {}", agent_card.name);
// Send a message
let task = client.send_message(
Message::user("What is the weather in San Francisco?")
).await?;
// Poll for completion
let result = client.poll_until_complete(task.id, 1000, 30).await?;
println!("Task status: {:?}", result.status);
// Access artifacts from completed task
for Artifact { artifact_id, .. } in &result.artifacts {
println!("Artifact: {artifact_id}");
}
Ok(())
}
See examples/simple_client.rs for a complete working example demonstrating agent discovery, message sending, task polling, and task listing.
Run the example with:
cargo run --example simple_client
Contributions in good faith are welcome! Please open an issue or submit a pull request. Do note that only if the authors deem it to be appropriate will they be considered.
Licensed under the Apache License, Version 2.0. See LICENSE for details.