diff --git a/nix/checks.nix b/nix/checks.nix index 49955a6c5fd..e847ef26cbd 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -260,6 +260,19 @@ json.dump(sorted(leaf_paths(DEFAULT_CONFIG)), sys.stdout, indent=2) echo "ok" > $out/result ''; + # Regression guard: messaging deps live outside [all], so the + # #messaging variant must actually ship discord.py — otherwise + # `nix profile install .#messaging` regresses to the broken default. + messaging-variant = pkgs.runCommand "hermes-messaging-variant" { } '' + set -e + echo "=== Checking discord.py importable from messaging variant ===" + ${self'.packages.messaging.hermesVenv}/bin/python3 -c \ + "import discord; print(discord.__version__)" + echo "PASS: discord.py importable from messaging variant venv" + mkdir -p $out + echo "ok" > $out/result + ''; + # ── Config merge + round-trip test ──────────────────────────────── # Tests the merge script (Nix activation behavior) across 7 # scenarios, then verifies Python's load_config() reads correctly. diff --git a/nix/packages.nix b/nix/packages.nix index d95133d26ae..a72a0d41437 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -2,7 +2,7 @@ { inputs, ... }: { perSystem = - { pkgs, inputs', ... }: + { pkgs, lib, inputs', ... }: let hermesAgent = pkgs.callPackage ./hermes-agent.nix { inherit (inputs) uv2nix pyproject-nix pyproject-build-systems; @@ -15,6 +15,39 @@ { packages = { default = hermesAgent; + + # Ships discord.py + python-telegram-bot + slack-sdk so a plain + # `nix profile install .#messaging` connects to Discord/Telegram/Slack + # on first run — lazy-install can't write to the read-only /nix/store. + messaging = hermesAgent.override { + extraDependencyGroups = [ "messaging" ]; + }; + + # All platform-portable optional integrations pre-built. + # matrix is Linux-only (oqs/liboqs lacks aarch64-darwin wheels). + full = hermesAgent.override { + extraDependencyGroups = [ + "anthropic" + "azure-identity" + "bedrock" + "daytona" + "dingtalk" + "edge-tts" + "exa" + "fal" + "feishu" + "firecrawl" + "hindsight" + "honcho" + "messaging" + "modal" + "parallel-web" + "tts-premium" + "vercel" + "voice" + ] ++ lib.optionals pkgs.stdenv.isLinux [ "matrix" ]; + }; + tui = hermesAgent.hermesTui; web = hermesAgent.hermesWeb; diff --git a/plugins/platforms/discord/adapter.py b/plugins/platforms/discord/adapter.py index efe0b5d1de7..58e1c223889 100644 --- a/plugins/platforms/discord/adapter.py +++ b/plugins/platforms/discord/adapter.py @@ -6163,7 +6163,7 @@ def register(ctx) -> None: check_fn=check_discord_requirements, is_connected=_is_connected, required_env=["DISCORD_BOT_TOKEN"], - install_hint="pip install 'hermes-agent[discord]'", + install_hint="pip install 'hermes-agent[messaging]'", # Interactive setup wizard — replaces the central # hermes_cli/setup.py::_setup_discord function. Same shape as Teams. setup_fn=interactive_setup, diff --git a/website/docs/getting-started/nix-setup.md b/website/docs/getting-started/nix-setup.md index 80e8cae9746..ea2beb1fb7a 100644 --- a/website/docs/getting-started/nix-setup.md +++ b/website/docs/getting-started/nix-setup.md @@ -46,6 +46,22 @@ hermes chat After `nix profile install`, `hermes`, `hermes-agent`, and `hermes-acp` are on your PATH. From here, the workflow is identical to the [standard installation](./installation.md) — `hermes setup` walks you through provider selection, `hermes gateway install` sets up a launchd (macOS) or systemd user service, and config lives in `~/.hermes/`. +:::warning Messaging platforms (Discord, Telegram, Slack) +The default package doesn't include messaging platform libraries — they were moved to on-demand installation, which can't work in Nix's read-only environment. If you plan to connect the agent to Discord, Telegram, or Slack, install the `messaging` variant: + +```bash +nix profile install github:NousResearch/hermes-agent#messaging +``` + +For all optional extras (voice, all providers, all platforms): + +```bash +nix profile install github:NousResearch/hermes-agent#full +``` + +The `full` variant adds ~700 MB to the closure. If you only need messaging platforms, `#messaging` adds just ~33 MB. +::: +
Building from a local clone @@ -319,6 +335,7 @@ Quick reference for the most common things Nix users want to customize: | Add API keys | `environmentFiles` | `[ config.sops.secrets."hermes-env".path ]` | | Give the agent a personality | `${services.hermes-agent.stateDir}/.hermes/SOUL.md` | manage the file directly | | Add MCP tool servers | `mcpServers.` | See [MCP Servers](#mcp-servers) | +| Enable Discord/Telegram/Slack | `extraDependencyGroups` | `[ "messaging" ]` | | Mount host directories into container | `container.extraVolumes` | `[ "/data:/data:rw" ]` | | Pass GPU access to container | `container.extraOptions` | `[ "--gpus" "all" ]` | | Use Podman instead of Docker | `container.backend` | `"podman"` | @@ -647,16 +664,44 @@ The package's `site-packages` is added to PYTHONPATH in the hermes wrapper. `imp ### Optional Dependency Groups (`extraDependencyGroups`) -For optional extras already declared in hermes-agent's `pyproject.toml` (e.g., memory providers like `hindsight` or `honcho`), use `extraDependencyGroups` to include them in the sealed venv at build time: +For optional extras declared in hermes-agent's `pyproject.toml`, use `extraDependencyGroups` to include them in the sealed venv at build time. This is required for any extra not in the default `[all]` set — on Nix, runtime installation into the read-only store is not possible. ```nix +# Enable Discord, Telegram, Slack +services.hermes-agent.extraDependencyGroups = [ "messaging" ]; +``` + +```nix +# Enable a memory provider services.hermes-agent = { extraDependencyGroups = [ "hindsight" ]; settings.memory.provider = "hindsight"; }; ``` -This is resolved by uv alongside core dependencies in a single pass — no PYTHONPATH patching, no collision risk. Available groups match the `[project.optional-dependencies]` keys in `pyproject.toml` (e.g., `"hindsight"`, `"honcho"`, `"voice"`, `"matrix"`, `"mistral"`, `"bedrock"`). +This is resolved by uv alongside core dependencies — no PYTHONPATH patching, no collision risk. Available groups: + +| Group | What it enables | +|-------|-----------------| +| `messaging` | Discord, Telegram, Slack | +| `matrix` | Matrix/Element (mautrix with encryption; Linux only) | +| `dingtalk` | DingTalk | +| `feishu` | Feishu/Lark | +| `voice` | Local speech-to-text (faster-whisper) | +| `edge-tts` | Edge TTS provider | +| `tts-premium` | ElevenLabs TTS | +| `anthropic` | Native Anthropic SDK (not needed via OpenRouter) | +| `bedrock` | AWS Bedrock (boto3) | +| `azure-identity` | Azure Entra ID auth | +| `honcho` | Honcho memory provider | +| `hindsight` | Hindsight memory provider | +| `modal` | Modal terminal backend | +| `daytona` | Daytona terminal backend | +| `exa` | Exa web search | +| `firecrawl` | Firecrawl web search | +| `fal` | FAL image generation | + +Or use the pre-built `#messaging` or `#full` flake packages instead of per-extra configuration (see [Quick Start](#quick-start-any-nix-user)). **When to use which:** @@ -966,6 +1011,7 @@ nix-store --query --roots $(docker exec hermes-agent readlink /data/current-pack | Symptom | Cause | Fix | |---|---|---| | `Cannot save configuration: managed by NixOS` | CLI guards active | Edit `configuration.nix` and `nixos-rebuild switch` | +| `No adapter available for discord` (or telegram/slack) | Messaging deps missing from the sealed Nix venv | Install `#messaging` variant: `nix profile install ...#messaging`. For NixOS module: `extraDependencyGroups = [ "messaging" ]`. Check `journalctl -u hermes-agent` for `FeatureUnavailable` or `requirements not met` for the underlying error. | | Container recreated unexpectedly | `extraVolumes`, `extraOptions`, or `image` changed | Expected — writable layer resets. Reinstall packages or use a custom image | | `hermes version` shows old version | Container not restarted | `systemctl restart hermes-agent` | | Permission denied on `/var/lib/hermes` | State dir is `0750 hermes:hermes` | Use `docker exec` or `sudo -u hermes` |