# A2A: Agent-to-Agent Communication Server

A lightweight, transport-agnostic framework for agent-to-agent communication based on JSON-RPC, implementing the [A2A Protocol](https://github.com/a2a-proto/a2a-protocol).

## Server

The A2A server provides a flexible JSON-RPC interface for agent-to-agent communication with support for multiple transport protocols.

### Features

- **Multiple Transport Protocols**:
  - HTTP JSON-RPC endpoint (`POST /rpc`)
  - WebSocket for bidirectional communication (`/ws`)
  - Server-Sent Events (SSE) for real-time updates (`/events`)
  - Standard I/O mode for CLI applications (`--stdio`)

- **Task-Based Workflow**:
  - Create and manage asynchronous tasks
  - Monitor task status through state transitions
  - Receive artifacts produced during task execution

- **Simple Event System**:
  - Real-time notifications for status changes
  - Artifact update events
  - Event replay for reconnecting clients

- **Extensible Handler System**:
  - Automatic handler discovery
  - Plugin system via entry points (`a2a.task_handlers`)
  - Custom handler development via subclassing `TaskHandler`
  
- **Intuitive URL Structure**:
  - Direct handler mounting at `/{handler_name}/rpc`, `/{handler_name}/ws`, and `/{handler_name}/events`
  - Default handler accessible at root paths (`/rpc`, `/ws`, `/events`)
  - Handler health checks at `/{handler_name}`

- **A2A Protocol Compliant**:
  - Agent Cards at `/.well-known/agent.json` and `/{handler_name}/.well-known/agent.json`
  - Standard Task/Message/Artifact structure
  - Streaming support

### Running the Server

```bash
# Basic usage (HTTP, WS, SSE on port 8000)
uv run a2a-server

# Specify host and port
uv run a2a-server --host 0.0.0.0 --port 8000

# Enable detailed logging
uv run a2a-server --log-level debug

# Run in stdio JSON-RPC mode
uv run a2a-server --stdio

# List all available task handlers
uv run a2a-server --list-handlers

# List all registered routes (useful for debugging)
uv run a2a-server --list-routes

# Register additional handler packages
uv run a2a-server --handler-package my_custom_module.handlers

# Disable automatic handler discovery
uv run a2a-server --no-discovery
```

### Example: Configuring Agents via YAML

You can configure multiple agents with their capabilities and agent cards in YAML:

```yaml
server:
  port: 8000

handlers:
  use_discovery: false
  default: chef_agent

  pirate_agent:
    type: a2a_server.tasks.handlers.google_adk_handler.GoogleADKHandler
    agent: a2a_server.sample_agents.pirate_agent.pirate_agent
    name: pirate_agent
    agent_card:
      name: Pirate Agent
      description: "Converts your text into salty pirate‑speak"
      url: "https://pirate.example.com"
      version: "0.1.0"
      documentationUrl: "https://pirate.example.com/docs"
      provider:
        organization: "Acme"
        url: "https://acme.example.com"
      capabilities:
        streaming: true
        pushNotifications: false
      authentication:
        schemes:
          - "Bearer"
      defaultInputModes:
        - "text/plain"
      defaultOutputModes:
        - "text/plain"
      skills:
        - id: pirate-talk
          name: Pirate Talk
          description: "Turn any message into pirate lingo"
          tags:
            - pirate
            - fun
          examples:
            - "Arrr! Give me yer loot!"

  chef_agent:
    type: a2a_server.tasks.handlers.google_adk_handler.GoogleADKHandler
    agent: a2a_server.sample_agents.chef_agent.chef_agent
    name: chef_agent
    agent_card:
      name: Chef Agent
      description: "Suggests delicious recipes from your ingredients"
      # Other fields can be automatically derived...
```

Then launch:

```bash
uv run a2a-server --config agent.yaml --log-level debug
```

### Interacting with the Server

```bash
# Create a task with default handler
curl -N -X POST http://127.0.0.1:8000/rpc \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"tasks/send",
    "params":{
      "message":{
        "role":"user",
        "parts":[{ "type":"text","text":"What can I make with chicken?" }]
      }
    }
  }'

# Create a task with specific handler
curl -N -X POST http://127.0.0.1:8000/pirate_agent/rpc \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"tasks/send",
    "params":{
      "message":{
        "role":"user",
        "parts":[{ "type":"text","text":"Tell me about the sea" }]
      }
    }
  }'

# Stream events from default handler
curl -N http://127.0.0.1:8000/events

# Stream events from specific handler
curl -N http://127.0.0.1:8000/pirate_agent/events

# Get the default agent card (A2A Protocol compliant)
curl http://127.0.0.1:8000/.well-known/agent.json

# Get a specific handler's agent card
curl http://127.0.0.1:8000/pirate_agent/.well-known/agent.json

# Check handler health
curl http://127.0.0.1:8000/pirate_agent
```

## URL Structure

The server provides a consistent URL structure:

### Default Handler
- `/rpc` - JSON-RPC endpoint for the default handler
- `/ws` - WebSocket endpoint for the default handler  
- `/events` - SSE endpoint for the default handler
- `/.well-known/agent.json` - Agent Card for the default handler (A2A Protocol compliant)

### Specific Handlers
- `/{handler_name}/rpc` - JSON-RPC endpoint for a specific handler
- `/{handler_name}/ws` - WebSocket endpoint for a specific handler
- `/{handler_name}/events` - SSE endpoint for a specific handler
- `/{handler_name}/.well-known/agent.json` - Agent Card for a specific handler (A2A Protocol compliant)

### Health Checks
- `/` - Root health check with information about all handlers
- `/{handler_name}` - Handler-specific health check

## Agent Cards

The server implements the A2A Protocol's Agent Card specification. Agent cards contain information about the agent's:

- Name, description, and version
- Provider information
- Capabilities (streaming, push notifications)
- Authentication requirements
- Supported input/output modes
- Skills (capabilities the agent can perform)

Agent cards are generated from:
1. YAML configuration in the `agent_card` section
2. Dynamically detected capabilities (streaming support, etc.)
3. Reasonable defaults for missing fields

## Handler Details

- **`google_adk_handler`** wraps raw Google ADK `Agent` instances via `ADKAgentAdapter` so `.invoke()`/`.stream()` always exist.
- **`prepare_handler_params`** treats the `name` parameter as a literal, allowing YAML overrides without import errors.

### Custom Handler Development

Subclass `TaskHandler`, implement `process_task`, and register via:

- **Automatic discovery** (`--handler-package`)
- **Entry points** in `setup.py` under `a2a.task_handlers`

### Installation

Clone the repo and install the core library:

```bash
git clone https://github.com/yourusername/a2a.git
cd a2a
pip install -e .
```

Install optional extras as needed:

```bash
pip install -e ".[jsonrpc]"    # core JSON-RPC only
pip install -e ".[server]"     # HTTP, WS, SSE server
pip install -e ".[client]"     # CLI client
pip install -e ".[adk]"        # Google ADK agent support
pip install -e ".[full]"       # All features
```

After installation, run the server or client using `uv run`:

```bash
uv run a2a-server --host 0.0.0.0 --port 8000 --log-level info
uv run a2a-client --help
```

### Requirements

- Python 3.9+
- HTTPX, WebSockets (for client)
- FastAPI, Uvicorn (for server)
- Pydantic v2+ (for JSON-RPC)

### Testing

```bash
pytest
```