swarm: show each agent's effective model and effort, and where they came from
Each agent now reports the model and effort it runs on, and where each
comes from (`swarm`, `agent_nix`, `local_file` or `default`), in its
turn-state header on `$SWARM.agent-state.<agent>`: `effort`,
`model_source` and `effort_source` join `model`. The shared
`swarm_queue_client::agent_inference::{Effective, Source}` types spell
those fields for both ends.
The Bus keeps a source next to the model and effort. `Bus::new` takes it
from the local fallback chain (`harness_state::local_model` /
`local_effort`, which now return the source with the value), a `/model`
or `/effort` pick sets `local_file`, and the swarm poller sets `swarm`
or, on a clear, the local chain's source. A swarm value equal to the one
the agent already runs is now applied once, so the source moves to
`swarm` and the header is republished; before, `next()` skipped it as
unchanged.
swarm-controller subscribes to every agent's header with the reader
grant it already holds for the state relay, and keeps the latest
inference fields per agent in memory (`inference::Reported`).
`GET /api/agents/{name}/inference` now answers
`{configured, effective}`, `effective` being `null` until the agent's
first header with these fields since the controller started.
`swarmctl agent inference get` prints both; `set` reads `configured`.
Refs #5034
This commit is contained in:
parent
6982b2ec14
commit
d723fac0be
20 changed files with 655 additions and 113 deletions
|
|
@ -21,11 +21,41 @@ swarmctl agent inference clear iris
|
|||
`continue` calls may name, read on each call
|
||||
([`subagent.md`](../tools/subagent.md#which-models-a-subagent-may-run-on)).
|
||||
The web UI's model picker doesn't use it.
|
||||
- `get` shows each field, naming the unset ones.
|
||||
- `get` shows each field, naming the unset ones, and then the model and
|
||||
effort the agent reports running on, each with where it comes from.
|
||||
- `clear` removes every field; the agent goes back to its own values.
|
||||
|
||||
The full flag reference is [`swarmctl-cli.md`](../tools/swarmctl-cli.md).
|
||||
|
||||
## What an agent runs on
|
||||
|
||||
`get` shows what the agent runs on next to what the swarm sets:
|
||||
|
||||
```text
|
||||
model: opus
|
||||
effort: (not set; the agent's own)
|
||||
subagent_models: (not set; the agent's own)
|
||||
running model: opus (swarm)
|
||||
running effort: medium (local_file)
|
||||
```
|
||||
|
||||
Each running value names where it comes from:
|
||||
|
||||
| source | meaning |
|
||||
| ------------ | -------------------------------------------------------------------------- |
|
||||
| `swarm` | the value set here |
|
||||
| `agent_nix` | `services.hyperhive.agent.model` or `effortLevel` in the agent's agent.nix |
|
||||
| `local_file` | a `/model` or `/effort` pick in the agent's web UI |
|
||||
| `default` | the harness's built-in default (`haiku`, `medium`) |
|
||||
|
||||
When the agent starts without a swarm value, its agent.nix model wins over
|
||||
its `/model` pick, and its `/effort` pick wins over its agent.nix effort.
|
||||
|
||||
The agent reports these whenever they change. swarm-controller keeps only
|
||||
what it has received since it started, so after a controller restart `get`
|
||||
shows `running: not reported…` for an agent until its next change (its next
|
||||
turn, or a setting changing).
|
||||
|
||||
## When an agent picks a change up
|
||||
|
||||
Each agent reads its settings every 10 seconds and switches on the next
|
||||
|
|
@ -55,7 +85,7 @@ Every field is optional, and `{}` reads the same as no key.
|
|||
|
||||
| method | path | body |
|
||||
| -------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `GET` | `/api/agents/<agent>/inference` | —; answers the stored value, `{}` when none |
|
||||
| `GET` | `/api/agents/<agent>/inference` | —; answers `{"configured": <the stored value, {} when none>, "effective": <what the agent reported, or null>}` |
|
||||
| `PUT` | `/api/agents/<agent>/inference` | the whole value, replacing the stored one; the controller refuses unknown fields, an unknown effort, or a model name with whitespace |
|
||||
| `DELETE` | `/api/agents/<agent>/inference` | —; answers 204 |
|
||||
|
||||
|
|
@ -72,4 +102,12 @@ The subagent daemon (`hive-subagent-mcp`'s `swarm_models`) reads
|
|||
`subagent_models` with the same direct get, under the same credential, on
|
||||
each `start` or `continue` that names a model.
|
||||
|
||||
`effective` comes from the agent's turn-state header on
|
||||
`$SWARM.agent-state.<agent>` ([`README.md`](README.md)), which carries
|
||||
`model`, `effort`, `model_source` and `effort_source`. swarm-controller
|
||||
subscribes to every agent's header with the reader grant it already holds for
|
||||
the state relay and keeps the latest per agent in memory. A header without
|
||||
those fields, from an agent that doesn't report them, leaves `effective`
|
||||
`null`.
|
||||
|
||||
</details>
|
||||
|
|
|
|||
Loading…
Reference in a new issue