AgentNode
The main API — connect to the mesh, send messages, handle RPCs, broadcast.
AgentNode is the primary interface. It manages identity, relay connection, messaging, RPC, and pub/sub.
Creating an agent#
use subway_core::AgentNode;
let node = AgentNode::builder()
.name("my-agent.relay")
.relay("relay.subway.dev:9000")
.build()
.await?;
println!("connected: {} ({})", node.name(), node.peer_id());Builder methods#
| Method | Description |
|---|---|
.name(str) | Agent name (required). .relay appended if no TLD. |
.relay(str) | Relay address as host:port. Default: relay.subway.dev:9000 |
.key_path(str) | Custom keypair storage path. Default: .subway/keys |
.with_mdns() | Enable mDNS for local network discovery |
.with_dht() | Enable DHT for distributed discovery |
.build() | Connect to relay and return SubwayResult<AgentNode> |
What .build() does#
- Loads or generates Ed25519 keypair from
key_path - Discovers relay multiaddr via
GET http://{host}:{port+1}/multiaddr - Creates the libp2p network with QUIC transport
- Connects to relay and reserves a circuit
- Registers name with relay
- Spawns background tasks: name renewal (30s), relay watchdog, request dispatcher
Instance methods#
| Method | Signature | Description |
|---|---|---|
peer_id() | → PeerId | Local peer identity |
name() | → &str | Registered agent name |
listen_addrs() | → &[Multiaddr] | Local listen addresses |
connected_peer_count() | → usize | Number of connected peers |
is_connected_to(pid) | → bool | Check connection to a peer |
send(name, msg) | → SubwayResult<()> | Send direct message |
call(name, req) | → SubwayResult<RpcResponse> | RPC call by name |
call_by_peer_id(pid, req) | → SubwayResult<RpcResponse> | RPC call by PeerId |
broadcast(topic, msg) | → SubwayResult<()> | Publish to topic |
subscribe(topic, handler) | → () | Subscribe to broadcasts |
unsubscribe(topic) | → () | Unsubscribe from topic |
on_message(handler) | → () | Handle incoming messages |
handle_rpc(handler) | → () | Handle RPC requests (sync) |
handle_rpc_async(handler) | → () | Handle RPC requests (async) |
resolve(name) | → SubwayResult<PeerId> | Name resolution |
new_agent_message(type, payload) | → AgentMessage | Create message envelope |
add_peer(pid, addr) | → SubwayResult<()> | Manually add peer |
dial_peer(addr) | → SubwayResult<()> | Manually dial peer |
Lifecycle#
AgentNode spawns several background tasks on creation:
- Name renewal — re-registers with relay every 30s
- Relay watchdog — monitors disconnection, reconnects with backoff
- Request dispatcher — routes incoming
SUBWAY_MSGandSUBWAY_RPC
All tasks shut down when the AgentNode is dropped.