---
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
license: apache-2.0
---
# π₯ HearthNet
### Community-Owned AI Mesh Β· Works When The Internet Doesn't
Local-First Β· Peer-to-Peer Β· Offline-Capable Β· Emergency-Ready
> **Build Small Hackathon entry** β Backyard AI track Β· π Tiny Titan Β· π€ Best Agent
>
> πΊ **Demo video:** *(link before June 15)*
> π£ **Social post:** *(link before June 15)*
---
## 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 a
routing bus, and keep working completely offline. When the internet returns, they sync up.
When it doesn't, they don't need it.
- A neighbourhood of 10 homes gets **10Γ the AI capacity** of any single device
- An offline community can still ask questions, share knowledge, send messages, and coordinate emergency response
- No cloud account, no API key, no monthly bill β hardware you already own
---
## Screenshots
Ask the Mesh
 |
Live Peer Topology
 |
Routing Trace
 |
Community Marketplace
 |
Direct Messages
 |
Invite QR Code
 |
Emergency Mode
 |
All 8 Tabs
 |
---
## π¦ 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 Ollama (best quality)
```bash
ollama pull llama3.2:3b # any Ollama model works
python app.py # auto-detects Ollama, prefers it over SmolLM2
```
### 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://: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
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
```
### MoE Expert Routing (Best Agent)
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 **SmolLM2-135M** β 135 million parameters, ~270 MB RAM.
For local installs, any Ollama 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
---
## 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) β
β Ollama β β(M05) β β Expert β β Marketplaceβ
β llama.cpp β βChromaβ β 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
Phase 1 β Core (M01βM13, X01βX04) Β· 17 modules
| 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 (Ollama, llama.cpp, HF Transformers, OpenAI fallback) | β
|
| M05 | RAG (chunker, ChromaDB, IngestPipeline, semantic search) | β
|| 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) | β
|
Phase 2 β Advanced (M14βM25, X05βX07) Β· 18 modules
| 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) | β
|
Phase 3 β Experimental (M26βM31, X08βX09) Β· feature-flag gated
| 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 |
---
## Local AI Backends
No mocks. No fake responses. Real local inference only.
| Backend | Activation | Notes |
|---------|-----------|-------|
| **Ollama** (preferred) | `ollama pull llama3.2:3b` + auto-detect | 70+ models, zero config |
| **llama.cpp** | Start server on port 8080 + auto-detect | Any GGUF model |
| **HF Transformers** | Default on HF Space (no config needed) | SmolLM2-135M default |
| **NVIDIA Nemotron** | `NVIDIA_API_KEY` env var | opt-in cloud; nemotron-70b/super-49b/mini-4b |
| **OpenBMB / MiniCPM** | `MINICPM_URL` env var (local NIM/llama.cpp) | local-first, OpenAI-compatible |
| **Modal** | `MODAL_ENDPOINT` env var | opt-in serverless GPU |
| **OpenAI API** | `OPENAI_API_KEY` env var | opt-in online fallback only |
All configured backends are registered on a single `llm.chat` / `llm.complete`
capability that advertises every served model in `params["models"]`; the caller
selects a model by name and the bus dispatches to the owning backend. Local
backends are always preferred; sponsor/cloud backends activate only when their
env var is set.
If nothing is available: `{"status": "unavailable"}` + clear UI message. 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
- **Bandit HIGH findings: 0** (verified in CI)
---
## Tests
```bash
python -m pytest tests/ -q # 548 tests
python -m pytest tests/ --ignore=tests/test_e2e_user_stories.py -q # skip Playwright
```
| Suite | Count | What it covers |
|-------|-------|----------------|
| Phase 1 core | 25 | Bus routing, emergency mode, snapshot, wiring |
| Phase 2 advanced | 40+ | Crypto, tokens, federation, OCR, DHT, group chat |
| Phase 3 experimental | 15 | MoE, distributed inference, fedlearn, LoRa, evidence |
| Integration (real services) | 60+ | RAG pipeline, LLM routing, marketplace, file blobs |
| UI regression | 6 | Tab build without NameError (HF Space crash guard) |
| E2E Playwright + API | 38 | All 8 tabs, Gradio API, user story flows, mesh connection |
| **Total** | **548** | Python 3.13 Β· pytest-asyncio 0.26 |
---
## Hackathon Entry
**Track:** ποΈ Backyard AI (Practical)
**Badges targeted:**
| Badge | Why |
|-------|-----|
| π **Tiny Titan** | Runs on SmolLM2-135M (135M params). Full mesh on Raspberry Pi 4. |
| π€ **Best Agent** | MoE routing + capability bus = distributed agentic AI across a mesh. Nodes specialise and route autonomously. |
| π¨ **Off Brand** | `app_nemotron.py` β custom purple-to-orange gradient UI, branded badge chips, Google Inter font. |
**Sponsor prizes targeted:**
| Prize | Why |
|-------|-----|
| π’ **NVIDIA Nemotron Hardware Prize** (RTX 5080) | `app_nemotron.py` β full Nemotron document intelligence Space. Structured extraction, Q&A, summarisation, push to mesh RAG. Uses `nvidia/llama-3.1-nemotron-nano-8b-instruct`. |
| π΅ **OpenBMB MiniCPM Best Build** ($2,500) | `MiniCPM` backend auto-detected via `MINICPM_URL` env var. `openbmb/MiniCPM4-8B` and `MiniCPM3-4B` supported out of the box. |
| β« **Modal Best Use** ($10k credits) | `ModalBackend` in `hearthnet/services/llm/backends/modal_backend.py`. Deploy with `scripts/modal_deploy.py`, set `MODAL_ENDPOINT` env var. |
**Why this fits Backyard AI:**
- Practical: solves real community resilience and emergency preparedness
- Local: runs on hardware people already own, zero cloud dependency
- Problem-solving: communications and AI when infrastructure fails
---
## 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/) |
---
## π§ͺ Testing & Coverage
### Test Suite: 932 Tests, 100% Pass Rate
HearthNet has **comprehensive test coverage** across all modules:
| Category | Tests | Status | Reports |
|----------|-------|--------|---------|
| **Phase 1 Core** (M01-M13, X01-X04) | 343 | β
Implemented | [M01-M13 Tests](tests/test_m*_spec.py) |
| **LLM Service** (M04) | 72 | β
Enhanced (50β75%+) | [M04 Enhanced](tests/test_m04_enhanced.py) |
| **RAG Service** (M05) | 57 | β
Enhanced (40β75%+) | [M05 Enhanced](tests/test_m05_enhanced.py) |
| **Observability** (X03) | 63 | β
Enhanced (48β75%+) | [X03 Enhanced](tests/test_x03_enhanced.py) |
| **Transport** (X01) | 69 | β
Enhanced (12β55%+) | [X01 Enhanced](tests/test_x01_enhanced.py) |
| **Phase 2/3 Specs** (M14-M32, X05-X09) | 216 | ποΈ Scaffolded | [P2/P3 Tests](tests/test_m1[4-9]_spec.py), [X0[5-9]](tests/test_x0[5-9]_spec.py) |
| **Reference Docs** | 80 | ποΈ Scaffolded | [API Contract](tests/test_capability_contract.py), [Glossary](tests/test_glossary.py) |
| **Total** | **932** | **100% Pass** | [Full Report](docs/reports/TEST_SUITE_REPORT.md) |
**Code Coverage: 44% (6,043 / 10,743 lines)**
- Well-covered (>70%): Identity, Bus, Types, UI core
- Moderate (40-70%): LLM, RAG, Chat
- Target for improvement: Transport server, backends, UI advanced
### Run Tests Locally
```bash
# Install test dependencies
pip install -r requirements-dev.txt
# Run all tests
python -m pytest tests/ -v
# Run with coverage report
python -m pytest tests/ --cov=hearthnet --cov-report=html --cov-report=term
# Open: htmlcov/index.html
# Run specific module
python -m pytest tests/test_m04_enhanced.py -v
# Run before commit (git hook)
bash pre-commit-hook.sh
```
### CI/CD Pipeline
**Automatic testing on:**
- β
Every push to `main` / `dev` branches
- β
Every pull request
- β
Before commit (local pre-commit hook)
**Configuration:** [.github/workflows/test.yml](.github/workflows/test.yml)
**Setup local pre-commit hook:**
```bash
cp pre-commit-hook.sh .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
# Now tests run automatically before each commit
git commit -m "my changes" # β tests run first!
```
### Test Documentation
- **Full Report:** [TEST_SUITE_REPORT.md](docs/reports/TEST_SUITE_REPORT.md) β 783 tests, all modules
- **Coverage Enhancement:** [COVERAGE_ENHANCEMENT_REPORT.md](COVERAGE_ENHANCEMENT_REPORT.md) β 149 new tests for M04/M05/X01/X03
- **Test Structure:** Each test follows Happy / Error / Edge pattern
- **No Mocks:** All implemented tests use real code paths
- **Integration Tests:** Cross-service messaging and capabilities
---
## π 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
---
## Links
| | |
|--|--|
| π€ HF Space (Live) | https://huggingface.co/spaces/build-small-hackathon/HearthNet |
| π GitHub (Source) | https://github.com/ckal/HearthNet |
| π€ HF Profile | https://huggingface.co/Chris4K |
| π¦ X / Twitter | https://x.com/zX14_7 |
| π» GitHub Profile | https://github.com/ckal |
---
Built with open source models and the belief that communities should own their AI.
Small model. Big mesh. Real resilience.