Python: basic python a2a support (#906)

* basic python a2a support

* fixes

* small fixes

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
Giles Odigwe
2025-09-29 10:53:45 -07:00
committed by GitHub
Unverified
parent fe6492ce60
commit c102706146
13 changed files with 1296 additions and 2 deletions
@@ -0,0 +1,31 @@
# A2A Agent Examples
This folder contains examples demonstrating how to create and use agents with the A2A (Agent-to-Agent) protocol from the `agent_framework` package to communicate with remote A2A agents.
For more information about the A2A protocol specification, visit: https://a2a-protocol.org/latest/
## Examples
| File | Description |
|------|-------------|
| [`agent_with_a2a.py`](agent_with_a2a.py) | The simplest way to connect to and use a single A2A agent. Demonstrates agent discovery via agent cards and basic message exchange using the A2A protocol. |
## Environment Variables
Make sure to set the following environment variables before running the example:
### Required
- `A2A_AGENT_HOST`: URL of a single A2A agent (for simple sample, e.g., `http://localhost:5001/`)
## Quick Testing with .NET A2A Servers
For quick testing and demonstration, you can use the pre-built .NET A2A servers from this repository:
**Quick Testing Reference**: Use the .NET A2A Client Server sample at:
`..\agent-framework\dotnet\samples\A2AClientServer`
### Run Python A2A Sample
```powershell
# Simple A2A sample (single agent)
uv run python agent_with_a2a.py
```
@@ -0,0 +1,75 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
import httpx
from a2a.client import A2ACardResolver
from agent_framework.a2a import A2AAgent
"""
Agent-to-Agent (A2A) Protocol Integration Sample
This sample demonstrates how to connect to and communicate with external agents using
the A2A protocol. A2A is a standardized communication protocol that enables interoperability
between different agent systems, allowing agents built with different frameworks and
technologies to communicate seamlessly.
For more information about the A2A protocol specification, visit: https://a2a-protocol.org/latest/
Key concepts demonstrated:
- Discovering A2A-compliant agents using AgentCard resolution
- Creating A2AAgent instances to wrap external A2A endpoints
- Converting Agent Framework messages to A2A protocol format
- Handling A2A responses (Messages and Tasks) back to framework types
To run this sample:
1. Set the A2A_AGENT_HOST environment variable to point to an A2A-compliant agent endpoint
Example: export A2A_AGENT_HOST="https://your-a2a-agent.example.com"
2. Ensure the target agent exposes its AgentCard at /.well-known/agent.json
3. Run: uv run python agent_with_a2a.py
The sample will:
- Connect to the specified A2A agent endpoint
- Retrieve and parse the agent's capabilities via its AgentCard
- Send a message using the A2A protocol
- Display the agent's response
Visit the README.md for more details on setting up and running A2A agents.
"""
async def main():
"""Demonstrates connecting to and communicating with an A2A-compliant agent."""
# Get A2A agent host from environment
a2a_agent_host = os.getenv("A2A_AGENT_HOST")
if not a2a_agent_host:
raise ValueError("A2A_AGENT_HOST environment variable is not set")
print(f"Connecting to A2A agent at: {a2a_agent_host}")
# Initialize A2ACardResolver
async with httpx.AsyncClient(timeout=60.0) as http_client:
resolver = A2ACardResolver(httpx_client=http_client, base_url=a2a_agent_host)
# Get agent card
agent_card = await resolver.get_agent_card(relative_card_path="/.well-known/agent.json")
print(f"Found agent: {agent_card.name} - {agent_card.description}")
# Create A2A agent instance
agent = A2AAgent(
name=agent_card.name, description=agent_card.description, agent_card=agent_card, url=a2a_agent_host
)
# Invoke the agent and output the result
print("\nSending message to A2A agent...")
response = await agent.run("Tell me a joke about a pirate.")
# Print the response
print("\nAgent Response:")
for message in response.messages:
print(message.text)
if __name__ == "__main__":
asyncio.run(main())