Repository navigation
feat(agents): add a Hermes Agent agent - #384
Merged
Merged
Conversation
Adds agents/hermes/, Nous Research's Hermes Agent behind the A2A agent framework: each turn is one in-process `hermes agentenv turn` (a subcommand of the agent's own Hermes plugin) in the context's own Hermes profile, its plugin hook events streamed as the trajectory. Registers the image, its alias, a smoke task, and the release/dependabot entries.
…efore letting go, and hold attachments to the turn limit - A snapshot load stages the archived profile beside the context's, then swaps the workspace and the profile in one thread, with the profile swap inside the workspace's, and binds the session, in one step a cancel can't abandon. A failed swap leaves the previous profile, session and workspace. - Thread work a cancel would have left running (the snapshot archives, tar, the profile write before a turn) now runs to its end before the caller lets go of the workspace or the context's lock. A PDF render is an async pdftoppm, killed and reaped on timeout or cancel, and http(s) attachments stream to disk with an async client. - A task's attachments are downloaded and rendered inside the turn's slot, so HERMES_MAX_CONCURRENT_TURNS bounds them too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
|
Thanks for the Hermes agent. I pushed review fixes to the branch (maintainer edits):
Verified on an Ubuntu 24.04 VM, against Scale's LiteLLM proxy:
CodeBuild needs a maintainer approval to start on this fork PR. 🤖 Generated with Claude Code |
… its own Two PDFs whose names share a stem (report.pdf and report, or report.PDF on a case-sensitive filesystem) rendered their pages under one prefix, so the second overwrote the first's and listed its leftovers. Each PDF's pages now go in a folder of their own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A page folder named after the PDF passed the filesystem's 255-byte limit for a name near it, and the OSError failed the task. The folder now takes a fixed prefix; its random suffix keeps two PDFs apart. Co-Authored-By: Claude Opus 5.5 <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.
What and why
Adds
agents/hermes/, an agent for Nous Research's Hermes Agent, built the same way as the other agents in the bundle. Tasks can name it ashermes(alias inaliases.toml) or as@local/agentenv-framework/agents/hermes.hermes agentenv turn, a subcommand that the agent's own Hermes plugin (agentenv_plugin/) adds. It runs the turn in that process, the wayhermes -zdoes, instead of handing it to a Hermes gateway. So the turn ends when that process ends, and a timeout or cancel kills the process and every tool it started.on_session_start,pre_tool_call,post_tool_call,post_api_request,api_request_error,post_llm_call,on_session_end). It writes each event as a JSON line to a pipe the bridge reads while the turn runs (trajectory/v1, live, formathermes-hook-events/1)./data/.hermes/profiles/ctx-<hash>), with its own config, sessions database and memory. A context's first turn starts a Hermes session, and later turns resume it with--resume.$LITELLM_BASE_URL/v1is configured as a named OpenAI-compatible custom provider, keyed fromLITELLM_API_KEY.[model.headers]and the run'sproject_id/task_idattribution go out asextra_headerson every model call, Hermes' auxiliary calls (titles, vision, compression) included. Tag joining matches the OpenCode agent.system_promptis written as the profile'sSOUL.md, the slot Hermes' own identity normally fills. Hermes then sends it as the system prompt.peer_agentsincluded, goes into the profile'smcp_servers, with theAgentEnv-Roleoverride. Installed skills go into one shared folder that every profile reads throughskills.external_dirs.python:3.11-slimwith Hermes installed by its own installer, pinned to thev0.22.5release commit. The installer script itself is checked against a SHA-256. Hermes' runtime (its own Python, Node and ripgrep) lives under/data/.hermes, separate from the A2A server's Python. Image size is about 2.9 GB.infra_build.py(image and smoke command),dependabot.yml, the aliases test, the infra-images test, the agents README and CONTRIBUTING. Adds ahermes-smoketask.The agent's
README.mdhas the Extension | Implementation table.agent-config,mcp-config,skill-config(inline and bundle),trajectory,snapshot(save/load),peer-agentsandattribution-probeare implemented;staging/v1is the SDK default. Not included in this PR:install/v1and the snapshot changelog. Both can follow if you want them.Verification
Run locally against the local backends, with the
[model]endpoint pointed at an OpenAI-compatible proxy andanthropic/claude-haiku-5.5as the model:agent-env run agents --task hermes-smoke: passed (deploy 3.8 s, prompt 12.2 s).agent-env a2a-agent put --id hermes-dev --dockerfile .../hermes/Dockerfile(full validator run against themailenv): every advertised check passed. That covers agent card,message/send/tasks/get, identity round trip, role, system prompt, MCP (search_emailsvia the gateway), trajectory, skill-config (skill_mdandskill_bundle), peer-agents (peer call returned the token), snapshot save + load with recall after load, andtool_call_count. It also covers every modality probe: text, png/jpeg/gif, png by https URI, pdf, and also the audio and video probes, which Hermes handled with its own tools. The card declares only text, images and PDF. The onlyfalserows are the two features this PR does not advertise: changelog and install/v1.tst/unit/agents/hermes/: 21 tests. Card contract, message contract (concurrency across contexts, one turn at a time within a context, session binding on cancel, config/MCP/file parts, snapshot round trip), and bridge tests that drive a scriptedhermesin a real subprocess: profile config, events read live, failure mapping,output_format, no fd leak. Timeout and cancel both kill Hermes and the tool it started. That last test was confirmed to fail with the process-tree kill swapped for a plainproc.kill().make lintis clean; the rest of the unit suite is left to CI.A Hermes turn peaked near 210 MB in the image (cgroup
memory.peak, running shell and Python tools). The concurrency cap budgets 400 MB per turn past 1 GB, overridable withHERMES_MAX_CONCURRENT_TURNS.

Confidence Score: 5/5
The changes since the previous review appear safe to merge.Summary
Adds Hermes Agent with per-context sessions, live events, attachments, skills and snapshots.
Reviews (4) · Last reviewed commit: "fix(agents): give Hermes PDF page folder..." · Reviewed by Greptile