feat(dash): show active model badge on agent cards (closes #2069)
Read the persisted model name from each agent's harness state file (harness/hyperhive-model) and surface it as a small blue badge on the container row in the SW4RM tab. - container_view.rs: add `active_model: Option<String>` to ContainerView; populated by new `read_active_model` helper that reads harness/hyperhive-model; only set when container is running (stale model info from a stopped agent is misleading) - container_view.rs: add active_model to ContainerView literal in host_stats test helper - tabs.js: render badge-model chip after needs-update, before reminders; add active_model to the row fingerprint so re-renders fire on model change - common.css: add .badge-model (blue, 80% opacity — informational)
This commit is contained in:
parent
c8ae3371e1
commit
4375ab6246
4 changed files with 42 additions and 0 deletions
|
|
@ -85,6 +85,11 @@ code {
|
||||||
color: var(--purple); border-color: var(--purple);
|
color: var(--purple); border-color: var(--purple);
|
||||||
text-shadow: 0 0 6px color-mix(in srgb, var(--purple) 40%, transparent);
|
text-shadow: 0 0 6px color-mix(in srgb, var(--purple) 40%, transparent);
|
||||||
}
|
}
|
||||||
|
/* Active Claude model badge on dashboard container rows. */
|
||||||
|
.badge-model {
|
||||||
|
color: var(--blue); border-color: var(--blue);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
/* Context-window usage badges on dashboard container rows. */
|
/* Context-window usage badges on dashboard container rows. */
|
||||||
.badge-ctx-ok {
|
.badge-ctx-ok {
|
||||||
color: var(--green); border-color: var(--green);
|
color: var(--green); border-color: var(--green);
|
||||||
|
|
|
||||||
|
|
@ -521,6 +521,7 @@ window.marked = marked;
|
||||||
needs_login: c.needs_login,
|
needs_login: c.needs_login,
|
||||||
needs_update: c.needs_update,
|
needs_update: c.needs_update,
|
||||||
pending_reminders: c.pending_reminders,
|
pending_reminders: c.pending_reminders,
|
||||||
|
active_model: c.active_model,
|
||||||
port: c.port,
|
port: c.port,
|
||||||
pending,
|
pending,
|
||||||
opRunning,
|
opRunning,
|
||||||
|
|
@ -726,6 +727,12 @@ window.marked = marked;
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (c.active_model) {
|
||||||
|
head.append(el('span',
|
||||||
|
{ class: 'badge badge-model', title: `active claude model: ${c.active_model}` },
|
||||||
|
c.active_model));
|
||||||
|
}
|
||||||
|
|
||||||
if (c.pending_reminders && c.pending_reminders > 0) {
|
if (c.pending_reminders && c.pending_reminders > 0) {
|
||||||
head.append(el('span',
|
head.append(el('span',
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,12 @@ pub struct ContainerView {
|
||||||
/// in the tree. See `docs/agent-hierarchy.md::Current state`.
|
/// in the tree. See `docs/agent-hierarchy.md::Current state`.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub parent: Option<String>,
|
pub parent: Option<String>,
|
||||||
|
/// The Claude model the agent's harness is currently using, read from
|
||||||
|
/// `harness/hyperhive-model`. `None` when the agent has never started
|
||||||
|
/// a turn or the file is absent. Only meaningful when `running` is
|
||||||
|
/// true; the dashboard skips the badge for stopped containers.
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub active_model: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the full container list. Wraps `lifecycle::list()` and
|
/// Build the full container list. Wraps `lifecycle::list()` and
|
||||||
|
|
@ -78,6 +84,14 @@ pub async fn build_all(coord: &Coordinator) -> Vec<ContainerView> {
|
||||||
let needs_login = running
|
let needs_login = running
|
||||||
&& (!claude_has_session(&Coordinator::agent_claude_dir(&logical))
|
&& (!claude_has_session(&Coordinator::agent_claude_dir(&logical))
|
||||||
|| auth_failed_sentinel(&logical));
|
|| auth_failed_sentinel(&logical));
|
||||||
|
// Read the active model from the harness state file. Only surfaced
|
||||||
|
// when the container is running — stale model info from a stopped
|
||||||
|
// agent is misleading (the model may change on next boot).
|
||||||
|
let active_model = if running {
|
||||||
|
read_active_model(&logical)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
out.push(ContainerView {
|
out.push(ContainerView {
|
||||||
port: lifecycle::agent_web_port(&logical),
|
port: lifecycle::agent_web_port(&logical),
|
||||||
running,
|
running,
|
||||||
|
|
@ -88,6 +102,7 @@ pub async fn build_all(coord: &Coordinator) -> Vec<ContainerView> {
|
||||||
deployed_sha,
|
deployed_sha,
|
||||||
pending_reminders,
|
pending_reminders,
|
||||||
parent,
|
parent,
|
||||||
|
active_model,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
|
@ -190,6 +205,20 @@ pub async fn read_agent_status_live(name: &str) -> (Option<String>, Option<i64>,
|
||||||
(text, set_at, true)
|
(text, set_at, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Read the active Claude model from the agent's harness state file
|
||||||
|
/// (`harness/hyperhive-model`). Returns `None` when the file is absent
|
||||||
|
/// or empty — callers should treat `None` as "model not yet known".
|
||||||
|
fn read_active_model(name: &str) -> Option<String> {
|
||||||
|
let path = Coordinator::agent_harness_dir(name).join("hyperhive-model");
|
||||||
|
let s = std::fs::read_to_string(path).ok()?;
|
||||||
|
let trimmed = s.trim();
|
||||||
|
if trimmed.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(trimmed.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Host-side hive + swarm display names, read from the c0re service's
|
/// Host-side hive + swarm display names, read from the c0re service's
|
||||||
/// own process env. The `hive-c0re.nix` module sets these from
|
/// own process env. The `hive-c0re.nix` module sets these from
|
||||||
/// `services.hyperhive.{hiveName, swarmName}`. The agent-side
|
/// `services.hyperhive.{hiveName, swarmName}`. The agent-side
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,7 @@ mod tests {
|
||||||
deployed_sha: None,
|
deployed_sha: None,
|
||||||
pending_reminders: 0,
|
pending_reminders: 0,
|
||||||
parent: None,
|
parent: None,
|
||||||
|
active_model: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue