mirror of
https://codeberg.org/muon/home.git
synced 2026-07-03 23:49:35 +00:00
Add hermes
This commit is contained in:
parent
28bb03187d
commit
609b3384c0
9 changed files with 526 additions and 6 deletions
|
|
@ -50,6 +50,11 @@ let
|
|||
# off | errors | verbose
|
||||
debug: "${cfg.debug}"
|
||||
|
||||
thinking:
|
||||
# Default reasoning effort for requests without reasoning_effort set.
|
||||
# none | minimal | low | medium | high | xhigh
|
||||
default-effort: "${cfg.thinking.defaultEffort}"
|
||||
|
||||
cloaking:
|
||||
cli-version: "2.1.88"
|
||||
entrypoint: "cli"
|
||||
|
|
@ -110,6 +115,23 @@ with lib; {
|
|||
description = "Log level: off | errors | verbose.";
|
||||
};
|
||||
|
||||
thinking = {
|
||||
defaultEffort = mkOption {
|
||||
type = types.enum [ "none" "minimal" "low" "medium" "high" "xhigh" ];
|
||||
default = "medium";
|
||||
description = ''
|
||||
Default Claude extended-thinking budget injected into every request
|
||||
that doesn't already carry a reasoning_effort field.
|
||||
none = thinking disabled
|
||||
minimal = 512 tokens
|
||||
low = 1 024 tokens
|
||||
medium = 8 192 tokens (default)
|
||||
high = 24 576 tokens
|
||||
xhigh = 32 768 tokens
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
|
|
|||
|
|
@ -31,5 +31,6 @@
|
|||
./atuin.nix
|
||||
./murmur.nix
|
||||
./auth2api.nix
|
||||
./hermes.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
136
modules/nixos/server/hermes.nix
Normal file
136
modules/nixos/server/hermes.nix
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mods.server.hermes;
|
||||
auth2apiCfg = config.mods.server.auth2api;
|
||||
|
||||
# auth2api exposes an OpenAI-compatible endpoint; point Hermes at it.
|
||||
auth2apiUrl = "http://${auth2apiCfg.host}:${toString auth2apiCfg.port}/v1";
|
||||
in
|
||||
with lib; {
|
||||
options.mods.server.hermes = {
|
||||
enable = mkEnableOption "Hermes AI agent (NousResearch)";
|
||||
|
||||
model = mkOption {
|
||||
type = types.str;
|
||||
default = "claude-sonnet-4-6";
|
||||
description = ''
|
||||
Model identifier as exposed by auth2api. Available aliases:
|
||||
sonnet, haiku, opus, claude-sonnet-4-6, claude-haiku-4-5, claude-opus-4-6, etc.
|
||||
Run: curl http://127.0.0.1:8317/v1/models
|
||||
'';
|
||||
};
|
||||
|
||||
container = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Run Hermes inside a persistent Ubuntu container.";
|
||||
};
|
||||
|
||||
hostUsers = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ config.mods.user.name ];
|
||||
description = ''
|
||||
Users that get a ~/.hermes symlink to the service stateDir and are
|
||||
added to the hermes group for shared file access.
|
||||
'';
|
||||
};
|
||||
|
||||
extraVolumes = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "Extra volume mounts (host:container:mode) for the container.";
|
||||
};
|
||||
};
|
||||
|
||||
addToSystemPackages = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Put the hermes CLI on the system PATH and set HERMES_HOME so the
|
||||
interactive CLI shares state with the gateway service.
|
||||
'';
|
||||
};
|
||||
|
||||
extraPackages = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [ ];
|
||||
description = "Extra Nix packages available to the agent at runtime.";
|
||||
};
|
||||
|
||||
stateDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/hermes";
|
||||
description = "State directory (HERMES_HOME parent).";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Hermes needs auth2api running to have a backend to call.
|
||||
assertions = [
|
||||
{
|
||||
assertion = auth2apiCfg.enable;
|
||||
message = "mods.server.hermes requires mods.server.auth2api.enable = true";
|
||||
}
|
||||
];
|
||||
|
||||
services.hermes-agent = {
|
||||
enable = true;
|
||||
|
||||
inherit (cfg) stateDir addToSystemPackages extraPackages;
|
||||
|
||||
# auth2api runs unauthenticated on localhost (api-keys: []), but Hermes's
|
||||
# provider resolver requires a non-empty key env var for any provider.
|
||||
# AUTH2API_KEY is a dummy — auth2api ignores Bearer tokens when api-keys: [].
|
||||
environment.AUTH2API_KEY = "auth2api";
|
||||
|
||||
# ── Model ──────────────────────────────────────────────────────────────
|
||||
# Declare auth2api as a named custom provider in the providers: section.
|
||||
# Hermes resolves it via resolve_user_provider, which accepts arbitrary
|
||||
# base_url + key_env without needing a built-in provider slug.
|
||||
settings = {
|
||||
providers.auth2api = {
|
||||
name = "auth2api (Claude via OAuth)";
|
||||
api = auth2apiUrl;
|
||||
key_env = "AUTH2API_KEY";
|
||||
transport = "openai_chat";
|
||||
};
|
||||
|
||||
model = {
|
||||
default = cfg.model;
|
||||
provider = "auth2api";
|
||||
};
|
||||
|
||||
toolsets = [ "all" ];
|
||||
max_turns = 100;
|
||||
|
||||
terminal = {
|
||||
backend = "local";
|
||||
timeout = 180;
|
||||
};
|
||||
|
||||
memory = {
|
||||
memory_enabled = true;
|
||||
user_profile_enabled = true;
|
||||
};
|
||||
|
||||
display = {
|
||||
compact = false;
|
||||
show_reasoning = true;
|
||||
};
|
||||
};
|
||||
|
||||
# ── Container ──────────────────────────────────────────────────────────
|
||||
container = mkIf cfg.container.enable {
|
||||
enable = true;
|
||||
backend = "docker";
|
||||
inherit (cfg.container) hostUsers extraVolumes;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue