-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.cursorrules
More file actions
104 lines (84 loc) · 3.44 KB
/
.cursorrules
File metadata and controls
104 lines (84 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# AgentAnycast Python SDK
Python SDK for the AgentAnycast P2P runtime. Communicates with the Go sidecar daemon via gRPC over Unix domain socket.
## Architecture
- Thin SDK layer: all P2P networking happens in the Go daemon (`agentanycastd`)
- SDK manages daemon lifecycle (download, start, health check, stop) automatically
- All public APIs are async (`async/await`), built on `asyncio`
- gRPC stubs are pre-generated and committed in `_generated/`
## Directory Structure
```
src/agentanycast/
__init__.py # Public re-exports: Node, AgentCard, Skill, etc.
node.py # Node class — main public API (start, send_task, on_task, serve_forever, stop)
daemon.py # DaemonManager — binary download, process management, health check
_grpc_client.py # gRPC client wrapper over Unix socket
card.py # AgentCard, Skill dataclasses
task.py # TaskHandle (client), IncomingTask (server), Message, Artifact, Part
did.py # PeerID <-> did:key bidirectional conversion
mcp.py # MCP Tool <-> A2A Skill mapping
exceptions.py # Exception hierarchy
adapters/
crewai.py # serve_crew() — CrewAI adapter
langgraph.py # serve_graph() — LangGraph adapter
compat/
agntcy.py # AGNTCY Directory client (lazy import)
cli/ # Click-based CLI (demo, discover, send, status, info)
_generated/ # Auto-generated protobuf/gRPC stubs (committed, do not edit)
tests/
test_node.py
test_card.py
test_task.py
test_did.py
test_mcp.py
examples/
```
## Common Patterns
### Basic agent server
```python
from agentanycast import Node, AgentCard, Skill
card = AgentCard(name="MyAgent", skills=[Skill(id="echo", description="Echo")])
async with Node(card=card) as node:
@node.on_task
async def handle(task):
text = task.messages[-1].parts[0].text
await task.complete(artifacts=[{"parts": [{"text": text}]}])
await node.serve_forever()
```
### Sending tasks
```python
result = await node.send_task(peer_id="12D3KooW...", message="Hello")
result = await node.send_task(skill="translate", message="Translate this")
result = await node.send_task(url="https://agent.example.com", message="Hello")
```
### Framework adapters
```python
from agentanycast.adapters.crewai import serve_crew
from agentanycast.adapters.langgraph import serve_graph
await serve_crew(crew, card=card)
await serve_graph(graph, card=card)
```
## Code Style
- Python 3.10+
- Line length: 100
- Linting: `ruff check .` (rules: E, F, I, N, W, UP)
- Formatting: `ruff format .`
- Type checking: `mypy src/` (strict mode, generated stubs excluded)
- Testing: `pytest` with `asyncio_mode = "auto"`
- Integration tests: marked `@pytest.mark.integration` (skipped by default)
- All public APIs must have type hints and docstrings
## Build & Test
```bash
pip install -e ".[dev]"
pytest
pytest tests/test_node.py::test_specific
ruff check . && ruff format --check .
mypy src/
```
## Key Types
- `Node` — main class; manages daemon, exposes send_task/on_task/discover
- `AgentCard` — agent identity + skills declaration
- `Skill` — single capability (id, description, input/output schemas)
- `IncomingTask` — server-side task with complete/fail/update/send_artifact
- `TaskHandle` — client-side task result with status/artifacts
- `Message` — contains list of Part (TextPart, DataPart, FilePart)
- `Artifact` — output container with parts and metadata