Skip to main content

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

EndpointMethodDescription
/.well-known/agent.jsonGETAgent Card for discovery
/statusGETServer 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)
)
ParameterTypeDefaultDescription
agentAgentSingle agent instance
agentsAgentTeamMulti-agent team
namestragent nameA2A endpoint name
descriptionstragent roleAgent description
urlstrhttp://localhost:8000/a2aA2A endpoint URL
versionstr"1.0.0"Version string
prefixstr""URL prefix
auth_tokenstrNoneBearer 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

FeatureDescription
Agent CardJSON metadata for agent discovery
Skills ExtractionAuto-generate skills from tools
Task ManagementStateful task lifecycle
StreamingSSE streaming for real-time updates
Lazy LoadingNo 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 TypeA2A FieldConversion
TextParttextPlain text → string
FileParturl / fileWithUriURI → image_url format
DataPartdataJSON 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.