hive-agent: re-send the turn-state header once a minute
The header on `$SWARM.agent-state.<agent>` went out only when a bus event changed it, and the core subject keeps nothing for a late subscriber. An idle agent therefore said nothing to a reader that attached after its last change: swarm-controller after a restart showed `effective: null` for that agent until its next turn, which can be hours. The publish loop now also wakes every 60 s and re-sends the current header through the same `publish` path (clearing the dedup state first). Transitions still go out as they happen. Same subject, same grant. An agent whose queue connection is down now logs `swarm agent state: publish skipped` once a minute even while idle, so the `hh-swarm-agent-state-publish-skipped` alert also fires for idle disconnected agents, not only busy ones. Refs #5034
This commit is contained in:
parent
d723fac0be
commit
19a045a401
8 changed files with 152 additions and 59 deletions
|
|
@ -8,11 +8,11 @@
|
|||
//! the agent's current state.
|
||||
//!
|
||||
//! **That difference is the one thing worth reading twice.** `hive-agent`
|
||||
//! publishes a header on transition, to a core subject — so a client that
|
||||
//! attaches mid-idle sees nothing until the next change, which for an agent
|
||||
//! parked overnight can be hours. A renderer therefore has to open with
|
||||
//! whatever `GET /api/agents/status` already gives it and let this stream
|
||||
//! sharpen it, rather than treating an empty stream as an empty agent. The
|
||||
//! publishes a header on transition and re-sends it once a minute, to a core
|
||||
//! subject — so a client that attaches mid-idle sees nothing for up to a
|
||||
//! minute. A renderer therefore has to open with whatever
|
||||
//! `GET /api/agents/status` already gives it and let this stream sharpen
|
||||
//! it, rather than treating an empty stream as an empty agent. The
|
||||
//! alternative would be a KV bucket written on every turn-state flip, which
|
||||
//! is the write rate this feature exists to avoid.
|
||||
//!
|
||||
|
|
@ -40,8 +40,8 @@ use crate::AppState;
|
|||
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",
|
||||
`ctx_usage`, `cost_usage`. Sent on transition and re-sent once a minute, live, \
|
||||
no replay",
|
||||
body = String, content_type = "text/event-stream"),
|
||||
(status = 400, description = "the agent name is not shaped like an identifier \
|
||||
(problem+json)", body = String),
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@
|
|||
//!
|
||||
//! What the agent runs on comes from its turn-state header
|
||||
//! (`$SWARM.agent-state.<agent>`), which [`Reported`] keeps the latest of.
|
||||
//! Agents publish a header only when it changes and the queue keeps none, so
|
||||
//! an agent that has not changed since this daemon started has no entry.
|
||||
//! Agents publish a header when it changes and re-send it once a minute, and
|
||||
//! the queue keeps none, so an agent has no entry for up to a minute after
|
||||
//! this daemon starts.
|
||||
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::sync::{Arc, Mutex, PoisonError};
|
||||
|
|
|
|||
Loading…
Reference in a new issue