Skip to content

Commit ead287e

Browse files
committed
docs: rewrite README with stronger hero and concise examples
1 parent 620d23b commit ead287e

File tree

1 file changed

+93
-140
lines changed

1 file changed

+93
-140
lines changed

README.md

Lines changed: 93 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,26 @@
11
# AgentAnycast Python SDK
22

3-
Python SDK for AgentAnycast -- decentralized A2A agent-to-agent communication over P2P.
3+
**Build P2P agents in Python.** Discover, communicate, and collaborate with AI agents across any network -- encrypted, decentralized, NAT-traversing.
44

5+
[![PyPI](https://img.shields.io/pypi/v/agentanycast?color=3776AB)](https://pypi.org/project/agentanycast/)
56
[![Python](https://img.shields.io/badge/Python-3.10+-3776AB?logo=python&logoColor=white)](https://python.org)
67
[![License](https://img.shields.io/badge/License-Apache%202.0-blue)](LICENSE)
78

8-
> **AgentAnycast is fully decentralized.** On a local network, it works with zero configuration. For cross-network communication, just deploy your own relay with a single command.
9-
10-
## Installation
11-
129
```bash
1310
pip install agentanycast
1411
```
1512

16-
With framework adapters:
17-
18-
```bash
19-
pip install agentanycast[crewai] # CrewAI integration
20-
pip install agentanycast[langgraph] # LangGraph integration
21-
pip install agentanycast[google-adk] # Google ADK integration
22-
pip install agentanycast[openai-agents] # OpenAI Agents SDK integration
23-
pip install agentanycast[claude] # Claude Agent SDK integration
24-
pip install agentanycast[strands] # AWS Strands Agents integration
25-
```
26-
27-
## How It Works
28-
29-
```
30-
┌─────────────┐ mDNS / Relay ┌─────────────┐
31-
│ Agent A │◄──────────────────────────────►│ Agent B │
32-
│ (Python) │ E2E encrypted (Noise) │ (Python) │
33-
└──────┬──────┘ └──────┬──────┘
34-
│ gRPC │ gRPC
35-
┌──────┴──────┐ ┌──────┴──────┐
36-
│ agentanycastd│ │ agentanycastd│
37-
│ (daemon) │ │ (daemon) │
38-
└─────────────┘ └──────────────┘
39-
```
40-
41-
- **Local network (LAN):** Agents discover each other automatically via mDNS. No relay needed.
42-
- **Cross-network (WAN):** Deploy your own relay server, then point agents to it. One command.
43-
4413
## Quick Start
4514

46-
### CLI
47-
48-
```bash
49-
# Start an echo agent
50-
agentanycast demo
51-
52-
# Discover agents by skill
53-
agentanycast discover translate
54-
55-
# Send a task to a specific agent
56-
agentanycast send 12D3KooW... "Hello!"
57-
58-
# Check node status
59-
agentanycast status
60-
```
61-
62-
### Python API
63-
64-
**Server agent:**
15+
**Create an agent:**
6516

6617
```python
6718
from agentanycast import Node, AgentCard, Skill
6819

6920
card = AgentCard(
7021
name="EchoAgent",
7122
description="Echoes back any message",
72-
skills=[Skill(id="echo", description="Echo messages")],
23+
skills=[Skill(id="echo", description="Echo the input")],
7324
)
7425

7526
async with Node(card=card) as node:
@@ -78,16 +29,13 @@ async with Node(card=card) as node:
7829
text = task.messages[-1].parts[0].text
7930
await task.complete(artifacts=[{"parts": [{"text": f"Echo: {text}"}]}])
8031

32+
print(f"Agent running — Peer ID: {node.peer_id}")
8133
await node.serve_forever()
8234
```
8335

84-
**Client agent:**
36+
**Send a task to another agent:**
8537

8638
```python
87-
from agentanycast import Node, AgentCard
88-
89-
card = AgentCard(name="Client", description="A client agent", skills=[])
90-
9139
async with Node(card=card) as node:
9240
handle = await node.send_task(
9341
peer_id="12D3KooW...",
@@ -97,145 +45,150 @@ async with Node(card=card) as node:
9745
print(result.artifacts[0].parts[0].text) # "Echo: Hello!"
9846
```
9947

100-
### Three Ways to Send a Task
48+
## Three Ways to Send a Task
10149

10250
```python
103-
# 1. Direct — by Peer ID
51+
# Direct — by Peer ID
10452
await node.send_task(peer_id="12D3KooW...", message=msg)
10553

106-
# 2. Anycast — by skill (relay resolves the target)
54+
# Anycast — by skill (relay resolves the target)
10755
await node.send_task(skill="translate", message=msg)
10856

109-
# 3. HTTP Bridge — to standard HTTP A2A agents
57+
# HTTP Bridge — to standard HTTP A2A agents
11058
await node.send_task(url="https://agent.example.com", message=msg)
11159
```
11260

113-
### Skill Discovery
61+
## CLI
11462

115-
```python
116-
# Find all agents offering a skill
117-
agents = await node.discover("translate")
63+
```bash
64+
agentanycast demo # Start an echo agent
65+
agentanycast discover translate # Find agents by skill
66+
agentanycast send 12D3KooW... "Hello!" # Send a task
67+
agentanycast status # Check node status
68+
agentanycast info # Show Peer ID, DID, version
69+
```
70+
71+
## How It Works
11872

119-
# With tag filtering
120-
agents = await node.discover("translate", tags={"lang": "fr"})
12173
```
74+
┌─────────────┐ mDNS / Relay ┌─────────────┐
75+
│ Agent A │<------------------------------>│ Agent B │
76+
│ (Python) │ E2E encrypted (Noise) │ (Python) │
77+
└──────┬──────┘ └──────┬──────┘
78+
| gRPC | gRPC
79+
┌──────┴──────┐ ┌──────┴──────┐
80+
│ agentanycastd│ │ agentanycastd│
81+
│ (Go daemon)│<---------- libp2p ------------>│ (Go daemon) │
82+
└─────────────┘ └──────────────┘
83+
```
84+
85+
- **LAN** -- agents discover each other via mDNS. Zero configuration.
86+
- **WAN** -- deploy a [self-hosted relay](https://github.com/AgentAnycast/agentanycast-relay) and point agents to it.
87+
- The Go daemon is **auto-downloaded and managed** by the SDK. No manual setup.
12288

12389
## Framework Adapters
12490

125-
Expose existing agent frameworks as P2P agents with one function call:
91+
Turn existing frameworks into P2P agents with one function call:
92+
93+
```bash
94+
pip install agentanycast[crewai] # CrewAI
95+
pip install agentanycast[langgraph] # LangGraph
96+
pip install agentanycast[google-adk] # Google ADK
97+
pip install agentanycast[openai-agents] # OpenAI Agents SDK
98+
pip install agentanycast[claude] # Claude Agent SDK
99+
pip install agentanycast[strands] # AWS Strands Agents
100+
```
126101

127102
```python
128-
# CrewAI
129103
from agentanycast.adapters.crewai import serve_crew
130-
await serve_crew(crew, card=card, relay="...")
131-
132-
# LangGraph
133104
from agentanycast.adapters.langgraph import serve_graph
134-
await serve_graph(compiled_graph, card=card, relay="...")
135-
136-
# Google ADK
137105
from agentanycast.adapters.adk import serve_adk_agent
138-
await serve_adk_agent(agent, card=card, relay="...")
139-
140-
# OpenAI Agents SDK
141106
from agentanycast.adapters.openai_agents import serve_openai_agent
107+
from agentanycast.adapters.claude_agent import serve_claude_agent
108+
from agentanycast.adapters.strands import serve_strands_agent
109+
110+
await serve_crew(crew, card=card, relay="...")
111+
await serve_graph(graph, card=card, relay="...")
112+
await serve_adk_agent(agent, card=card, relay="...")
142113
await serve_openai_agent(agent, card=card, relay="...")
114+
await serve_claude_agent(prompt_template="...", card=card)
115+
await serve_strands_agent(agent, card=card)
116+
```
143117

144-
# Claude Agent SDK
145-
from agentanycast.adapters.claude_agent import serve_claude_agent
146-
await serve_claude_agent(
147-
prompt_template="You are a helpful assistant. User query: {input}",
148-
card=AgentCard(name="claude-agent", skills=[Skill(id="chat")]),
149-
relay="/ip4/relay.example.com/tcp/4001/p2p/12D3KooW...",
150-
)
118+
## Skill Discovery
151119

152-
# AWS Strands
153-
from agentanycast.adapters.strands import serve_strands_agent
154-
agent = Agent(model="us.anthropic.claude-sonnet-4-20250514")
155-
await serve_strands_agent(
156-
agent,
157-
card=AgentCard(name="strands-agent", skills=[Skill(id="reasoning")]),
158-
relay="/ip4/relay.example.com/tcp/4001/p2p/12D3KooW...",
159-
)
120+
```python
121+
agents = await node.discover("translate")
122+
agents = await node.discover("translate", tags={"lang": "fr"})
160123
```
161124

162125
## Interoperability
163126

164-
### W3C DID
165-
166127
```python
128+
# W3C DID
167129
from agentanycast.did import peer_id_to_did_key, did_key_to_peer_id
168-
from agentanycast.did import did_web_to_url, url_to_did_web
169-
170130
did = peer_id_to_did_key("12D3KooW...") # "did:key:z6Mk..."
171131
pid = did_key_to_peer_id("did:key:z6Mk...") # "12D3KooW..."
172132

173-
url = did_web_to_url("did:web:example.com:agents:myagent")
174-
# "https://example.com/agents/myagent/did.json"
175-
```
176-
177-
### MCP (Model Context Protocol)
178-
179-
```python
133+
# MCP Tool <-> A2A Skill mapping
180134
from agentanycast.mcp import mcp_tools_to_agent_card
181-
182135
card = mcp_tools_to_agent_card(mcp_tools, name="MCPAgent")
183-
```
184-
185-
### A2A v1.0 Protocol Compatibility
186136

187-
```python
137+
# A2A v1.0 JSON format
188138
from agentanycast.compat.a2a_v1 import task_to_a2a_json, task_from_a2a_json
189139

190-
# Convert internal Task ↔ official A2A v1.0 JSON format
191-
a2a_json = task_to_a2a_json(task)
192-
task = task_from_a2a_json(a2a_json)
193-
```
194-
195-
### OASF (Open Agentic Schema Framework)
196-
197-
```python
198-
from agentanycast.compat.oasf import card_to_oasf_record, card_from_oasf_record
199-
200-
# Convert AgentCard ↔ OASF records for AGNTCY Agent Directory
201-
record = card_to_oasf_record(card, authors=["org"])
202-
card = card_from_oasf_record(record)
140+
# OASF / AGNTCY Directory
141+
from agentanycast.compat.oasf import card_to_oasf_record
142+
from agentanycast.compat.agntcy import AGNTCYDirectory
203143
```
204144

205-
### AGNTCY Directory
145+
## API Reference
206146

207-
```python
208-
from agentanycast.compat.agntcy import AGNTCYDirectory
147+
### Node
209148

210-
directory = AGNTCYDirectory(base_url="https://directory.agntcy.org")
211-
agents = await directory.search("translation")
212-
```
149+
| Method | Description |
150+
|---|---|
151+
| `Node(card, relay?, home?, ...)` | Create a node with an AgentCard and optional config |
152+
| `async with Node(...) as node` | Context manager -- starts/stops daemon automatically |
153+
| `send_task(peer_id?, skill?, url?, message=)` | Send a task using any addressing mode |
154+
| `discover(skill, tags?)` | Find agents by skill with optional tag filtering |
155+
| `on_task(handler)` | Register handler for incoming tasks |
156+
| `serve_forever()` | Block and process incoming tasks until stopped |
213157

214-
## API Reference
158+
### Core Types
215159

216160
| Class | Description |
217161
|---|---|
218-
| `Node` | Main entry point. Manages daemon lifecycle, sends and receives tasks. |
219-
| `AgentCard` | Describes an agent's identity, capabilities, and metadata. |
220-
| `Skill` | Defines a single skill an agent can perform. |
221-
| `TaskHandle` | Returned by `send_task()`. Call `wait()` to block until the remote agent responds. |
222-
| `IncomingTask` | Passed to task handlers. Provides the incoming message and methods to respond. |
162+
| `AgentCard` | Agent identity, capabilities, and metadata |
163+
| `Skill` | A single capability an agent can perform |
164+
| `TaskHandle` | Returned by `send_task()`. Call `wait()` for the result. |
165+
| `IncomingTask` | Passed to task handlers. Provides message data and response methods. |
223166

224-
## Node Options
167+
### Node Options
225168

226169
| Parameter | Description | Default |
227170
|---|---|---|
228-
| `card` | Your agent's `AgentCard` | Required |
229-
| `relay` | Relay server multiaddr for cross-network communication | `None` (LAN only) |
171+
| `card` | Agent's `AgentCard` | Required |
172+
| `relay` | Relay multiaddr for cross-network communication | `None` (LAN only) |
230173
| `daemon_path` | Path to a local `agentanycastd` binary | Auto-download |
231174
| `daemon_addr` | Address of an externally managed daemon | Auto-managed |
232175
| `key_path` | Path to Ed25519 identity key file | `<home>/key` |
233-
| `home` | Data directory for daemon state. Use different values to run multiple nodes on the same machine. | `~/.agentanycast` |
176+
| `home` | Data directory. Use different values for multiple nodes. | `~/.agentanycast` |
177+
178+
## Development
179+
180+
```bash
181+
pip install -e ".[dev]" # Install in editable mode with dev deps
182+
pytest # Run all tests
183+
ruff check . # Lint
184+
ruff format . # Format
185+
mypy src/ # Type check (strict)
186+
```
234187

235188
## Requirements
236189

237190
- Python 3.10+
238-
- The [agentanycastd](https://github.com/AgentAnycast/agentanycast-node) daemon (auto-managed by the SDK, or bring your own)
191+
- The [agentanycastd](https://github.com/AgentAnycast/agentanycast-node) daemon (auto-managed by the SDK)
239192

240193
## License
241194

0 commit comments

Comments
 (0)