a2a-web-client 0.2.0

Generic web client library for building A2A agent frontends
Documentation
# a2a-client


A reusable Rust library for building web-based frontends for A2A (Agent-to-Agent) Protocol agents.

## Overview


`a2a-client` provides reusable components, utilities, and client wrappers for creating web applications that interact with A2A protocol agents. It's designed to be integrated into your own web applications, not used as a standalone application.

## Features


- 🔌 **Unified Client API** - Single interface for HTTP and WebSocket transports
- 📡 **SSE Streaming** - Server-Sent Events with automatic fallback to polling
- 🎨 **View Models** - Ready-to-use view models for tasks and messages
- 🔄 **Auto-reconnection** - Resilient WebSocket connections with retry logic
- 🧩 **Modular Components** - Use only what you need via feature flags
- 🦀 **Type-safe** - Leverages Rust's type system for protocol correctness

## Installation


Add to your `Cargo.toml`:

```toml
[dependencies]
a2a-client = { path = "../a2a-client" }

# For Axum integration with SSE streaming components

a2a-client = { path = "../a2a-client", features = ["axum-components"] }
```

## Quick Start


### Basic HTTP Client


```rust
use a2a_client::WebA2AClient;

#[tokio::main]

async fn main() -> anyhow::Result<()> {
    // Create a client connected to your A2A agent
    let client = WebA2AClient::new_http("http://localhost:8080".to_string());

    // Send a message and get a task
    let message = a2a_rs::domain::Message::builder()
        .text("Hello, agent!")
        .build();

    let task = client.http.send_message(&message, None).await?;
    println!("Task ID: {}", task.id);

    Ok(())
}
```

### With WebSocket Support


```rust
use a2a_client::WebA2AClient;

#[tokio::main]

async fn main() -> anyhow::Result<()> {
    // Auto-detect available transports
    let client = WebA2AClient::auto_connect("http://localhost:8080").await?;

    if client.has_websocket() {
        println!("WebSocket support detected!");
    }

    Ok(())
}
```

### SSE Streaming with Axum


```rust
use a2a_client::{WebA2AClient, components::create_sse_stream};
use axum::{Router, routing::get, extract::{State, Path}};
use std::sync::Arc;

#[tokio::main]

async fn main() -> anyhow::Result<()> {
    let client = Arc::new(
        WebA2AClient::new_with_websocket(
            "http://localhost:8080".to_string(),
            "ws://localhost:8080/ws".to_string()
        )
    );

    let app = Router::new()
        .route("/stream/:task_id", get(stream_handler))
        .with_state(client);

    // Start server...
    Ok(())
}

async fn stream_handler(
    State(client): State<Arc<WebA2AClient>>,
    Path(task_id): Path<String>,
) -> axum::response::sse::Sse<impl futures::Stream<Item = Result<axum::response::sse::Event, std::convert::Infallible>>> {
    create_sse_stream(client, task_id)
}
```

## Architecture


```
a2a-client/
├── src/
│   ├── lib.rs              # Core client API
│   ├── components/         # Reusable UI components
│   │   ├── streaming.rs    # SSE streaming helpers
│   │   └── task_viewer.rs  # View models for tasks/messages
│   └── utils/              # Utilities
│       └── formatters.rs   # Display formatting
└── examples/               # Usage examples (coming soon)
```

## Core Components


### `WebA2AClient`


The main client struct that wraps both HTTP and WebSocket clients:

```rust
pub struct WebA2AClient {
    pub http: HttpClient,
    pub ws: Option<Arc<WebSocketClient>>,
}
```

**Methods:**
- `new_http(base_url)` - HTTP-only client
- `new_with_websocket(http_url, ws_url)` - Client with both transports
- `auto_connect(base_url)` - Auto-detect available transports
- `has_websocket()` - Check if WebSocket is available
- `websocket()` - Get WebSocket client reference

### View Models


#### `TaskView`


Display model for task lists:

```rust
pub struct TaskView {
    pub task_id: String,
    pub state: String,
    pub message_count: usize,
    pub last_message_preview: Option<String>,
}
```

#### `MessageView`


Display model for individual messages:

```rust
pub struct MessageView {
    pub id: String,
    pub role: String,
    pub content: String,
}
```

### Streaming Components


#### `create_sse_stream`


Creates a Server-Sent Events stream for task updates:

```rust
pub fn create_sse_stream(
    client: Arc<WebA2AClient>,
    task_id: String,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>>
```

**Features:**
- Automatic WebSocket connection with retry logic
- Graceful fallback to HTTP polling
- Emits `task-update`, `task-status`, and `artifact` events
- Keep-alive heartbeat

### Formatters


```rust
// Format task state for display
pub fn format_task_state(state: &TaskState) -> String;

// Extract text from message parts
pub fn format_message_content(parts: &[Part]) -> String;

// Truncate text for previews
pub fn truncate_preview(text: &str, max_len: usize) -> String;
```

## Features


### `axum-components` (default)


Enables Axum-specific components like SSE streaming support.

```toml
[dependencies]
a2a-client = { path = "../a2a-client", default-features = false }  # Minimal
a2a-client = { path = "../a2a-client" }  # With Axum components
```

## Integration with A2A Agents


This library works seamlessly with agents built using:
- `a2a-rs` - Core protocol implementation
- `a2a-agents` - Declarative agent framework
- `a2a-agent-reimbursement` - Example agent implementation

## Development


### Building


```bash
cargo build --all-features
```

### Testing


```bash
# Unit tests

cargo test

# Integration tests (requires running agent)

cargo test --features integration-tests
```

## Examples


See the `examples/` directory for complete working examples:

- `basic_client.rs` - Simple HTTP client usage (coming soon)
- `sse_streaming.rs` - SSE streaming with Axum (coming soon)
- `websocket_client.rs` - WebSocket integration (coming soon)

## Roadmap


See [TODO.md](TODO.md) for planned features and improvements.

## Contributing


This library is part of the [a2a-rs](../README.md) workspace. Contributions are welcome!

## License


MIT

## See Also


- [a2a-rs]../a2a-rs - Core A2A protocol implementation
- [a2a-agents]../a2a-agents - Declarative agent framework
- [A2A Protocol Specification]../spec - Protocol documentation