Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 06cc749b69 | |||
| b49d5c4f72 |
@@ -41,6 +41,10 @@
|
|||||||
tuwunel = 3024;
|
tuwunel = 3024;
|
||||||
honcho = 3025;
|
honcho = 3025;
|
||||||
|
|
||||||
|
# Agent infrastructure
|
||||||
|
hermes-api = 8642;
|
||||||
|
hermes-dashboard = 9119;
|
||||||
|
|
||||||
# Home automation
|
# Home automation
|
||||||
homarr = 7575;
|
homarr = 7575;
|
||||||
|
|
||||||
|
|||||||
@@ -7,31 +7,6 @@
|
|||||||
# Edge TTS: Seraphina — friendly, multilingual German female voice (free, no API key)
|
# Edge TTS: Seraphina — friendly, multilingual German female voice (free, no API key)
|
||||||
edgeVoice = "de-DE-SeraphinaMultilingualNeural";
|
edgeVoice = "de-DE-SeraphinaMultilingualNeural";
|
||||||
|
|
||||||
# Hermes v0.14 moved Matrix from matrix-nio to lazy-installed mautrix.
|
|
||||||
# Lazy pip installs cannot work in the read-only Nix Python environment, so
|
|
||||||
# provide the Matrix runtime deps declaratively and put their site-packages on
|
|
||||||
# the gateway process PYTHONPATH at interpreter startup.
|
|
||||||
matrixPython = pkgs.python312.withPackages (ps: let
|
|
||||||
# Hermes lazy_deps pins this exact version. nixpkgs currently ships an
|
|
||||||
# older aiosqlite, and lazy_deps treats version mismatches as missing.
|
|
||||||
aiosqlite_0_22_1 = ps.aiosqlite.overridePythonAttrs (_old: rec {
|
|
||||||
version = "0.22.1";
|
|
||||||
src = pkgs.fetchFromGitHub {
|
|
||||||
owner = "omnilib";
|
|
||||||
repo = "aiosqlite";
|
|
||||||
tag = "v${version}";
|
|
||||||
hash = "sha256-voOOFo1OwaRQ3JsDHlBrngP+8ajf0kTNKXJyOaJiTs4=";
|
|
||||||
};
|
|
||||||
});
|
|
||||||
in [
|
|
||||||
(ps.mautrix.override {withOlm = true;})
|
|
||||||
ps.markdown
|
|
||||||
aiosqlite_0_22_1
|
|
||||||
ps.asyncpg
|
|
||||||
ps.aiohttp-socks
|
|
||||||
]);
|
|
||||||
matrixPythonPath = "${matrixPython}/lib/python3.12/site-packages";
|
|
||||||
|
|
||||||
# Build skills using agents flake lib for hermes user
|
# Build skills using agents flake lib for hermes user
|
||||||
hermesSkills = inputs.agents.lib.mkSkills {
|
hermesSkills = inputs.agents.lib.mkSkills {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
@@ -54,17 +29,10 @@
|
|||||||
in {
|
in {
|
||||||
virtualisation.docker.enable = true;
|
virtualisation.docker.enable = true;
|
||||||
|
|
||||||
# Matrix E2EE uses libolm via python-olm. libolm is archived upstream and
|
|
||||||
# marked insecure in nixpkgs, but Hermes Matrix encrypted rooms currently
|
|
||||||
# still require it through mautrix[encryption].
|
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
|
||||||
"olm-3.2.16"
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /home/hermes/.config 0755 hermes hermes -"
|
"d /var/lib/hermes/.config 0755 hermes hermes -"
|
||||||
"d /home/hermes/.config/tea 0755 hermes hermes -"
|
"d /var/lib/hermes/.config/tea 0755 hermes hermes -"
|
||||||
"L+ /home/hermes/.config/tea/yml - - - - ${pkgs.writeText "tea-yml" ''
|
"L+ /var/lib/hermes/.config/tea/yml - - - - ${pkgs.writeText "tea-yml" ''
|
||||||
logins:
|
logins:
|
||||||
- name: m3ta
|
- name: m3ta
|
||||||
url: https://code.m3ta.dev
|
url: https://code.m3ta.dev
|
||||||
@@ -88,24 +56,29 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Ensure 'uv' is in the hermes-agent service PATH so CronJobs and terminal
|
|
||||||
# sessions can use 'uv run' for PEP 723 scripts (e.g. garmin-daily.py).
|
|
||||||
systemd.services.hermes-agent = {
|
|
||||||
path = [pkgs.uv];
|
|
||||||
environment = {
|
|
||||||
PYTHONPATH = matrixPythonPath;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.hermes-agent = {
|
services.hermes-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
addToSystemPackages = true;
|
addToSystemPackages = true;
|
||||||
|
# v0.14 lazy-installs heavy optional backends by default. In the sealed
|
||||||
|
# Nix package, include the backends this host config actively uses so the
|
||||||
|
# gateway, Matrix bridge, memory, web search, and TTS work
|
||||||
|
# without runtime pip/uv mutation.
|
||||||
|
extraDependencyGroups = [
|
||||||
|
"matrix"
|
||||||
|
"honcho"
|
||||||
|
"exa"
|
||||||
|
"edge-tts"
|
||||||
|
];
|
||||||
|
|
||||||
extraPackages = with pkgs; [
|
extraPackages = with pkgs; [
|
||||||
docker
|
docker
|
||||||
git
|
git
|
||||||
|
curl
|
||||||
|
jq
|
||||||
tea
|
tea
|
||||||
nix
|
nix
|
||||||
|
python3Minimal
|
||||||
|
uv
|
||||||
zellij
|
zellij
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -134,7 +107,7 @@ in {
|
|||||||
# Bind to 0.0.0.0 so the Netbird interface can reach it.
|
# Bind to 0.0.0.0 so the Netbird interface can reach it.
|
||||||
API_SERVER_ENABLED = "true";
|
API_SERVER_ENABLED = "true";
|
||||||
API_SERVER_HOST = "0.0.0.0";
|
API_SERVER_HOST = "0.0.0.0";
|
||||||
API_SERVER_PORT = "8642";
|
API_SERVER_PORT = toString (config.m3ta.ports.get "hermes-api");
|
||||||
};
|
};
|
||||||
|
|
||||||
# ── Container mode (podman) ──────────────────────────────────────────
|
# ── Container mode (podman) ──────────────────────────────────────────
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
# Netbird mesh VPN range — dashboard only accessible from mesh peers.
|
# Netbird mesh VPN range — dashboard only accessible from mesh peers.
|
||||||
# m3-atlas Traefik proxies to this port over Netbird.
|
# m3-atlas Traefik proxies to this port over Netbird.
|
||||||
netbirdRange = "100.64.0.0/16";
|
netbirdRange = "100.64.0.0/16";
|
||||||
|
apiPort = config.m3ta.ports.get "hermes-api";
|
||||||
|
dashboardPort = config.m3ta.ports.get "hermes-dashboard";
|
||||||
|
|
||||||
# Reference the hermes-agent package from the running service config
|
# Reference the hermes-agent package from the running service config
|
||||||
hermesPkg = config.services.hermes-agent.package or (inputs.hermes-agent.packages.${pkgs.stdenv.hostPlatform.system}.default or pkgs.hermes-agent);
|
hermesPkg = config.services.hermes-agent.package or (inputs.hermes-agent.packages.${pkgs.stdenv.hostPlatform.system}.default or pkgs.hermes-agent);
|
||||||
@@ -14,10 +16,10 @@ in {
|
|||||||
# ── Hermes Dashboard systemd service ───────────────────────────────────
|
# ── Hermes Dashboard systemd service ───────────────────────────────────
|
||||||
# Web UI for managing Hermes Agent — sessions, config, kanban, cron, etc.
|
# Web UI for managing Hermes Agent — sessions, config, kanban, cron, etc.
|
||||||
#
|
#
|
||||||
# Flow: Browser → dash.m3ta.dev (TLS via m3-atlas Traefik) → Netbird → :9119
|
# Flow: Browser → dash.m3ta.dev (TLS via m3-atlas Traefik) → Netbird → :${toString dashboardPort}
|
||||||
#
|
#
|
||||||
# --insecure is required to bind 0.0.0.0 (hermes refuses non-localhost otherwise).
|
# --insecure is required to bind 0.0.0.0 (hermes refuses non-localhost otherwise).
|
||||||
# Safe because firewall restricts port 9119 to Netbird mesh only.
|
# Safe because firewall restricts the dashboard/API ports to Netbird mesh only.
|
||||||
systemd.services.hermes-dashboard = {
|
systemd.services.hermes-dashboard = {
|
||||||
description = "Hermes Agent Web Dashboard";
|
description = "Hermes Agent Web Dashboard";
|
||||||
after = ["network.target" "hermes-agent.service"];
|
after = ["network.target" "hermes-agent.service"];
|
||||||
@@ -29,7 +31,7 @@ in {
|
|||||||
User = "hermes";
|
User = "hermes";
|
||||||
Group = "hermes";
|
Group = "hermes";
|
||||||
|
|
||||||
ExecStart = "${hermesPkg}/bin/hermes dashboard --host 0.0.0.0 --port 9119 --no-open --insecure";
|
ExecStart = "${hermesPkg}/bin/hermes dashboard --host 0.0.0.0 --port ${toString dashboardPort} --no-open --insecure";
|
||||||
|
|
||||||
# Environment matching the hermes-agent service
|
# Environment matching the hermes-agent service
|
||||||
Environment = [
|
Environment = [
|
||||||
@@ -51,15 +53,17 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# ── Firewall: Dashboard only from Netbird mesh ─────────────────────────
|
# ── Firewall: Hermes network endpoints only from Netbird mesh ──────────
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
extraCommands = ''
|
extraCommands = ''
|
||||||
# Allow Hermes Dashboard (9119/tcp) only from Netbird mesh VPN
|
# Allow Hermes Dashboard and OpenAI-compatible API only from Netbird mesh VPN
|
||||||
ip46tables -A nixos-fw -p tcp --dport 9119 -s ${netbirdRange} -j nixos-fw-accept
|
ip46tables -A nixos-fw -p tcp --dport ${toString dashboardPort} -s ${netbirdRange} -j nixos-fw-accept
|
||||||
|
ip46tables -A nixos-fw -p tcp --dport ${toString apiPort} -s ${netbirdRange} -j nixos-fw-accept
|
||||||
'';
|
'';
|
||||||
|
|
||||||
extraStopCommands = ''
|
extraStopCommands = ''
|
||||||
ip46tables -D nixos-fw -p tcp --dport 9119 -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
ip46tables -D nixos-fw -p tcp --dport ${toString dashboardPort} -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
||||||
|
ip46tables -D nixos-fw -p tcp --dport ${toString apiPort} -s ${netbirdRange} -j nixos-fw-accept 2>/dev/null || true
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user