HearthNet-Nemotron / scripts /connect_to_hf.py
GitHub Actions
fix: HF bus /bus/v1/call uses Body(...) not Request (422 on Space FastAPI)
428efdf
Raw
History Blame Contribute Delete
3.24 kB
"""Connect a local HearthNet node to the public HuggingFace Space and route a
real capability call to it over HTTPS.
Usage:
python scripts/connect_to_hf.py
python scripts/connect_to_hf.py --ask "How do I purify water?"
What it does (all real, no mocks):
1. Builds a local in-process HearthNet node (with discovery + HTTP transport).
2. Calls ``discovery.peer.add`` -> fetches the Space's ``/manifest`` and
registers its capabilities (llm.chat, rag.query, moe.*, ...) as remote
routable entries.
3. Routes an ``llm.chat`` (and ``rag.query``) call which the bus dispatches to
the Space via ``POST https://<space>/bus/v1/call``.
Requires the Space to expose the bus endpoints (mounted in app.py). If the
Space is still building or asleep, peer.add returns a clear ``partition`` error.
"""
from __future__ import annotations
import argparse
import asyncio
HF_SPACE_URL = "https://build-small-hackathon-hearthnet.hf.space"
async def _run(space_url: str, question: str) -> int:
from hearthnet.node import HearthNode
node = HearthNode("ed25519:local-cli", "Local CLI", "ed25519:community")
local_caps = sorted({e.descriptor.name for e in node.bus.registry.all_local()})
print(f"[1/4] Local node up. Local capabilities: {local_caps}")
print(f"[2/4] Peering with {space_url} via discovery.peer.add ...")
add = await node.bus.call("discovery.peer.add", (1, 0), {"input": {"endpoint": space_url}})
if add.get("error"):
print(f" x peer.add failed: {add['error']} - {add.get('message', '')}")
print(" The Space may still be building or asleep. Open the UI once and retry.")
return 1
out = add["output"]
print(f" + Peer added: {out['node_id'][:24]}...")
print(f" Remote capabilities now routable: {out['capabilities']}")
remote = sorted({e.descriptor.name for e in node.bus.registry.all_remote()})
print(f"[3/4] Bus registry remote entries: {remote}")
print(f'[4/4] Routing llm.chat to the Space - asking: "{question}"')
try:
chat = await node.bus.call(
"llm.chat",
(1, 0),
{"input": {"messages": [{"role": "user", "content": question}]}},
)
msg = chat.get("output", {}).get("message", {}).get("content", "")
meta = chat.get("meta", {})
print(f" + Space replied ({meta.get('model', '?')}):")
print(f" {msg.strip()[:500]}")
except Exception as exc:
print(f" x llm.chat routing failed: {exc}")
return 1
print()
print("=" * 62)
print(" Connected. Your local node is peered with the HF Space and")
print(" routed a real llm.chat call to it over HTTPS.")
print(" RAG: node.bus.call('rag.query', (1,0), {'input': {'query': '...'}})")
print("=" * 62)
return 0
def main() -> None:
parser = argparse.ArgumentParser(description="Peer a local node with the HF Space")
parser.add_argument("--space-url", default=HF_SPACE_URL)
parser.add_argument("--ask", default="In one sentence, how do I store water safely?")
args = parser.parse_args()
raise SystemExit(asyncio.run(_run(args.space_url, args.ask)))
if __name__ == "__main__":
main()