AgentStatusRow: status_set_at as RFC 3339 UTC, not a raw unix int

This commit is contained in:
damocles 2026-09-07 13:15:59 +02:00 committed by mara
commit 9a47a837e5
2 changed files with 12 additions and 7 deletions

View file

@ -8,6 +8,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::Path; use std::path::Path;
use chrono::{DateTime, Utc};
use serde::Serialize; use serde::Serialize;
use crate::coordinator::Coordinator; use crate::coordinator::Coordinator;
@ -69,10 +70,11 @@ pub struct ContainerView {
/// status is treated as stale rather than surfaced. /// status is treated as stale rather than surfaced.
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub status_text: Option<String>, pub status_text: Option<String>,
/// Unix timestamp (seconds) `status_text` was last set. `None` /// When `status_text` was last set, RFC 3339 UTC on the wire (see
/// exactly when `status_text` is `None`. /// `hive_sh4re::wire_time`). `None` exactly when `status_text` is
/// `None`.
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub status_set_at: Option<i64>, pub status_set_at: Option<DateTime<Utc>>,
/// The agent's turn loop is parked: the container is up and still /// The agent's turn loop is parked: the container is up and still
/// serving its web UI / MCP daemons, but it drives no turns and its /// serving its web UI / MCP daemons, but it drives no turns and its
/// inbox messages queue unacked until it resumes. Sourced from the /// inbox messages queue unacked until it resumes. Sourced from the
@ -171,7 +173,8 @@ pub async fn build_all(hive: &crate::coordinator::HiveEnv) -> Vec<ContainerView>
// would re-derive `running` with its own `lifecycle::is_running` // would re-derive `running` with its own `lifecycle::is_running`
// shell-out when this loop already has it for free. // shell-out when this loop already has it for free.
let (status_text, status_set_at) = if running { let (status_text, status_set_at) = if running {
read_agent_status(&logical) let (text, set_at) = read_agent_status(&logical);
(text, set_at.map(hive_sh4re::wire_time::from_secs))
} else { } else {
(None, None) (None, None)
}; };

View file

@ -2,6 +2,7 @@
//! `HostRequest::AgentStatus` return, plus the per-account matrix //! `HostRequest::AgentStatus` return, plus the per-account matrix
//! identity shape surfaced by `GetAgentMeta`. //! identity shape surfaced by `GetAgentMeta`.
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// One entry in a `ListDescendants` result. /// One entry in a `ListDescendants` result.
@ -77,10 +78,11 @@ pub struct AgentStatusRow {
/// applies for every other reader of this data). /// applies for every other reader of this data).
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub status_text: Option<String>, pub status_text: Option<String>,
/// Unix timestamp (seconds) `status_text` was last set. `None` /// When `status_text` was last set, RFC 3339 UTC on the wire (see
/// exactly when `status_text` is `None`. /// `hive_sh4re::wire_time`). `None` exactly when `status_text` is
/// `None`.
#[serde(default, skip_serializing_if = "Option::is_none")] #[serde(default, skip_serializing_if = "Option::is_none")]
pub status_set_at: Option<i64>, pub status_set_at: Option<DateTime<Utc>>,
} }
/// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s /// One matrix identity an agent can act as, surfaced in `GetAgentMeta`'s