104 lines
4.9 KiB
Rust
104 lines
4.9 KiB
Rust
//! Container/agent-roster wire shapes: what `ListDescendants` and
|
|
//! `HostRequest::AgentStatus` return, plus the per-account matrix
|
|
//! identity shape surfaced by `GetAgentMeta`.
|
|
|
|
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// One entry in a `ListDescendants` result.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ContainerInfo {
|
|
/// Logical agent name (no `h-` prefix).
|
|
pub name: String,
|
|
/// Whether the container is currently running.
|
|
pub running: bool,
|
|
}
|
|
|
|
/// One row in a `HostRequest::AgentStatus` result — the operator-CLI
|
|
/// projection of the dashboard's per-agent `ContainerView`. Carries the
|
|
/// agent's running/health flags plus the technical state an operator
|
|
/// wants in a roster overview (`hivectl list-agents`).
|
|
//
|
|
// Four orthogonal, independently-observed facts about one agent, each
|
|
// rendered as its own column/token by `hivectl list-agents` and read
|
|
// individually by `--json` consumers. Any combination is meaningful
|
|
// (a stopped agent can be paused and need an update), so folding them
|
|
// into a state machine or nested flag structs would only add
|
|
// `serde(flatten)` indirection to preserve the same flat JSON. Same
|
|
// rationale as `LifecycleScope` in hive-host-sock.
|
|
#[allow(
|
|
clippy::struct_excessive_bools,
|
|
reason = "flat wire projection of independent per-agent flags"
|
|
)]
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct AgentStatusRow {
|
|
/// Logical agent name (no `h-` prefix).
|
|
pub name: String,
|
|
/// Whether the container is currently running.
|
|
pub running: bool,
|
|
/// The container's unit is in systemd's `failed` state — it exhausted
|
|
/// its bounded restarts and gave up, as opposed to being stopped
|
|
/// deliberately. Orthogonal to `running`, like every other flag here:
|
|
/// a failed unit is not running, but a not-running unit is usually
|
|
/// just off.
|
|
#[serde(default)]
|
|
pub failed: bool,
|
|
/// Config commit is pending — the locked rev differs from the
|
|
/// agent's proposed/applied config (a rebuild would change it).
|
|
pub needs_update: bool,
|
|
/// The agent has no live claude session and is parked waiting for
|
|
/// the operator's re-auth flow.
|
|
pub needs_login: bool,
|
|
/// First 12 chars of the sha the meta flake currently has locked for
|
|
/// this agent's input. `None` when the agent has no locked rev yet.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub deployed_sha: Option<String>,
|
|
/// Count of this agent's pending reminders.
|
|
#[serde(default)]
|
|
pub pending_reminders: u64,
|
|
/// The agent's turn loop is parked (pause marker present in its
|
|
/// harness dir): the container may well be up and serving, it just
|
|
/// drives no turns. Orthogonal to `running` — an agent can be
|
|
/// paused while stopped, and pause survives a restart.
|
|
#[serde(default)]
|
|
pub paused: bool,
|
|
/// Parent in the topology tree. `None` marks a root-level agent.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub parent: Option<String>,
|
|
/// The Claude model the agent's harness is currently using. Mirrors
|
|
/// `container_view::ContainerView::active_model`: `None` when the
|
|
/// agent has never started a turn, the field is absent from its
|
|
/// harness state file, or the container isn't running.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub active_model: Option<String>,
|
|
/// The agent's current free-text status, set via the `set_status`
|
|
/// tool. `None` when unset or the container isn't running — a
|
|
/// stopped agent's on-disk status is a stale snapshot from before
|
|
/// the stop (same rule `container_view::read_agent_status_live`
|
|
/// applies for every other reader of this data).
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub status_text: Option<String>,
|
|
/// When `status_text` was last set, RFC 3339 UTC on the wire (see
|
|
/// `hive_sh4re::wire_time`). `None` exactly when `status_text` is
|
|
/// `None`.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub status_set_at: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
/// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s
|
|
/// `matrix_accounts`. Field names match the daemon's `matrix-accounts.json`
|
|
/// snapshot (written by `hive-matrix-mcp`'s account registry) so hive-c0re
|
|
/// deserializes the snapshot straight into `Vec<MatrixIdentity>`; the
|
|
/// snapshot's `live` / `is_primary` fields are ignored here (only live
|
|
/// accounts are listed).
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MatrixIdentity {
|
|
/// Logical account name (the `account` arg on the matrix MCP tools).
|
|
pub name: String,
|
|
/// Matrix user id (`@user:server`). `None` if the session restored
|
|
/// without a known user id yet.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub user_id: Option<String>,
|
|
/// Homeserver base URL this account is on.
|
|
pub homeserver: String,
|
|
}
|