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
|
|
@ -17,9 +17,10 @@
|
|||
//! is the write rate this feature exists to avoid.
|
||||
//!
|
||||
//! **The payload is passed through opaquely**, same as the terminal relay:
|
||||
//! this daemon never inspects a header, so it does not depend on
|
||||
//! this relay never inspects a header, so it does not depend on
|
||||
//! `hive-agent`'s type to re-serialise one. The bytes on the wire are what
|
||||
//! `hive-agent::swarm_agent_state::publish` sent.
|
||||
//! `hive-agent::swarm_agent_state::publish` sent. [`crate::inference`]
|
||||
//! reads its own fields out of the same subject separately.
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::time::SystemTime;
|
||||
|
|
@ -36,9 +37,10 @@ use crate::AppState;
|
|||
params(("name" = String, Path, description = "agent whose turn state to stream")),
|
||||
responses(
|
||||
(status = 200, description = "server-sent event stream; each event's `data` is one \
|
||||
turn-state header, JSON as hive-agent published it (opaque to this daemon) — \
|
||||
`turn_state`, `turn_state_since` (ISO 8601 UTC), `agent_state`, `model`, \
|
||||
`resolved_model`, `context_window_tokens`, `ctx_usage`, `cost_usage`. Sent on \
|
||||
turn-state header, JSON as hive-agent published it (opaque to this relay) — \
|
||||
`turn_state`, `turn_state_since` (ISO 8601 UTC), `agent_state`, `model`, `effort`, \
|
||||
`model_source`, `effort_source`, `resolved_model`, `context_window_tokens`, \
|
||||
`ctx_usage`, `cost_usage`. Sent on \
|
||||
transition only, live, no replay: an idle agent emits nothing until it changes",
|
||||
body = String, content_type = "text/event-stream"),
|
||||
(status = 400, description = "the agent name is not shaped like an identifier \
|
||||
|
|
|
|||
Loading…
Reference in a new issue