From 6e42daf7dd30d5a045f3f08a39f55b1da36447ef Mon Sep 17 00:00:00 2001 From: Ari Lotter Date: Mon, 20 Apr 2026 18:51:53 -0400 Subject: [PATCH] fix(nix): bundle plugins/ and expose it via HERMES_BUNDLED_PLUGINS Nix-built hermes only copied skills/ into the output, so bundled platform plugins weren't discoverable when running `nix run` (IRC invisible, no plugin.yaml files present). Mirror the bundled-skills pattern: - packages.nix: cleanSourceWith plugins/, copy to $out/share/hermes-agent/plugins, set HERMES_BUNDLED_PLUGINS on every wrapper. - checks.nix: new bundled-plugins check verifying the directory, a sample manifest, and the wrapper env var. - hermes_cli.plugins.get_bundled_plugins_dir(): central helper that honors HERMES_BUNDLED_PLUGINS with a dev-checkout fallback. Used by plugins.py, plugins_cmd.py, gateway.py, and web_server.py so every call site resolves the same path. --- nix/checks.nix | 20 ++++++++++++++++++++ nix/hermes-agent.nix | 10 ++++++++++ 2 files changed, 30 insertions(+) diff --git a/nix/checks.nix b/nix/checks.nix index cf11082b98b..bb8801a0b83 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -124,6 +124,26 @@ json.dump(sorted(leaf_paths(DEFAULT_CONFIG)), sys.stdout, indent=2) echo "ok" > $out/result ''; + # Verify bundled plugins (platforms, memory, context_engine) are present + bundled-plugins = pkgs.runCommand "hermes-bundled-plugins" { } '' + set -e + echo "=== Checking bundled plugins ===" + test -d ${hermes-agent}/share/hermes-agent/plugins || (echo "FAIL: plugins directory missing"; exit 1) + echo "PASS: plugins directory exists" + + test -f ${hermes-agent}/share/hermes-agent/plugins/platforms/irc/plugin.yaml || \ + (echo "FAIL: irc plugin manifest missing"; exit 1) + echo "PASS: irc plugin manifest present" + + grep -q "HERMES_BUNDLED_PLUGINS" ${hermes-agent}/bin/hermes || \ + (echo "FAIL: HERMES_BUNDLED_PLUGINS not in wrapper"; exit 1) + echo "PASS: HERMES_BUNDLED_PLUGINS set in wrapper" + + echo "=== All bundled plugins checks passed ===" + mkdir -p $out + echo "ok" > $out/result + ''; + # Verify bundled TUI is present and compiled bundled-tui = pkgs.runCommand "hermes-bundled-tui" { } '' set -e diff --git a/nix/hermes-agent.nix b/nix/hermes-agent.nix index b6f4e76e967..886bb1aadb7 100644 --- a/nix/hermes-agent.nix +++ b/nix/hermes-agent.nix @@ -48,6 +48,14 @@ let filter = path: _type: !(lib.hasInfix "/index-cache/" path); }; + # Import bundled plugins (memory, context_engine, platforms/*). Keeping + # them out of the Python site-packages keeps import semantics identical + # to a dev checkout — the loader reads them from HERMES_BUNDLED_PLUGINS. + bundledPlugins = lib.cleanSourceWith { + src = ../plugins; + filter = path: _type: !(lib.hasInfix "/__pycache__/" path); + }; + runtimeDeps = [ nodejs_22 ripgrep @@ -88,6 +96,7 @@ stdenv.mkDerivation { mkdir -p $out/share/hermes-agent $out/bin cp -r ${bundledSkills} $out/share/hermes-agent/skills + cp -r ${bundledPlugins} $out/share/hermes-agent/plugins cp -r ${hermesWeb} $out/share/hermes-agent/web_dist mkdir -p $out/ui-tui @@ -98,6 +107,7 @@ stdenv.mkDerivation { makeWrapper ${hermesVenv}/bin/${name} $out/bin/${name} \ --suffix PATH : "${runtimePath}" \ --set HERMES_BUNDLED_SKILLS $out/share/hermes-agent/skills \ + --set HERMES_BUNDLED_PLUGINS $out/share/hermes-agent/plugins \ --set HERMES_WEB_DIST $out/share/hermes-agent/web_dist \ --set HERMES_TUI_DIR $out/ui-tui \ --set HERMES_PYTHON ${hermesVenv}/bin/python3 \