nix: move the agent option namespace under services.hyperhive.agent
Every per-agent harness option lived at the top-level `hyperhive.*` while the host tier has always been `services.hyperhive.*`. Move all 52 agent-tier option leaves (33 top-level names across 16 modules) to `services.hyperhive.agent.*`, repoint every read, and keep existing agent configs evaluating through one `mkRenamedOptionModule` per old leaf path in the new nix/agent-modules/renamed-options.nix. The shims are per leaf rather than per namespace: `user`, `mcp`, `otel`, `queue`, `docs`, `forge`, `frontend`, `github`, `gui`, `logs`, `matrix` and `cargo` are plain attrsets of declarations, not submodule-typed options, so a parent-path rename would not reach their children. Three read-only options (`frontend.mergedDist`, `queue.clientIdFile`, `queue.clientSecretFile`) deliberately get no shim — a rename contributes a definition, which a read-only option refuses; the exclusions are commented in place. Refs #4473
This commit is contained in:
parent
60393d0e32
commit
3662eda440
21 changed files with 531 additions and 290 deletions
|
|
@ -9,11 +9,11 @@
|
|||
...
|
||||
}:
|
||||
let
|
||||
userName = config.hyperhive.user.name;
|
||||
userName = config.services.hyperhive.agent.user.name;
|
||||
homeDir = "/home/${userName}";
|
||||
in
|
||||
{
|
||||
options.hyperhive.model = lib.mkOption {
|
||||
options.services.hyperhive.agent.model = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "haiku";
|
||||
example = "sonnet";
|
||||
|
|
@ -34,7 +34,7 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.availableModels = lib.mkOption {
|
||||
options.services.hyperhive.agent.availableModels = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [
|
||||
"haiku"
|
||||
|
|
@ -54,7 +54,7 @@ in
|
|||
Configure hive-wide by setting a shared default (e.g. in your
|
||||
`agent.nix` shared defaults) or per-agent to narrow the menu — for example a
|
||||
haiku-only agent can hide `opus` and `sonnet`. The *current* model is
|
||||
still set by `hyperhive.model` and remains switchable at runtime via the
|
||||
still set by `services.hyperhive.agent.model` and remains switchable at runtime via the
|
||||
UI; this option only controls which choices the picker presents.
|
||||
|
||||
Values are the short model names that `claude --model` accepts:
|
||||
|
|
@ -62,7 +62,7 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.effortLevel = lib.mkOption {
|
||||
options.services.hyperhive.agent.effortLevel = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"low"
|
||||
"medium"
|
||||
|
|
@ -87,7 +87,7 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.autoCompact = lib.mkOption {
|
||||
options.services.hyperhive.agent.autoCompact = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
|
|
@ -106,7 +106,7 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.useApiKey = lib.mkOption {
|
||||
options.services.hyperhive.agent.useApiKey = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
|
|
@ -121,14 +121,14 @@ in
|
|||
`~/.claude/` as "needs login" for this agent (see
|
||||
`hive_c0re::container_view`'s `needs_login` computation).
|
||||
|
||||
Set this AND `hyperhive.backendEnvironmentFile` together — this
|
||||
Set this AND `services.hyperhive.agent.backendEnvironmentFile` together — this
|
||||
option changes what the harness believes about its own login state,
|
||||
the other actually supplies the credentials `claude` reads. Neither
|
||||
is useful alone.
|
||||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.backendEnvironmentFile = lib.mkOption {
|
||||
options.services.hyperhive.agent.backendEnvironmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "/agents/myagent/harness/openrouter.env";
|
||||
|
|
@ -160,12 +160,12 @@ in
|
|||
so a path that doesn't exist yet — an operator setting this option
|
||||
before creating the file, or a fresh host rebuild before state is
|
||||
restored — makes systemd skip it rather than refuse to start the
|
||||
harness. See `hyperhive.useApiKey`'s doc for the option this one is
|
||||
harness. See `services.hyperhive.agent.useApiKey`'s doc for the option this one is
|
||||
paired with.
|
||||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.extraWebProxies = lib.mkOption {
|
||||
options.services.hyperhive.agent.extraWebProxies = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = { };
|
||||
example = lib.literalExpression ''{ "stats" = "http://127.0.0.1:3737"; }'';
|
||||
|
|
@ -192,21 +192,21 @@ in
|
|||
|
||||
config = {
|
||||
assertions = [
|
||||
# hyperhive.model must be a non-empty string — an empty value causes
|
||||
# services.hyperhive.agent.model must be a non-empty string — an empty value causes
|
||||
# the harness to pass an invalid model flag to claude.
|
||||
{
|
||||
assertion = config.hyperhive.model != "";
|
||||
message = "hyperhive.model must not be empty (set it to e.g. \"haiku\" or \"sonnet\")";
|
||||
assertion = config.services.hyperhive.agent.model != "";
|
||||
message = "services.hyperhive.agent.model must not be empty (set it to e.g. \"haiku\" or \"sonnet\")";
|
||||
}
|
||||
# The current model must appear in the quick-picker menu, otherwise the
|
||||
# UI would offer no way back to the model the agent is actually running.
|
||||
{
|
||||
assertion =
|
||||
config.hyperhive.availableModels == [ ]
|
||||
|| builtins.elem config.hyperhive.model config.hyperhive.availableModels;
|
||||
config.services.hyperhive.agent.availableModels == [ ]
|
||||
|| builtins.elem config.services.hyperhive.agent.model config.services.hyperhive.agent.availableModels;
|
||||
message =
|
||||
"hyperhive.model (\"${config.hyperhive.model}\") must be one of "
|
||||
+ "hyperhive.availableModels ([ ${lib.concatStringsSep " " config.hyperhive.availableModels} ]) "
|
||||
"services.hyperhive.agent.model (\"${config.services.hyperhive.agent.model}\") must be one of "
|
||||
+ "services.hyperhive.agent.availableModels ([ ${lib.concatStringsSep " " config.services.hyperhive.agent.availableModels} ]) "
|
||||
+ "— add it to the list or change the model.";
|
||||
}
|
||||
];
|
||||
|
|
@ -214,17 +214,17 @@ in
|
|||
# HIVE_DEFAULT_MODEL seeds the initial model selection when no
|
||||
# persisted model choice exists in the state dir.
|
||||
environment.variables = {
|
||||
HIVE_DEFAULT_MODEL = config.hyperhive.model;
|
||||
HIVE_DEFAULT_MODEL = config.services.hyperhive.agent.model;
|
||||
# Comma-separated menu for the per-agent UI model quick-picker
|
||||
# (see hyperhive.availableModels). The harness surfaces it to the
|
||||
# (see services.hyperhive.agent.availableModels). The harness surfaces it to the
|
||||
# frontend; an empty value falls back to the built-in default list.
|
||||
HIVE_AVAILABLE_MODELS = lib.concatStringsSep "," config.hyperhive.availableModels;
|
||||
# Per-agent baseline effort (see hyperhive.effortLevel). The
|
||||
HIVE_AVAILABLE_MODELS = lib.concatStringsSep "," config.services.hyperhive.agent.availableModels;
|
||||
# Per-agent baseline effort (see services.hyperhive.agent.effortLevel). The
|
||||
# harness resolves operator-override-file → this env → "medium"
|
||||
# and passes it to claude --effort at turn launch.
|
||||
HIVE_DEFAULT_EFFORT = config.hyperhive.effortLevel;
|
||||
HIVE_DEFAULT_EFFORT = config.services.hyperhive.agent.effortLevel;
|
||||
}
|
||||
// lib.optionalAttrs (!config.hyperhive.autoCompact) {
|
||||
// lib.optionalAttrs (!config.services.hyperhive.agent.autoCompact) {
|
||||
# Zero watermark disables proactive compaction; the reactive path
|
||||
# (compact-on-overflow) still fires when the session is truly full.
|
||||
HIVE_COMPACT_WATERMARK_TOKENS = "0";
|
||||
|
|
@ -253,8 +253,8 @@ in
|
|||
environment = {
|
||||
SHELL = "${pkgs.bashInteractive}/bin/bash";
|
||||
HOME = homeDir;
|
||||
HIVE_STATIC_DIR = "${config.hyperhive.frontend.mergedDist}";
|
||||
HIVE_ASSETS_DIR = "${config.hyperhive.packages.assets}/share/hyperhive";
|
||||
HIVE_STATIC_DIR = "${config.services.hyperhive.agent.frontend.mergedDist}";
|
||||
HIVE_ASSETS_DIR = "${config.services.hyperhive.agent.packages.assets}/share/hyperhive";
|
||||
# Unix-socket path for the harness web UI. All agents always bind
|
||||
# here; there is no TCP fallback. Path matches
|
||||
# `hive_c0re::agent_sockets::socket_path_for(name)` so lifecycle
|
||||
|
|
@ -274,30 +274,30 @@ in
|
|||
# (see ./mcp.nix) via the same option. Always set — network
|
||||
# isolation is unconditional, so a fixed per-container port is
|
||||
# collision-free.
|
||||
HYPERHIVE_MCP_HTTP_PORT = toString config.hyperhive.mcp.httpPort;
|
||||
HYPERHIVE_MCP_HTTP_PORT = toString config.services.hyperhive.agent.mcp.httpPort;
|
||||
}
|
||||
// lib.optionalAttrs config.hyperhive.gui.enable {
|
||||
// lib.optionalAttrs config.services.hyperhive.agent.gui.enable {
|
||||
# Tells the harness which fixed VNC port weston bound, and (by
|
||||
# its presence) that gui is enabled — the harness `/screen/ws`
|
||||
# relay reads this instead of a runtime marker file. The port is
|
||||
# container-local + fixed (network isolation is unconditional),
|
||||
# so the same value for every gui agent is fine. See
|
||||
# ./weston-vnc.nix::hyperhive.gui.vncPort.
|
||||
HIVE_GUI_VNC_PORT = toString config.hyperhive.gui.vncPort;
|
||||
# ./weston-vnc.nix::services.hyperhive.agent.gui.vncPort.
|
||||
HIVE_GUI_VNC_PORT = toString config.services.hyperhive.agent.gui.vncPort;
|
||||
}
|
||||
// lib.optionalAttrs (config.hyperhive.extraWebProxies != { }) {
|
||||
// lib.optionalAttrs (config.services.hyperhive.agent.extraWebProxies != { }) {
|
||||
# JSON object {"<path>": "<upstream>"} for the transparent
|
||||
# reverse-proxies. See `hyperhive.extraWebProxies` option
|
||||
# reverse-proxies. See `services.hyperhive.agent.extraWebProxies` option
|
||||
# and `web_ui/proxy.rs::extra_proxy_service`.
|
||||
HIVE_EXTRA_WEB_PROXIES = builtins.toJSON config.hyperhive.extraWebProxies;
|
||||
HIVE_EXTRA_WEB_PROXIES = builtins.toJSON config.services.hyperhive.agent.extraWebProxies;
|
||||
}
|
||||
// lib.optionalAttrs config.hyperhive.useApiKey {
|
||||
// lib.optionalAttrs config.services.hyperhive.agent.useApiKey {
|
||||
# Tells the harness not to wait for a Claude OAuth session — see
|
||||
# `hyperhive.useApiKey`'s own description for the full mechanism.
|
||||
# `services.hyperhive.agent.useApiKey`'s own description for the full mechanism.
|
||||
HIVE_USE_API_KEY = "1";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${config.hyperhive.packages.hive-agent}/bin/${binary}";
|
||||
ExecStart = "${config.services.hyperhive.agent.packages.hive-agent}/bin/${binary}";
|
||||
# Pin the journal identity to the binary name (otherwise systemd
|
||||
# derives SyslogIdentifier from the ExecStart basename).
|
||||
SyslogIdentifier = binary;
|
||||
|
|
@ -321,10 +321,10 @@ in
|
|||
User = userName;
|
||||
Group = userName;
|
||||
}
|
||||
// lib.optionalAttrs (config.hyperhive.backendEnvironmentFile != null) {
|
||||
# See `hyperhive.backendEnvironmentFile`'s own description for
|
||||
// lib.optionalAttrs (config.services.hyperhive.agent.backendEnvironmentFile != null) {
|
||||
# See `services.hyperhive.agent.backendEnvironmentFile`'s own description for
|
||||
# the file shape and the leading-`-` rationale.
|
||||
EnvironmentFile = "-${config.hyperhive.backendEnvironmentFile}";
|
||||
EnvironmentFile = "-${config.services.hyperhive.agent.backendEnvironmentFile}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue