๐ณ Cookbook: Rock-Paper-Scissors (A2A Edition)¶
A playful demonstration of Agent-to-Agent communication. Two agents compete in the classic game over the Stargate P2P network. No practical purposeโjust pure fun! ๐ฎ
๐ฏ What You'll Build¶
Two agents: 1. Player One: Makes a move and challenges Player Two 2. Player Two: Receives the challenge, responds with a move, determines winner
They communicate entirely via the A2A protocol!
๐๏ธ Phase 1: Create Player One¶
1. Scaffold¶
2. Configure .env¶
3. Create the Game Tool¶
In app/tools/rps.py:
import random
from app.tools.base import tool
MOVES = ["rock", "paper", "scissors"]
@tool(name="play_rps", category="game")
def play_rps(opponent_move: str = "") -> dict:
"""
Play Rock-Paper-Scissors.
If opponent_move is empty, make a move.
If opponent_move is provided, determine the winner.
"""
my_move = random.choice(MOVES)
if not opponent_move:
return {"my_move": my_move, "status": "waiting_for_opponent"}
# Determine winner
if my_move == opponent_move:
result = "tie"
elif (my_move == "rock" and opponent_move == "scissors") or \
(my_move == "paper" and opponent_move == "rock") or \
(my_move == "scissors" and opponent_move == "paper"):
result = "i_win"
else:
result = "i_lose"
return {
"my_move": my_move,
"opponent_move": opponent_move,
"result": result
}
4. Start Server¶
๐ฎ Phase 2: Create Player Two¶
1. Scaffold¶
2. Configure .env¶
3. Same Game Tool¶
Copy the same rps.py from Player One.
4. Start Server¶
๐ Phase 3: The Challenge Script¶
Create a script that orchestrates a game:
# game_master.py
import asyncio
from app.tools.a2a import RemoteAgentCallTool
async def play_game():
caller = RemoteAgentCallTool()
# Step 1: Player One makes a move
print("๐ฎ Player One is thinking...")
p1_response = await caller.execute(
target_url="http://localhost:8001",
message="Make your Rock-Paper-Scissors move!"
)
p1_move = extract_move(p1_response)
print(f" Player One chose: {p1_move}")
# Step 2: Player Two responds and judges
print("๐ฎ Player Two is responding...")
p2_response = await caller.execute(
target_url="http://localhost:8002",
message=f"Opponent played {p1_move}. What's your move?"
)
result = extract_result(p2_response)
# Step 3: Announce winner
print("\n" + "="*40)
if result == "tie":
print("๐ค It's a TIE!")
elif result == "i_win":
print("๐ Player TWO wins!")
else:
print("๐ Player ONE wins!")
print("="*40)
def extract_move(response):
# Parse the agent's response to get the move
# (Implementation depends on response format)
return response.get("my_move", "rock")
def extract_result(response):
return response.get("result", "tie")
asyncio.run(play_game())
๐ Phase 4: Run the Game!¶
With both agents running:
Output:
๐ฎ Player One is thinking...
Player One chose: scissors
๐ฎ Player Two is responding...
========================================
๐ Player TWO wins!
========================================
๐ Phase 5: Play Over the Real Network¶
1. Register Both Agents¶
2. Discover Opponent¶
Instead of hardcoding URLs, find your opponent:
from app.tools.a2a import SearchAgentsTool
search = SearchAgentsTool()
opponents = await search.execute(query="rock paper scissors")
opponent_url = opponents[0].base_url
Now you can play with agents anywhere in the world! ๐
๐ญ Why This Matters¶
This silly game demonstrates:
| Concept | Demonstrated |
|---|---|
| A2A Messaging | Agents sending structured requests |
| Tool Execution | Remote tool invocation over HTTP |
| Agent Discovery | Finding agents by capability |
| P2P Communication | Decentralized, no central server |
The same patterns power serious applications like multi-agent research teams, financial trading bots, and distributed AI systems.
๐งฉ Bonus Challenge¶
- Tournament Mode: Run 100 games and track statistics
- Memory: Agents remember past games and adapt strategy
- Trash Talk: Add a personality agent that comments on each move ๐