remove c0re.preBuildAgentTemplates and agentBaseToplevel
This commit is contained in:
parent
4d85ec4c21
commit
8a7f254c74
7 changed files with 84 additions and 98 deletions
|
|
@ -515,28 +515,6 @@ For a hive-wide cap across all containers together, set
|
||||||
`systemd.slices.machine.serviceConfig.CPUQuota` in your NixOS
|
`systemd.slices.machine.serviceConfig.CPUQuota` in your NixOS
|
||||||
config — all nspawn containers live in `machine.slice`.
|
config — all nspawn containers live in `machine.slice`.
|
||||||
|
|
||||||
### Pre-building agent templates
|
|
||||||
|
|
||||||
`preBuildAgentTemplates` (default `false`) causes the host NixOS
|
|
||||||
build to pre-fetch the `agent-base` container system closure, which every
|
|
||||||
agent builds from, into `/nix/store`, instead of
|
|
||||||
leaving that work to the first `nixos-container start`. The
|
|
||||||
trade-off:
|
|
||||||
|
|
||||||
- **On** (recommended for x86_64 hosts that care about first-spawn
|
|
||||||
latency): the first `nixos-container start` for any new agent
|
|
||||||
completes in seconds because nothing remains to fetch. Cost:
|
|
||||||
`preBuildAgentTemplates` adds the full nixpkgs runtime closure + claude-code + the harness
|
|
||||||
binary to the host system closure (low single-digit GB
|
|
||||||
additional).
|
|
||||||
- **Off** (default): the host closure stays lean; the first spawn
|
|
||||||
does all the eval + fetch work at runtime (can take a few
|
|
||||||
minutes on a fresh store).
|
|
||||||
|
|
||||||
**Note**: the meta flake pins the toplevel to `x86_64-linux`. Enabling on an
|
|
||||||
`aarch64` host forces a cross-compilation or remote-builder build,
|
|
||||||
which is almost never desired. Leave off on non-x86 hosts.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
|
||||||
|
|
@ -133,14 +133,6 @@
|
||||||
assets = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.assets;
|
assets = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.assets;
|
||||||
xdgIcons = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.xdg-icons;
|
xdgIcons = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.xdg-icons;
|
||||||
hyperhiveRev = lib.mkDefault (self.rev or null);
|
hyperhiveRev = lib.mkDefault (self.rev or null);
|
||||||
# The agent-base toplevel every container builds from — wired into
|
|
||||||
# `system.extraDependencies` when
|
|
||||||
# `services.hyperhive.deploy.hive-controller.preBuildAgentTemplates` is on so
|
|
||||||
# the host system closure pre-fetches the heavy build
|
|
||||||
# inputs. x86_64-linux only (nixosConfigurations are
|
|
||||||
# hardcoded to that system); the gate keeps aarch64 hosts
|
|
||||||
# from pulling them in via cross-build.
|
|
||||||
agentBaseToplevel = lib.mkDefault self.packages.x86_64-linux.agent-base-toplevel;
|
|
||||||
};
|
};
|
||||||
services.hyperhive.deploy.swarm-controller.package =
|
services.hyperhive.deploy.swarm-controller.package =
|
||||||
lib.mkDefault
|
lib.mkDefault
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,13 @@ let
|
||||||
certificate. Remove this definition; the leaf or directory it named is read
|
certificate. Remove this definition; the leaf or directory it named is read
|
||||||
by nothing now and can be deleted.
|
by nothing now and can be deleted.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# Shared by the removed options that pre-fetched the agent-base closure.
|
||||||
|
agentPrebuildRemoved = ''
|
||||||
|
Hives pull agent closures from the swarm cache; nothing builds locally, so
|
||||||
|
there is no agent-base closure to pre-fetch into the host store. Remove
|
||||||
|
this definition.
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
|
@ -223,14 +230,18 @@ in
|
||||||
[ "services" "hyperhive" "c0re" "hyperhiveRev" ]
|
[ "services" "hyperhive" "c0re" "hyperhiveRev" ]
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "hyperhiveRev" ]
|
[ "services" "hyperhive" "deploy" "hive-controller" "hyperhiveRev" ]
|
||||||
)
|
)
|
||||||
(lib.mkRenamedOptionModule
|
(lib.mkRemovedOptionModule [
|
||||||
[ "services" "hyperhive" "c0re" "agentBaseToplevel" ]
|
"services"
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "agentBaseToplevel" ]
|
"hyperhive"
|
||||||
)
|
"c0re"
|
||||||
(lib.mkRenamedOptionModule
|
"agentBaseToplevel"
|
||||||
[ "services" "hyperhive" "c0re" "preBuildAgentTemplates" ]
|
] agentPrebuildRemoved)
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "preBuildAgentTemplates" ]
|
(lib.mkRemovedOptionModule [
|
||||||
)
|
"services"
|
||||||
|
"hyperhive"
|
||||||
|
"c0re"
|
||||||
|
"preBuildAgentTemplates"
|
||||||
|
] agentPrebuildRemoved)
|
||||||
(lib.mkRenamedOptionModule
|
(lib.mkRenamedOptionModule
|
||||||
[ "services" "hyperhive" "c0re" "modelPrices" ]
|
[ "services" "hyperhive" "c0re" "modelPrices" ]
|
||||||
[ "services" "hyperhive" "deploy" "hive-controller" "modelPrices" ]
|
[ "services" "hyperhive" "deploy" "hive-controller" "modelPrices" ]
|
||||||
|
|
|
||||||
|
|
@ -170,16 +170,6 @@ in
|
||||||
# above for the rationale.
|
# above for the rationale.
|
||||||
environment.etc."hyperhive/serve.json".text = serveConfigJson;
|
environment.etc."hyperhive/serve.json".text = serveConfigJson;
|
||||||
|
|
||||||
# Pull the agent-base toplevel into the host system closure.
|
|
||||||
# `system.extraDependencies` adds paths to the system build
|
|
||||||
# without referencing them at runtime — nixos-rebuild fetches /
|
|
||||||
# builds them, they end up in /nix/store, and the first
|
|
||||||
# nixos-container update + start for an agent has nothing left to
|
|
||||||
# do. Gated because the closure is sizeable and pinned to x86_64.
|
|
||||||
system.extraDependencies = lib.optionals controllerCfg.preBuildAgentTemplates [
|
|
||||||
controllerCfg.agentBaseToplevel
|
|
||||||
];
|
|
||||||
|
|
||||||
# Unprivileged coordinator user. hive-c0re runs as this user;
|
# Unprivileged coordinator user. hive-c0re runs as this user;
|
||||||
# privileged operations are delegated to hive-priv which runs as
|
# privileged operations are delegated to hive-priv which runs as
|
||||||
# root, socket-activated at /run/hive/priv.sock (./hive-priv.nix).
|
# root, socket-activated at /run/hive/priv.sock (./hive-priv.nix).
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,32 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
agentPrebuildRemoved = ''
|
||||||
|
Hives pull agent closures from the swarm cache; nothing builds locally, so
|
||||||
|
there is no agent-base closure to pre-fetch into the host store. Remove
|
||||||
|
this definition.
|
||||||
|
'';
|
||||||
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
(lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "managerToplevel" ] ''
|
(lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "managerToplevel" ] ''
|
||||||
Every agent, ruth included, builds from `agentBaseToplevel`. Remove this definition.
|
Every agent, ruth included, builds from the `agent-base` configuration. Remove this definition.
|
||||||
'')
|
'')
|
||||||
|
(lib.mkRemovedOptionModule [
|
||||||
|
"services"
|
||||||
|
"hyperhive"
|
||||||
|
"deploy"
|
||||||
|
"hive-controller"
|
||||||
|
"agentBaseToplevel"
|
||||||
|
] agentPrebuildRemoved)
|
||||||
|
(lib.mkRemovedOptionModule [
|
||||||
|
"services"
|
||||||
|
"hyperhive"
|
||||||
|
"deploy"
|
||||||
|
"hive-controller"
|
||||||
|
"preBuildAgentTemplates"
|
||||||
|
] agentPrebuildRemoved)
|
||||||
(lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "hyperhiveDocs" ] ''
|
(lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "hyperhiveDocs" ] ''
|
||||||
Agents take their reference docs from the pinned `hyperhive` input, which
|
Agents take their reference docs from the pinned `hyperhive` input, which
|
||||||
carries `docs/`. Remove this definition.
|
carries `docs/`. Remove this definition.
|
||||||
|
|
@ -99,42 +120,6 @@
|
||||||
it is.
|
it is.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
agentBaseToplevel = lib.mkOption {
|
|
||||||
type = lib.types.package;
|
|
||||||
defaultText = lib.literalExpression "hyperhive.packages.x86_64-linux.agent-base-toplevel";
|
|
||||||
description = ''
|
|
||||||
Pre-built agent-base container system closure, pulled into the
|
|
||||||
host system closure when `preBuildAgentTemplates` is on. Wired
|
|
||||||
by `nixosModules.default`; only evaluated when that option is
|
|
||||||
enabled.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
preBuildAgentTemplates = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
example = true;
|
|
||||||
description = ''
|
|
||||||
Pre-fetch the agent-base container system closure, which every
|
|
||||||
agent builds from, into the host's /nix/store as part of this
|
|
||||||
host's NixOS build, instead of letting the first agent spawn
|
|
||||||
do all the work.
|
|
||||||
|
|
||||||
Enabling this adds roughly the full nixpkgs runtime closure +
|
|
||||||
claude-code + the harness binary to your system closure size
|
|
||||||
(low single-digit GB), but the first `nixos-container start`
|
|
||||||
for any agent then completes in seconds instead of minutes
|
|
||||||
because nothing's left to fetch.
|
|
||||||
|
|
||||||
Off by default because the toplevel is pinned to
|
|
||||||
`x86_64-linux` (nixos-containers run native arch). Enabling
|
|
||||||
on an aarch64 host would force nix to build the x86 closure
|
|
||||||
via cross or a remote builder, which is rarely what you want.
|
|
||||||
Flip to `true` on an x86_64 host when you care more about
|
|
||||||
first-spawn latency than host store size — or just
|
|
||||||
`nix build .#agent-base-toplevel` once manually to warm the
|
|
||||||
store.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
modelPrices = lib.mkOption {
|
modelPrices = lib.mkOption {
|
||||||
type = lib.types.attrsOf (
|
type = lib.types.attrsOf (
|
||||||
|
|
|
||||||
|
|
@ -1469,9 +1469,7 @@ let
|
||||||
c0re.frontend = pkgs.coreutils;
|
c0re.frontend = pkgs.coreutils;
|
||||||
c0re.assets = pkgs.gnused;
|
c0re.assets = pkgs.gnused;
|
||||||
c0re.xdgIcons = pkgs.gnugrep;
|
c0re.xdgIcons = pkgs.gnugrep;
|
||||||
c0re.agentBaseToplevel = pkgs.findutils;
|
|
||||||
c0re.hyperhiveRev = "abc123";
|
c0re.hyperhiveRev = "abc123";
|
||||||
c0re.preBuildAgentTemplates = true;
|
|
||||||
c0re.modelPrices.sonnet = {
|
c0re.modelPrices.sonnet = {
|
||||||
input = 1.0;
|
input = 1.0;
|
||||||
output = 2.0;
|
output = 2.0;
|
||||||
|
|
@ -1501,10 +1499,8 @@ let
|
||||||
&& path c.frontend == path pkgs.coreutils
|
&& path c.frontend == path pkgs.coreutils
|
||||||
&& path c.assets == path pkgs.gnused
|
&& path c.assets == path pkgs.gnused
|
||||||
&& path c.xdgIcons == path pkgs.gnugrep
|
&& path c.xdgIcons == path pkgs.gnugrep
|
||||||
&& path c.agentBaseToplevel == path pkgs.findutils
|
|
||||||
&& path c.servedFrontend == path pkgs.coreutils
|
&& path c.servedFrontend == path pkgs.coreutils
|
||||||
&& c.hyperhiveRev == "abc123"
|
&& c.hyperhiveRev == "abc123"
|
||||||
&& c.preBuildAgentTemplates
|
|
||||||
&& c.modelPrices.sonnet.cache_write == 4.0
|
&& c.modelPrices.sonnet.cache_write == 4.0
|
||||||
&& c.agentCpuQuota == "300%"
|
&& c.agentCpuQuota == "300%"
|
||||||
&& c.agentMemoryMax == "8G"
|
&& c.agentMemoryMax == "8G"
|
||||||
|
|
@ -1519,9 +1515,7 @@ let
|
||||||
"frontend"
|
"frontend"
|
||||||
"assets"
|
"assets"
|
||||||
"xdgIcons"
|
"xdgIcons"
|
||||||
"agentBaseToplevel"
|
|
||||||
"hyperhiveRev"
|
"hyperhiveRev"
|
||||||
"preBuildAgentTemplates"
|
|
||||||
"modelPrices"
|
"modelPrices"
|
||||||
"agentCpuQuota"
|
"agentCpuQuota"
|
||||||
"agentMemoryMax"
|
"agentMemoryMax"
|
||||||
|
|
@ -1539,6 +1533,48 @@ let
|
||||||
&& serve.build_slots == 3
|
&& serve.build_slots == 3
|
||||||
&& old.users.groups.hive-admin.members == [ "alice" ];
|
&& old.users.groups.hive-admin.members == [ "alice" ];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
# Under either namespace, each removed pre-fetch option fails evaluation naming
|
||||||
|
# itself and the swarm cache. The controls are a host that sets none, and
|
||||||
|
# a host that sets a moved sibling option (`buildSlots`), which warns
|
||||||
|
# but does not fail.
|
||||||
|
name = "a definition of a removed agent-base pre-fetch option fails evaluation, naming the option and the swarm cache";
|
||||||
|
ok =
|
||||||
|
let
|
||||||
|
refused =
|
||||||
|
m: path:
|
||||||
|
lib.any (
|
||||||
|
a:
|
||||||
|
!a.assertion
|
||||||
|
&& lib.hasInfix "services.hyperhive.${path}" a.message
|
||||||
|
&& lib.hasInfix "swarm cache" a.message
|
||||||
|
) m.assertions;
|
||||||
|
setting = lib.listToAttrs (
|
||||||
|
lib.concatMap
|
||||||
|
(
|
||||||
|
ns:
|
||||||
|
lib.mapAttrsToList
|
||||||
|
(name: value: {
|
||||||
|
name = "${ns}.${name}";
|
||||||
|
value = hiveWithController (lib.setAttrByPath (lib.splitString "." "${ns}.${name}") value);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
preBuildAgentTemplates = true;
|
||||||
|
agentBaseToplevel = pkgs.findutils;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
[
|
||||||
|
"c0re"
|
||||||
|
"deploy.hive-controller"
|
||||||
|
]
|
||||||
|
);
|
||||||
|
sibling = hiveWithController { c0re.buildSlots = 3; };
|
||||||
|
in
|
||||||
|
lib.length (lib.attrNames setting) == 4
|
||||||
|
&& lib.all (path: refused setting.${path} path) (lib.attrNames setting)
|
||||||
|
&& !(lib.any (path: refused bare path) (lib.attrNames setting))
|
||||||
|
&& !(lib.any (path: refused sibling path) (lib.attrNames setting));
|
||||||
|
}
|
||||||
{
|
{
|
||||||
# What the moved options render with their defaults: the flake source, the agent limits
|
# What the moved options render with their defaults: the flake source, the agent limits
|
||||||
# and build slots in serve.json, the sudoless-hivectl group's members,
|
# and build slots in serve.json, the sudoless-hivectl group's members,
|
||||||
|
|
|
||||||
|
|
@ -285,13 +285,7 @@ in
|
||||||
ghidra-12-1 = pkgs.callPackage ./ghidra-12-1.nix { };
|
ghidra-12-1 = pkgs.callPackage ./ghidra-12-1.nix { };
|
||||||
|
|
||||||
# Pre-built system closure every agent container builds from. Exposed as a package
|
# Pre-built system closure every agent container builds from. Exposed as a package
|
||||||
# so operators can `nix build .#agent-base-toplevel` (or wire
|
# so operators can `nix build .#agent-base-toplevel`.
|
||||||
# them into their host system closure via the
|
|
||||||
# `preBuildAgentTemplates` option on the hive-c0re module —
|
|
||||||
# see nix/host-modules/hive-c0re/options.nix). Speeds up the first agent
|
|
||||||
# spawn dramatically because the heavy lifting (nixpkgs +
|
|
||||||
# claude-code + hive-agent binary) is already in the store
|
|
||||||
# when the meta evaluator goes to build the container.
|
|
||||||
#
|
#
|
||||||
# nixosConfigurations are pinned to x86_64-linux (nixos-
|
# nixosConfigurations are pinned to x86_64-linux (nixos-
|
||||||
# containers only run native arch), so this toplevel is
|
# containers only run native arch), so this toplevel is
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue