Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: per-agent cap on concurrently running subagents

Nothing capped how many subagents an agent runs at once; the operator
wants to set that per agent from swarm-ui (#5234, shape (b)).

AgentInference gains `max_subagents: Option<u32>`. An absent field
decodes as None, so every stored value still parses and means "no cap",
which is today's behaviour.

swarm-controller accepts 1..=32 on PUT. 0 would refuse every start; 32
is far more concurrent claude sessions than one agent container has
memory for, so anything above it is a typo, not a cap.

The subagent daemon already read the agent's agent-inference key for
subagent_models; it now reads it on every start and continue (not only
those naming a model) and refuses a new run once the cap's worth of
names is tracked, counted under the same lock as the name reservation.
Every tracked slot counts: running, starting, a goal run between turns,
and an interrupted one still exiting. A goal re-prompt never goes
through the reservation, so it is never refused. A failed read applies
no cap, as it falls back for models.

swarmctl's `inference set` does GET, merge, PUT; its mirror type now
carries the field so a set from the CLI keeps a cap set in swarm-ui
instead of dropping it, and `get` prints it.
This commit is contained in:
atlas 2026-10-13 19:24:13 +02:00 • committed by mara
commit 9a71d1e094
10 changed files with 393 additions and 94 deletions

View file

@ -221,11 +221,12 @@ live rows only.
The agent's detail panel shows its model and effort under **inference**, each
with where it comes from: the swarm, its agent.nix, its own pick, or the
default. Below them is the subagent model list the swarm sets, or "its own"
when it sets none. **edit** opens a dialog with the three fields, filled with
what the swarm stores; saving does a `PUT /api/agents/{agent}/inference` of
default. Below them are the subagent model list the swarm sets, or "its own"
when it sets none, and the subagent cap, which reads "no cap" when unset.
**edit** opens a dialog with the four fields, filled with what the swarm
stores; saving does a `PUT /api/agents/{agent}/inference` of
the whole value. A field you leave empty stays out of it, so the agent keeps
its own value for that field. **clear the swarm's setting** sends the `DELETE`.
its own value for that field; an empty max subagents is no cap. **clear the swarm's setting** sends the `DELETE`.
The panel reads `GET /api/agents/{agent}/inference`; before the agent's first
report reaches the controller, it shows the swarm's stored values only.
[inference](inference.md) describes the settings themselves.