Hermes
Route Hermes command approvals and kanban block/review pauses into the HITLy inbox.
Hermes Agent is a Python agent. HITLy does not run inside Hermes — a drop-in plugin POSTs pauses to HITLy, and applies the decision on the Hermes host.
Hermes “personas” are named profiles (~/.hermes/profiles/<name>/, each with its own SOUL.md). Cron is only one unattended runner.
How it works with HITLy
Command approval (CLI, gateway, /background)
Dangerous terminal / execute_code calls pause in Hermes tools/approval.py. Selecting security.approval.transport: hitly replaces the built-in prompt (including Telegram /approve).
- The plugin
present()starts a local webhook listener and POSTs the command +resumeUrlto HITLy. - The plugin waits on the local callback (not polling HITLy).
- Reviewer decides in HITLy.
- HITLy POSTs JSON to
resumeUrl. Accept maps to Hermesonce; reject / timeout maps todeny. - Hermes still enforces
approvals.timeout(default 300 seconds). HITLy SLA can be longer; the command still denies when Hermes times out.
Kanban workers (autonomous profiles)
The gateway dispatcher spawns hermes -p <profile> for board tasks. Those workers exit when they need a human — they call kanban_block or kanban_request_review. That is the HITL path for unattended personas.
- The plugin POSTs a HITLy card (
kind: kanban) with aresumeUrlpointing to the local webhook. - Reviewer decides in HITLy.
- HITLy POSTs the decision JSON to
resumeUrl. - Gateway poller receives callback →
hermes kanban comment+unblock(accept) or comment only (reject).
HITLy never POSTs into hermes dashboard (localhost-only by default).
What HITLy cannot wait on
| Path | Hermes gate | HITLy |
|---|---|---|
| Cron jobs | approvals.cron_mode: deny or approve | No wait. Documented only. |
| Kanban shell commands | approvals.kanban_mode: deny or approve | Same. Workers should kanban_block instead. |
delegate_task | delegation.subagent_auto_approve (default deny) | Out of scope |
Setup
- Create a HITLy project with plugin Hermes and copy the project API key.
- Copy the plugin into Hermes:
cp -R examples/hermes ~/.hermes/plugins/hitly
hermes plugins enable hitly- Configure:
plugins:
enabled: [hitly]
entries:
hitly:
settings:
api_url: http://localhost:3001
api_key: hitly_...
project_id: prj_...
security:
approval:
transport: hitly
transport_fallback: denyKanban ingest works even if transport is unset. Command routing needs both the plugin and security.approval.transport: hitly.
HITLY_API_URL, HITLY_API_KEY, and HITLY_PROJECT_ID are env fallbacks for the same settings.
Resume callback requirements
The resumeUrl must be reachable from the HITLy process. Same-machine OSS deployments work fine (127.0.0.1). Cloud HITLy cannot reach a laptop localhost unless you use a tunnel (ngrok, Tailscale Funnel, etc.).
Decision mapping
| HITLy | Command transport | Kanban |
|---|---|---|
accept | Hermes once | comment + unblock |
respond | — | comment (body) + unblock |
reject | deny | comment, leave blocked |
| expire / cancel / timeout | deny | comment, leave blocked |