alpha
Login
or
Join now
lass.pds.lassul.us
/
superconfig
Star
0
Fork
1
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
This repository has no description
Star
0
Fork
1
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
1
Pipelines
machines.coaxmetal: run hermes-voice
author
lassulus
date
1 week ago
(Oct 9, 2026, 11:00 PM CEST)
commit
46943c86
46943c86e634a4334cf10f46a735570ef90958a6
parent
0fe4adc3
0fe4adc3602d8b6a7a14deee7ec3007a9c3778d6
+95
2 changed files
Expand all
Collapse all
Unified
Split
machines
coaxmetal
config.nix
hermes-voice.nix
+1
machines/coaxmetal/config.nix
View file
Reviewed
···
24
24
../../configs/crit.nix
25
25
./strom.nix
26
26
./hermes.nix
27
27
+
./hermes-voice.nix
27
28
];
28
29
29
30
system.stateVersion = "24.05";
+94
machines/coaxmetal/hermes-voice.nix
View file
Reviewed
···
1
1
+
{
2
2
+
config,
3
3
+
lib,
4
4
+
pkgs,
5
5
+
self,
6
6
+
...
7
7
+
}:
8
8
+
let
9
9
+
port = 8790;
10
10
+
in
11
11
+
{
12
12
+
# hermes-voice (tools/hermes-voice): live voice conversations with Hermes
13
13
+
# through OpenAI's gpt-live-1. Runs next to Hermes so its API key never
14
14
+
# leaves this host; reachable over retiolum and publicly as
15
15
+
# https://voice.lassul.us through neoprism (configs/hermes-proxy.nix).
16
16
+
#
17
17
+
# SECURITY: the page drives Hermes, which has terminal tools and code
18
18
+
# execution as lass (machines/coaxmetal/hermes.nix). The access token below
19
19
+
# is the gate on every API route; treat it like the hermes-api key.
20
20
+
systemd.services.hermes-voice = {
21
21
+
description = "hermes-voice: live voice conversations with Hermes";
22
22
+
wantedBy = [ "multi-user.target" ];
23
23
+
wants = [ "network-online.target" ];
24
24
+
after = [
25
25
+
"network-online.target"
26
26
+
"hermes-agent.service"
27
27
+
];
28
28
+
serviceConfig = {
29
29
+
ExecStart = lib.escapeShellArgs [
30
30
+
(lib.getExe self.packages.${pkgs.stdenv.hostPlatform.system}.hermes-voice)
31
31
+
"--listen"
32
32
+
"[::]:${toString port}"
33
33
+
# The API server binds the retiolum address (hermes.nix), not
34
34
+
# loopback; traffic to the host's own address goes through lo.
35
35
+
"--hermes-url"
36
36
+
"http://${config.networking.hostName}.r:8642"
37
37
+
"--hermes-key-file"
38
38
+
"%d/hermes-key"
39
39
+
"--openai-key-file"
40
40
+
"%d/openai-key"
41
41
+
"--access-token-file"
42
42
+
"%d/access-token"
43
43
+
];
44
44
+
LoadCredential = [
45
45
+
"hermes-key:${config.clan.core.vars.generators.hermes-api.files."api_key".path}"
46
46
+
"openai-key:${config.clan.core.vars.generators.hermes-voice-openai.files."api-key".path}"
47
47
+
"access-token:${config.clan.core.vars.generators.hermes-voice.files."access-token".path}"
48
48
+
];
49
49
+
DynamicUser = true;
50
50
+
Restart = "on-failure";
51
51
+
CapabilityBoundingSet = "";
52
52
+
NoNewPrivileges = true;
53
53
+
PrivateDevices = true;
54
54
+
PrivateTmp = true;
55
55
+
ProtectHome = true;
56
56
+
ProtectSystem = "strict";
57
57
+
ProtectKernelTunables = true;
58
58
+
ProtectKernelModules = true;
59
59
+
ProtectControlGroups = true;
60
60
+
RestrictAddressFamilies = [
61
61
+
"AF_INET"
62
62
+
"AF_INET6"
63
63
+
];
64
64
+
RestrictNamespaces = true;
65
65
+
LockPersonality = true;
66
66
+
SystemCallArchitectures = "native";
67
67
+
};
68
68
+
};
69
69
+
70
70
+
# Only retiolum: neoprism's proxy and devices on the mesh. Every other
71
71
+
# interface keeps the default DROP (configs/default.nix).
72
72
+
networking.firewall.interfaces.retiolum.allowedTCPPorts = [ port ];
73
73
+
74
74
+
# OpenAI project key with GPT-Live access; billed per second of open voice
75
75
+
# session. persist=true so the prompt value is stored once.
76
76
+
clan.core.vars.generators.hermes-voice-openai.prompts.api-key = {
77
77
+
description = "OpenAI API key for hermes-voice (gpt-live-1)";
78
78
+
type = "hidden";
79
79
+
persist = true;
80
80
+
};
81
81
+
82
82
+
# What the page sends as its bearer token. Read it out for the phone with
83
83
+
# clan vars get coaxmetal hermes-voice/access-token
84
84
+
clan.core.vars.generators.hermes-voice = {
85
85
+
files."access-token" = { };
86
86
+
runtimeInputs = [
87
87
+
pkgs.coreutils
88
88
+
pkgs.openssl
89
89
+
];
90
90
+
script = ''
91
91
+
openssl rand -hex 32 | tr -d '\n' > "$out/access-token"
92
92
+
'';
93
93
+
};
94
94
+
}