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 &nbsp;Β·&nbsp; Peer-to-Peer &nbsp;Β·&nbsp; Offline-Capable &nbsp;Β·&nbsp; 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>