Paseo build docs: README, mermaid diagram, Archify map — Docker on .13, pi provider, OmniRoute
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# secrets — never commit
|
||||
.env
|
||||
*.env
|
||||
138
README.md
Normal file
138
README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Paseo — Agent Orchestration on the Home Lab
|
||||
|
||||
**Multi-agent orchestration GUI (Paseo 0.7.2) self-hosted in Docker on `.13`, driving real pi
|
||||
coding agents (0.82.1) through OmniRoute.**
|
||||
|
||||
> Maintained by Sam · Gitea — [sam/paseo](https://gitea.lab.audasmedia.com.au/sam/paseo) ·
|
||||
> interactive map: [maps.lab → Paseo](https://maps.lab.audasmedia.com.au/paseo/docs/system-map.html)
|
||||
|
||||
---
|
||||
|
||||
## What it is
|
||||
|
||||
[Paseo](https://github.com/getpaseo/paseo) is a client-server orchestration layer for AI coding
|
||||
agents: one **daemon** manages agent processes and streams their output to desktop, CLI, mobile and
|
||||
web clients. On this lab it runs **inside Docker on the always-on host `.13`**, with **pi** (the
|
||||
coding agent) baked into the image and LLM traffic routed through the existing **OmniRoute** proxy
|
||||
on `.13:20129`.
|
||||
|
||||
- **Local-first** — agents run on our machines/dev environment; no telemetry.
|
||||
- **Pi is a first-class provider** — the daemon spawns `pi --mode rpc` (pi 0.82.1, no Nix changes).
|
||||
- **One console** — `paseo ls` / `attach` / `logs` from anywhere: `.27`, `.51`, mobile, web UI.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph CLIENTS["Clients"]
|
||||
D27[".27 desktop<br/>paseo CLI"]
|
||||
D51[".51 laptop<br/>paseo CLI"]
|
||||
M["Mobile / web UI<br/>browser"]
|
||||
end
|
||||
subgraph S13["Paseo daemon (.13 — Docker, always-on)"]
|
||||
D["Paseo daemon 0.7.2<br/>:6767 · auth"]
|
||||
PI["pi agent 0.82.1<br/>pi --mode rpc<br/>@earendil pi + omni ext"]
|
||||
CFG["pi config<br/>/home/paseo/.pi"]
|
||||
W["workspaces<br/>/workspace/demo"]
|
||||
PWD["PASEO_PASSWORD<br/>.env (600)"]
|
||||
end
|
||||
subgraph LLM["LLM routing"]
|
||||
OR["OmniRoute<br/>.13:20129"]
|
||||
OP["OpenCode-Go /<br/>OpenRouter / DeepSeek / Gemini"]
|
||||
end
|
||||
D27 -->|"PASEO_HOST + password"| D
|
||||
D51 -->|"PASEO_HOST + password"| D
|
||||
M -->|"https :6767"| D
|
||||
D -->|"spawns / manages"| PI
|
||||
PI -->|"reads settings + models"| CFG
|
||||
PI -->|"works in"| W
|
||||
D -->|"protects"| PWD
|
||||
PI -->|"httpx /v1 (omni provider)"| OR
|
||||
OR -->|"combo routing"| OP
|
||||
```
|
||||
|
||||
## Directory map
|
||||
|
||||
```
|
||||
paseo/
|
||||
├── README.md ← this file
|
||||
└── docs/
|
||||
├── system.mmd ← Mermaid source (single source of truth)
|
||||
├── system.architecture.json ← Archify source
|
||||
├── system-map.html ← interactive Archify map
|
||||
└── diagrams/
|
||||
├── system.png
|
||||
└── system.svg
|
||||
```
|
||||
|
||||
## Quick start (client)
|
||||
|
||||
```bash
|
||||
# .27 / .51 (one-time)
|
||||
npm install -g @getpaseo/cli@0.7.2
|
||||
|
||||
export PASEO_HOST=192.168.20.13:6767
|
||||
export PASEO_PASSWORD=<from .13: /home/sam/Docker/Containers/paseo/.env>
|
||||
|
||||
paseo status # daemon reachable?
|
||||
paseo ls # running agents
|
||||
paseo run --provider pi --model omni/openrouter/qwen/qwen3.7-flash \
|
||||
--cwd /workspace/demo "describe this workspace"
|
||||
paseo logs <agent-id> # full activity timeline
|
||||
```
|
||||
|
||||
Web UI: `http://192.168.20.13:6767` (password). Mobile: browser over LAN/Tailscale.
|
||||
|
||||
## Deployment (server, `.13`)
|
||||
|
||||
| Item | Value |
|
||||
|---|---|
|
||||
| Compose dir | `/home/sam/Docker/Containers/paseo/` |
|
||||
| Image | `ghcr.io/getpaseo/paseo:latest` + custom stage |
|
||||
| Daemon | 0.7.2 · `restart: always` · :6767 |
|
||||
| pi | `@earendil-works/pi-coding-agent@0.82.1` (baked, `--mode rpc`) |
|
||||
| Extensions | `omniroute-pi-ext-integration` (baked) |
|
||||
| Config | `./paseo-home:/home/paseo` (persists pi + paseo config) |
|
||||
| Workspace | `./workspace:/workspace` (agent project area) |
|
||||
| LLM | pi → omni provider → `http://192.168.20.13:20129/v1` (OmniRoute) |
|
||||
| Secrets | `.env` (chmod 600) — `PASEO_PASSWORD`, `OMNIROUTE_API_KEY` |
|
||||
|
||||
**Build note:** base image runs as user `paseo` (uid 1000) with root-owned `/usr/local` — so pi and
|
||||
the extension are installed at **build time** under `USER root` in the Dockerfile, then dropped back
|
||||
to `USER paseo` for runtime.
|
||||
|
||||
## Verified end-to-end (2026-09-09)
|
||||
|
||||
```
|
||||
$ paseo run --provider pi --model omni/openrouter/qwen/qwen3.7-flash \
|
||||
--cwd /workspace/demo --title paseo-demo --background \
|
||||
"List files, read HELLO.txt, write DEMO_SUMMARY.md"
|
||||
|
||||
AGENT ID 560ffca0-… STATUS running PROVIDER pi CWD /workspace/demo
|
||||
↓
|
||||
AGENT ID 560ffca0-… STATUS idle PROVIDER pi/omni/openrouter/qwen/qwen3.7-flash
|
||||
↓ → wrote ./workspace/demo/DEMO_SUMMARY.md (correct content)
|
||||
↓ → `paseo logs` shows full timeline (user → thought → shell → read)
|
||||
↓ → web UI :6767 → HTTP 200
|
||||
```
|
||||
|
||||
## Known findings
|
||||
|
||||
- **OmniRoute combo regression:** the default `default-opencode-go-ds-flash` combo currently returns
|
||||
`400 missing x-opencode-session` (OpenCode-Go leg) — affects host pi too, not just the container.
|
||||
Working legs verified: `openrouter/qwen/qwen3.7-flash`, `openrouter/openai/gpt-5.6-sol`,
|
||||
`aug/claude-haiku-4.5`. Fix the combo/credentials on OmniRoute to restore the default path.
|
||||
- Paseo is pre-1.0 (0.7.2) — pin the version; expect breaking changes between releases.
|
||||
- CLI runtime install on `.27` carries 3 low/medium CVEs in transitive deps (`qs`, `uuid`,
|
||||
`@ai-sdk/provider-utils`) — vet/npq scanned clean, author verified.
|
||||
|
||||
## Why it matters
|
||||
|
||||
- **Proof the stack composes:** Nix pi binary stays untouched; the lab's OmniRoute routing powers a
|
||||
third-party orchestrator; one always-on Docker host (.13) gives fleet control from any device.
|
||||
- **A pattern for multi-agent work:** workspaces + `pi --mode rpc` + OmniRoute is a base for
|
||||
coordinating several pi agents on real projects — exactly the coordination layer the lab needs.
|
||||
|
||||
---
|
||||
|
||||
*Documentation project — no proprietary code. 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: 65 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: 25 KiB |
13677
docs/system-map.html
Normal file
13677
docs/system-map.html
Normal file
File diff suppressed because it is too large
Load Diff
164
docs/system.architecture.json
Normal file
164
docs/system.architecture.json
Normal file
@@ -0,0 +1,164 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"diagram_type": "architecture",
|
||||
"meta": {
|
||||
"title": "Paseo on the Home Lab",
|
||||
"quality_profile": "showcase",
|
||||
"viewBox": [1120, 600]
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"id": "cli",
|
||||
"type": "frontend",
|
||||
"label": "paseo CLI",
|
||||
"sublabel": ".27 / .51",
|
||||
"pos": [120, 120]
|
||||
},
|
||||
{
|
||||
"id": "web",
|
||||
"type": "frontend",
|
||||
"label": "Web UI / mobile",
|
||||
"sublabel": "browser :6767",
|
||||
"pos": [120, 240]
|
||||
},
|
||||
{
|
||||
"id": "daemon",
|
||||
"type": "backend",
|
||||
"label": "Paseo daemon",
|
||||
"sublabel": "0.7.2 · :6767 · auth",
|
||||
"pos": [420, 120]
|
||||
},
|
||||
{
|
||||
"id": "pi",
|
||||
"type": "backend",
|
||||
"label": "pi agent",
|
||||
"sublabel": "0.82.1 · --mode rpc",
|
||||
"pos": [420, 300]
|
||||
},
|
||||
{
|
||||
"id": "cfg",
|
||||
"type": "database",
|
||||
"label": "pi config",
|
||||
"sublabel": "paseo-home/.pi",
|
||||
"pos": [700, 300]
|
||||
},
|
||||
{
|
||||
"id": "ws",
|
||||
"type": "database",
|
||||
"label": "workspace",
|
||||
"sublabel": "/workspace/demo",
|
||||
"pos": [700, 440]
|
||||
},
|
||||
{
|
||||
"id": "omni",
|
||||
"type": "backend",
|
||||
"label": "OmniRoute",
|
||||
"sublabel": ".13:20129",
|
||||
"pos": [760, 120]
|
||||
},
|
||||
{
|
||||
"id": "llm",
|
||||
"type": "external",
|
||||
"label": "LLM providers",
|
||||
"sublabel": "combo routing",
|
||||
"pos": [940, 120]
|
||||
}
|
||||
],
|
||||
"boundaries": [
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "clients",
|
||||
"wraps": ["cli", "web"]
|
||||
},
|
||||
{
|
||||
"kind": "region",
|
||||
"label": "Paseo daemon (.13 Docker)",
|
||||
"wraps": ["daemon", "pi", "cfg", "ws"]
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"id": "cli-to-daemon",
|
||||
"from": "cli",
|
||||
"to": "daemon",
|
||||
"label": "PASEO_HOST + password",
|
||||
"labelAt": [270, 60]
|
||||
},
|
||||
{
|
||||
"id": "web-to-daemon",
|
||||
"from": "web",
|
||||
"to": "daemon",
|
||||
"label": "https :6767"
|
||||
},
|
||||
{
|
||||
"id": "daemon-to-pi",
|
||||
"from": "daemon",
|
||||
"to": "pi",
|
||||
"label": "spawns / manages",
|
||||
"labelAt": [480, 205],
|
||||
"fromSide": "bottom",
|
||||
"toSide": "top"
|
||||
},
|
||||
{
|
||||
"id": "pi-to-cfg",
|
||||
"from": "pi",
|
||||
"to": "cfg",
|
||||
"label": "reads settings + models",
|
||||
"labelAt": [700, 370]
|
||||
},
|
||||
{
|
||||
"id": "pi-to-ws",
|
||||
"from": "pi",
|
||||
"to": "ws",
|
||||
"label": "works in",
|
||||
"labelAt": [700, 520]
|
||||
},
|
||||
{
|
||||
"id": "pi-to-omni",
|
||||
"from": "pi",
|
||||
"to": "omni",
|
||||
"label": "omni provider /v1",
|
||||
"labelAt": [590, 225],
|
||||
"fromSide": "right",
|
||||
"toSide": "bottom"
|
||||
},
|
||||
{
|
||||
"id": "omni-to-llm",
|
||||
"from": "omni",
|
||||
"to": "llm",
|
||||
"label": "combo routing",
|
||||
"labelAt": [910, 194]
|
||||
}
|
||||
],
|
||||
"cards": [
|
||||
{
|
||||
"dot": "cyan",
|
||||
"title": "Proven end-to-end",
|
||||
"items": [
|
||||
"paseo run --provider pi → agent 560ffca0 (pi/omni/openrouter/qwen/qwen3.7-flash)",
|
||||
"Agent read HELLO.txt, wrote DEMO_SUMMARY.md into /workspace/demo",
|
||||
"paseo logs shows full timeline (user → thought → shell → read)",
|
||||
"Web UI http://192.168.20.13:6767 → HTTP 200"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "emerald",
|
||||
"title": "Deployment facts",
|
||||
"items": [
|
||||
"Container: /home/sam/Docker/Containers/paseo/ (restart: always)",
|
||||
"pi + omniroute ext baked at build time (USER root) — image runs as paseo (uid 1000)",
|
||||
"pi 0.82.1 in container; host Nix pi untouched",
|
||||
"Secrets only in .env (chmod 600)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"dot": "amber",
|
||||
"title": "Findings",
|
||||
"items": [
|
||||
"OmniRoute default combo (default-opencode-go-ds-flash) → 400 x-opencode-session issue",
|
||||
"Working models: openrouter/qwen/qwen3.7-flash, openrouter/openai/gpt-5.6-sol, aug/claude-haiku-4.5",
|
||||
"Fix combo/credentials on OmniRoute to restore the default path"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
26
docs/system.mmd
Normal file
26
docs/system.mmd
Normal file
@@ -0,0 +1,26 @@
|
||||
flowchart LR
|
||||
subgraph CLIENTS["Clients"]
|
||||
D27[".27 desktop<br/>paseo CLI"]
|
||||
D51[".51 laptop<br/>paseo CLI"]
|
||||
M["Mobile / web UI<br/>browser"]
|
||||
end
|
||||
subgraph S13["Paseo daemon (.13 — Docker, always-on)"]
|
||||
D["Paseo daemon 0.7.2<br/>:6767 · auth"]
|
||||
PI["pi agent 0.82.1<br/>pi --mode rpc<br/>@earendil pi + omni ext"]
|
||||
CFG["pi config<br/>/home/paseo/.pi"]
|
||||
W["workspaces<br/>/workspace/demo"]
|
||||
PWD["PASEO_PASSWORD<br/>.env (600)"]
|
||||
end
|
||||
subgraph LLM["LLM routing"]
|
||||
OR["OmniRoute<br/>.13:20129"]
|
||||
OP["OpenCode-Go /<br/>OpenRouter / DeepSeek / Gemini"]
|
||||
end
|
||||
D27 -->|"PASEO_HOST + password"| D
|
||||
D51 -->|"PASEO_HOST + password"| D
|
||||
M -->|"https :6767"| D
|
||||
D -->|"spawns / manages"| PI
|
||||
PI -->|"reads settings + models"| CFG
|
||||
PI -->|"works in"| W
|
||||
D -->|"protects"| PWD
|
||||
PI -->|"httpx /v1 (omni provider)"| OR
|
||||
OR -->|"combo routing"| OP
|
||||
Reference in New Issue
Block a user