A2A (Agent2Agent Protocol)
PraisonAI supports the A2A Protocol for agent-to-agent communication, enabling your agents to be discovered and collaborate with other AI agents.
Overview
The A2A Protocol is an open standard for inter-agent communication that enables:
- Discovery: Agents publish Agent Cards for discovery by other agents
- Collaboration: Agents can delegate tasks and exchange context
- Interoperability: Works with any A2A-compatible agent system
Quick Start
from praisonaiagents import Agent, A2A
def search_web(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
agent = Agent(
name="Research Assistant",
role="Research Analyst",
goal="Help users research topics",
tools=[search_web]
)
# One-liner A2A server
a2a = A2A(agent=agent)
a2a.serve(port=8000)
Endpoints
| Endpoint | Method | Description |
|---|
/.well-known/agent.json | GET | Agent Card for discovery |
/status | GET | Server status |
Agent Card
The Agent Card is a JSON metadata document that describes your agent’s capabilities:
{
"name": "Research Assistant",
"url": "http://localhost:8000/a2a",
"version": "1.0.0",
"description": "Research Analyst. Help users research topics",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "search_web",
"name": "search_web",
"description": "Search the web for information.",
"tags": ["tool"]
}
],
"provider": {
"name": "PraisonAI"
}
}
Configuration Options
a2a = A2A(
agent=agent, # PraisonAI Agent instance
name="Custom Name", # Override agent name
description="Custom description",
url="http://localhost:8000/a2a", # A2A endpoint URL
version="1.0.0", # Agent version
prefix="/api", # Router prefix
tags=["A2A", "Research"], # OpenAPI tags
auth_token="sk-my-secret", # Bearer token auth (optional)
)
| Parameter | Type | Default | Description |
|---|
agent | Agent | — | Single agent instance |
agents | AgentTeam | — | Multi-agent team |
name | str | agent name | A2A endpoint name |
description | str | agent role | Agent description |
url | str | http://localhost:8000/a2a | A2A endpoint URL |
version | str | "1.0.0" | Version string |
prefix | str | "" | URL prefix |
auth_token | str | None | Bearer token for POST /a2a auth |
Authentication
Protect your A2A endpoint with bearer token authentication:
a2a = A2A(agent=agent, auth_token="sk-my-secret-key")
a2a.serve(port=8000)
Clients must include the token:
curl -X POST http://localhost:8000/a2a \
-H "Authorization: Bearer sk-my-secret-key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "message/send", "id": "1", ...}'
The discovery endpoint (/.well-known/agent.json) remains public per A2A spec — only POST /a2a requires authentication.
Multi-Agent Support
Expose multi-agent workflows — A2A routes messages to agents.start() when a team is provided:
from praisonaiagents import Agent, AgentTeam, Task, A2A
researcher = Agent(name="Researcher", role="Research Analyst", goal="Research topics")
writer = Agent(name="Writer", role="Content Writer", goal="Write content")
task1 = Task(description="Research AI trends", agent=researcher)
task2 = Task(description="Write a report", agent=writer)
team = AgentTeam(agents=[researcher, writer], tasks=[task1, task2])
a2a = A2A(agents=team, name="Research Team")
a2a.serve(port=8000)
When both agent and agents are provided, the single agent takes priority.
Docker Deployment
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
requirements.txt:
praisonaiagents
fastapi
uvicorn
Features
| Feature | Description |
|---|
| Agent Card | JSON metadata for agent discovery |
| Skills Extraction | Auto-generate skills from tools |
| Task Management | Stateful task lifecycle |
| Streaming | SSE streaming for real-time updates |
| Lazy Loading | No performance impact when not used |
A2A Protocol Concepts
Task States
Tasks in A2A go through a lifecycle:
submitted - Task received
working - Agent is processing
input-required - Waiting for user input
completed - Task finished successfully
failed - Task failed
cancelled - Task was cancelled
Message Parts
A2A messages support multimodal content — all part types are parsed and converted:
| Part Type | A2A Field | Conversion |
|---|
TextPart | text | Plain text → string |
FilePart | url / fileWithUri | URI → image_url format |
DataPart | data | JSON object → text |
# Send multimodal message
curl -X POST http://localhost:8000/a2a \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "message/send",
"id": "1",
"params": {
"message": {
"role": "user",
"parts": [
{"type": "text", "text": "Analyze this image"},
{"type": "file", "url": "https://example.com/chart.png"}
]
}
}
}'
Artifacts
Artifacts are outputs generated by the agent:
from praisonaiagents import Artifact, TextPart
artifact = Artifact(
artifact_id="report-001",
name="Research Report",
description="AI trends analysis",
parts=[TextPart(text="Report content...")]
)
Examples
See the examples/python/a2a directory for complete examples.