Skip to content

feat(hermes): declarative gateway deps via uv dependency group - #1660

Merged
shunkakinoki merged 2 commits into
mainfrom
feat/hermes-deps
May 5, 2026
Merged

feat(hermes): declarative gateway deps via uv dependency group#1660
shunkakinoki merged 2 commits into
mainfrom
feat/hermes-deps

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented May 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add hermes dependency group to pyproject.toml with python-telegram-bot[webhooks] and croniter
  • Update home-manager/services/hermes/activate.sh to install deps into hermes venv at activation time via uv pip install --group hermes
  • Renovate will track version updates for these deps

Test plan

  • uv pip install --group hermes installs correctly into hermes venv
  • make shell-test passes (1397 examples, 0 failures)
  • Verify hermes-gateway starts without "not installed" warnings after activation

Summary by cubic

Make Hermes gateway runtime deps declarative via a hermes uv group with auto-install on activation, and add a hermes-dashboard service. Prefer a dedicated HERMES_TELEGRAM_TOKEN; Renovate tracks versions to avoid missing-deps warnings.

  • New Features

    • Added hermes-dashboard systemd user service (port 9119, --insecure for k3s).
    • HERMES_TELEGRAM_TOKEN is now used for the Telegram bot, with fallback to TELEGRAM_TOKEN/secrets.
  • Dependencies

    • hermes group in pyproject.toml: python-telegram-bot[webhooks]>=22.6,<23, croniter>=6.0.0,<7, fastapi[standard]>=0.115.0, uvicorn>=0.30.0.
    • Activation installs the group into the Hermes venv using uv pip with the venv’s Python.

Written for commit 7a9f188. Summary will update on new commits.

Add hermes dependency group to pyproject.toml for Renovate tracking.
Install python-telegram-bot and croniter into hermes venv at activation.
@indent-zero

indent-zero Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor
PR Summary

Makes hermes gateway runtime extras (python-telegram-bot[webhooks], croniter) declarative for Renovate tracking and installs them into the hermes-agent virtualenv on every home-manager switch. This unblocks the gateway from needing manual uv pip install after a fresh setup, while keeping version pins in one place.

  • Adds a new [dependency-groups].hermes block to pyproject.toml containing python-telegram-bot[webhooks]>=22.6,<23 and croniter>=6.0.0,<7.
  • Extends home-manager/services/hermes/activate.sh with a guarded uv pip install --group hermes --project ~/dotfiles --python <hermes-agent venv> after the existing directory setup.
  • Updates the script header comment to reflect the new responsibility.

Issues

4 potential issues found:

  • 2>/dev/null || true swallows every failure mode (uv missing, network down, resolver conflicts, pyproject parse warnings), so a broken activation is indistinguishable from a successful one. Sibling installer home-manager/modules/uv-globals/install-uv-globals.sh instead guards on command -v uv/network and prints Failed to install ... — match that pattern so failures are visible in the activation log. → Autofix
  • home-manager/services/hermes/default.nix does not export ${pkgs.uv}/bin on PATH before invoking activate.sh, unlike uv-globals and cargo-globals. Today this works because pkgs.uv is in home-manager/packages/default.nix:94, but a future removal from home.packages (or a host that opts out) will silently turn the new install into a no-op — pin the path explicitly to match the established pattern. → Autofix
  • Next uv sync on hermes-agent reverts the install: the activation injects python-telegram-bot[webhooks] into the venv, but scripts/update-local-binaries.sh:223 runs a bare uv sync (no --extra messaging), which removes extraneous packages — verified empirically. The gateway will crash-loop until the next home-manager switch re-runs activation. → Autofix
  • croniter in the new hermes group is redundant — upstream NousResearch/hermes-agent already declares it as a core dependency (the upstream pyproject explicitly notes "croniter is now a core dependency"), so uv sync already installs it. Only python-telegram-bot[webhooks] actually needs the extra install path; keeping croniter here just adds version-drift maintenance. → Autofix

CI Checks

Waiting for CI checks...


⚡ Autofix All Issues

@mesa-dot-dev

mesa-dot-dev Bot commented May 4, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Hermes dashboard service now available on port 9119 with automatic startup and recovery capabilities.
  • Configuration & Setup

    • Enhanced token configuration with improved fallback support.
    • Automated runtime dependency installation and management.

Walkthrough

The PR extends the Hermes service infrastructure by adding a dashboard service, updating token resolution with environment variable fallback priority, defining service dependencies, and installing runtime packages during activation.

Changes

Hermes Service Infrastructure

Layer / File(s) Summary
Dependencies
pyproject.toml
New [dependency-groups].hermes defines runtime packages: python-telegram-bot[webhooks]>=22.6,<23, croniter>=6.0.0,<7, fastapi[standard]>=0.115.0, and uvicorn>=0.30.0.
Token Configuration
config/hermes/hydrate.sh
TELEGRAM_TOKEN resolution now chains fallbacks: HERMES_TELEGRAM_TOKEN → existing TELEGRAM_TOKEN → secrets directory telegram-token.
Runtime Installation
home-manager/services/hermes/activate.sh
On activation, conditionally runs uv pip install with the hermes dependency group into $HOME_DIR/.venv if the virtualenv exists; errors are suppressed.
Service Definitions
home-manager/services/hermes/default.nix
Adds hermes-dashboard systemd user service running hermes dashboard on 0.0.0.0:9119 with --insecure flag, always restart policy, and logging to /tmp/hermes/hermes-dashboard.log. Service is enabled and depends on default.target.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • shunkakinoki/dotfiles#1658: Both PRs modify the same Hermes integration files (config/hermes/hydrate.sh, home-manager/services/hermes/activate.sh, and default.nix), with this PR extending token fallback logic and adding a dashboard service on top of the gateway setup from that PR.

Poem

🐰 A dashboard blooms, where tokens flow free,
Dependencies nest in the dependency tree,
Fallbacks stack high, from env to the ground,
Hermes takes flight with a port-bound sound!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a declarative hermes dependency group via uv and installing it during activation.
Description check ✅ Passed The description is directly related to the changeset, detailing the new dependency group, activation script updates, dashboard service, and token handling changes.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/hermes-deps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@mesa-dot-dev

mesa-dot-dev Bot commented May 4, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Make Hermes gateway runtime deps declarative with a new hermes uv group and auto-install them into the Hermes venv during activation. Renovate now tracks these versions and activation avoids missing-deps warnings.

What changed?

  • home-manager/services/hermes/activate.sh: Updated to automatically install runtime dependencies using uv pip install --group hermes into the Hermes virtual environment during activation.
  • pyproject.toml: A new hermes dependency group has been added, including python-telegram-bot[webhooks] and croniter to support the Hermes gateway runtime.

Description generated by Mesa. Update settings

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces automated installation of Hermes gateway runtime dependencies via the activate.sh script and defines these dependencies in pyproject.toml. Feedback suggests replacing hardcoded paths with configurable environment variables and removing stderr redirection to improve debuggability during dependency installation.

chmod 700 "$HOME_DIR/.hermes"

# Install hermes gateway runtime deps from pyproject.toml dependency group
HERMES_VENV="$HOME_DIR/ghq/github.com/NousResearch/hermes-agent/.venv"

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.

medium

The path to the virtual environment is hardcoded to a specific ghq directory structure. This makes the script brittle if the repository is cloned elsewhere. Consider allowing this path to be overridden via an environment variable to improve portability.

Suggested change
HERMES_VENV="$HOME_DIR/ghq/github.com/NousResearch/hermes-agent/.venv"
HERMES_VENV="${HERMES_VENV_PATH:-$HOME_DIR/ghq/github.com/NousResearch/hermes-agent/.venv}"

Comment on lines +18 to +20
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "$HOME_DIR/dotfiles" 2>/dev/null || true

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.

medium

Silencing stderr with 2>/dev/null makes it difficult to diagnose failures during the dependency installation (e.g., if uv is missing, the network is down, or there are version conflicts). It is better to allow the error output to be visible, especially since the exit code is already safely ignored with || true. Additionally, the --project path is hardcoded to ~/dotfiles; using an environment variable would make this more flexible.

Suggested change
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "$HOME_DIR/dotfiles" 2>/dev/null || true
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "${DOTFILES_DIR:-$HOME_DIR/dotfiles}" || true

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="home-manager/services/hermes/activate.sh">

<violation number="1" location="home-manager/services/hermes/activate.sh:20">
P1: Do not silence and ignore `uv pip install` failures; this can leave Hermes missing runtime dependencies while activation appears successful.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

if [ -d "$HERMES_VENV" ]; then
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "$HOME_DIR/dotfiles" 2>/dev/null || true

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.

P1: Do not silence and ignore uv pip install failures; this can leave Hermes missing runtime dependencies while activation appears successful.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At home-manager/services/hermes/activate.sh, line 20:

<comment>Do not silence and ignore `uv pip install` failures; this can leave Hermes missing runtime dependencies while activation appears successful.</comment>

<file context>
@@ -11,3 +11,11 @@ mkdir -p "$HOME_DIR/.hermes/memories"
+if [ -d "$HERMES_VENV" ]; then
+  uv pip install --python "$HERMES_VENV/bin/python" \
+    --group hermes \
+    --project "$HOME_DIR/dotfiles" 2>/dev/null || true
+fi
</file context>
Suggested change
--project "$HOME_DIR/dotfiles" 2>/dev/null || true
--project "$HOME_DIR/dotfiles"

if [ -d "$HERMES_VENV" ]; then
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "$HOME_DIR/dotfiles" 2>/dev/null || true

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.

Next uv sync on hermes-agent will undo this install.

Upstream NousResearch/hermes-agent's pyproject.toml only declares python-telegram-bot[webhooks]>=22.6,<23 under the optional [messaging] (and [termux]) extras — croniter is already a core dep. Meanwhile scripts/update-local-binaries.sh:223 runs a bare uv sync against the hermes-agent repo, and uv sync removes packages that aren't in the project's pyproject by default (verified locally: a uv sync after uv pip install python-telegram-bot removed it: - python-telegram-bot==22.7, - httpx, - httpcore, ...).

So the runtime sequence becomes:

  1. ulb builds the venv → no python-telegram-bot (the messaging extra wasn't requested).
  2. home-manager switch → this script reinstalls python-telegram-bot.
  3. User runs ulb again for any reason → uv sync strips python-telegram-bot.
  4. systemd starts hermes-gateway → import fails, Restart=always + StartLimitBurst=10 kicks in until it stops.

Until the user remembers to re-run home-manager switch, the gateway is dead. Cleaner long-term fix: pass --extra messaging to the uv sync call inside scripts/update-local-binaries.sh for the hermes-agent build (and drop this whole install block + the hermes group from pyproject.toml). Alternative: add an ExecStartPre to home-manager/services/hermes/default.nix that re-runs this install before each gateway start.

if [ -d "$HERMES_VENV" ]; then
uv pip install --python "$HERMES_VENV/bin/python" \
--group hermes \
--project "$HOME_DIR/dotfiles" 2>/dev/null || true

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.

Silent failure hides every install error.

With 2>/dev/null || true, all of the following exit 0 with zero output:

  • uv not on PATH (verified: PATH=/usr/bin:/bin bash -c 'uv pip install ... 2>/dev/null || true' → exit 0, nothing printed even though uv: command not found fired on stderr).
  • Network unreachable.
  • Resolver/version conflicts (e.g. if hermes-agent later pins an incompatible version).
  • The existing exclude-newer = "1 week" parse warning that uv 0.8.x emits on this repo's pyproject.toml (visible in dry-run).

When hermes-gateway later crashes due to missing deps, there will be nothing in the home-manager activation log to point at the cause.

Compare to the codebase's own pattern in home-manager/modules/uv-globals/install-uv-globals.sh:24-27, 70:

if ! command -v uv &>/dev/null; then
  echo "uv not found, skipping uv globals install"
  exit 0
fi
...
uv tool install "$pkg" ... 2>/dev/null || echo "Failed to install $pkg, skipping..."

Suggested change here: drop the 2>/dev/null and replace || true with || echo "[hermes] failed to install runtime deps" >&2, plus an explicit command -v uv guard. That keeps the script non-fatal but lets the user see why nothing was installed.

Comment thread pyproject.toml
# Hermes gateway runtime deps - installed into hermes venv via uv pip install
hermes = [
"python-telegram-bot[webhooks]>=22.6,<23",
"croniter>=6.0.0,<7",

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.

croniter is already a core dep of hermes-agent.

Upstream NousResearch/hermes-agent's pyproject.toml lists croniter>=6.0.0,<7 as a core dependency (the project explicitly notes "croniter is now a core dependency; this extra kept for back-compat"). So uv sync against the hermes-agent repo will always install it — the line here just creates a second version pin that has to be kept in sync with upstream.

The only dep that genuinely benefits from this declarative install path is python-telegram-bot[webhooks], since it lives in upstream's optional [messaging] (and [termux]) extras and is therefore not installed by a bare uv sync.

Safe to drop just this line. Even better: switch the build to uv sync --extra messaging in scripts/update-local-binaries.sh and remove the whole hermes group + the install block in activate.sh (see the other comment).

Suggested change
"croniter>=6.0.0,<7",
hermes = [
"python-telegram-bot[webhooks]>=22.6,<23",
]

- Add hermes-dashboard systemd service (port 9119, --insecure for k3s)
- Use HERMES_TELEGRAM_TOKEN env var for dedicated bot
- Add fastapi/uvicorn to hermes dependency group
@shunkakinoki
shunkakinoki merged commit baadc86 into main May 5, 2026
30 of 32 checks passed
@shunkakinoki
shunkakinoki deleted the feat/hermes-deps branch May 5, 2026 00:39
@indent-zero indent-zero Bot mentioned this pull request May 5, 2026
1 task
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