Tools Software WebUI — tool-system docs, diagrams, Archify map
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# documentation repo — nothing sensitive expected
|
||||
*.local
|
||||
.env
|
||||
145
README.md
Normal file
145
README.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# Tools Software WebUI
|
||||
|
||||
**One interface layer for the AI tool system: a multi-machine agent console (Pi Dashboard), LLM
|
||||
routing (OmniRoute), automation (n8n · Prefect · LangChain), and a per-folder pi-agent model — all
|
||||
self-hosted on a home network.**
|
||||
|
||||
> Developed by Sam · [tools-software-webui](https://gitea.lab.audasmedia.com.au/sam/tools-software-webui "Gitea") ·
|
||||
> interactive map at [maps.lab.audasmedia.com.au](https://maps.lab.audasmedia.com.au)
|
||||
|
||||
---
|
||||
|
||||
## What it is
|
||||
|
||||
A coherent tool ecosystem for driving **pi** (the AI coding agent) from anywhere: watch what every
|
||||
agent is doing on every machine, route its LLM traffic through one resilient proxy, automate around
|
||||
it, and keep each project's context lean with a strict per-folder model.
|
||||
|
||||
Built on four layers that compose cleanly:
|
||||
|
||||
| Layer | Tool | Role |
|
||||
|---|---|---|
|
||||
| Console | **Pi Dashboard** (Go TUI + Python portal) | Live view of every pi session on every machine — what's running, where, status |
|
||||
| LLM routing | **OmniRoute** | One proxy, prioritized "combo" fallback chains (OpenCode-Go → OpenRouter → DeepSeek → Gemini) |
|
||||
| Automation | **n8n · Prefect 3 · LangChain** | Visual workflows, code pipelines, Python glue |
|
||||
| AI toolkit | **pi + extensions + MCP** | Sub-agent orchestration, tasks, memory, LSP, dashboards |
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph CLIENTS["Clients"]
|
||||
D27[".27 main dev<br/>NixOS"]
|
||||
D51[".51 laptop<br/>NixOS"]
|
||||
M["Mobile<br/>Termux / Tailscale / KDE Connect"]
|
||||
end
|
||||
subgraph LAB["Home lab (.lab.audasmedia.com.au)"]
|
||||
C["Caddy reverse proxy<br/>.35"]
|
||||
G["Gitea<br/>.35 :3001/:2222"]
|
||||
P["Pi-hole DNS<br/>.35"]
|
||||
end
|
||||
subgraph S13["Web-facing + Docker host (.13)"]
|
||||
N["n8n :5678"]
|
||||
PR["Prefect 3 :4200"]
|
||||
OR["OmniRoute :20129"]
|
||||
OW["Open WebUI :3000"]
|
||||
POR["Console portal :8500"]
|
||||
DSH["dsh chat :3081-84"]
|
||||
JK["Jervis voice :8501"]
|
||||
EN["engram .13:7437"]
|
||||
HH["headroom :8787"]
|
||||
end
|
||||
subgraph AGENTS["pi agents (per machine)"]
|
||||
EXT["dashboard.ts ext"]
|
||||
SUB["pi-subagents 18 types"]
|
||||
TS["pi-tasks"]
|
||||
MCP["MCP servers"]
|
||||
end
|
||||
D27 -->|"pi sessions"| AGENTS
|
||||
D51 -->|"pi sessions"| AGENTS
|
||||
M -->|"Tailscale / SSH"| D27
|
||||
M -->|"NTFY alerts"| AGENTS
|
||||
AGENTS -->|"state JSON"| EXT
|
||||
EXT -->|"~/.pi/agent/dashboard"| POR
|
||||
EXT -->|"notify"| M
|
||||
AGENTS -->|"LLM (omni provider)"| OR
|
||||
OR -->|"Caddy"| C
|
||||
C -->|"gitea.lab"| G
|
||||
C -->|"n8n/console.lab"| S13
|
||||
N -.->|"webhooks / triggers"| AGENTS
|
||||
PR -.->|"pipelines"| AGENTS
|
||||
AGENTS -->|"compress"| HH
|
||||
AGENTS -->|"memory"| EN
|
||||
```
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Every pi session reports.** A `dashboard.ts` extension writes heartbeat state to
|
||||
`~/.pi/agent/dashboard/<session>.json` (cwd/folder, agent status, model, attach target).
|
||||
2. **State is collected on the server.** The Go TUI (`pi-dashboard`) polls local + remote state over
|
||||
SSH; the Python console portal renders it in a browser.
|
||||
3. **Act from one table.** Attach to any session, review its changes with Hunk, open its task board
|
||||
(Tuxedo) — notifications via NTFY/Apprise.
|
||||
4. **LLM traffic is proxied.** pi talks to the `omni` provider; OmniRoute applies priority fallback
|
||||
combos so work continues if one provider fails.
|
||||
5. **Automation wraps it.** n8n webhooks and Prefect pipelines trigger around the agents.
|
||||
|
||||
## Directory map
|
||||
|
||||
```
|
||||
tools-software-webui/
|
||||
├── README.md ← this file
|
||||
└── docs/
|
||||
├── system.mmd ← Mermaid source (single source of truth)
|
||||
├── system-map.html ← interactive Archify architecture map
|
||||
└── diagrams/
|
||||
├── system.png ← rendered diagram (PNG, 2×)
|
||||
└── system.svg ← rendered diagram (vector)
|
||||
```
|
||||
|
||||
## Access
|
||||
|
||||
| Target | Route |
|
||||
|---|---|
|
||||
| Console (agent table) | Go TUI on `.27`/`.13` · web: Admin → Pi Dashboard (portal :8500 via Caddy) |
|
||||
| n8n | `n8n.home.lab` (LAN + auth) or Tailscale direct |
|
||||
| Prefect | CLI/API from dev machines → `http://<server-13>:4200` |
|
||||
| OmniRoute (OpenAI-compatible) | `http://192.168.20.13:20129/v1` · `https://omniroute.lab.audasmedia.com.au/v1` |
|
||||
| Open WebUI | `http://192.168.20.13:3000` |
|
||||
| Gitea | `gitea.lab.audasmedia.com.au` (:3001 web / :2222 ssh) |
|
||||
| Mobile | Tailscale app · Termux (SSH) · KDE Connect · NTFY alerts |
|
||||
|
||||
## Technology stack
|
||||
|
||||
- **pi** — Nix-managed coding agent (uniform v0.82.1 on `.27/.13/.51`); global packages:
|
||||
`pi-memctx`, `pi-mcp-adapter`, `@tintinweb/pi-subagents` (18 agents), `@tintinweb/pi-tasks`,
|
||||
`omniroute-pi-ext-integration`; MCP servers (`codebase-memory`, `code-review-graph`).
|
||||
- **Pi Dashboard** — Go + Bubble Tea TUI, `dashboard.ts` extension, Tuxedo (todo.txt), Hunk (diff),
|
||||
NTFY/Apprise notifications.
|
||||
- **OmniRoute** — Docker LLM proxy on `.13` with combo routing (484 models).
|
||||
- **Automation** — n8n (visual), Prefect 3 (code pipelines), LangChain (Python library).
|
||||
- **Services** — Outline (docs), Vikunja (tasks), Gitea (git + asset source `pi-config`),
|
||||
Caddy (reverse proxy), Pi-hole (DNS), Tailscale (mesh VPN).
|
||||
- **Infra** — NixOS `.27/.13/.51`, Ubuntu Docker host `.35`, Proxmox `.28`.
|
||||
|
||||
## Why it matters
|
||||
|
||||
- **One console, every machine.** Attach to, review, and task-track any pi agent from any device —
|
||||
no separate dashboards per host.
|
||||
- **Resilient LLM access.** Combo routing means provider outages degrade gracefully, not stop work.
|
||||
- **Lean by design.** Per-folder `.pi/settings.json` (arrays replace, not merge) keeps each
|
||||
project's agent context minimal; Nix manages the pi binary uniformly.
|
||||
- **Agent coordination built in.** 18 sub-agent types, worktrees, scheduling, dependency-tracked
|
||||
tasks — a base that scales to multi-agent project work.
|
||||
|
||||
## Related projects
|
||||
|
||||
- [pi-dashboard](https://gitea.lab.audasmedia.com.au/sam/pi-dashboard) — the Go console viewer
|
||||
- [family_home_lab](https://gitea.lab.audasmedia.com.au/sam/family_home_lab) — the family console
|
||||
the portal is part of
|
||||
- Docs: Obsidian `200 projects/Tools Software WebUI/` · Outline project `Tools Software WebUI` ·
|
||||
Vikunja project `Tools Software WebUI`
|
||||
|
||||
---
|
||||
|
||||
*Documentation-only project — no proprietary code included. Secrets never appear in this repo.*
|
||||
BIN
docs/diagrams/system.png
Normal file
BIN
docs/diagrams/system.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
1
docs/diagrams/system.svg
Normal file
1
docs/diagrams/system.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 36 KiB |
13725
docs/system-map.html
Normal file
13725
docs/system-map.html
Normal file
File diff suppressed because it is too large
Load Diff
193
docs/system.architecture.json
Normal file
193
docs/system.architecture.json
Normal file
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"diagram_type": "architecture",
|
||||
"meta": {
|
||||
"title": "Tools Software WebUI",
|
||||
"quality_profile": "showcase",
|
||||
"viewBox": [1120, 620]
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"id": "agents",
|
||||
"type": "backend",
|
||||
"label": "pi agents",
|
||||
"sublabel": "per machine (.27/.13/.51)",
|
||||
"pos": [120, 160]
|
||||
},
|
||||
{
|
||||
"id": "ext",
|
||||
"type": "backend",
|
||||
"label": "dashboard.ts",
|
||||
"sublabel": "extension",
|
||||
"pos": [330, 160]
|
||||
},
|
||||
{
|
||||
"id": "smc",
|
||||
"type": "database",
|
||||
"label": "state JSON",
|
||||
"sublabel": "~/.pi/agent/dashboard",
|
||||
"pos": [520, 160]
|
||||
},
|
||||
{
|
||||
"id": "tui",
|
||||
"type": "frontend",
|
||||
"label": "pi-dashboard",
|
||||
"sublabel": "Go TUI",
|
||||
"pos": [710, 100]
|
||||
},
|
||||
{
|
||||
"id": "portal",
|
||||
"type": "frontend",
|
||||
"label": "console portal",
|
||||
"sublabel": "Python :8500",
|
||||
"pos": [710, 260]
|
||||
},
|
||||
{
|
||||
"id": "omni",
|
||||
"type": "backend",
|
||||
"label": "OmniRoute",
|
||||
"sublabel": "LLM :20129",
|
||||
"pos": [330, 370]
|
||||
},
|
||||
{
|
||||
"id": "n8n",
|
||||
"type": "backend",
|
||||
"label": "n8n",
|
||||
"sublabel": ":5678",
|
||||
"pos": [140, 470]
|
||||
},
|
||||
{
|
||||
"id": "prefect",
|
||||
"type": "backend",
|
||||
"label": "Prefect 3",
|
||||
"sublabel": ":4200",
|
||||
"pos": [350, 470]
|
||||
},
|
||||
{
|
||||
"id": "headroom",
|
||||
"type": "backend",
|
||||
"label": "headroom",
|
||||
"sublabel": "compress :8787",
|
||||
"pos": [140, 370]
|
||||
},
|
||||
{
|
||||
"id": "caddy",
|
||||
"type": "external",
|
||||
"label": "Caddy",
|
||||
"sublabel": "reverse proxy .35",
|
||||
"pos": [920, 300]
|
||||
},
|
||||
{
|
||||
"id": "gitea",
|
||||
"type": "external",
|
||||
"label": "Gitea",
|
||||
"sublabel": ":3001/:2222",
|
||||
"pos": [920, 120]
|
||||
},
|
||||
{
|
||||
"id": "phone",
|
||||
"type": "external",
|
||||
"label": "Mobile",
|
||||
"sublabel": "Termux / KDE Connect",
|
||||
"pos": [920, 480]
|
||||
}
|
||||
],
|
||||
"boundaries": [
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "console & telemetry",
|
||||
"wraps": ["ext", "smc", "tui", "portal"]
|
||||
},
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "web-facing host (.13)",
|
||||
"wraps": ["omni", "n8n", "prefect", "headroom"]
|
||||
},
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "home lab (.35)",
|
||||
"wraps": ["caddy", "gitea"]
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "agents-to-ext",
|
||||
"from": "agents",
|
||||
"to": "ext",
|
||||
"label": "runs every session",
|
||||
"labelAt": [285, 150]
|
||||
},
|
||||
{
|
||||
"id": "ext-to-smc",
|
||||
"from": "ext",
|
||||
"to": "smc",
|
||||
"label": "writes JSON"
|
||||
},
|
||||
{
|
||||
"id": "smc-to-tui",
|
||||
"from": "smc",
|
||||
"to": "tui",
|
||||
"label": "ssh pull / read",
|
||||
"labelAt": [665, 90]
|
||||
},
|
||||
{
|
||||
"id": "smc-to-portal",
|
||||
"from": "smc",
|
||||
"to": "portal",
|
||||
"label": "collected on .13",
|
||||
"fromSide": "bottom",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "agents-to-omni",
|
||||
"from": "agents",
|
||||
"to": "omni",
|
||||
"label": "LLM (omni provider)",
|
||||
"fromSide": "bottom",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "omni-to-caddy",
|
||||
"from": "omni",
|
||||
"to": "caddy",
|
||||
"label": "combo routing"
|
||||
},
|
||||
{
|
||||
"id": "caddy-to-gitea",
|
||||
"from": "caddy",
|
||||
"to": "gitea",
|
||||
"label": "gitea.lab"
|
||||
}
|
||||
],
|
||||
"cards": [
|
||||
{
|
||||
"dot": "cyan",
|
||||
"title": "Core loop",
|
||||
"items": [
|
||||
"Every pi session runs dashboard.ts → heartbeat JSON per machine",
|
||||
"Collected on .13; rendered by Go TUI and Python portal",
|
||||
"LLM traffic proxied through OmniRoute with priority fallback combos",
|
||||
"Headroom compresses heavy contexts; NTFY alerts mobile on completion",
|
||||
"n8n webhooks / Prefect pipelines can trigger around the agents"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "emerald",
|
||||
"title": "Access routes",
|
||||
"items": [
|
||||
"Console: pi-dashboard TUI on .27/.13 · portal Admin via console.lab",
|
||||
"n8n :5678 · Prefect :4200 · Open WebUI :3000 on .13",
|
||||
"Phone: Tailscale + Termux SSH + KDE Connect + NTFY"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "amber",
|
||||
"title": "Decisions",
|
||||
"items": [
|
||||
"Windmill not needed — n8n (canvas) + Prefect (pipelines) cover it",
|
||||
"Paseo / Pi Web UI deferred to roadmap — current console suffices",
|
||||
"Gitea Actions recommended: auto-sync ~/.agents clones on push"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
43
docs/system.mmd
Normal file
43
docs/system.mmd
Normal file
@@ -0,0 +1,43 @@
|
||||
flowchart LR
|
||||
subgraph CLIENTS["Clients"]
|
||||
D27[".27 main dev<br/>NixOS"]
|
||||
D51[".51 laptop<br/>NixOS"]
|
||||
M["Mobile<br/>Termux / Tailscale / KDE Connect"]
|
||||
end
|
||||
subgraph LAB["Home lab (.lab.audasmedia.com.au)"]
|
||||
C["Caddy reverse proxy<br/>.35"]
|
||||
G["Gitea<br/>.35 :3001/:2222"]
|
||||
P["Pi-hole DNS<br/>.35"]
|
||||
end
|
||||
subgraph S13["Web-facing + Docker host (.13)"]
|
||||
N["n8n :5678"]
|
||||
PR["Prefect 3 :4200"]
|
||||
OR["OmniRoute :20129"]
|
||||
OW["Open WebUI :3000"]
|
||||
POR["Console portal :8500"]
|
||||
DSH["dsh chat :3081-84"]
|
||||
JK["Jervis voice :8501"]
|
||||
EN["engram .13:7437"]
|
||||
HH["headroom :8787"]
|
||||
end
|
||||
subgraph AGENTS["pi agents (per machine)"]
|
||||
EXT["dashboard.ts ext"]
|
||||
SUB["pi-subagents 18 types"]
|
||||
TS["pi-tasks"]
|
||||
MCP["MCP servers"]
|
||||
end
|
||||
D27 -->|"pi sessions"| AGENTS
|
||||
D51 -->|"pi sessions"| AGENTS
|
||||
M -->|"Tailscale / SSH"| D27
|
||||
M -->|"NTFY alerts"| AGENTS
|
||||
AGENTS -->|"state JSON"| EXT
|
||||
EXT -->|"~/.pi/agent/dashboard"| POR
|
||||
EXT -->|"notify"| M
|
||||
AGENTS -->|"LLM (omni provider)"| OR
|
||||
OR -->|"Caddy"| C
|
||||
C -->|"gitea.lab"| G
|
||||
C -->|"n8n/console.lab"| S13
|
||||
N -.->|"webhooks / triggers"| AGENTS
|
||||
PR -.->|"pipelines"| AGENTS
|
||||
AGENTS -->|"compress"| HH
|
||||
AGENTS -->|"memory"| EN
|
||||
Reference in New Issue
Block a user