Skip to content

feat(dispatch): gateway-free Hermes CLI dispatch provider#737

Open
b-yelverton wants to merge 2 commits into
builderz-labs:mainfrom
b-yelverton:feat/hermes-dispatch-provider
Open

feat(dispatch): gateway-free Hermes CLI dispatch provider#737
b-yelverton wants to merge 2 commits into
builderz-labs:mainfrom
b-yelverton:feat/hermes-dispatch-provider

Conversation

@b-yelverton

Copy link
Copy Markdown

Summary

Mission Control already surfaces Hermes observability (sessions, cron, memory, transcripts under ~/.hermes), but there is currently no way to dispatch a task to a Hermes agent — the direct-dispatch providers are Anthropic / OpenAI / local only. This PR completes that loop.

An agent whose config.dispatchModel is hermes/<profile> is dispatched by running the Hermes CLI one-shot as that profile:

hermes -p <profile> -z "<prompt>"

Because a Hermes profile already carries its own model, provider, tools, and SOUL, the task runs as that agent — no model/soul override is injected, no API key is needed, and no gateway is required. It slots into the existing callDirectly provider routing, mirroring the adjacent callClaudeViaCli path.

What changed

  • pickProvider recognizes the hermes/ prefix (new 'hermes' DirectProvider)
  • callHermesViaCli — spawns the CLI shell-free (argv array); profile is validated against Hermes' own ^[a-z0-9][a-z0-9_-]{0,63}$ rule before it can reach argv or the filesystem profile lookup
  • routed on the raw dispatchModel in callDirectly (since classifyDirectModel strips the prefix), leaving the anthropic/openai/local paths untouched
  • isDirectDispatchAvailable treats an installed hermes binary as a valid gateway-free backend
  • binary resolved via HERMES_BIN / $HOME/.local/bin / /usr/local/bin / the agent venv

Hardening (vs the path it mirrors)

  • captured stdout/stderr bounded at 5 MB, child aborted on overflow
  • SIGTERMSIGKILL escalation after a 5s grace on timeout/abort
  • single-settle guard so overlapping timeout/overflow/close can't double-resolve
  • refuses to dispatch an empty prompt

Test Plan

Verified end-to-end on a live deployment (Hermes 0.16.0):

  • Task created in MC, assigned to a hermes/<profile> agent, dispatched via the new path — log shows Dispatching task via Hermes CLITask dispatched and completed; task reached quality_review with the agent's real output, dispatch_attempts=0
  • Aegis review of the result also dispatched through the same path
  • pnpm typecheck clean
  • Re-verified after the hardening commit

Caveats (for maintainer judgement)

  • One-shot only (hermes -z) — no live streaming or session continuity, unlike a gateway-backed path. Fits queue/batch dispatch, not interactive sessions.
  • Audience is Hermes users specifically; no effect on deployments without Hermes installed (the provider is only selected by an explicit hermes/ dispatchModel).

🤖 Generated with Claude Code

b-yelverton and others added 2 commits June 10, 2026 04:10
Routes agents whose dispatchModel is `hermes/<profile>` to the local
`hermes -p <profile> -z <prompt>` one-shot, so a task runs as that real
Hermes agent (its own model/provider/soul) with no API key or gateway.

- pickProvider recognizes the `hermes/` prefix
- callHermesViaCli spawns without a shell; profile validated against
  Hermes' own [a-z0-9][a-z0-9_-]{0,63} rule before reaching argv
- routed on the RAW dispatchModel in callDirectly (classifyDirectModel
  strips the prefix), leaving anthropic/openai/local paths untouched
- isDirectDispatchAvailable treats an installed hermes binary as a
  valid gateway-free backend

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ompt

Defense-in-depth on the hermes dispatch path before upstreaming:
- cap captured stdout/stderr at 5MB and abort if a child floods it
- escalate SIGTERM -> SIGKILL after a 5s grace on timeout/abort
- guard a single-settle so overlapping timeout/overflow/close can't
  double-resolve the promise
- refuse to dispatch an empty prompt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@b-yelverton b-yelverton requested a review from 0xNyk as a code owner June 10, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant