feat: resource_pressure - disk free, CPU freq/throttle/temp, GPU temp via nvidia-smi
This commit is contained in:
@@ -78,6 +78,20 @@ function postureTooltip(agent: Agent): string {
|
||||
if (agent.reboot_pending !== undefined) {
|
||||
lines.push(`Reboot required: ${agent.reboot_pending ? 'YES ⚠' : 'no ✓'}`);
|
||||
}
|
||||
// Resource pressure
|
||||
const tempLabel = agent.gpu_temp_c !== undefined ? `GPU ${agent.gpu_temp_c}°C` : agent.cpu_temp_c !== undefined ? `CPU ${agent.cpu_temp_c}°C` : null;
|
||||
if (tempLabel || agent.disk_free_pct !== undefined || agent.cpu_throttle !== undefined) {
|
||||
lines.push('──────────────────────');
|
||||
if (tempLabel) lines.push(`Temp: ${tempLabel}${agent.cpu_throttle ? ' THROTTLED' : ''}`);
|
||||
if (agent.disk_free_pct !== undefined) {
|
||||
lines.push(`Disk: ${agent.disk_free_gb?.toFixed(1) ?? '?'} GB free (${agent.disk_free_pct}% of ${agent.disk_total_gb?.toFixed(0) ?? '?'} GB)`);
|
||||
}
|
||||
if (agent.cpu_freq_mhz && agent.cpu_max_mhz) {
|
||||
lines.push(`CPU freq: ${agent.cpu_freq_mhz} / ${agent.cpu_max_mhz} MHz`);
|
||||
}
|
||||
if (agent.gpu_usage_pct !== undefined) lines.push(`GPU util: ${agent.gpu_usage_pct}%`);
|
||||
}
|
||||
|
||||
if (agent.services?.length) {
|
||||
lines.push('──────────────────────');
|
||||
lines.push('Services (T1007):');
|
||||
@@ -102,7 +116,34 @@ function pendingBadge(agent: Agent): { label: string; cls: string } | null {
|
||||
function rebootBadge(agent: Agent): { label: string; cls: string } | null {
|
||||
if (agent.reboot_pending === undefined) return null;
|
||||
if (agent.reboot_pending) return { label: 'REBOOT!', cls: 'rb-pending' };
|
||||
return null; // no badge when not pending — cleaner UI
|
||||
return null;
|
||||
}
|
||||
|
||||
// ── Resource pressure badges ───────────────────────────────────────────────
|
||||
|
||||
function thermalBadge(agent: Agent): { label: string; cls: string } | null {
|
||||
const t = agent.gpu_temp_c ?? agent.cpu_temp_c;
|
||||
if (t === undefined) return null;
|
||||
if (t > 80) return { label: `${t}°`, cls: 'therm-hot' };
|
||||
if (t > 65) return { label: `${t}°`, cls: 'therm-warm' };
|
||||
return null; // cool enough — no badge clutter
|
||||
}
|
||||
|
||||
function diskBadge(agent: Agent): { label: string; cls: string } | null {
|
||||
const pct = agent.disk_free_pct;
|
||||
if (pct === undefined) return null;
|
||||
if (pct < 5) return { label: `DISK ${pct}%`, cls: 'disk-crit' };
|
||||
if (pct < 15) return { label: `DISK ${pct}%`, cls: 'disk-warn' };
|
||||
return null; // plenty of space — no badge
|
||||
}
|
||||
|
||||
function throttleBadge(agent: Agent): { label: string; cls: string } | null {
|
||||
if (!agent.cpu_throttle) return null;
|
||||
const pct = agent.cpu_freq_mhz && agent.cpu_max_mhz
|
||||
? Math.round(agent.cpu_freq_mhz / agent.cpu_max_mhz * 100)
|
||||
: null;
|
||||
const label = pct !== null ? `THRTTL ${pct}%` : 'THRTTL';
|
||||
return { label, cls: 'therm-warm' };
|
||||
}
|
||||
|
||||
// ── Service helpers (T1007) ────────────────────────────────────────────────
|
||||
@@ -516,6 +557,24 @@ export default function CruciblePage() {
|
||||
{a.agent_elevated && (
|
||||
<div className="cn-elevated" title="Running as Administrator / root">ADMIN</div>
|
||||
)}
|
||||
{(() => { const tb = thermalBadge(a); return tb && (
|
||||
<div
|
||||
className={`cn-thermal ${tb.cls}`}
|
||||
title={`CPU: ${a.cpu_temp_c ?? '?'}°C GPU: ${a.gpu_temp_c ?? '?'}°C`}
|
||||
>{tb.label}</div>
|
||||
); })()}
|
||||
{(() => { const db = diskBadge(a); return db && (
|
||||
<div
|
||||
className={`cn-disk ${db.cls}`}
|
||||
title={`Disk: ${a.disk_free_gb?.toFixed(1) ?? '?'} GB free of ${a.disk_total_gb?.toFixed(0) ?? '?'} GB`}
|
||||
>{db.label}</div>
|
||||
); })()}
|
||||
{(() => { const trb = throttleBadge(a); return trb && (
|
||||
<div
|
||||
className={`cn-throttle ${trb.cls}`}
|
||||
title={`CPU running at ${a.cpu_freq_mhz ?? '?'} MHz (max ${a.cpu_max_mhz ?? '?'} MHz)`}
|
||||
>{trb.label}</div>
|
||||
); })()}
|
||||
</div>
|
||||
{a.services && a.services.length > 0 && (
|
||||
<div className="cn-services">
|
||||
|
||||
Reference in New Issue
Block a user