agents: read the memory cap at boot, not from the build
An agent's memory cap was rendered into its flake (`memoryMaxBytes` → `services.hyperhive.agent.claudeMemoryMaxBytes`), so the closure depended on it and a changed cap reached the JSC heap ceiling and the subagent `MemoryHigh=` only after a rebuild. hive-c0re now writes the effective `MemoryMax=` in bytes to the agent's runtime dir (`/run/hive/memory-max-bytes` inside) in `write_dropins`, from the same value the drop-in gets. The file is removed for `infinity` or a RAM percentage, and left alone when the drop-in is kept. Inside the container, `nix/agent-modules/memory-cap.nix` reads it at boot: an environment generator sets `BUN_JSC_forceRAMSize` (75%) for every unit and `machinectl shell`, `/etc/set-environment` exports it in login shells, and a unit generator writes `MemoryHigh=` (2/3) as a drop-in for `hive-subagent-daemon`. The render drops `memoryMaxBytes`, the agent option is removed (both spellings fail eval with a removal message), and `effective_memory_bytes_from` goes with its only caller. Part of #5081 (slice S0-2).
This commit is contained in:
parent
c8df666bf3
commit
0d619e215e
15 changed files with 416 additions and 287 deletions
|
|
@ -11,25 +11,6 @@
|
|||
}:
|
||||
let
|
||||
userName = config.services.hyperhive.agent.user.name;
|
||||
# This container's own effective `MemoryMax=` in bytes, baked in per
|
||||
# agent by meta.rs's flake render — see
|
||||
# `services.hyperhive.agent.claudeMemoryMaxBytes` in ./claude-settings.nix. `null`
|
||||
# when the cap is `infinity` or a RAM percentage, i.e. when the module
|
||||
# has no byte count to size anything against.
|
||||
containerMemoryMaxBytes = config.services.hyperhive.agent.claudeMemoryMaxBytes;
|
||||
# Two thirds of the container's cap, as the soft ceiling on everything
|
||||
# the subagent daemon runs. The daemon spawns nested `claude` sessions
|
||||
# as plain children, so its cgroup already *is* the "all subagents"
|
||||
# cgroup and a unit-level ceiling bounds the set without a slice.
|
||||
#
|
||||
# `MemoryHigh=` and not `MemoryMax=`: this throttles rather than walls.
|
||||
# Past it the kernel reclaims aggressively and the cgroup stalls, so a
|
||||
# subagent that overshoots gets visibly slow and the remaining third
|
||||
# stays available for the agent's own turn — but a subagent that
|
||||
# genuinely needs more than two thirds still gets it when the container
|
||||
# has the memory to spare, which is what keeps overprovisioning
|
||||
# (several agents that rarely compile at the same time) working.
|
||||
subagentMemoryHigh = containerMemoryMaxBytes * 2 / 3;
|
||||
# Set on the harness only for an ACP agent on the opencode preset
|
||||
# (./agent-service.nix).
|
||||
acpApiKeyEnv = config.systemd.services.hive-agent.environment.HIVE_ACP_API_KEY_ENV or null;
|
||||
|
|
@ -475,12 +456,11 @@ in
|
|||
# actually chose and leaves the daemon serving, which is also what
|
||||
# lets it report the kill rather than vanish and be restarted.
|
||||
OOMPolicy = "continue";
|
||||
# `MemoryHigh=` is a drop-in from ./memory-cap.nix, sized at boot from
|
||||
# the container's cap.
|
||||
User = userName;
|
||||
Group = userName;
|
||||
}
|
||||
// lib.optionalAttrs (containerMemoryMaxBytes != null) {
|
||||
MemoryHigh = toString subagentMemoryHigh;
|
||||
}
|
||||
// lib.optionalAttrs subagentReadsStore {
|
||||
# Bare id: inherits the credential the container manager passed in,
|
||||
# the same form ./queue-identity.nix uses.
|
||||
|
|
|
|||
Loading…
Reference in a new issue