a2a-web-client 0.8.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 transport
- 📡 **SSE Streaming** - Server-Sent Events with automatic fallback to polling
- 🎨 **View Models** - Ready-to-use view models for tasks and messages
- 🧩 **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(())
}
```

### 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_http(
            "http://localhost:8080".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

```mermaid
flowchart TD
    subgraph WebApp[Web Application / Frontend]
        UI[UI / Frontend Component]
        AppState[AppState]
        TaskView[TaskView / MessageView]
    end

    subgraph Client[a2a-client Crate]
        WebClient[WebA2AClient]
        HTTPClient[HttpClient]
        SSE[create_sse_stream]
    end

    subgraph Server[A2A Agent Server]
        AgentCard[/agent-card Endpoint]
        Tasks[/tasks Endpoint]
    end

    UI --> AppState
    AppState --> WebClient
    WebClient --> HTTPClient

    HTTPClient -->|Discover Transport / Fetch Card| AgentCard
    HTTPClient -->|Send messages / Poll fallback| Tasks

    SSE -->|Fetch Updates| HTTPClient
    SSE -->|Emit Task Events| UI
    TaskView -->|Map Domain Model| AppState
```

```
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,
}
```

**Methods:**
- `new_http(base_url)` - HTTP-only client
- `auto_connect(base_url)` - Auto-detect available transports

### 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:**
- 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
- [`korps`]https://github.com/EmilLindfors/korps - Declarative agent framework

## 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)

## Roadmap

See the workspace [TODO.md](../TODO.md) for open and deferred work.

## 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
- [korps]https://github.com/EmilLindfors/korps - Declarative agent framework (separate repo)
- [A2A Protocol Specification]../spec - Protocol documentation