ai tooling testbed for new tools + models
  • Python 69.6%
  • Shell 26.6%
  • Dockerfile 3.8%
Find a file
Jesse Garcia 34359f463c feat(litellm): add 6 cluster-side complexity routers, remove work-auto
- Replace personal-auto passthrough with 6 domain-specific routers:
  auto-code-{low,high}, auto-agent-{low,high}, auto-work-{low,high}
- Add mysubs/claudecode/claude-haiku-4.5 passthrough
- Remove work-auto local complexity router (handled by cluster)
- Update comments referencing work-auto
2026-10-15 18:58:41 -06:00
claude feat(claude): mirror the host's Claude Code settings into both lanes 2026-09-25 12:00:09 -06:00
compose feat(litellm): add 6 cluster-side complexity routers, remove work-auto 2026-10-15 18:58:41 -06:00
docs feat(compose): per-service host bind address 2026-10-09 12:20:51 -06:00
profiles refactor(hermes): collapse MINI/FAST aux lanes into single HERMES_MODEL_UTILITY 2026-09-30 23:35:31 -06:00
scripts feat(mcp): provision shared OAuth gateway 2026-10-01 14:58:33 -06:00
skills +big updates 2026-09-01 17:42:48 -06:00
tests feat(compose): per-service host bind address 2026-10-09 12:20:51 -06:00
zsh refactor: rename homelab stack to Perch 2026-09-30 15:56:25 -06:00
.env.example feat(compose): per-service host bind address 2026-10-09 12:20:51 -06:00
.gitignore feat(mcp): provision shared OAuth gateway 2026-10-01 14:58:33 -06:00
.justfile feat(mcp): provision shared OAuth gateway 2026-10-01 14:58:33 -06:00
a2a-wire.py refactor: rename homelab stack to Perch 2026-09-30 15:56:25 -06:00
compose.yaml feat(compose): per-service host bind address 2026-10-09 12:20:51 -06:00
config.yaml refactor(hermes): collapse MINI/FAST aux lanes into single HERMES_MODEL_UTILITY 2026-09-30 23:35:31 -06:00
Dockerfile feat(memory): share Hindsight bank with Pi and Aider 2026-09-30 16:55:31 -06:00
entrypoint.sh feat(mcp): provision shared OAuth gateway 2026-10-01 14:58:33 -06:00
pytest.ini +testing 2026-09-17 16:21:39 -06:00
README.md Add experimental Ollaya ROCm profile for TUX 2026-10-05 20:44:59 -06:00

Perch

A Docker Compose homelab stack for Hermes, specialist agents, model routing, memory and tools. The gateway exposes an OpenAI-compatible API on 127.0.0.1:8642. ph is an optional zsh shortcut for the just recipes, not a separate CLI.

Setup

Requires Docker with Compose; just is recommended for the commands below.

just setup                 # interactive wizard: image tools, services, memory
# or: cp .env.example .env  # configure by hand
just up                    # one Hermes gateway
just health                # checks a real model turn, not just liveness

At minimum, set API_SERVER_KEY (e.g. openssl rand -hex 32), GATEWAY_BASE_URL (OpenAI-compatible URL ending in /v1), GATEWAY_API_KEY, and model names served by that URL in .env. The example's HERMES_MODEL=work-auto needs the local litellm profile and its configured upstream; for a remote proxy, use a model it actually serves. just setup generates service credentials but leaves the gateway URL, key and model selection to you. It prints the next commands; it does not start the stack.

config.yaml defines Hermes' default profile; .env supplies deployment-specific URLs, keys and model names. See configuration and services for the routing, profiles, ports and persistence details. .env.example is the complete list of switches and defaults.

Everyday commands

Command Purpose
just up [mem0 litellm …] Start Hermes and selected optional Compose profiles
just up agents [litellm …] Instead run four always-on agents with A2A
just down [agents] Stop the stack (use agents for agents mode)
just chat [--profile code-agent] Hermes CLI; validates profile names and reports active wrappers
just agent claude|pi|aider [args] Run a coding CLI inside the container
just mcp-setup Configure the remote MCP gateway for Hermes, Claude and Pi
just run <subcommand> Run any Hermes subcommand, e.g. just run kanban watch
just health [--quick] Check the gateway (--quick skips the model turn)
just logs [service …] / just shell Diagnose a running container
just rebuild [profiles …] Rebuild after Dockerfile, entrypoint or image-tool changes
just agents-status / just peers Inspect the agents mode mesh
just volumes ls|inspect|prune Inspect or delete persistent state (prune asks for confirmation)

Examples:

just up litellm                         # local proxy; requires POSTGRES_PASSWORD
just up mem0 litellm                    # memory plus proxy
just up hindsight litellm               # start memory service; see backend switch below
just up searxng browser                 # search and Chromium
just up litellm llamacpp                # local GPU model behind LiteLLM
just chat --profile research-agent
just agent aider -m "refactor the parser"

just up and just up agents are mutually exclusive: both would claim port 8642. just restart restarts existing containers but does not load changes to .env; run just up again to recreate them. A changed HERMES_WITH_* build switch needs just rebuild (and preferably a new PERCH_TAG). Running plain Compose is possible (docker compose up -d), but the recipes also set host uid/gid and mount the directory where you invoked just as /opt/data/workspace.

To make recipes available from any directory, source zsh/perch.zsh in your zsh config. ph forwards to any recipe (ph up agents); phc, pha, phu, phd, phr, phl, phst, phsh are shortcuts. Set PERCH_ZSH_SHORT=0 before sourcing to keep only long names.

Choose your stack

Each service is opt-in; a bare just up starts only Hermes. All published ports bind to loopback.

Profile Host endpoint What it does / required configuration
litellm :4000 Model proxy and registry in compose/inference/litellm.config.yaml; set POSTGRES_PASSWORD, HOMELAB_PROXY_URL for hosted models
mem0 :8000 Memory; set POSTGRES_PASSWORD, MEM0_JWT_SECRET, MEM0_HOST=http://localhost:8000
hindsight :8888 (UI :9999) Alternative memory; set POSTGRES_PASSWORD; run alongside litellm for LLM/embedding calls
searxng :8080 Private search; set SEARXNG_URL=http://searxng:8080
browser :9222 Headless Chromium; set BROWSER_CDP_URL=http://172.28.99.10:9222
llamacpp :8081 GPU-backed llama.cpp model for local LiteLLM; configured for AMD/ROCm
ollaya :11435 Separate gateway for typed decision models (routing/triage/intent), not chat; upstream CPU/CUDA image; TypeSafe-compatible POST /v1/systemone; registered in LiteLLM as a pass-through
ollaya-rocm :11435 Experimental TUX-specific Ollaya build with llama.cpp HIP/ROCm support for GGUF decision models; mutually exclusive with ollaya (same port)
headroom :8787 Optional context-compression proxy; must also set routing URLs

mem0, hindsight and litellm pull in a single, unpublished Postgres with separate databases. Starting Hindsight does not change Hermes' memory provider: set HINDSIGHT_API_URL=http://hindsight:8888 to switch from the mem0 provider in config.yaml. This same URL enables Pi and Aider's Hindsight integrations. Keep it empty if you only want Hindsight's MCP endpoint (http://hindsight:8888/mcp/<bank>/). See memory and model routing.

The image includes all optional tools by default; HERMES_WITH_* flags in .env.example select smaller builds (coding CLIs, language toolchains, DinD, etc.). The code-agent and code-review-agent profiles depend on claude and pi respectively. Image tools are independent of Compose service profiles; selecting a service does not install a CLI. See image variants.

Agents and integrations

Four profiles live under profiles/: general-agent, code-agent, research-agent, code-review-agent. In single-container mode Kanban dispatches profile workers; in just up agents each has a gateway, isolated home and authenticated A2A endpoint. See agents and A2A for ports, delegation and adding profiles.

Claude Code, Pi and Aider use your proxy, not a separate subscription. Claude needs ANTHROPIC_BASE_URL without /v1; Pi and Aider inherit GATEWAY_BASE_URL unless overridden. To share a remote streamable-HTTP MCP endpoint across every running Hermes agent plus Claude and Pi, set MCP_UPSTREAM_URL and optionally MCP_UPSTREAM_NAME, recreate the stack with just up [agents], then run just mcp-setup. The command configures all three clients and walks through their OAuth approvals; each client persists and refreshes its own tokens. Optional Headroom, Caveman and Ponytail operate at different layers, and enabling one for Hermes does not automatically enable it for the coding CLIs. See coding CLIs and token reduction.

To connect Neovim or another OpenAI client, use base URL http://127.0.0.1:8642/v1, model hermes-agent, and bearer token API_SERVER_KEY.

Development and reference

uv venv .venv --python 3.13
uv pip install --python .venv/bin/python pytest pyyaml
just test                 # static checks, no Docker
just test-integration     # requires a running stack
just eval -k code-agent  # profile evals; requires `just up agents`