feat(us-016): outbound relay client for NAT/internet pipeline hops

Nodes behind NAT (5G, WSL2, home routers) can now participate in
distributed pipeline inference over the internet via the relay server.

- torch_server: add module-level _relay_hop() that opens a WebSocket
  to relay.../rpc/{peer_id}, sends the binary activation with
  body_base64 encoding, and returns (status, headers, body)
- torch_server: _get_remaining_route returns list[dict] (was list[tuple])
  preserving relay_addr from injected X-Meshnet-Route header and
  from /v1/route slow-path node info
- torch_server: _run_downstream_pipeline dispatches via _relay_hop
  when hop has relay_addr; falls back to direct HTTP on relay error
- tracker server: downstream_hops dicts include relay_addr when node
  has one registered, so head node knows how to reach each peer
- relay_bridge: binary bodies (bfloat16 activations) use body_base64;
  response preserves all X-Meshnet-* headers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dobromir Popov
2026-06-30 18:02:25 +03:00
parent 4f79b2d177
commit 8157151102
3 changed files with 119 additions and 33 deletions

View File

@@ -1074,7 +1074,10 @@ class _TrackerHandler(http.server.BaseHTTPRequestHandler):
covered_up_to = rs - 1
route_hops: list[dict] = []
for rn in route_nodes:
route_hops.append({"endpoint": rn.endpoint, "start_layer": covered_up_to + 1})
hop: dict = {"endpoint": rn.endpoint, "start_layer": covered_up_to + 1}
if rn.relay_addr:
hop["relay_addr"] = rn.relay_addr
route_hops.append(hop)
covered_up_to = rn.shard_end if rn.shard_end is not None else covered_up_to
# Strip the first-shard node we're about to proxy to — it's already handling the request.
downstream_hops = [h for h in route_hops if h["endpoint"].rstrip("/") != node.endpoint.rstrip("/")]