Merged
Conversation
Adds Nous Research's Hermes Agent as a fourth built-in agent alongside claude-code, codex, and opencode. Hermes is a provider-agnostic Python CLI that dispatches to Anthropic/OpenAI/OpenRouter/Gemini/etc; it ships no weights and needs no GPU. Changes: - images/hermes/Dockerfile pins HERMES_VERSION=v2026.4.16, installs the minimal [mcp,acp] extras into an isolated venv on top of the base image (ffmpeg is the only extra apk dep). - pkg/domain/agent adds MCPConfigFormatHermes. - internal/infra/vm/mcpconfig emits ~/.hermes/config.yaml with a sandbox-tools entry under mcp_servers, merging with any pre-existing YAML so user MCP servers survive. Introduces a mergeYAMLMapEntries helper parallel to the JSON/TOML ones. - internal/infra/agent/registry registers the hermes agent with an anthropic/openai/openrouter/gemini locked egress profile. Messaging gateway hosts (Telegram / Discord / Slack / WhatsApp / Matrix) are deliberately excluded — enabling those extras is a future opt-in. - Taskfile and docker-bake wire image-hermes into image-all / image-push and the default bake group so CI and release build it.
- Drop ffmpeg: only used by voice/TTS extras that are not installed. Saves ~80 MB from every VM boot for a disabled feature. - Collapse clone + venv + install + link into one RUN, and rm the source tree after pip install (installed code lives in site-packages, the clone is dead weight). Saves ~15 MB and one layer. - Drop pip install --upgrade pip; Wolfi's pip is recent enough. - Drop the hermes-agent symlink so an upstream [project.scripts] rename can't break the build. The primary hermes CLI is sufficient; the direct agent loop is still reachable via venv/bin/hermes-agent. - Add OCI image labels (source, description, license) for GHCR provenance.
Cross-referenced the Hermes integration against the upstream NousResearch/hermes-agent repo and fixed four drifts: - Locked egress now covers Nous Portal (*.nousresearch.com) and the HuggingFace router (HF_TOKEN was forwarded without a matching host allowance, so locked-profile users would silently fail). - Settings manifest injects ~/.hermes/SOUL.md instead of AGENTS.md. Upstream loads AGENTS.md from the project CWD, not HERMES_HOME; SOUL.md is the real HERMES_HOME identity file. - injectHermesMCP no longer writes a transport: http key. Upstream selects transport by presence of url vs command; the extra key is unread today and could collide with future upstream schema. - Test flipped to assert transport is absent, guarding regression. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Found during a sanity-check run: `bbox list` showed hermes, but the root command's long-help "Supported agents" line was stale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Nous Research's Hermes Agent as a fourth built-in agent alongside
claude-code,codex, andopencode. Hermes is a provider-agnostic Python CLI that dispatches to Anthropic/OpenAI/OpenRouter/Gemini/etc. — it ships no weights and needs no GPU, so it slots cleanly into the existing agent contract.images/hermes/Dockerfile) — pinsHERMES_VERSION=v2026.4.16, installs the minimal[mcp,acp]extras into an isolated venv on top of the shared base image. Only extra apk dep isffmpeg. Heavy optional extras (messaging,slack,matrix,voice,rl,bedrock, …) are intentionally deferred — they can be layered on later.pkg/domain/agent,internal/infra/vm/mcpconfig.go) — newMCPConfigFormatHermes+injectHermesMCPthat writes~/.hermes/config.yamland deep-merges asandbox-toolsentry undermcp_servers, preserving any pre-existing YAML. AmergeYAMLMapEntrieshelper parallels the existing JSON/TOML helpers.internal/infra/agent/registry.go) —hermesentry with locked egress forapi.anthropic.com/api.openai.com/openrouter.ai/generativelanguage.googleapis.com. Env-forwardsANTHROPIC_API_KEY,OPENAI_API_KEY,OPENROUTER_API_KEY,GEMINI_API_KEY,GOOGLE_API_KEY,HF_TOKEN,HERMES_*. Credentials persist via~/.hermes/.image-hermesTaskfile target wired intoimage-all/image-push;docker-bake.hclhermestarget added to the default group so CI and release pick it up.Explicitly out of scope (for follow-up)
~/.hermes/config.yamlis not injected via the settings manifest — the settings injector has no YAML format yet, and that file can contain host-side MCP endpoints that must not leak into the guest.hermes setupruns inside the VM on first launch.Test plan
task fmt && task lint— 0 issuestask test— all tests pass, including the newTestInjectHermesMCP*cases and the expanded registry teststask image-base && task image-hermes— verify image builds on a Linux hostbbox hermes --helpinside a freshly-built VMbbox hermes -q "hello"with a real provider key~/.hermes/config.yamlin the guest to confirm thesandbox-toolsMCP entry is present and points at the vmcp proxy🤖 Generated with Claude Code