| title | Run agents | ||
|---|---|---|---|
| description | Install and manage the bundled Hermes agent with the hal0 agent CLI — provisioning, personas, gated-action approvals, and per-persona spending budgets. | ||
| sidebar |
|
import { Steps, Aside, Tabs, TabItem, Code } from '@astrojs/starlight/components';
hal0 can run a bundled agent — Hermes — provisioned into a
hal0-managed virtualenv and driven through the hal0 agent CLI. The agent
gets a persona (system prompt + tool gating), an approvals queue for
gated/destructive actions, and an optional per-persona spending budget.
sudo hal0 agent install hermesInstalling Hermes runs a three-step foreground pipeline:
-
Toolchain — ensures
python3(≥3.11), the venv stdlib,pip, andpipxvia the distro helper. Idempotent. -
Provision — creates the managed venv under
/var/lib/hal0/venvs/hermes, pip-installshermes-agent, installs thehermesshim, and registers the agent. -
Enable —
systemctl enable --now hal0-agent@hermesso the agent runs and survives reboot.
Run it as root: provisioning writes under root-owned /var/lib/hal0 and
then chowns the provisioned trees to the hal0 user (the shared agent runtime
user). If you run it as a normal user it aborts cleanly up front with a sudo
hint rather than crashing mid-build.
Pass --switch to atomically uninstall whatever agent is currently
installed before installing this one.
OpenCode is a terminal coding agent with native OpenAI-compatible providers and MCP support. It's a lightweight alternative to Hermes — no managed venv, just a CLI plus a single JSON config.
hal0 agent install opencodeThis runs installer/agents/opencode.sh (a track-latest npm install -g opencode-ai; no version pin, by design) and writes
~/.config/opencode/opencode.json wiring:
- Provider — hal0 as an
@ai-sdk/openai-compatibleprovider at$HAL0_API_URL/v1(the hal0-api gateway), with thehal0/*slot virtuals as the model set andhal0/agentas the default. The gateway live-resolves to whichever slot is loaded — warm the slot you want first (a cold slot returnsslot … is warming — not ready to serve). - Memory — the hindsight-backed
hal0-memoryMCP mount (/mcp/memory/mcp, agent-scoped viaX-hal0-Agent).
hal0 agent list # installed bundled agents
hal0 agent list --json
hal0 agent status hermes # provisioning checkpoint, per phase
hal0 agent peers # every published agent identity cardlist only shows agents installed on this host; peers searches the
agents memory dataset for every identity card any host has published
(needs the memory API reachable — it dies with a clear error otherwise).
hal0 agent log hermes
hal0 agent log hermes --phase provisionPer-phase provisioning logs from the agent's state directory.
hal0 agent reprovision hermes # idempotent re-converge
hal0 agent reprovision hermes --repair # force every phase
hal0 agent upgrade hermes # bump the version pin + repair
hal0 agent upgrade hermes --to 0.15.3 # pin a specific versionreprovision is a stable wrapper over the same state machine that
install runs. For finer control — skipping a phase, staging the
hermes-agent wheel offline, or a dry run that doesn't persist the
checkpoint — drop to the underlying command directly:
hal0 agent bootstrap hermes --dry-run
hal0 agent bootstrap hermes --repair --verbose
hal0 agent bootstrap hermes --skip-phase provision_venv --offlineTo restart the running Hermes process without re-provisioning anything (no config re-render, no ownership reconcile), restart the systemd unit directly or hit its restart endpoint:
sudo systemctl restart hal0-agent@hermes
curl -X POST http://localhost:8080/api/agents/hermes/restarthal0 agent uninstall hermes
hal0 agent uninstall hermes --keep-memoryDefault uninstall tears down the agent's private memory namespace too;
--keep-memory preserves it so a re-install reuses the identity card.
A persona is a TOML file pairing a system prompt with tool gating. Manage
them with the personas sub-app:
hal0 agent personas list # list + mark the active one
hal0 agent personas show <id> # print a persona's TOML (good template)
hal0 agent personas activate <id> # switch active + nudge a hot-reloadActivating writes the active.txt pointer atomically and best-effort
nudges a running Hermes to hot-reload. If Hermes isn't running, the next
restart picks up the new active persona. To author your own, copy
personas show output, change the persona id, and save it under the
persona store.
Destructive or gated tool calls don't execute immediately — they land in an approvals queue you review:
hal0 agent approvals list # pending requests
hal0 agent approvals approve <id> # let it run
hal0 agent approvals deny <id> # reject itEach pending row shows the request id, the tool, the requesting agent
(client_id), when it was enqueued, and a one-line summary built from the
tool's primary argument. The dashboard's Agent → Approvals tab renders the
same queue.
The Operator Board (dashboard ▸ Board) — Hermes agent tasks move across Triage → To-do → Scheduled → Ready lanes.
Each persona can carry spending caps so an autonomous loop can't drain a
paid provider pool. Caps live in the persona's [persona.budget]
sub-table:
[persona.budget]
daily_usd = 5.0
monthly_usd = 50.0
lifetime_usd = 200.0
per_call_max_usd = 0.50
hard_cap = trueEvery cap is optional — omit one to leave that window uncapped, or set it
to 0.0 to block every paid request. hard_cap = true (the default)
denies requests that would overshoot; hard_cap = false lets them through
but still reports the breach so the caller can log a warning. Spend is
tracked in an append-only ledger per persona, aggregated over daily,
monthly, and lifetime windows.
Check the configured caps plus running spend for a persona over the API (there's no dedicated CLI verb for this yet):
curl http://localhost:8080/api/agents/hermes/personas/hermes/budgetThe same route accepts a PUT with a {"daily_usd": ..., ...} body to
change the caps without hand-editing the persona TOML.
Every gated tool invocation is journaled. Pull an agent's recent MCP activity:
curl 'http://localhost:8080/api/agents/hermes/activity?limit=50'Each row carries tool, args, gated, outcome, timestamp, and the
client_id the action was attributed to.
- Enable memory — the recall store agents read and write.
- Connect external providers — wire the paid upstream a budget caps spend against.
