diff --git a/nix/checks.nix b/nix/checks.nix index 92da740b5a..3c9aa3af25 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -195,7 +195,7 @@ json.dump(sorted(leaf_paths(DEFAULT_CONFIG)), sys.stdout, indent=2) # Verify extraPythonPackages PYTHONPATH injection extra-python-packages = let - testPkg = pkgs.python312Packages.pyyaml; + testPkg = pkgs.python312Packages.pyfiglet; hermesWithExtra = pkgs.callPackage ./hermes-agent.nix { inherit (inputs) uv2nix pyproject-nix pyproject-build-systems; npm-lockfile-fix = inputs'.npm-lockfile-fix.packages.default; diff --git a/nix/nixosModules.nix b/nix/nixosModules.nix index 219090c30d..9e55a0f511 100644 --- a/nix/nixosModules.nix +++ b/nix/nixosModules.nix @@ -28,6 +28,8 @@ let cfg = config.services.hermes-agent; + effectivePackage = if cfg.extraPythonPackages == [ ] then cfg.package + else cfg.package.override { inherit (cfg) extraPythonPackages; }; hermes-agent = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.default; # Deep-merge config type (from 0xrsydn/nix-hermes-agent) @@ -479,6 +481,31 @@ ''; }; + extraPythonPackages = mkOption { + type = types.listOf types.package; + default = [ ]; + description = '' + Python packages to add to PYTHONPATH for entry-point plugin discovery. + These are pip-packaged plugins that register via the + hermes_agent.plugins entry-point group. Each package must be built + with the same Python interpreter as hermes (python312). + ''; + example = literalExpression '' + [ + (pkgs.python312Packages.buildPythonPackage { + pname = "rtk-hermes"; + version = "1.0.0"; + src = pkgs.fetchFromGitHub { + owner = "ogallotti"; + repo = "rtk-hermes"; + rev = "main"; + hash = "sha256-..."; + }; + }) + ] + ''; + }; + restart = mkOption { type = types.str; default = "always"; @@ -593,7 +620,7 @@ # so interactive shells share state (sessions, skills, cron) with the # gateway service instead of creating a separate ~/.hermes/. (lib.mkIf cfg.addToSystemPackages { - environment.systemPackages = [ cfg.package ]; + environment.systemPackages = [ effectivePackage ]; environment.variables.HERMES_HOME = "${cfg.stateDir}/.hermes"; }) @@ -832,7 +859,7 @@ HERMES_NIX_ENV_EOF # reads them at Python startup — no systemd EnvironmentFile needed. ExecStart = lib.concatStringsSep " " ([ - "${cfg.package}/bin/hermes" + "${effectivePackage}/bin/hermes" "gateway" ] ++ cfg.extraArgs); @@ -855,7 +882,7 @@ HERMES_NIX_ENV_EOF }; path = [ - cfg.package + effectivePackage pkgs.bash pkgs.coreutils pkgs.git @@ -880,11 +907,11 @@ HERMES_NIX_ENV_EOF preStart = '' # Stable symlinks — container references these, not store paths directly - ln -sfn ${cfg.package} ${cfg.stateDir}/current-package + ln -sfn ${effectivePackage} ${cfg.stateDir}/current-package ln -sfn ${containerEntrypoint} ${cfg.stateDir}/current-entrypoint # GC roots so nix-collect-garbage doesn't remove store paths in use - ${pkgs.nix}/bin/nix-store --add-root ${cfg.stateDir}/.gc-root --indirect -r ${cfg.package} 2>/dev/null || true + ${pkgs.nix}/bin/nix-store --add-root ${cfg.stateDir}/.gc-root --indirect -r ${effectivePackage} 2>/dev/null || true ${pkgs.nix}/bin/nix-store --add-root ${cfg.stateDir}/.gc-root-entrypoint --indirect -r ${containerEntrypoint} 2>/dev/null || true # Check if container needs (re)creation