- Three inbound routes from docs/hub-api.md: POST /ask, POST /approve, GET /health. - Five-step pipeline in src/hub, with packages hear, understand, check, route, answer. - Routing through OmniRoute with the capability list and routing.md. The never-route control check runs before any LLM call. - One real destination: Jervis house TTS, started out of band. - Fake /ask project (src/tests/fakeproject) for the round-trip test. - Append-only, size-capped request log. Bearer auth, source match, rate limit. - Tests: all packages pass, including the fake /ask round trip. Race clean. - Dockerfile and compose updated to mount routing.md and secrets, log on tmpfs. Co-Authored-By: Paperclip <noreply@paperclip.ing>
116 lines
3.7 KiB
Markdown
116 lines
3.7 KiB
Markdown
# Central AI Hub
|
|
|
|
One small service that every way in reaches every ability through. Built once,
|
|
shared by the phone app, the house voice, chat, and the admin app.
|
|
|
|
## Demonstrated Skills & Tech Stack
|
|
|
|
- **Core Technologies**: Go 1.25 service · HTTP JSON API · MQTT · LLM
|
|
intent routing · OmniRoute gateway · Docker
|
|
- **Entry routes**: `POST /ask` · `POST /approve` · `GET /health`
|
|
(frozen in `docs/hub-api.md`)
|
|
- **Key Tools**: Jervis (voice) · Home Assistant · Paperclip · Artemis ·
|
|
internet use control · Apprise / NTFY · OmniRoute
|
|
- **Engineering Capabilities**: service design · intent routing · authorization
|
|
and approval flows · event-driven integration · deterministic safety for
|
|
high-consequence actions
|
|
|
|
## Quick Start
|
|
|
|
### Run the Hub
|
|
|
|
```bash
|
|
# Build and run the container (Docker host 192.168.20.13).
|
|
docker compose up -d --build
|
|
|
|
# Liveness (no token).
|
|
curl -s http://192.168.20.13:8788/health
|
|
|
|
# Ask a question (source esp32 speaks the reply on the house speakers).
|
|
curl -s -X POST http://192.168.20.13:8788/ask \
|
|
-H "Authorization: Bearer $HUB_TOKEN_ESP32" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"text":"what does Harry have on today?","asker":"sam","source":"esp32"}'
|
|
```
|
|
|
|
The Hub reads `HUB_TOKEN_*`, `OMNIROUTE_API_KEY`, and the project tokens from
|
|
`~/.config/environment.d/10-secrets.conf` (mounted read-only, never committed).
|
|
|
|
### Test without a network
|
|
|
|
```bash
|
|
scripts/hub-test.sh
|
|
```
|
|
|
|
The fake `/ask` project in `src/tests/fakeproject/` proves the round trip.
|
|
|
|
### Phase 1 — prove the Paperclip round trip
|
|
|
|
```bash
|
|
# 1. Create an agent API key in Paperclip.
|
|
# 2. Export it for the test only.
|
|
export PAPERCLIP_API_KEY=<redacted>
|
|
# 3. File one job.
|
|
scripts/paperclip-roundtrip.sh --title "round-trip test"
|
|
```
|
|
|
|
Full steps: `docs/outline/04-agent-runbook.md`.
|
|
|
|
## System Architecture
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
subgraph IN["Ways in"]
|
|
PHONE["Phone app<br/>wake word + voice"]
|
|
ADMIN["Admin app<br/>restricted actions"]
|
|
ESP["ESP32 voice<br/>Hey Jervis"]
|
|
DSH["dsh chat"]
|
|
CONSOLE["Console portal"]
|
|
end
|
|
|
|
HUB{{"HUB<br/>hear - understand - check - route - answer"}}
|
|
|
|
subgraph OUT["Peers and services<br/>(the Hub is not a destination)"]
|
|
HA["Home Assistant"]
|
|
SPK["Speakers<br/>Jervis TTS"]
|
|
NET["Internet control<br/>parental limits"]
|
|
ART["Artemis<br/>phone screen"]
|
|
PC["Paperclip<br/>work bench"]
|
|
WEB["Web search"]
|
|
APP["Apprise / NTFY"]
|
|
end
|
|
|
|
PHONE --> HUB
|
|
ESP --> HUB
|
|
DSH --> HUB
|
|
CONSOLE --> HUB
|
|
ADMIN --> HUB
|
|
HUB --> HA
|
|
HUB --> SPK
|
|
HUB --> ART
|
|
HUB --> WEB
|
|
HUB --> APP
|
|
HUB -- "ask only (query)" --> NET
|
|
HUB -- "slow job (approved)" --> PC
|
|
ADMIN -- "control + tap to approve" --> NET
|
|
PC -. result .-> HUB
|
|
```
|
|
|
|
*Interactive architecture map:* [maps.lab.audasmedia.com.au/central_ai_llm_master](https://maps.lab.audasmedia.com.au/central_ai_llm_master/docs/)
|
|
|
|
## Usage & Configuration
|
|
|
|
- **Model calls** go through OmniRoute at `http://192.168.20.13:20129/v1`.
|
|
- **Secrets** come from `~/.config/environment.d/10-secrets.conf`.
|
|
- **Paperclip** is at `http://192.168.20.13:3100`. An API key is required.
|
|
- **Home Assistant** is at `http://192.168.20.30:8123`.
|
|
- **Jervis** (voice) is at `http://192.168.20.13:8501`.
|
|
- **Hub** is at `http://192.168.20.13:8788` (local Docker container).
|
|
|
|
The design brief is `hub_brief.md`. Project instructions are `AGENTS.md`.
|
|
|
|
The interface between the Hub and every data project is `docs/ask-contract.md`.
|
|
The frozen inbound API (ways in to the Hub) is `docs/hub-api.md`.
|
|
Every other project is a **peer**, not a sub-project. A high-consequence control
|
|
(for example, cutting the kids' internet) does **not** route through the Hub.
|