Spaces:
Running on Zero
Running on Zero
File size: 28,963 Bytes
c284afa 76973b4 69b76bd 76973b4 69b76bd 7a597fd 76973b4 b3661f0 76973b4 c284afa 76973b4 b1ec6c0 76973b4 c284afa 69b76bd b1ec6c0 b3661f0 b1ec6c0 c284afa b3661f0 b9c58f7 3d52fa4 b9c58f7 b3661f0 3d52fa4 146edc4 c284afa ef27d38 146edc4 f08047d c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 c284afa b9c58f7 c284afa b9c58f7 c284afa b3661f0 b9c58f7 146edc4 3d52fa4 146edc4 b9c58f7 4cd8837 b3661f0 c284afa ef27d38 c284afa ef27d38 c284afa ef27d38 c284afa ef27d38 c284afa b3661f0 c284afa b3661f0 38bd54a 2e84546 66a1a95 2e84546 66a1a95 38bd54a c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 b9c58f7 b3661f0 c284afa b9c58f7 c284afa b3661f0 38bd54a 66a1a95 38bd54a c284afa b3661f0 c284afa b9c58f7 c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 c284afa 4cd8837 b3661f0 c284afa b3661f0 4cd8837 c284afa b3661f0 c284afa 4cd8837 c284afa b3661f0 b9c58f7 c284afa b3661f0 c284afa c91b229 c284afa c91b229 c284afa b3661f0 c284afa b1ec6c0 c284afa b9c58f7 c284afa 74c4a03 c284afa b9c58f7 b1ec6c0 b9c58f7 146edc4 b9c58f7 4cd8837 b3661f0 4cd8837 c284afa b9c58f7 146edc4 b9c58f7 c284afa b3661f0 4cd8837 c284afa 4cd8837 c284afa b9c58f7 146edc4 b9c58f7 c284afa 74c4a03 c284afa 4cd8837 c284afa 4cd8837 c284afa 4cd8837 c284afa b3661f0 c284afa b3661f0 c284afa b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 c284afa b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 b3661f0 b9c58f7 31d4f9b b9c58f7 31d4f9b b9c58f7 b3661f0 b9c58f7 b3661f0 c284afa b3661f0 c284afa 66a1a95 c284afa b3661f0 b9c58f7 21c2afa b9c58f7 2e84546 b9c58f7 21c2afa b1ec6c0 2e84546 b9c58f7 2e84546 b9c58f7 2e84546 c284afa b3661f0 c284afa 2e84546 b9c58f7 b3661f0 c284afa b9c58f7 | 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | ---
title: HearthNet
emoji: π₯
colorFrom: purple
colorTo: pink
sdk: gradio
sdk_version: 6.18.0
python_version: '3.10'
app_file: app.py
pinned: true
short_description: Community-Owned AI Mesh That Works When The Internet Doesn't
tags:
- backyard-ai
- tiny-titan
- best-agent
- nemotron
- minicpm
- modal
- codex
license: apache-2.0
---
# π¬ HearthNet Β· Document Intelligence
> **Companion Space** to [π₯ HearthNet](https://huggingface.co/spaces/build-small-hackathon/HearthNet) β the main community AI mesh.
> This Space extends the mesh with NVIDIA Nemotron-powered document intelligence: structured extraction, Q&A, summarisation, and one-click RAG ingest into any mesh node.
> When no `NVIDIA_API_KEY` is set, falls back to **SmolLM2-135M** locally (no API key needed).
### NVIDIA Nemotron Document Intelligence Β· Part of the HearthNet Mesh
<p align="center">
<strong>Local-First Β· Peer-to-Peer Β· Offline-Capable Β· Emergency-Ready</strong>
</p>
<p align="center">
<a href="https://huggingface.co/spaces/build-small-hackathon/HearthNet"><img src="https://img.shields.io/badge/π€%20HF%20Space-Live-blue" alt="HF Space"></a>
<a href="https://github.com/ckal/HearthNet"><img src="https://img.shields.io/badge/GitHub-source-black" alt="GitHub"></a>
<img src="https://img.shields.io/badge/python-3.13%2B-blue" alt="Python 3.13+">
<img src="https://img.shields.io/badge/license-Apache%202.0-green" alt="License">
<img src="https://img.shields.io/badge/backends-llama.cpp%20|%20Ollama-orange" alt="Backends">
<img src="https://img.shields.io/badge/routing-intelligent%20mesh-purple" alt="Routing">
<a href="#-agent-mode-react-tool-calling"><img src="https://img.shields.io/badge/agent-ReAct%20tool%20calling-blueviolet" alt="Agent"></a>
<a href="#-testing--coverage"><img src="https://img.shields.io/badge/tests-390%2B%20passing-brightgreen" alt="Tests"></a>
<a href="#features"><img src="https://img.shields.io/badge/features-routing%20trace-teal" alt="Routing Trace"></a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/π%20Tiny%20Titan-MiniCPM3--4B%20|%20Nemotron%20Mini%204B-ff69b4" alt="Tiny Titan">
<img src="https://img.shields.io/badge/π€%20Best%20Agent-multi--step%20tools-blueviolet" alt="Best Agent">
<img src="https://img.shields.io/badge/NVIDIA-Nemotron%203%20Nano-76b900" alt="Nemotron">
<img src="https://img.shields.io/badge/OpenBMB-MiniCPM%20multi--model-1f6feb" alt="OpenBMB">
</p>
> **Build Small Hackathon entry** β Backyard AI track Β· π Tiny Titan Β· π€ Best Agent π«₯ press e or a to see the easter egg.
>
> πΊ **Demo video:** <a href="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/hf_hackathon_screenrecording_v1.webm">HF Space Recording</a> Β· <a href="https://videos.simpleshow.com/8vSfxilim8">Simple Show Demo</a>
<video width="640" height="360" controls>
<source src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/hf_hackathon_screenrecording_v1.webm" type="video/webm">
Your browser does not support the video tag.
</video>
> π£ **Social post:** [tweet on x](https://twitter.com/zX14_7/status/2064853015622775047) [tweet on x](https://twitter.com/zX14_7/status/2064853015622775047)
>
> **June 14 bug-fix release:** 8 critical bugs fixed β seed corpus now actually ingested,
> node lifecycle corrected (`stop()` previously silently no-oped), sticky session memory
> leak patched, corpus writes go to the right directory.
> See [hackathon_final_step.md](hackathon_final_step.md) for the full analysis.
---
## The Idea
What happens to your neighbourhood's AI when the power grid flickers, the ISP goes down, or the cloud API bill hits?
**HearthNet answers: nothing changes.** It keeps running.
Every household with a Raspberry Pi, an old laptop, or any device running Python becomes a **node**
in a local AI mesh. Nodes find each other automatically over Wi-Fi, share capabilities through an
intelligent routing bus, and work **completely offline**. When the internet is available, nodes **automatically route requests to the best provider** β whether local, nearby on LAN, or across the internet via relay. You see exactly which node answered.
- A neighbourhood of 10 homes gets **10Γ the AI capacity** of any single device
- **Offline-first**: all features work without internet; internet is optional for mesh expansion
- **Transparent routing**: every Ask/Chat/RAG request shows which node served it (local or remote)
- Ask questions, share knowledge, send messages, coordinate emergency response β all offline
- No cloud account, no API key, no monthly bill β hardware you already own
---
## Features
### Agent Mode (ReAct tool calling)
Flip the **Agent mode** toggle in the Ask tab and the model stops being a chatbot and starts being an **agent**: it plans, calls real mesh tools over several steps, reads the results, and only then answers. Every step is shown live β **Thought β Tool β Observation β Answer**.
The agent's tools are bound to **real capabilities already on the bus** (no mock handlers):
`search_corpus` (RAG), `list_corpora`, `translate`, `list_marketplace`, `route_expert` (MoE), and `identify_plant` (vision). The loop uses a JSON `action:` protocol that works even on **tiny models with no native function-calling** β so a 4B MiniCPM or Nemotron Mini can drive the same agent as a 49B reasoner. There is also a **fully in-browser WebLLM agent** (WebGPU, zero server) for true offline tool use.
> π‘ **Try the browser agent:** press **`a`** (or just type **`hearthnet`**) anywhere on the dashboard to open the in-browser WebLLM agent showcase. Press **`e`** for the live mesh/news ticker, **`Esc`** to close.
### π§ Intelligent Routing (NEW)
When you ask a question, the bus scores available LLM nodes by latency, load, and reliability. Your request goes to the **best node right now** β whether it's local, your neighbour's device, or a peer across the internet. Failover is automatic: if the preferred node can't help, the next-best provider takes over **invisibly**.
**Routing Trace** shows you exactly where your request was served:
- π **Local**: Answered by this device
- π **Remote (node-id)**: Routed to a peer node (LAN or internet)
- β **Error**: No suitable provider found
### π¬ Chat Over LAN & Internet
Direct 1:1 messages work completely offline on your Wi-Fi. Connect to the internet (via relay hub on HF Space) and chat with anyone in the mesh, regardless of network. No accounts, no passwordsβjust show them your QR code.
### π Federated RAG
Share a corpus of documents with your community. Any node can search across **all available corpora** automatically, with results ranked by relevance. Works offline on local copies; syncs and queries remote corpora when internet is available.
### π€ MOE Expert Routing
Nodes advertise their specialisations. Queries automatically route to the best experts in your mesh for better answers.
### π¨ Emergency Mode
When connectivity drops, the UI automatically switches to degraded mode. Nodes keep working offline. When restored, changes sync. Perfect for neighbourhood coordination during outages.
---
## Screenshots
<table>
<tr>
<td><strong>Ask the Mesh</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/02-alice-ask-response.png" alt="LLM routes query to best node" width="380"></td>
<td><strong>Live Peer Topology</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/08c-alice-mesh-live.png" alt="SVG peer graph" width="380"></td>
</tr>
<tr>
<td><strong>Routing Trace</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/01-hf-space-live.png" alt="Shows which node answered" width="380"></td>
<td><strong>Community Marketplace</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/04-alice-marketplace.png" alt="Post and browse offers" width="380"></td>
</tr>
<tr>
<td><strong>Direct Messages</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/03-alice-chat.png" alt="Delivery confirmation" width="380"></td>
<td><strong>Invite QR Code</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/07-alice-settings.png" alt="Join mesh via QR" width="380"></td>
</tr>
<tr>
<td><strong>Emergency Mode</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/06-alice-emergency.png" alt="Connectivity indicator" width="380"></td>
<td><strong>All 8 Tabs</strong><br><img src="https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/docs/screenshots/08-alice-settings-peers.png" alt="All tabs" width="380"></td>
</tr>
</table>
---
## π¦ Downloads & Builds
Get HearthNet for your platform:
| Platform | Download | Format | Size | Notes |
|----------|----------|--------|------|-------|
| **Android (PWA)** | [Web App](https://huggingface.co/spaces/build-small-hackathon/HearthNet) | Web | ~5MB | Install from browser - no download needed |
| **Android (Native)** | [app-debug.apk](https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/build/android/HearthNetApp/platforms/android/app/build/outputs/apk/debug/app-debug.apk) | APK | 3.56MB | Native Android app via USB or direct install |
| **Windows Desktop** | [HearthNet.exe](https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/dist/HearthNet.exe) | EXE | 212MB | Standalone executable - download & run |
| **Linux Desktop** | `python build/quickstart.py linux` | AppImage | ~120MB | Build on Linux or use script |
| **macOS Desktop** | `python build/quickstart.py macos` | .app | ~200MB | Native macOS app bundle |
| **Python (Any OS)** | [Source](https://github.com/ckal/HearthNet) | Python | - | `python app.py` - full mesh node |
| **Docker** | [Dockerfile](Dockerfile) | Container | 2GB | `docker run -p 7860:7860 hearthnet:latest` |
| **Guides & Docs** | [BUILD_GUIDE.md](docs/guides/BUILD_GUIDE.md) | Markdown | - | How to build for each platform |
**Recommended Paths:**
- π **Fastest** (5 min): PWA Web App - instant, no install
- π» **Desktop** (3 min): Download EXE/AppImage and run
- π³ **Server**: Docker container deployment
- π See [BUILD_GUIDE.md](docs/guides/BUILD_GUIDE.md) for detailed instructions
---
## Quick Start
```bash
# Clone and install
git clone https://huggingface.co/spaces/build-small-hackathon/HearthNet
cd HearthNet
pip install -e ".[dev]"
# Run
python app.py # open http://127.0.0.1:7860
```
### With llama.cpp (recommended β fast, offline)
```bash
# 1. Download a GGUF model
wget https://huggingface.co/lmstudio-community/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf
# 2. Start llama.cpp server
./llama-server -m Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf -p 8080
# 3. Run HearthNet (auto-detects llama.cpp on port 8080)
python app.py
```
**Why llama.cpp?**
- β‘ Fast inference on CPU (no GPU required)
- πΎ Runs the best models offline (8B params fits on 16GB RAM)
- π§ GGUF format is efficient and portable
- π No API key, no cloud, no latency
### Alternative: Ollama
```bash
ollama pull llama3.2:3b # any Ollama model works
python app.py # auto-detects Ollama
```
### On Android (PWA - Recommended)
```bash
# 1. Start HearthNet on your computer (Windows, Mac, or Linux)
python app.py
# 2. Find your computer IP address
# Windows: ipconfig | grep IPv4
# Mac/Linux: ifconfig | grep "inet " | grep -v 127
# 3. Open on Android device in Chrome/Firefox:
# http://<YOUR_IP>:7860
# 4. Tap menu β "Install app" or "Add to Home screen"
```
**π± Full Android Setup Guide:** [ANDROID_DEPLOYMENT_GUIDE.md](docs/guides/ANDROID_DEPLOYMENT_GUIDE.md)
- β
PWA (instant, no build)
- π§ Native APK (optional, advanced)
### Connect your local node to the live HF Space
```bash
# Get an invite code from the Space Settings tab
# Then redeem it locally:
python -m hearthnet.cli invite redeem \
"hnvite://v1/hf-space-1c95381d?host=build-small-hackathon-hearthnet.hf.space&port=443&transport=https&level=member"
python -m hearthnet.cli peers # Space node should appear
```
---
## How It Works
### Capability Bus
Every feature is a **named capability** on the bus. Any node can call any capability;
the bus routes to the best available provider automatically:
```python
# LLM inference β routes to fastest/best node in the mesh
result = await bus.call("llm.chat", (1, 0), {
"input": {"messages": [{"role": "user", "content": "What plants grow near water?"}]}
})
# RAG β routes to the node holding that corpus
result = await bus.call("rag.query", (1, 0), {
"params": {"corpus": "community"},
"input": {"query": "emergency water purification", "k": 3}
})
# Or from the CLI β no Python needed
python -m hearthnet.cli call llm.chat 1 0 '{"input":{"messages":[{"role":"user","content":"Hello!"}]}}'
python -m hearthnet.cli capabilities # list all available capabilities across mesh
```
### Zero-Config Discovery
```bash
# Device 1 β already running
python app.py
# Device 2 β same Wi-Fi
python app.py
# Both nodes see each other in ~5 seconds (mDNS + UDP broadcast)
# No IP addresses, no router config, no firewall rules
```
### Intelligent Routing & Failover
When you ask a question:
1. **Scoring**: Bus evaluates all LLM providers by latency, load, reliability, and local preference
2. **Selection**: Request goes to the best provider
3. **Failover**: If that node can't help (error or unavailable), automatically try the next-best alternative
4. **Tracing**: Result includes `_routed_via` showing which node served it
```python
# Node A has no LLM backend (would normally fail)
# Node B has llama.cpp running
# You ask Node A a question β Node A routes to Node B β B answers β A shows you the result
# Tracing shows: "_routed_via": "node-b-id"
result = await bus.call("llm.chat", (1, 0), {...})
# result includes "_routed_via": "node-b-id" β Shows the true origin
```
### MoE Expert Routing
Nodes advertise specialisations. Queries route to the best expert automatically:
```python
# A medical Raspberry Pi registers itself:
await bus.call("moe.register", (1, 0), {
"input": {
"expert_id": "model:medical-pi",
"topic_tags": ["first_aid", "medication", "triage"],
"confidence_score": 0.90,
}
})
# Any node's medical query now routes there:
result = await bus.call("moe.route", (1, 0), {
"input": {"query": "emergency first aid for burns", "top_k": 3}
})
# β {"candidates": [{"expert_id": "model:medical-pi", "score": 0.94}]}
```
### Offline Model Distribution
A node without internet pulls model weights from a LAN peer, chunk by chunk:
```python
models = await bus.call("model.list", (1, 0), {"input": {}})
job = await bus.call("model.pull", (1, 0), {
"input": {"model_name": "llama3.2:3b", "source_node": "peer-id"}
})
# Progress via model.status; BLAKE3 content-addressed so never duplicated
```
---
## What Makes This "Tiny"
The HF Space demo uses **MiniCPM3-4B** β 4B params, strong instruction following, under the 32B Tiny Titan limit. Set `MODEL_ID=HuggingFaceTB/SmolLM2-135M-Instruct` to run 135M ultra-light mode on Pi-class devices.
For local installs, any GGUF model works (1Bβ8B for significantly better quality).
The architecture is model-agnostic; the routing layer handles the rest.
**Real semantic RAG, not a toy:** when `sentence-transformers` is installed the
embedding service loads `BAAI/bge-small-en-v1.5` (~130 MB, CPU-friendly) so
`rag.query` performs genuine semantic retrieval. Without it, the service falls
back to a deterministic hash embedder and says so β no silent fakery.
**Why this qualifies for Tiny Titan:**
A full mesh of 10 Raspberry Pi 4 nodes (4 GB RAM each) can run:
- 135M model locally per node (always available, zero latency)
- Load-balanced routing for larger models across the mesh
- Full offline capability: discovery, RAG, chat, marketplace β no internet needed
---
## Local AI Backends
**No mocks. No fake responses. Real local inference only.**
HearthNet prioritizes local, private models. Cloud backends are **opt-in only** (env vars).
### Local Backends (Primary)
| Backend | Activation | Notes |
|---------|-----------|-------|
| **llama.cpp** (recommended) | Start server on port 8080 + auto-detect | Any GGUF model; fastest on CPU |
| **Ollama** | `ollama pull llama3.2:3b` + auto-detect | 70+ models, easy management |
| **HF Transformers** | Default on HF Space (no config needed) | MiniCPM3-4B (override with `MODEL_ID`) |
| **OpenBMB / MiniCPM** | `MINICPM_URL` env var (local server) | Local-first, OpenAI-compatible API |
### Optional Cloud Backends (Opt-In via Env Vars)
| Backend | Activation | Notes |
|---------|-----------|-------|
| **NVIDIA Nemotron** | `NVIDIA_API_KEY` env var | For RTX nodes: nemotron-70b/mini-4b |
| **Modal** | `MODAL_ENDPOINT` env var | Serverless GPU inference |
| **OpenAI API** | `OPENAI_API_KEY` env var | Fallback only; not recommended for offline mesh |
All configured backends are registered on the `llm.chat` capability. The routing bus selects the best backend based on:
1. **Local first**: llama.cpp, Ollama, HF Transformers always preferred
2. **Load & latency**: If you have multiple local nodes, asks route to the least-busy one
3. **Failover**: If local is unavailable and you have internet, remote nodes or cloud backends are tried
If no suitable backend is available: clear error message returned. Never silent, never fabricated.
---
## Security
- **Ed25519** β all node manifests and invite links signed with PyNaCl
- **X3DH + Double Ratchet** β end-to-end encrypted chat (M23)
- **BLAKE3** β content-addressed file blobs (tamper-evident)
- **localhost-only CLI** β all admin HTTP restricted to 127.0.0.1
- **Capability token `exp` claim** β checked in `bus.handle_call()` before routing; expired tokens receive `{"error": "token_expired"}` without hitting any handler
- **Token signature verification** β Ed25519 signature checking is implemented in `AuthService` (`auth.token.verify`) and is available on the bus. The HTTP transport (`/bus/v1/call`) currently passes tokens to `handle_call()` where expiry is enforced; full per-request signature verification on inbound HTTP calls is a planned hardening step.
- **Bandit HIGH findings: 0** (verified in CI)
---
## Architecture
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Gradio UI (8 tabs) β
β Ask Β· Chat Β· Mesh Β· Marketplace Β· Files Β· Emergency Β· β
β Settings Β· Getting Started β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
ββββββββββββββΌβββββββββββββ
β Capability Bus (M03) β
β route Β· score Β· trace β
ββββββ¬βββββββ¬βββββββ¬βββββββ
β β β
ββββββββββββΌβ ββββΌββββ ββΌβββββββββββ ββββββββββββββ
β LLM (M04) β β RAG β β MoE (M27) β β Chat (M10) β
βllama.cpp β β(M05) β β Expert β β Marketplaceβ
β Ollama β βSQLiteβ β Registry β β (M06) Filesβ
βHF Transfm β βEmbed β βββββββββββββ ββββββββββββββ
βββββββ¬ββββββ ββββ¬ββββ
βββββββ¬βββββββ
ββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββ
β Transport (X01) Β· Discovery (M02 mDNS/UDP) β
β Events (X02 SQLite/Lamport) Β· E2E Encrypt (M23) β
β Identity (M01 Ed25519) Β· Observability (X03) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## Module Reference
<details>
<summary><strong>Phase 1 β Core (M01βM13, X01βX04) Β· 17 modules</strong></summary>
| Module | Description | Status |
|--------|-------------|--------|
| M01 | Node identity (Ed25519, manifests, canonical JSON) | β
|
| M02 | Peer discovery (mDNS, UDP broadcast, PeerRegistry) | β
|
| M03 | Capability bus (schema validation, routing, tracing) | β
|
| M04 | LLM service (llama.cpp, Ollama, HF Transformers, cloud fallback) | β
|
| M05 | RAG (chunker, SQLite/ChromaDB vector store, IngestPipeline, federated scatter-gather) | β
|
| M06 | Marketplace (event-sourced, Lamport-clocked posts) | β
|
| M07 | File blobs (BLAKE3 hash, content-addressed, chunked transfer) | β
|
| M08 | Gradio UI (8 tabs: Ask, Chat, Mesh, Marketplace, Files, Emergency, Settings, Getting Started) | β
|
| M09 | Emergency mode (async connectivity probe, auto-degrade on offline) | β
|
| M10 | Chat (event-backed 1:1 direct messaging, Lamport delivery order) | β
|
| M11 | Embeddings (embed.text, SentenceTransformer `bge-small-en-v1.5`, SimpleHashBackend fallback, batch support) | β
|
| M12 | CLI (click, ask / peers / marketplace / call / capabilities) | β
|
| M13 | Onboarding (invite QR, hnvite:// deep links, PyNaCl signing) | β
|
| X01 | Transport (FastAPI server, 12 REST endpoints, TLS) | β
|
| X02 | Events (SQLite, Lamport clocks, ReplayEngine, snapshots) | β
|
| X03 | Observability (structured JSON logging, metrics, distributed tracing) | β
|
| X04 | Config (typed frozen dataclasses, TOML, env overlay) | β
|
</details>
<details>
<summary><strong>Phase 2 β Advanced (M14βM25, X05βX07) Β· 18 modules</strong></summary>
| Module | Description | Status |
|--------|-------------|--------|
| M14 | Federation (bilateral cross-community trust, manifest signing) | β
|
| M15 | Relay tier (NAT traversal, keepalive, push token registry) | β
|
| M16 | Capability tokens (Ed25519 JWS-style hntoken://v1/ format) | β
|
| M17 | OCR (Tesseract + TrOCR backends, graceful degradation) | β
|
| M18 | Translation (NLLB backend, LRU cache, 4000-char limit) | β
|
| M19 | STT/TTS (Whisper local STT, Edge TTS synthesis) | β
|
| M20 | Vision (Florence-2 image describe, structured output) | β
|
| M21 | Tool calls (LLM mid-generation bus dispatch, ToolExecutor, plant_identify) | β
|
| M22 | Mobile native (Flutter contract, hnapp:// invites, push authority) | β
|
| M23 | E2E encryption (X3DH key agreement, Double Ratchet, AEAD envelope) | β
|
| M24 | Reranking (BGE + CrossEncoder backends, 100-doc limit) | β
|
| M25 | Group chat (ThreadService, ThreadViewStore, event-sourced threads) | β
|
| X05 | DHT (Kademlia node, 256-bucket routing table, bootstrap) | β
|
| X06 | WebSocket upgrade (bidirectional pubsub, WsClient) | β
|
| X07 | Federated metrics (NodeMetricsTick, MetricsAggregator, OTLP) | β
|
</details>
<details>
<summary><strong>Phase 3 β Experimental (M26βM31, X08βX09) Β· feature-flag gated</strong></summary>
| Module | Description | Status |
|--------|-------------|--------|
| M26 | Distributed inference (ShardDescriptor, PipelineOrchestrator, model.pull) | registered |
| M27 | MoE routing (ExpertRegistry, MoeRouter, moe.route/register/list) | registered |
| M28 | Federated learning (FedLearnCoordinator, RoundManifest, gradient aggregation) | experimental |
| M29 | LoRa beacons (32-byte frames, 868 MHz offline signaling) | experimental |
| M30 | Evidence graph / EBKH (ClaimStore, attestations, disputes) | experimental |
| M31 | Civil defense NRW (AuditChain, role certs, structured alerts) | experimental |
| X08 | Tensor transport (chunked binary tensor streaming) | experimental |
| X09 | Conformance suite (protocol test harness) | experimental |
</details>
---
## π§ͺ Testing & Coverage
### Comprehensive Test Suite: 390+ Tests
HearthNet includes rigorous tests for all core capabilities:
| Suite | Count | Coverage |
|-------|-------|----------|
| **Phase 1 Core** (M01-M13, X01-X04) | 120+ | Bus routing, discovery, identity, emergency mode |
| **Intelligent Routing** (NEW) | 8+ | Failover, latency scoring, tracing, stamping |
| **Chat & Messaging** (M10) | 35+ | Direct messages, cross-node delivery, event-sourced |
| **RAG & Search** (M05) | 25+ | Local corpus, semantic search, federated queries |
| **LLM Service** (M04) | 20+ | Multiple backends (llama.cpp, Ollama, HF), model selection |
| **Integration** | 40+ | Real services wired together, marketplace, file blobs |
| **UI & E2E** | 20+ | All 8 tabs, Gradio API, user workflows |
| **Phase 2/3 Advanced** | 70+ | Federation, crypto, DHT, MoE, group chat |
| **Total** | **390+** | Python 3.13 Β· pytest-asyncio Β· Full async test suite |
### Run Tests Locally
```bash
# Full suite
python -m pytest tests/ -v
# Specific module (e.g., routing tests)
python -m pytest tests/test_bus_failover.py -v
# With coverage report
python -m pytest tests/ --cov=hearthnet --cov-report=term-missing
# Skip slow E2E tests
python -m pytest tests/ --ignore=tests/test_e2e_user_stories.py -v
```
**All tests pass** on Python 3.13 with pytest-asyncio.
**Focus areas:**
- β
Well-covered: Bus routing, identity, chat, discovery, emergency mode
- π― Strong: LLM service, RAG pipeline, marketplace, event system
- π Expanding: Transport layer, UI advanced features, observability metrics
---
## π Deployment & Source
| Resource | Purpose |
|----------|---------|
| **HF Space** (Primary) | [https://huggingface.co/spaces/build-small-hackathon/HearthNet](https://huggingface.co/spaces/build-small-hackathon/HearthNet) | Live demo + Downloads |
| **GitHub** (Mirror/CI) | [https://github.com/ckal/HearthNet](https://github.com/ckal/HearthNet) | Source control + Issue tracking |
**Deployment Architecture:**
- π‘ **HF Space**: Live demo, PWA app, binary downloads (exe, apk, etc.)
- π **GitHub**: Source repository, CI/CD, releases, issue tracking
- π **Sync**: Changes push to both simultaneously
**Build Artifacts Available:**
- Windows EXE: [dist/HearthNet.exe](https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/dist/HearthNet.exe) (212 MB)
- Android APK: [build/android/.../app-debug.apk](https://huggingface.co/spaces/build-small-hackathon/HearthNet/resolve/main/build/android/HearthNetApp/platforms/android/app/build/outputs/apk/debug/app-debug.apk) (3.56 MB)
- Build scripts: [BUILD_GUIDE.md](docs/guides/BUILD_GUIDE.md) for EXE, AppImage, .app, Docker
---
## Contributing & Docs
| Resource | Link |
|----------|------|
| Architecture | [ARCHITECTURE.md](docs/ARCHITECTURE.md) |
| System overview | [docs/00-OVERVIEW.md](docs/00-OVERVIEW.md) |
| Capability contract | [docs/CAPABILITY_CONTRACT.md](docs/CAPABILITY_CONTRACT.md) |
| Roadmap | [docs/roadmap.md](docs/roadmap.md) |
| Task tracker | [tasks.md](tasks.md) |
| Phase 2+3 specs | [docs/p2_p3/](docs/p2_p3/) |
---
## Hackathon Entry
**Track:** ποΈ Backyard AI (Practical)
**Why HearthNet wins:**
π **Tiny Titan:** Runs on MiniCPM3-4B (4B params, under 32B limit). Ultra-light mode with SmolLM2-135M (135M) via `MODEL_ID` env var for Raspberry Pi and edge devices.
π€ **Best Agent:** Capability bus + intelligent routing = distributed agentic system. Nodes score, select, and failover to the best provider autonomously. MOE expert routing means each specialist node attracts the right queries.
**Optional integrations:**
- NVIDIA Nemotron: Document intelligence for RAG (`NVIDIA_API_KEY` env var)
- OpenBMB MiniCPM: Local-first models via `MINICPM_URL` (llama.cpp-compatible)
- Modal: Serverless GPU as remote node (`MODAL_ENDPOINT` env var)
---
## Links
| | |
|--|--|
| π€ HF Space (Live) | https://huggingface.co/spaces/build-small-hackathon/HearthNet |
| π GitHub (Source) | https://github.com/ckal/HearthNet |
| π Architecture | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
| π§ͺ Tests | `python -m pytest tests/ -v` |
---
<p align="center">
Built with open source models and the belief that communities should own their AI.<br>
<em>Small model. Big mesh. Real resilience.</em>
</p>
|