Skip to content

Correctly install Hermes Agent dependencies#2834

Closed
benbarclay wants to merge 1 commit into
NVIDIA:mainfrom
NousResearch:hermes_agent_dependencies_uv_npm
Closed

Correctly install Hermes Agent dependencies#2834
benbarclay wants to merge 1 commit into
NVIDIA:mainfrom
NousResearch:hermes_agent_dependencies_uv_npm

Conversation

@benbarclay

@benbarclay benbarclay commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

This change introduces UV to sync the .[all] target for all python dependencies. This was introduced due to missing dependencies such as discord.py in the logs.

Additionally runs npm install to get the JS dependencies for the TUI and web dashboards.

Technically the UV part of this change is optional, though it's easier than handling the virtualenv, etc manually in the container. I can remove that part if desired.

Changes

  • Adds UV for python dependencies
  • Uses UV to install Hermes Agent python dependencies in a virtualenv
  • Does an npm install

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Ben Barclay ben@nousresearch.com

Summary by CodeRabbit

  • Chores
    • Improved Hermes Agent build and deployment process with enhanced dependency management and isolation for better build reliability.

This change introduces UV to sync the .[all] target for all python dependencies. This was introduced due to missing dependencies such as `discord.py` in the logs.

Additionally runs npm install to get the JS dependencies for the TUI and web dashboards.
@copy-pr-bot

copy-pr-bot Bot commented May 1, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The Hermes Agent Docker build process transitions from a direct pip installation with pinned dependencies to a structured multi-step approach: installing the uv package manager, extracting source to /opt/hermes, creating a Python virtual environment, installing in editable mode with extras, running npm install for Node dependencies, and verifying the installation.

Changes

Cohort / File(s) Summary
Docker Build Configuration
agents/hermes/Dockerfile.base
Installation process refactored from direct GitHub archive pip install to multi-stage setup using uv package manager, virtual environment, editable mode installation with .[all] extras, npm dependency installation, and updated container PATH.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A Docker dream, now built with care,
With uv swift and venv fair,
Editable modes and extras bright,
npm bundled, everything tight,
Hermes springs forth, version verified right! 🚀

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: improving the Hermes Agent dependency installation process by switching from direct pip install to a multi-step setup using uv and npm.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
agents/hermes/Dockerfile.base (2)

99-104: Recommend running Hermes E2E workflows for this dependency-bootstrap change.

Given this modifies Hermes install/bootstrap behavior, run hermes-e2e and rebuild-hermes-e2e before merge to cover onboarding, health probes, and live inference.

As per coding guidelines, agents/hermes/** recommends: hermes-e2e and rebuild-hermes-e2e.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agents/hermes/Dockerfile.base` around lines 99 - 104, This change alters
Hermes bootstrap (see Dockerfile.base RUN uv venv and uv pip install -e
".[all]") so before merging run the Hermes E2E suites: execute hermes-e2e and
rebuild-hermes-e2e to validate onboarding, health probes, and live inference; if
failures occur, iterate on the Dockerfile.base install steps (uv venv/uv pip
install) until both e2e commands pass and then re-run hermes --version
verification in the image build.

99-101: Use npm ci instead of npm install for deterministic installs.

Lines 99-101 use npm install, which can resolve different transitive versions over time. The upstream Hermes tarball contains package-lock.json files, making npm ci the appropriate choice for reproducible builds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agents/hermes/Dockerfile.base` around lines 99 - 101, Replace the failing
non-deterministic install step in the Dockerfile RUN line: locate the RUN line
that contains "uv venv && uv pip install --no-cache-dir -e \".[all]\" && npm
install --prefer-offline --no-audit" and change the npm invocation to "npm ci"
(preserving any compatible flags or removing flags that npm ci doesn't accept)
so the build uses the lockfile for deterministic installs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@agents/hermes/Dockerfile.base`:
- Line 97: The Dockerfile currently downloads the Hermes tarball with
HERMES_VERSION without verifying integrity; update the RUN that creates
/opt/hermes to also fetch a checksum (or .sha256/.asc) for the same release,
verify it before extraction (e.g., curl -fL
.../hermes-agent-${HERMES_VERSION}.tar.gz -o /tmp/hermes.tar.gz and curl -fL
.../hermes-agent-${HERMES_VERSION}.tar.gz.sha256 -o /tmp/hermes.sha256 && echo
"<expected-format>" | sha256sum -c /tmp/hermes.sha256 or run sha256sum
/tmp/hermes.tar.gz && compare), fail the build on mismatch, and only then tar
-xz -C /opt/hermes --strip-components=1; reference the existing RUN that uses
HERMES_VERSION and the target directory /opt/hermes to locate where to add
checksum download and sha256 verification steps.
- Line 96: Replace the unpinned pip install of "uv" with a pinned version by
introducing an ARG named UV_VERSION (mirroring the existing HERMES_VERSION ARG
pattern) and update the RUN pip3 install invocation to install "uv" using that
UV_VERSION (i.e., pip3 install --no-cache-dir --break-system-packages
uv==${UV_VERSION}) so the base image build becomes deterministic; modify the
existing RUN pip3 install line and add the new ARG UV_VERSION above it.

---

Nitpick comments:
In `@agents/hermes/Dockerfile.base`:
- Around line 99-104: This change alters Hermes bootstrap (see Dockerfile.base
RUN uv venv and uv pip install -e ".[all]") so before merging run the Hermes E2E
suites: execute hermes-e2e and rebuild-hermes-e2e to validate onboarding, health
probes, and live inference; if failures occur, iterate on the Dockerfile.base
install steps (uv venv/uv pip install) until both e2e commands pass and then
re-run hermes --version verification in the image build.
- Around line 99-101: Replace the failing non-deterministic install step in the
Dockerfile RUN line: locate the RUN line that contains "uv venv && uv pip
install --no-cache-dir -e \".[all]\" && npm install --prefer-offline --no-audit"
and change the npm invocation to "npm ci" (preserving any compatible flags or
removing flags that npm ci doesn't accept) so the build uses the lockfile for
deterministic installs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 853200f4-7f32-4b67-b466-f66e01139a52

📥 Commits

Reviewing files that changed from the base of the PR and between f9d21af and 2a1a9d7.

📒 Files selected for processing (1)
  • agents/hermes/Dockerfile.base

"pyyaml==6.0.3" \
"python-telegram-bot>=21.0" \
&& hermes --version
RUN pip3 install --no-cache-dir --break-system-packages uv

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether uv is pinned in this Dockerfile
rg -n 'pip3 install.*\buv\b' agents/hermes/Dockerfile.base
rg -n 'ARG UV_VERSION|uv==|uv~=' agents/hermes/Dockerfile.base

Repository: NVIDIA/NemoClaw

Length of output: 121


🏁 Script executed:

#!/bin/bash
# Check overall versioning pattern in Dockerfile.base
head -n 120 agents/hermes/Dockerfile.base | grep -E 'pip3 install|apt-get install|RUN|FROM'

Repository: NVIDIA/NemoClaw

Length of output: 729


🏁 Script executed:

#!/bin/bash
# Check for ARG declarations and understand versioning strategy
head -n 30 agents/hermes/Dockerfile.base | grep -E 'ARG|FROM'
rg -n 'ARG HERMES_VERSION|ARG UV_VERSION' agents/hermes/Dockerfile.base

Repository: NVIDIA/NemoClaw

Length of output: 212


Pin uv to a fixed version to match the file's versioning strategy.

Line 96 installs uv unpinned, creating non-deterministic base-image rebuilds. The file already pins HERMES_VERSION via ARG and the base image by digest; uv should follow the same pattern.

Suggested fix:

ARG UV_VERSION=0.x.y
RUN pip3 install --no-cache-dir --break-system-packages uv==${UV_VERSION}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agents/hermes/Dockerfile.base` at line 96, Replace the unpinned pip install
of "uv" with a pinned version by introducing an ARG named UV_VERSION (mirroring
the existing HERMES_VERSION ARG pattern) and update the RUN pip3 install
invocation to install "uv" using that UV_VERSION (i.e., pip3 install
--no-cache-dir --break-system-packages uv==${UV_VERSION}) so the base image
build becomes deterministic; modify the existing RUN pip3 install line and add
the new ARG UV_VERSION above it.

"python-telegram-bot>=21.0" \
&& hermes --version
RUN pip3 install --no-cache-dir --break-system-packages uv
RUN mkdir /opt/hermes && curl -L https://github.com/NousResearch/hermes-agent/archive/refs/tags/${HERMES_VERSION}.tar.gz | tar -xz -C /opt/hermes --strip-components=1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether checksum validation exists for Hermes tarball download
rg -n 'hermes-agent/archive/refs/tags/\$\{HERMES_VERSION\}\.tar\.gz' agents/hermes/Dockerfile.base
rg -n 'HERMES_TARBALL_SHA256|sha256sum -c|gpg' agents/hermes/Dockerfile.base

Repository: NVIDIA/NemoClaw

Length of output: 301


Add integrity verification for the downloaded Hermes tarball.

Line 97 fetches the Hermes agent source from GitHub without verifying checksums or signatures. This weakens supply-chain security guarantees for a production base image. The same Dockerfile already validates checksums for other downloads (gosu on line 51), establishing a consistent security pattern that should apply here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agents/hermes/Dockerfile.base` at line 97, The Dockerfile currently downloads
the Hermes tarball with HERMES_VERSION without verifying integrity; update the
RUN that creates /opt/hermes to also fetch a checksum (or .sha256/.asc) for the
same release, verify it before extraction (e.g., curl -fL
.../hermes-agent-${HERMES_VERSION}.tar.gz -o /tmp/hermes.tar.gz and curl -fL
.../hermes-agent-${HERMES_VERSION}.tar.gz.sha256 -o /tmp/hermes.sha256 && echo
"<expected-format>" | sha256sum -c /tmp/hermes.sha256 or run sha256sum
/tmp/hermes.tar.gz && compare), fail the build on mismatch, and only then tar
-xz -C /opt/hermes --strip-components=1; reference the existing RUN that uses
HERMES_VERSION and the target directory /opt/hermes to locate where to add
checksum download and sha256 verification steps.

@ericksoa ericksoa self-assigned this May 1, 2026
@ericksoa ericksoa added integration: hermes Hermes integration behavior v0.0.33 labels May 1, 2026
@wscurran wscurran added dependencies Pull requests that update a dependency file and removed v0.0.33 labels May 1, 2026
@wscurran

wscurran commented May 1, 2026

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR that proposes a way to correctly install Hermes Agent dependencies by introducing UV to sync python dependencies and running npm install.

cv pushed a commit that referenced this pull request May 1, 2026
…2846)

This is a maintainer experiment that builds on Ben Barclay's PR #2834.
Ben identified the right install gap: the Hermes image needs the
dependencies required for supported runtime integrations, otherwise
users hit missing-package failures after onboarding.

This branch keeps that direction while narrowing the dependency surface
for NemoClaw:

- targets the selected Hermes release `v2026.4.23` / `0.11.0`
- verifies the GitHub release tarball by SHA256 before extraction
- installs Hermes with `uv sync --frozen --no-dev --extra messaging
--extra web` by default instead of `[all]`
- preserves the `/usr/local/bin/hermes` final-image contract used by
policy and e2e checks
- grants the Hermes gateway group write access to runtime state
directories while keeping config files non-group-writable
- opens `/tmp/gateway.log` from inside the `gateway` user context so
capability-dropping does not block startup
- updates the Hermes manifest expected version to `2026.4.23`
- leaves OpenClaw dependency handling unchanged

The intent is to prebake the Hermes dependencies that map to
NemoClaw-supported onboarding integrations today: Telegram, Discord,
Slack, and the API/health runtime. Larger or unsupported integrations
should stay out of the base image and be installed by the agent workflow
when enabled.

Local validation completed:

- `docker build --progress=plain -f agents/hermes/Dockerfile.base -t
nemoclaw-hermes-base-experiment .`
- `docker build --progress=plain -f agents/hermes/Dockerfile.base
--build-arg HERMES_VERSION=v2026.4.13 --build-arg
HERMES_TARBALL_SHA256=5e4529b8cb6e4821eb916b81517e48125109b1764d6d1e68a204a9f0ddf2d98c
--build-arg HERMES_UV_EXTRAS=messaging -t
nemoclaw-hermes-old-base-e2e-rebuild-test .`
- `docker build --progress=plain -f agents/hermes/Dockerfile --build-arg
BASE_IMAGE=nemoclaw-hermes-base-experiment -t
nemoclaw-hermes-final-experiment .`
- final image resolves `hermes` to `/usr/local/bin/hermes` and reports
`Hermes Agent v0.11.0 (2026.4.23)`
- imports present: `telegram`, `discord`, `slack_bolt`, `fastapi`,
`uvicorn`
- imports absent: `faster_whisper`, `mautrix`, `boto3`,
`dingtalk_stream`, `lark_oapi`
- entrypoint gateway health check returns
`{"status":"ok","platform":"hermes-agent"}` through port `8642`
- `npm test -- test/sandbox-provisioning.test.ts
src/lib/agent-defs.test.ts src/lib/sandbox-version.test.ts`
- `npm run validate:configs`
- `npm run typecheck:cli`
- `npx prek run --all-files --stage pre-push`

Focused e2e passed on this branch:
https://github.com/NVIDIA/NemoClaw/actions/runs/25222726016

Earlier focused e2e on this experiment found four useful issues that
this branch now addresses: first the image contract expected
`/usr/local/bin/hermes`, then the gateway needed writable Hermes runtime
state under `/sandbox/.hermes`, then the entrypoint opened
`/tmp/gateway.log` before switching to the `gateway` user. The rebuild
e2e also needed its old-version fixture pinned to the matching tarball
checksum and extras profile. The final OpenShell-specific blocker was
that the Hermes executable is a symlink into /opt/hermes, so the Hermes
policy now grants read-only access to that venv path.

Related context:

- Contributor PR: #2834
- Hermes version selection context: #2745

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Enhanced startup logging with improved diagnostics for troubleshooting
sandbox initialization issues
* Added runtime diagnostics to capture system state and logs when errors
occur

* **Chores**
  * Updated Hermes agent to v2026.4.23
* Improved build pipeline with better dependency verification and
deterministic installation
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ben Barclay <ben@nousresearch.com>
@ericksoa

ericksoa commented May 2, 2026

Copy link
Copy Markdown
Contributor

Thanks to Ben Barclay and the NousResearch team for identifying the Hermes dependency-bootstrap gap and proposing the original fix here. I opened a maintainer follow-up in #2872 that carries that work into the current NemoClaw base-image flow, with credit in the PR description and commit metadata.

cv pushed a commit that referenced this pull request May 4, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Follows up on NousResearch's dependency-bootstrap proposal in #2834 and
the maintainer-side #2846 by carrying the remaining root Node dependency
install into the Hermes base image. The existing `uv sync` step covers
the supported Python integration extras; this adds deterministic `npm
ci` from the Hermes root lockfile so browser tooling such as
`agent-browser` is available in the extracted Hermes tree.

## Credit
Thanks to Ben Barclay and the NousResearch team for the original PR
#2834. They identified the Hermes dependency-bootstrap gap and proposed
the direction this follow-up carries into the current NemoClaw
base-image flow.

## Related Issue
Follow-up to #2834 and #2846.

## Changes
- Install Hermes root Node dependencies with `npm ci --prefer-offline
--no-audit --no-fund` after the existing `uv sync` step.
- Remove transient `/tmp/camoufox-*` installer downloads in the same
Docker layer so large temporary archives do not persist into the image.
- Document why the root Node install belongs in the Hermes base image.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [ ] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Additional validation:
- `git diff --check`
- `docker build --progress=plain --output=type=cacheonly -f
agents/hermes/Dockerfile.base .`
  - validated the `uv sync` step
  - validated the new `npm ci` step
- validated `/usr/local/bin/hermes --version` reports `Hermes Agent
v0.11.0 (2026.4.23)`

---
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Optimized the container image build by removing temporary build
artifacts to reduce clutter and image size.
* Made tooling dependencies for browser-related features explicit so
tooling is reliably present during build.
* Ensured Node package installation runs deterministically during image
creation to improve build stability and reproducibility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Co-authored-by: Ben Barclay <ben@nousresearch.com>
@wscurran

wscurran commented May 8, 2026

Copy link
Copy Markdown
Contributor

Closing as superseded by #2872. That follow-up carried the Hermes dependency-bootstrap work into the current base-image flow, credited @benbarclay and the NousResearch team for the original direction, and merged on 2026-05-04. Thanks again for identifying the dependency gap here.

@wscurran wscurran closed this May 8, 2026
@wscurran wscurran added the chore Build, CI, dependency, or tooling maintenance label Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Build, CI, dependency, or tooling maintenance dependencies Pull requests that update a dependency file integration: hermes Hermes integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants