Skip to content

feat(nix): declarative plugin installation for NixOS module #14453

@alt-glitch

Description

@alt-glitch

Problem

There is no declarative way to install third-party hermes plugins in a NixOS-managed deployment. The Nix package builds a sealed Python venv via uv2nix with all deps baked in at build time. The existing extraPackages option only adds to the systemd service PATH, not the Python environment.

This means:

  • Pip-packaged plugins using importlib.metadata entry points (group hermes_agent.plugins) can't be discovered — they're not on sys.path
  • Directory-based plugins in ~/.hermes/plugins/ work for simple cases, but anything with Python dependencies fails because those deps aren't in the sealed venv
  • Users are left with workarounds: imperative hermes plugins install, manual PYTHONPATH hacks, or pip install inside a container

Proposed solution

Two-tier approach:

Tier 1: extraPythonPackages (pure Nix)

For plugin authors who ship Nix packaging. Uses overlay + callPackage to make the hermes package overridable:

services.hermes-agent.package = pkgs.hermes-agent.override {
  extraPythonPackages = [
    (pkgs.python312Packages.buildPythonPackage { ... })
  ];
};

The wrapper injects these onto PYTHONPATH via makeSearchPath. The base uv2nix venv stays sealed.

Prerequisites:

Tier 2: extraPlugins (uv-managed, impure)

For any pip/git plugin — the path that actually matters for the community. The NixOS activation script uses uv to install plugins into a sidecar venv:

services.hermes-agent = {
  extraPlugins = [
    "hermes-lcm"
    "git+https://github.com/user/hermes-some-plugin"
  ];
};

At activation time:

  1. uv venv creates a sidecar venv using the same Python as the base package
  2. uv pip install resolves and installs each plugin's dependency tree
  3. The wrapper adds the sidecar venv's site-packages to PYTHONPATH
  4. importlib.metadata.entry_points() discovers the plugins

This is impure (hits the network at activation time) but is the only realistic path for plugins that are just a GitHub repo with a pyproject.toml.

Prior art

Scope

  • Extract package to callPackage-able nix/hermes-agent.nix
  • Add nix/overlays.nix + wire into flake.nix
  • Add extraPythonPackages parameter (tier 1)
  • Add extraPlugins NixOS module option + activation script (tier 2)
  • Update NixOS module docs

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havearea/nixNix flake, NixOS module, container packagingcomp/pluginsPlugin system and bundled pluginstype/featureNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions