events: HIVE_DEFAULT_MODEL takes priority over persisted model (closes #319)

This commit is contained in:
damocles 2026-05-23 00:38:17 +02:00
parent cd9831b39e
commit 77b249076f
2 changed files with 68 additions and 17 deletions

View file

@ -2,6 +2,11 @@
pkgs,
lib,
config,
# Flake inputs routed through _module.args by the agent flake.nix.
# Default to {} so the module evaluates cleanly even when the agent
# flake doesn't set up the routing pattern (e.g. during standalone
# nixos-rebuild without a flake wrapper).
flakeInputs ? { },
...
}:
{
@ -20,13 +25,12 @@
default = "haiku";
example = "sonnet";
description = ''
Default claude model for this agent. Sets the `HIVE_DEFAULT_MODEL`
environment variable consumed by the harness at boot; if no
persisted model choice exists in the agent's state dir the harness
falls back to this value. The operator can still switch the model at
runtime via the per-agent web UI that choice is persisted to the
state dir and takes precedence over this default until the agent is
purged.
Claude model for this agent. Sets the `HIVE_DEFAULT_MODEL`
environment variable; the harness applies it at boot and it takes
priority over any persisted runtime override. The operator can still
switch the model at runtime via the per-agent web UI that choice
is tracked in the state dir for the current session but is reset by
any rebuild that changes this option.
Valid values are the short model names that `claude --model` accepts:
`"haiku"`, `"sonnet"`, `"opus"` (or any future identifier). Context
@ -320,6 +324,42 @@
};
config = {
assertions = [
# Guard the inputs-routed-as-output pattern: the agent flake.nix is
# expected to set `_module.args.flakeInputs = builtins.removeAttrs inputs ["self"]`.
# If `self` leaks into flakeInputs the agent gets a spurious attrset
# entry that can shadow real inputs and is almost certainly a bug.
{
assertion = !(builtins.hasAttr "self" flakeInputs);
message = ''
hyperhive: `flakeInputs` must not contain "self".
In your agent flake.nix, use:
_module.args.flakeInputs = builtins.removeAttrs inputs [ "self" ];
'';
}
# hyperhive.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\")";
}
# hyperhive.forge.url must look like an HTTP URL when non-default.
{
assertion =
config.hyperhive.forge.url == ""
|| lib.hasPrefix "http://" config.hyperhive.forge.url
|| lib.hasPrefix "https://" config.hyperhive.forge.url;
message = "hyperhive.forge.url must be an http:// or https:// URL (got: \"${config.hyperhive.forge.url}\")";
}
# hyperhive.icon must reference an SVG file when set.
{
assertion =
config.hyperhive.icon == null
|| lib.hasSuffix ".svg" (toString config.hyperhive.icon);
message = "hyperhive.icon must point to an .svg file";
}
];
environment.etc."hyperhive/extra-mcp.json".text = builtins.toJSON config.hyperhive.extraMcpServers;
# Operator-set per-agent icon (hyperhive.icon). When configured, the