A2A Protocol
Enable agent-to-agent communication with Google's A2A protocol, agent cards, JSON-RPC messaging, and task lifecycle management.
A2A Protocol
PromptRails implements the Agent-to-Agent (A2A) protocol, an open standard by Google for inter-agent communication. A2A enables agents to discover each other, exchange messages, and coordinate on tasks across different systems and platforms.
What is A2A?
The A2A protocol defines a standard way for AI agents to:
- Discover other agents through agent cards
- Communicate using JSON-RPC messages
- Coordinate work through a task lifecycle
- Exchange results via task artifacts
This enables multi-agent architectures where specialized agents collaborate to solve complex problems, even when running on different platforms.
Agent Cards
An agent card is a machine-readable description of an agent's capabilities. It includes:
- Agent name and description
- Supported input/output formats
- Available skills and capabilities
- Authentication requirements
- Endpoint URL
Agent cards enable automated discovery -- one agent can find and evaluate other agents based on their published capabilities.
# Get an agent's A2A card
card = client.a2a.get_agent_card("your-agent-id")
print(f"Name: {card.name}")
print(f"Description: {card.description}")
print(f"Skills: {[skill.name for skill in card.skills]}")JSON-RPC Messaging
A2A communication uses JSON-RPC 2.0 as the transport format. Messages include:
{
"jsonrpc": "2.0",
"method": "tasks/send",
"params": {
"id": "task-id",
"message": {
"role": "user",
"parts": [
{
"type": "text",
"text": "Analyze this dataset and generate a report"
}
]
}
}
}Task Lifecycle
A2A tasks follow a defined lifecycle:
submitted -> working -> completed
-> failed
-> canceled
-> rejected
-> input_required -> (user provides input) -> working
Task Statuses
| Status | Description |
|---|---|
submitted | Task has been submitted to the agent |
working | Agent is actively processing the task |
input_required | Agent needs additional input to continue |
completed | Task finished successfully |
failed | Task encountered an error |
canceled | Task was cancelled by the requester |
rejected | Agent rejected the task (e.g., outside its capabilities) |
Creating and Managing Tasks
Send a Task
task = client.a2a.send_message(
"your-agent-id",
"Summarize the Q4 sales report",
context_id="optional-conversation-context"
)
print(f"Task ID: {task.id}")
print(f"Status: {task.status.state}")Get Task Status
task = client.a2a.get_task("task-id")
print(f"Status: {task.status.state}")
print(f"Messages: {len(task.messages)}")
print(f"Artifacts: {len(task.artifacts)}")Cancel a Task
client.a2a.cancel_task("task-id")Task Artifacts
When a task completes, the agent may produce artifacts -- structured outputs that represent the work product:
{
"artifacts": [
{
"type": "text",
"text": "The Q4 sales report shows a 15% increase..."
},
{
"type": "file",
"name": "report.pdf",
"mimeType": "application/pdf",
"data": "base64-encoded-content"
}
]
}Multi-Agent Coordination
A2A enables patterns like:
Sequential Processing
Agent A processes data, then passes results to Agent B for further analysis:
# Agent A: Data extraction
task_a = client.a2a.send_message(
"data-extractor-agent",
"Extract sales data from Q4"
)
# Wait for completion, then pass to Agent B
# Agent B: Analysis
task_b = client.a2a.send_message(
"analyst-agent",
f"Analyze: {task_a_result}",
context_id=task_a.context_id
)Parallel Processing
Multiple agents work on different aspects simultaneously:
import asyncio
async def multi_agent_analysis():
async with AsyncPromptRails(api_key="your-key") as client:
tasks = await asyncio.gather(
client.a2a.send_message("sentiment-agent", "Analyze sentiment"),
client.a2a.send_message("topic-agent", "Extract key topics"),
client.a2a.send_message("summary-agent", "Summarize the conversation"),
)
return tasksInput-Required Flow
An agent can request additional input during processing:
task = client.a2a.send_message("agent-id", initial_message)
# Check if the agent needs more input
if task.status and task.status.state == "input_required":
# Provide additional input
task = client.a2a.send_message(
"agent-id",
"Additional context...",
task_id=task.id,
)Task Fields
| Field | Type | Description |
|---|---|---|
id | KSUID | Unique task identifier |
context_id | string | Conversation context identifier |
status | object | Current task status payload |
messages | array | Message history |
artifacts | array | Task outputs |
metadata | JSON | Custom metadata |
created_at | timestamp | Creation time |
updated_at | timestamp | Last update time |
Related Topics
- Agents -- Agents that participate in A2A
- Executions -- A2A tasks create executions
- Python SDK -- Python A2A client
- JavaScript SDK -- JavaScript A2A client