In‑memory FSM for the A2A Protocol with Pydantic v2 models
Project description
A2A: Agent-to-Agent Communication Server
A lightweight, transport-agnostic framework for agent-to-agent communication based on JSON-RPC, implementing the 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)
- HTTP JSON-RPC endpoint (
-
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}
- Direct handler mounting at
-
A2A Protocol Compliant:
- Agent Cards at
/.well-known/agent.jsonand/{handler_name}/.well-known/agent.json - Standard Task/Message/Artifact structure
- Streaming support
- Agent Cards at
Running the Server
# 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:
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:
uv run a2a-server --config agent.yaml --log-level debug
Interacting with the Server
# 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:
- YAML configuration in the
agent_cardsection - Dynamically detected capabilities (streaming support, etc.)
- Reasonable defaults for missing fields
Handler Details
google_adk_handlerwraps raw Google ADKAgentinstances viaADKAgentAdapterso.invoke()/.stream()always exist.prepare_handler_paramstreats thenameparameter 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.pyundera2a.task_handlers
Installation
Clone the repo and install the core library:
git clone https://github.com/yourusername/a2a.git
cd a2a
pip install -e .
Install optional extras as needed:
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:
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
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file a2a_server-0.1.0.tar.gz.
File metadata
- Download URL: a2a_server-0.1.0.tar.gz
- Upload date:
- Size: 37.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c01ba54d866c537736f4605fe1c8aa956170b223f2ec96c10c8cc52a9714ab54
|
|
| MD5 |
a25a744e0a3c66c76bee110951dfd1b6
|
|
| BLAKE2b-256 |
266e7c679e72d964d19af18b4b8473f9a845c0a02f6ca2e80663b99e677f045f
|
File details
Details for the file a2a_server-0.1.0-py3-none-any.whl.
File metadata
- Download URL: a2a_server-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff6a76a984f693e5f63bfad6fec617912482c24f07aecea9f4ac0dd1508d137e
|
|
| MD5 |
7706795b6b03f91940388e35ab0740c8
|
|
| BLAKE2b-256 |
f94dc6d93b18b2522bc7fe7ddde758c730135a377d9ef5d90713b393a5af0976
|