Initial Central AI Hub docs: brief, rules, README, outline context, architecture
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.env
|
||||
*.visual-check.*
|
||||
91
AGENTS.md
Normal file
91
AGENTS.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Central AI Hub (`central_ai_llm_master`)
|
||||
|
||||
## Mission
|
||||
|
||||
Build the **Hub**. The Hub is one small service. Every way in reaches every
|
||||
ability through it. Build the ability once. All ways in get it.
|
||||
|
||||
## Authority
|
||||
|
||||
Read `hub_brief.md` in this folder first. It is the agreed design. If this file
|
||||
and the brief disagree, the brief wins.
|
||||
|
||||
- `hub_brief.md` — the agreed brief (source of truth).
|
||||
- `README.md` — technical readme.
|
||||
- `docs/outline/` — AI context. Start with `00-index.md`.
|
||||
|
||||
## What the Hub does
|
||||
|
||||
Five steps, in order:
|
||||
|
||||
1. **Hear** — take voice or text from any way in.
|
||||
2. **Understand** — the LLM works out what was asked.
|
||||
3. **Check** — is this person allowed to ask for this?
|
||||
4. **Route** — send it to the right destination.
|
||||
5. **Answer** — return a short reply in the right shape for the device.
|
||||
|
||||
The reply can be text, spoken audio (TTS), Artemis commands, a notification, an
|
||||
email, or a mix. TTS can play on the house speakers or on the phone.
|
||||
|
||||
## The dividing line
|
||||
|
||||
> Does this need a decision, or does it need to happen?
|
||||
|
||||
- **Happen** — fast and certain. Go straight to the destination. No LLM in the
|
||||
path of the action.
|
||||
- **Decision** — slow, multi-step, worth recording. Send to Paperclip.
|
||||
|
||||
**Paperclip is the work bench, not the switchboard.**
|
||||
|
||||
## Rules
|
||||
|
||||
1. All models go through **OmniRoute**. Never call a provider directly.
|
||||
2. All secrets come from **`environment.d`**. Never hard-code.
|
||||
3. Own service, own port, own folder.
|
||||
4. No LLM in the path of a fast or consequential action.
|
||||
5. Paperclip only for slow, multi-step, recorded work.
|
||||
6. Replies return to the source and stay short.
|
||||
7. Restricted actions need **tap-to-approve** on the admin app.
|
||||
8. Only the admin app changes parental controls.
|
||||
9. A new ability registers with the Hub. Build it once.
|
||||
|
||||
## Build order
|
||||
|
||||
1. **Thin slice, end to end.** Issue a Paperclip API key. File one job from a
|
||||
script. Get the result announced back. Prove the round trip.
|
||||
2. **Hub skeleton.** Hear → understand → route → answer, with one destination.
|
||||
3. **Approval flow.** "Did you ask for this?" on the admin app.
|
||||
4. **Internet control.** Standalone service with a plain API. Device-side
|
||||
enforcement. Admin-only.
|
||||
5. **Artemis.** Standalone service with a plain API. Screen control only.
|
||||
6. **Move Jervis's tools** into the Hub. Jervis becomes voice-only.
|
||||
7. **Phone Kotlin app.** Wake word, voice to the Hub, replies and approvals.
|
||||
8. **Email and school pipelines.** Stay independent. Connect when ready.
|
||||
|
||||
## Definition of done (phase 1)
|
||||
|
||||
- A Paperclip API key exists.
|
||||
- One job is filed by script and its result is spoken.
|
||||
- The round trip is recorded in `docs/outline/04-agent-runbook.md`.
|
||||
|
||||
## How this project relates to the other projects
|
||||
|
||||
This project owns the **shared Hub**. It does not own the destinations.
|
||||
|
||||
| Project | Relation |
|
||||
|---|---|
|
||||
| Email agent | Own pipeline. Reports through the Hub when ready. |
|
||||
| Compass / NHS | Own pipeline. Reports through the Hub when ready. |
|
||||
| Internet use control | Destination. Exposes a plain API. The Hub calls it. |
|
||||
| Artemis | Destination. Exposes a plain API. The Hub calls it. |
|
||||
| Jervis | Becomes voice-only. Its tools move here. |
|
||||
| dsh | Calls the Hub for actions. |
|
||||
|
||||
Each project writes its own docs. Do not copy theirs here. Link to them.
|
||||
|
||||
## Do not
|
||||
|
||||
- Do not build one central brain. No single personality or memory.
|
||||
- Do not put Paperclip in the path of a fast command.
|
||||
- Do not duplicate a destination inside the Hub.
|
||||
- Do not add a spoken keycode as the only lock for restricted actions.
|
||||
81
README.md
Normal file
81
README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# 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 or Python service · HTTP JSON API · MQTT · LLM
|
||||
intent routing · OmniRoute gateway · Docker
|
||||
- **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
|
||||
|
||||
```bash
|
||||
# Phase 1 — prove the Paperclip round trip
|
||||
# 1. Create an agent API key in Paperclip.
|
||||
# 2. Export it for the test only.
|
||||
export PAPERCLIP_API_KEY=<redacted>
|
||||
# 3. File one job.
|
||||
curl -s -X POST http://192.168.20.13:3100/api/issues \
|
||||
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title":"round-trip test","description":"prove the return path"}'
|
||||
```
|
||||
|
||||
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["Destinations"]
|
||||
HA["Home Assistant"]
|
||||
SPK["Speakers<br/>Jervis TTS"]
|
||||
NET["Internet control"]
|
||||
ART["Artemis<br/>phone screen"]
|
||||
PC["Paperclip<br/>slow jobs"]
|
||||
WEB["Web search"]
|
||||
APP["Apprise / NTFY"]
|
||||
end
|
||||
|
||||
PHONE --> HUB
|
||||
ESP --> HUB
|
||||
DSH --> HUB
|
||||
CONSOLE --> HUB
|
||||
ADMIN --> HUB
|
||||
HUB --> HA
|
||||
HUB --> SPK
|
||||
HUB --> NET
|
||||
HUB --> ART
|
||||
HUB --> PC
|
||||
HUB --> WEB
|
||||
HUB --> APP
|
||||
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`.
|
||||
|
||||
The design brief is `hub_brief.md`. Project instructions are `AGENTS.md`.
|
||||
61
docs/archify/hub.architecture.json
Normal file
61
docs/archify/hub.architecture.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"diagram_type": "architecture",
|
||||
"meta": {
|
||||
"title": "Central AI Hub",
|
||||
"output": "docs/hub-architecture-map.html",
|
||||
"quality_profile": "showcase",
|
||||
"views": [
|
||||
{
|
||||
"id": "fast-command",
|
||||
"label": "Fast command",
|
||||
"focus": ["esp32", "hub", "ha", "spk"],
|
||||
"note": "A fast command goes straight to the destination. No LLM waits in the action path."
|
||||
},
|
||||
{
|
||||
"id": "slow-job",
|
||||
"label": "Slow job",
|
||||
"focus": ["phone", "hub", "pc"],
|
||||
"note": "A slow job goes to Paperclip. The result returns to the Hub later."
|
||||
},
|
||||
{
|
||||
"id": "restricted",
|
||||
"label": "Restricted action",
|
||||
"focus": ["admin", "hub", "net"],
|
||||
"note": "Only the admin app can change parental controls. Voice may ask; the app confirms."
|
||||
}
|
||||
]
|
||||
},
|
||||
"components": [
|
||||
{ "id": "phone", "type": "frontend", "label": "Phone app", "sublabel": "wake word + voice", "pos": [40, 80], "size": [150, 64] },
|
||||
{ "id": "admin", "type": "security", "label": "Admin app", "sublabel": "restricted actions", "pos": [40, 200], "size": [150, 64] },
|
||||
{ "id": "esp32", "type": "external", "label": "ESP32 voice", "sublabel": "Hey Jervis", "pos": [40, 320], "size": [150, 64] },
|
||||
{ "id": "dsh", "type": "frontend", "label": "dsh chat", "sublabel": "per person", "pos": [40, 440], "size": [150, 64] },
|
||||
{ "id": "hub", "type": "backend", "label": "Hub", "sublabel": "hear - understand - check - route - answer", "pos": [390, 260], "size": [190, 80], "tag": "one shared service" },
|
||||
{ "id": "ha", "type": "external", "label": "Home Assistant", "sublabel": "devices, timers", "pos": [790, 40], "size": [160, 64] },
|
||||
{ "id": "spk", "type": "external", "label": "Speakers", "sublabel": "Jervis TTS", "pos": [790, 150], "size": [160, 64] },
|
||||
{ "id": "net", "type": "backend", "label": "Internet control", "sublabel": "parental limits", "pos": [790, 260], "size": [160, 64] },
|
||||
{ "id": "art", "type": "backend", "label": "Artemis", "sublabel": "phone screen", "pos": [790, 370], "size": [160, 64] },
|
||||
{ "id": "pc", "type": "backend", "label": "Paperclip", "sublabel": "slow jobs", "pos": [790, 480], "size": [160, 64] },
|
||||
{ "id": "web", "type": "cloud", "label": "Web search", "sublabel": "Tavily", "pos": [790, 590], "size": [160, 64] },
|
||||
{ "id": "app", "type": "backend", "label": "Apprise / NTFY", "sublabel": "notify + email", "pos": [790, 700], "size": [160, 64] }
|
||||
],
|
||||
"boundaries": [
|
||||
{ "kind": "region", "label": "Ways in", "wraps": ["phone", "admin", "esp32", "dsh"], "pad": 26 },
|
||||
{ "kind": "region", "label": "Destinations", "wraps": ["ha", "spk", "net", "art", "pc", "web", "app"], "pad": 26 }
|
||||
],
|
||||
"connections": [
|
||||
{ "id": "phone-in", "from": "phone", "to": "hub", "label": "voice or text" },
|
||||
{ "id": "admin-in", "from": "admin", "to": "hub", "label": "restricted" },
|
||||
{ "id": "esp-in", "from": "esp32", "to": "hub", "label": "command" },
|
||||
{ "id": "dsh-in", "from": "dsh", "to": "hub", "label": "action request" },
|
||||
{ "id": "to-ha", "from": "hub", "to": "ha", "label": "do it" },
|
||||
{ "id": "to-spk", "from": "hub", "to": "spk", "label": "speak" },
|
||||
{ "id": "to-net", "from": "hub", "to": "net", "label": "confirm" },
|
||||
{ "id": "to-art", "from": "hub", "to": "art", "label": "screen control" },
|
||||
{ "id": "to-pc", "from": "hub", "to": "pc", "label": "file job" },
|
||||
{ "id": "to-web", "from": "hub", "to": "web", "label": "search" },
|
||||
{ "id": "to-app", "from": "hub", "to": "app", "label": "notify" },
|
||||
{ "id": "pc-back", "from": "pc", "to": "hub", "label": "result", "variant": "dashed" }
|
||||
]
|
||||
}
|
||||
BIN
docs/diagrams/hub-architecture.png
Normal file
BIN
docs/diagrams/hub-architecture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
13716
docs/hub-architecture-map.html
Normal file
13716
docs/hub-architecture-map.html
Normal file
File diff suppressed because it is too large
Load Diff
36
docs/hub-architecture.mmd
Normal file
36
docs/hub-architecture.mmd
Normal file
@@ -0,0 +1,36 @@
|
||||
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["Destinations"]
|
||||
HA["Home Assistant"]
|
||||
SPK["Speakers<br/>Jervis TTS"]
|
||||
NET["Internet control"]
|
||||
ART["Artemis<br/>phone screen"]
|
||||
PC["Paperclip<br/>slow jobs"]
|
||||
WEB["Web search"]
|
||||
APP["Apprise / NTFY"]
|
||||
end
|
||||
|
||||
PHONE --> HUB
|
||||
ESP --> HUB
|
||||
DSH --> HUB
|
||||
CONSOLE --> HUB
|
||||
ADMIN --> HUB
|
||||
HUB --> HA
|
||||
HUB --> SPK
|
||||
HUB --> NET
|
||||
HUB --> ART
|
||||
HUB --> PC
|
||||
HUB --> WEB
|
||||
HUB --> APP
|
||||
PC -. result .-> HUB
|
||||
|
||||
click HUB "https://maps.lab.audasmedia.com.au/central_ai_llm_master/docs/" "View Archify Map"
|
||||
38
docs/outline/00-index.md
Normal file
38
docs/outline/00-index.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Central AI Hub — AI Document Index
|
||||
|
||||
> **Target**: AI Agents
|
||||
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
|
||||
|
||||
## Document Catalog (Inject Specific Document)
|
||||
|
||||
Read this index to inject the exact file you need. Do not search all files.
|
||||
|
||||
| Document Title | Path | Scope / Description |
|
||||
| :--- | :--- | :--- |
|
||||
| **System Overview** | `docs/outline/01-system-overview.md` | Explains the Hub purpose, its five steps, and the destinations. |
|
||||
| **Configuration & Env** | `docs/outline/02-config-and-env.md` | Lists services, ports, env vars, and secret paths. |
|
||||
| **Code Structure Map** | `docs/outline/03-code-map.md` | Shows the planned folder layout and entry points. |
|
||||
| **AI Agent Runbook** | `docs/outline/04-agent-runbook.md` | Gives steps to build, test, and restart Hub work. |
|
||||
| **Design Brief** | `hub_brief.md` | The agreed design. This file is the source of truth. |
|
||||
| **Project Rules** | `AGENTS.md` | Mission, rules, build order, and project relations. |
|
||||
|
||||
---
|
||||
|
||||
## System Summary
|
||||
|
||||
The Hub is one service. Every way in reaches every ability through it. The Hub
|
||||
does five steps: hear, understand, check, route, and answer. The Hub does not
|
||||
hold a personality or a memory. The Hub does not do the destination work.
|
||||
|
||||
## Core Configuration
|
||||
|
||||
- **Env File**: `~/.config/environment.d/10-secrets.conf`
|
||||
- **Config Directory**: `docs/`
|
||||
- **Active Ports**: Hub port not allocated yet.
|
||||
|
||||
## Agent Restart Steps
|
||||
|
||||
1. Read the Document Catalog above. Inject only required files.
|
||||
2. Read `hub_brief.md`.
|
||||
3. Check git status: `git status`.
|
||||
4. Check recent commits: `git log -n 5 --oneline`.
|
||||
59
docs/outline/01-system-overview.md
Normal file
59
docs/outline/01-system-overview.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Central AI Hub — System Overview
|
||||
|
||||
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
|
||||
|
||||
## Purpose
|
||||
|
||||
The Hub is one service. Every way in reaches every ability through the Hub. Build
|
||||
each ability once. All ways in get it.
|
||||
|
||||
Today, Jervis (voice) and dsh (chat) each understand the user and act. A third
|
||||
way in, the phone app, would repeat the same work. The Hub stops this repeat.
|
||||
|
||||
## The Five Steps
|
||||
|
||||
1. **Hear** — take voice or text from any way in.
|
||||
2. **Understand** — the LLM works out what the user asked.
|
||||
3. **Check** — test whether the user may ask for this.
|
||||
4. **Route** — send the request to one destination.
|
||||
5. **Answer** — return a short reply in the right shape.
|
||||
|
||||
## Ways In
|
||||
|
||||
- Phone app (Kotlin) — wake word, voice, controls.
|
||||
- Admin app (Kotlin) — restricted actions only.
|
||||
- ESP32 voice — "Hey Jervis".
|
||||
- dsh chat — per-person chat.
|
||||
- Console portal — web dashboard.
|
||||
|
||||
## Destinations
|
||||
|
||||
| Destination | Job |
|
||||
|---|---|
|
||||
| Home Assistant | Lights, switches, timers, calendar. |
|
||||
| Speakers (Jervis) | Speak and announce. |
|
||||
| Internet control | Parental limits on kids' devices. |
|
||||
| Artemis | Operate the phone screen. |
|
||||
| Paperclip | Slow, multi-step, recorded work. |
|
||||
| Web search | Tavily search. |
|
||||
| Apprise / NTFY | Notifications and email. |
|
||||
|
||||
## Reply Shapes
|
||||
|
||||
The Hub returns one reply. The reply can hold text, spoken audio (TTS), Artemis
|
||||
commands, a notification, or an email. TTS can play on the house speakers or on
|
||||
the phone. The Hub returns the reply to the source.
|
||||
|
||||
## The Dividing Line
|
||||
|
||||
The Hub asks one question: does this need a decision, or does it need to happen?
|
||||
|
||||
- **Happen** — fast and certain. Go straight to the destination. No LLM in the
|
||||
path of the action.
|
||||
- **Decision** — slow, multi-step, worth recording. Send to Paperclip.
|
||||
|
||||
## What the Hub Is Not
|
||||
|
||||
- Not a central brain. No single personality or memory.
|
||||
- Not Paperclip. The Hub does not wait minutes for an answer.
|
||||
- Not a destination. The Hub does not turn off the internet itself.
|
||||
43
docs/outline/02-config-and-env.md
Normal file
43
docs/outline/02-config-and-env.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Central AI Hub — Configuration & Environment
|
||||
|
||||
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
|
||||
|
||||
## Secrets
|
||||
|
||||
All secrets come from `~/.config/environment.d/10-secrets.conf` on each machine.
|
||||
Never hard-code a secret. Never commit a secret.
|
||||
|
||||
Relevant keys:
|
||||
|
||||
| Key | Use |
|
||||
|---|---|
|
||||
| `OMNIROUTE_API_KEY` | Model calls through OmniRoute. |
|
||||
| `PAPERCLIP_API_KEY` | File jobs to Paperclip. Does not exist yet. |
|
||||
| `TAVILY_API_KEY` | Web search. |
|
||||
| `OL_API_KEY` | Outline docs. |
|
||||
| `VIKUNJA_TOKEN` | Vikunja tasks. |
|
||||
| `GITEA_TOKEN` | Gitea repository. |
|
||||
|
||||
## Services and Ports
|
||||
|
||||
| Service | Host | Port | Use |
|
||||
|---|---|---|---|
|
||||
| OmniRoute | 192.168.20.13 | 20129 | Model gateway. |
|
||||
| Paperclip | 192.168.20.13 | 3100 | Job orchestration. |
|
||||
| Jervis (voice) | 192.168.20.13 | 8501 | Speak and announce. |
|
||||
| Home Assistant | 192.168.20.30 | 8123 | Devices and timers. |
|
||||
| MQTT | 192.168.20.13 | 1883 | Voice topics. |
|
||||
| Apprise | 192.168.20.35 | 8210 | Notifications. |
|
||||
| Hub | not allocated | — | This service. |
|
||||
|
||||
## Config Paths
|
||||
|
||||
- Brief: `hub_brief.md`
|
||||
- Rules: `AGENTS.md`
|
||||
- Docs: `docs/`
|
||||
- Outline context: `docs/outline/`
|
||||
|
||||
## Rule
|
||||
|
||||
A new project gets its own service, its own port, and its own folder. Do not
|
||||
merge a destination into the Hub.
|
||||
56
docs/outline/03-code-map.md
Normal file
56
docs/outline/03-code-map.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Central AI Hub — Code Structure Map
|
||||
|
||||
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
|
||||
> **Status**: Planned. The Hub is not built yet.
|
||||
|
||||
## Planned Folder Layout
|
||||
|
||||
```text
|
||||
central_ai_llm_master/
|
||||
AGENTS.md project rules for agents
|
||||
hub_brief.md agreed design (source of truth)
|
||||
README.md technical readme
|
||||
docs/
|
||||
hub-architecture.mmd Mermaid source
|
||||
hub-architecture-map.html Archify map
|
||||
diagrams/ rendered images
|
||||
archify/ Archify JSON input
|
||||
outline/ AI context documents
|
||||
vikunja-tasks.json human task list
|
||||
src/ Hub service code (to build)
|
||||
main.* HTTP entry point
|
||||
hear/ takes voice or text
|
||||
understand/ LLM intent routing
|
||||
check/ authorization and approval
|
||||
route/ dispatch to a destination
|
||||
answer/ reply shaping (text, TTS, notify)
|
||||
destinations/ one client per destination
|
||||
tests/ unit and round-trip tests
|
||||
```
|
||||
|
||||
## Entry Points
|
||||
|
||||
| Entry point | Use |
|
||||
|---|---|
|
||||
| `POST /ask` | Send a voice transcript or text. Returns a reply. |
|
||||
| `POST /approve` | Admin app confirms a restricted action. |
|
||||
| `GET /health` | Liveness check. |
|
||||
|
||||
The API contract is not final. See `hub_brief.md`.
|
||||
|
||||
## Primary Dependencies
|
||||
|
||||
- HTTP server (Go or Python — decide before build).
|
||||
- HTTP client for OmniRoute, Home Assistant, Paperclip.
|
||||
- MQTT client for voice topics.
|
||||
- Tavily API client for web search.
|
||||
|
||||
## Destinations
|
||||
|
||||
Each destination gets one client under `src/destinations/`. The client calls the
|
||||
destination API. The client does not hold business logic.
|
||||
|
||||
## Source Control
|
||||
|
||||
- Gitea: `sam/central_ai_llm_master`
|
||||
- Local: `/home/sam/paseo/projects/central_ai_llm_master/`
|
||||
55
docs/outline/04-agent-runbook.md
Normal file
55
docs/outline/04-agent-runbook.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Central AI Hub — AI Agent Runbook
|
||||
|
||||
> **Writing Style**: ASD-STE100 Simplified Technical English (`ste-writing`).
|
||||
|
||||
## Phase 1 — Prove the Paperclip Round Trip
|
||||
|
||||
This phase has no Hub code. It proves the missing link: a job that leaves and a
|
||||
result that returns.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Create a Paperclip agent API key for this project.
|
||||
- Paperclip board: `http://192.168.20.13:3100`.
|
||||
- Store the key in `~/.config/environment.d/10-secrets.conf` as
|
||||
`PAPERCLIP_API_KEY`. Never commit it.
|
||||
2. File one job with `curl`. Use the issue-create endpoint.
|
||||
3. Confirm the job appears in the Paperclip board.
|
||||
4. Wait for the agent to close the job.
|
||||
5. Send the result to Jervis `POST /announce` so the house speaks it.
|
||||
6. Record the result in this file.
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
export PAPERCLIP_API_KEY=<from secrets>
|
||||
curl -s -X POST http://192.168.20.13:3100/api/issues \
|
||||
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title":"round-trip test","description":"prove the return path"}'
|
||||
|
||||
# Speak the result.
|
||||
curl -s -X POST http://192.168.20.13:8501/announce \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"text":"Round trip works."}'
|
||||
```
|
||||
|
||||
### Definition of Done
|
||||
|
||||
- The job appears in Paperclip.
|
||||
- The job closes.
|
||||
- The house speaks the result.
|
||||
- This file records the result.
|
||||
|
||||
## After Phase 1
|
||||
|
||||
Follow the build order in `AGENTS.md`. Do not start a destination before the
|
||||
round trip works.
|
||||
|
||||
## Health Checks
|
||||
|
||||
```bash
|
||||
curl -s http://192.168.20.13:3100/health # Paperclip
|
||||
curl -s http://192.168.20.13:8501/health # Jervis
|
||||
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.20.30:8123/ # HA
|
||||
```
|
||||
16
docs/vikunja-tasks.json
Normal file
16
docs/vikunja-tasks.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"title": "Central AI Hub - Human Task Overview",
|
||||
"description": "High-level task checklist for human team members.",
|
||||
"tasks": [
|
||||
{ "title": "Create Paperclip agent API key and store in secrets", "done": false },
|
||||
{ "title": "Prove the Paperclip round trip (file job, speak result)", "done": false },
|
||||
{ "title": "Decide the Hub language and port", "done": false },
|
||||
{ "title": "Build the Hub skeleton (hear, understand, route, answer)", "done": false },
|
||||
{ "title": "Add the tap-to-approve flow on the admin app", "done": false },
|
||||
{ "title": "Build the internet control destination service", "done": false },
|
||||
{ "title": "Build the Artemis destination service", "done": false },
|
||||
{ "title": "Move Jervis action tools into the Hub", "done": false },
|
||||
{ "title": "Build the phone Kotlin app", "done": false },
|
||||
{ "title": "Connect the email and school pipelines", "done": false }
|
||||
]
|
||||
}
|
||||
150
hub_brief.md
Normal file
150
hub_brief.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# The Hub — a short brief
|
||||
|
||||
**Purpose:** tell every project where it fits and the rules it must follow.
|
||||
**Written:** 2026-10-10
|
||||
**Status:** agreed direction, not a build order.
|
||||
|
||||
---
|
||||
|
||||
## The idea in one line
|
||||
|
||||
**Share the plumbing. Keep the brains separate. Put one small hub in the middle.**
|
||||
|
||||
Every way in (phone, house voice, chat) reaches every ability (lights, internet,
|
||||
Artemis, Paperclip) through one place — built once, not repeated.
|
||||
|
||||
---
|
||||
|
||||
## What already works (do not rebuild)
|
||||
|
||||
| System | What it is |
|
||||
|---|---|
|
||||
| **Jervis** | The house voice. ESP32 "Hey Jervis" → STT → agent → TTS → speakers. Controls HA, timers, reminders, shopping, calendar, music, weather, web search, family messages. |
|
||||
| **dsh** | Per-person chat (sam / jo / harry / finn). Memory, images, video, documents. |
|
||||
| **Console portal** | Logins and dashboard for the family. |
|
||||
| **Front Door Cam** | Its own separate ESP32. Visitor detection, Gemini sees the person, voice asks them to speak. |
|
||||
| **OmniRoute** | The model gateway. All models go through here. |
|
||||
| **Home Assistant** | Devices, timers, calendar, notifications. |
|
||||
| **Shared** | Apprise, Snapcast, STT/TTS, n8n, secrets in `environment.d`. |
|
||||
|
||||
These stay. The hub is added, not a replacement.
|
||||
|
||||
---
|
||||
|
||||
## What is new
|
||||
|
||||
- The **Hub** (this brief).
|
||||
- **Email agent** — its own pipeline.
|
||||
- **School (Compass / Teams)** — its own pipeline.
|
||||
- **Internet use control** — a destination the hub calls.
|
||||
- **Artemis** — a destination the hub calls.
|
||||
- **Kotlin phone app** — a new way in (wake word, voice, controls).
|
||||
- **Admin app + kids app** — parental control, admin only.
|
||||
|
||||
---
|
||||
|
||||
## What the Hub is
|
||||
|
||||
One service that does five steps:
|
||||
|
||||
1. **Hear** — takes voice or text from any way in.
|
||||
2. **Understand** — the LLM works out what was asked.
|
||||
3. **Check** — is this person allowed to ask for this?
|
||||
4. **Route** — sends it to the right destination.
|
||||
5. **Answer** — returns a short reply in the right shape for the device.
|
||||
|
||||
The reply can be **text**, **spoken audio (TTS)**, **Artemis commands**, **a phone
|
||||
notification**, **an email**, or a mix. TTS can play on the **house speakers** or
|
||||
on the **phone**.
|
||||
|
||||
### What the Hub is NOT
|
||||
|
||||
- **Not a central brain.** It does not hold one personality or one memory.
|
||||
- **Not Paperclip.** It never waits minutes for an answer.
|
||||
- **Not a destination.** It does not turn off the internet itself. It sends the
|
||||
request to the service that does.
|
||||
|
||||
### The dividing line
|
||||
|
||||
One question sorts every request:
|
||||
|
||||
> **Does this need a decision, or does it need to happen?**
|
||||
|
||||
- **Happen** (fast, certain) → straight to the destination: HA, internet control,
|
||||
Artemis, speakers. No LLM in the path of the action.
|
||||
- **Decision** (slow, multi-step, worth recording) → Paperclip.
|
||||
|
||||
**Paperclip is the work bench, not the switchboard.** It is never in the path of
|
||||
a fast or high-consequence command.
|
||||
|
||||
---
|
||||
|
||||
## Where each system fits
|
||||
|
||||
| System | Role | With the Hub |
|
||||
|---|---|---|
|
||||
| **Jervis** | House voice | Becomes the **voice** (speak / announce), not a list of tools. Its action tools move into the Hub over time. |
|
||||
| **dsh** | Chat | Calls the Hub for actions instead of keeping its own copies. |
|
||||
| **Console portal** | Login + dashboard | Unchanged. May show Hub status and approvals. |
|
||||
| **Front Door Cam** | Visitor intercom | Stays separate. May use the Hub only to speak. |
|
||||
| **Email agent** | Own pipeline (n8n) | Standalone. May report results through the Hub. |
|
||||
| **School agent** | Own pipeline (n8n) | Standalone. May report results through the Hub. |
|
||||
| **Internet control** | Destination | The Hub calls its API. Enforcement happens on the kids' devices. |
|
||||
| **Artemis** | Destination | The Hub calls its API. Artemis touches the phone screen. |
|
||||
| **Paperclip** | Work bench | The Hub files jobs and hears the answer back. |
|
||||
| **Phone app** | Way in | Sends voice to the Hub. Shows replies, notifications, approvals. |
|
||||
|
||||
---
|
||||
|
||||
## Rules every project follows
|
||||
|
||||
1. **All models go through OmniRoute.** Never call a provider directly.
|
||||
2. **All secrets come from `environment.d`.** Never hard-code.
|
||||
3. **Own service, own port, own folder.** Do not merge into another project.
|
||||
4. **No LLM in the path of a fast or consequential action.** Deterministic calls
|
||||
for anything that turns something off.
|
||||
5. **Paperclip only for slow, multi-step, recorded work.** Never make a person
|
||||
wait on it.
|
||||
6. **Replies return to the source, and stay short.** Speaker → one line. Phone →
|
||||
notification. Chat → text. No long-winded answers.
|
||||
7. **Restricted commands need tap-to-approve** on the admin app. This includes
|
||||
parental controls and any job filed to Paperclip.
|
||||
8. **Only the admin app can change parental controls.** Kids' apps and desktop
|
||||
exes may only obey and report.
|
||||
9. **New work registers with the Hub.** A capability is added once, and every way
|
||||
in gets it.
|
||||
|
||||
---
|
||||
|
||||
## Safety
|
||||
|
||||
- **Voice is shared and unauthenticated.** Anyone in the house can speak.
|
||||
- **The admin app is the only trusted door** for restricted actions.
|
||||
- **A spoken keycode is not the lock.** It can be overheard and misheard. Voice
|
||||
may *ask*; the admin app **confirms** with "Did you ask for this?".
|
||||
- **Approval is required** for parental controls and Paperclip jobs.
|
||||
|
||||
---
|
||||
|
||||
## Build order
|
||||
|
||||
1. **Thin slice, end to end.** Issue a Paperclip API key, file one job from a
|
||||
script, and get the result announced back. Proves the round trip.
|
||||
2. **Hub skeleton.** Hear → understand → route → answer, with one destination
|
||||
(HA or speakers) working.
|
||||
3. **Approval flow.** "Did you ask for this?" on the admin app.
|
||||
4. **Internet control.** Standalone service with a plain API. Device-side
|
||||
enforcement. Admin-only.
|
||||
5. **Artemis.** Standalone service with a plain API. Screen control only.
|
||||
6. **Move Jervis's tools** into the Hub. Jervis becomes voice-only.
|
||||
7. **Phone Kotlin app.** Wake word, voice to the Hub, replies and approvals.
|
||||
8. **Email and school pipelines** stay independent and connect when ready.
|
||||
|
||||
---
|
||||
|
||||
## What is still open
|
||||
|
||||
- Exact API contract for a job (title, brief, project, agent).
|
||||
- How Artemis receives voice (stream vs file) and when phone TTS is used.
|
||||
- Which Paperclip company / projects to use.
|
||||
- Identity: how the Hub knows which family member is speaking.
|
||||
Reference in New Issue
Block a user