summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-06-16 21:21:39 +0200
committerMel <mel@rnrd.eu>2026-06-16 21:21:39 +0200
commitc771e8ad2fe2a0a2e755fbf5bba764b732bc2209 (patch)
tree59d9b11c4e7185ae0604ba7ae64778fec753bd31 /modules
parent3c736fab4e673f99b58ec71b11690b12396985bb (diff)
downloadnetwork-c771e8ad2fe2a0a2e755fbf5bba764b732bc2209.tar.zst
network-c771e8ad2fe2a0a2e755fbf5bba764b732bc2209.zip
Extract renard agent configuration into a foundation module, allowing other hosts to have it's user
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'modules')
-rw-r--r--modules/agent.nix168
-rw-r--r--modules/foundation/agent.nix196
-rw-r--r--modules/foundation/default.nix1
3 files changed, 197 insertions, 168 deletions
diff --git a/modules/agent.nix b/modules/agent.nix
deleted file mode 100644
index 880919b..0000000
--- a/modules/agent.nix
+++ /dev/null
@@ -1,168 +0,0 @@
-{ config, pkgs, hermes-agent, ... }:
-
-{
-  imports = [
-    hermes-agent.nixosModules.default
-  ];
-
-  age.secrets.renard-agent = {
-    file = ../secrets/renard-agent.age;
-    owner = "renard";
-    group = "renard";
-    mode = "0440";
-  };
-
-  users.groups.renard = { };
-  users.users.renard = {
-    isSystemUser = true;
-    group = "renard";
-    home = "/home/renard";
-    createHome = true;
-    shell = pkgs.bashInteractive;
-  };
-
-  services.hermes-agent = {
-    enable = true;
-
-    # the agent has it's own user on the host under
-    # which it runs and can change state at.
-    user = "renard";
-    group = "renard";
-    stateDir = "/home/renard";
-    createUser = false;
-
-    extraDependencyGroups = [ "messaging" ];
-
-    # packages for the agent to work with.
-    # it should also always be able to call `nix-shell` to gain access to more tools.
-    extraPackages = with pkgs; [
-      nix
-      nixfmt-rfc-style
-
-      openssh
-      tailscale
-
-      docker_29
-
-      jq
-      yq-go
-      ripgrep
-      fd
-      tree
-      file
-      unzip
-      gnused
-      gawk
-
-      curl
-      wget
-
-      htop
-      glances
-      lsof
-      iproute2
-      iputils
-      inetutils
-
-      dig
-      tcpdump
-      nmap
-
-      git
-
-      vim
-    ];
-
-    environmentFiles = [
-      # required secrets:
-      # * OPENROUTER_API_KEY
-      # * DISCORD_BOT_TOKEN
-      # * DISCORD_ALLOWED_USERS
-      config.age.secrets.renard-agent.path
-    ];
-
-    documents = {
-      "SOUL.md" = ../assets/agent/SOUL.md;
-    };
-
-    settings = {
-      model = {
-        provider = "openrouter";
-        # my current favorite budget model, with recent price
-        # changes by far the cheapest for the performance,
-        # with other chinese models also being close.
-        # only modality is text, requires auxiliary vision model!
-        # native price: $0.44/m in, $0.87/m out.
-        default = "deepseek/deepseek-v4-pro";
-      };
-
-      agent = {
-        reasoning_effort = "high"; # 'high' rated highest in benchmarks, tune to taste!
-        max_turns = 90;
-      };
-
-      auxiliary.vision = {
-        # auxiliary vision model for image comprehension.
-        # this qwen model is built for this exact use-case and is extremely
-        # cheap for the performance (though below gemini), however,
-        # it does not do any reasoning on the visual input!
-        # possible upgrade path for reasoning: qwen3-vl-30b-a3b-thinking
-        # native price: $0.13/m in, $1.56/m out.
-        provider = "openrouter";
-        model = "qwen/qwen3-vl-32b-instruct";
-        timeout = 120;
-      };
-
-      toolsets = [ "all" ];
-
-      terminal = {
-        backend = "local";
-        persistent_shell = true;
-        timeout = 180;
-      };
-
-      memory = {
-        memory_enabled = true;
-        user_profile_enabled = true;
-      };
-
-      # slightly higher limits and targets than default for better
-      # long session preservation.
-      compression = {
-        enabled = true;
-        threshold = 0.75;
-        target_ratio = 0.35;
-        protect_last_n = 40;
-      };
-
-      # progressive message editing, a little silly in discord but looks like
-      # the classic llm chats.
-      streaming = {
-        enabled = true;
-      };
-      display = {
-        streaming = true; # small regression with streaming.enabled, keep both on.
-        tool_progress = "new"; # only show fresh new tool calls, not every call.
-      };
-
-      discord = {
-        require_mention = false;
-        thread_require_mention = false;
-        auto_thread = false;
-        reactions = true;
-        history_backfill = true;
-        allow_mentions = {
-          everyone = false;
-          roles = false;
-          users = true;
-          replied_user = true;
-        };
-      };
-
-      unauthorized_dm_behavior = "ignore"; # ignore strangers
-
-      timezone = "Europe/Berlin";
-      group_sessions_per_user = false;
-    };
-  };
-}
diff --git a/modules/foundation/agent.nix b/modules/foundation/agent.nix
new file mode 100644
index 0000000..6ac25aa
--- /dev/null
+++ b/modules/foundation/agent.nix
@@ -0,0 +1,196 @@
+{
+  config,
+  pkgs,
+  lib,
+  hermes-agent,
+  ...
+}:
+
+let
+  inherit (lib) mkEnableOption mkIf mkMerge;
+  cfg = config.foundation.agent;
+
+  # the set of tools the agent has access to by default.
+  # it should also always be able to call `nix-shell` to gain access to more tools.
+  agentPackages = with pkgs; [
+    nix
+    nixfmt-rfc-style
+
+    openssh
+    tailscale
+
+    docker_29
+
+    jq
+    yq-go
+    ripgrep
+    fd
+    tree
+    file
+    unzip
+    gnused
+    gawk
+
+    curl
+    wget
+
+    htop
+    glances
+    lsof
+    iproute2
+    iputils
+    inetutils
+
+    dig
+    tcpdump
+    nmap
+
+    git
+
+    vim
+  ];
+in
+{
+  imports = [
+    hermes-agent.nixosModules.default
+  ];
+
+  options.foundation.agent = {
+    home = mkEnableOption "the 'renard' agent to live on this machine";
+    neighbor = mkEnableOption "letting the 'renard' agent access this machine";
+  };
+
+  config = mkMerge [
+    # both the home and each neighbor have a user for the agent.
+    (mkIf (cfg.home || cfg.neighbor) {
+      users = {
+        groups.renard = { };
+
+        users.renard = {
+          isSystemUser = true;
+          group = "renard";
+          home = "/home/renard";
+          createHome = true;
+          shell = pkgs.bashInteractive;
+          packages = agentPackages;
+        };
+      };
+    })
+
+    # the agent lives at home.
+    (mkIf cfg.home {
+      age.secrets.renard-agent = {
+        file = ../../secrets/renard-agent.age;
+        owner = "renard";
+        group = "renard";
+        mode = "0440";
+      };
+
+      services.hermes-agent = {
+        enable = true;
+
+        user = "renard";
+        group = "renard";
+        stateDir = "/home/renard";
+        createUser = false;
+
+        extraDependencyGroups = [ "messaging" ];
+
+        # both the user and the path house the same package set
+        extraPackages = agentPackages;
+
+        environmentFiles = [
+          # required secrets:
+          # * OPENROUTER_API_KEY
+          # * DISCORD_BOT_TOKEN
+          # * DISCORD_ALLOWED_USERS
+          config.age.secrets.renard-agent.path
+        ];
+
+        documents = {
+          "SOUL.md" = ../../assets/agent/SOUL.md;
+        };
+
+        settings = {
+          model = {
+            provider = "openrouter";
+            # my current favorite budget model, with recent price
+            # changes by far the cheapest for the performance,
+            # with other chinese models also being close.
+            # only modality is text, requires auxiliary vision model!
+            # native price: $0.44/m in, $0.87/m out.
+            default = "deepseek/deepseek-v4-pro";
+          };
+
+          agent = {
+            reasoning_effort = "high"; # 'high' rated highest in benchmarks, tune to taste!
+            max_turns = 90;
+          };
+
+          auxiliary.vision = {
+            # auxiliary vision model for image comprehension.
+            # this qwen model is built for this exact use-case and is extremely
+            # cheap for the performance (though below gemini), however,
+            # it does not do any reasoning on the visual input!
+            # possible upgrade path for reasoning: qwen3-vl-30b-a3b-thinking
+            # native price: $0.13/m in, $1.56/m out.
+            provider = "openrouter";
+            model = "qwen/qwen3-vl-32b-instruct";
+            timeout = 120;
+          };
+
+          toolsets = [ "all" ];
+
+          terminal = {
+            backend = "local";
+            persistent_shell = true;
+            timeout = 180;
+          };
+
+          memory = {
+            memory_enabled = true;
+            user_profile_enabled = true;
+          };
+
+          # slightly higher limits and targets than default for better
+          # long session preservation.
+          compression = {
+            enabled = true;
+            threshold = 0.75;
+            target_ratio = 0.35;
+            protect_last_n = 40;
+          };
+
+          # progressive message editing, a little silly in discord but looks like
+          # the classic llm chats.
+          streaming = {
+            enabled = true;
+          };
+          display = {
+            streaming = true; # small regression with streaming.enabled, keep both on.
+            tool_progress = "new"; # only show fresh new tool calls, not every call.
+          };
+
+          discord = {
+            require_mention = false;
+            thread_require_mention = false;
+            auto_thread = false;
+            reactions = true;
+            history_backfill = true;
+            allow_mentions = {
+              everyone = false;
+              roles = false;
+              users = true;
+              replied_user = true;
+            };
+          };
+
+          unauthorized_dm_behavior = "ignore"; # ignore strangers
+
+          timezone = "Europe/Berlin";
+          group_sessions_per_user = false;
+        };
+      };
+    })
+  ];
+}
diff --git a/modules/foundation/default.nix b/modules/foundation/default.nix
index fa84750..558f80a 100644
--- a/modules/foundation/default.nix
+++ b/modules/foundation/default.nix
@@ -7,5 +7,6 @@
     ./monitoring
     ./www
     ./vpn.nix
+    ./agent.nix
   ];
 }