From 13de75938663afdc1d9c8baa45707ffca6cf2c48 Mon Sep 17 00:00:00 2001 From: Alexa Amundson <118287761+blackboxprogramming@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:04:23 -0600 Subject: [PATCH] feat: Pi fleet map with live node status and agent capacity --- app/(app)/fleet/page.tsx | 136 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 app/(app)/fleet/page.tsx diff --git a/app/(app)/fleet/page.tsx b/app/(app)/fleet/page.tsx new file mode 100644 index 0000000..7c18750 --- /dev/null +++ b/app/(app)/fleet/page.tsx @@ -0,0 +1,136 @@ +"use client"; +import { useEffect, useState } from "react"; + +interface PiNode { + hostname: string; ip: string; role: "primary" | "secondary" | "backup"; + agent_capacity: number; agents_active: number; + services: string[]; tunnel_active: boolean; + ollama_models: string[]; uptime_pct: number; +} + +const PI_NODES: PiNode[] = [ + { hostname: "aria64", ip: "192.168.4.38", role: "primary", agent_capacity: 22500, agents_active: 0, + services: ["ollama", "agent-runtime", "cloudflared"], tunnel_active: true, + ollama_models: ["qwen2.5:7b", "deepseek-r1:7b"], uptime_pct: 99.9 }, + { hostname: "blackroad-pi", ip: "192.168.4.64", role: "secondary", agent_capacity: 7500, agents_active: 0, + services: ["ollama", "agent-runtime"], tunnel_active: false, + ollama_models: ["llama3.2:3b"], uptime_pct: 99.5 }, + { hostname: "lucidia", ip: "192.168.4.99", role: "backup", agent_capacity: 0, agents_active: 0, + services: ["agent-runtime"], tunnel_active: false, + ollama_models: [], uptime_pct: 98.2 }, +]; + +const ROLE_COLOR: Record = { + primary: "text-green-400 border-green-700", secondary: "text-blue-400 border-blue-700", + backup: "text-zinc-400 border-zinc-700", +}; + +function PingDot({ active }: { active: boolean }) { + return ( + + {active && } + + + ); +} + +export default function FleetPage() { + const [nodes, setNodes] = useState(PI_NODES); + const [reachable, setReachable] = useState>({}); + + useEffect(() => { + // Poll /api/fleet for live status + const poll = async () => { + try { + const r = await fetch("/api/fleet"); + if (r.ok) { + const data = await r.json(); + setNodes(data.nodes ?? PI_NODES); + setReachable(data.reachable ?? {}); + } + } catch {} + }; + poll(); + const id = setInterval(poll, 15_000); + return () => clearInterval(id); + }, []); + + const totalCapacity = nodes.reduce((s, n) => s + n.agent_capacity, 0); + const totalActive = nodes.reduce((s, n) => s + n.agents_active, 0); + + return ( +
+
+

Pi Fleet

+

+ {nodes.length} nodes · {totalCapacity.toLocaleString()} agent capacity · {totalActive.toLocaleString()} active +

+
+ + {/* Summary cards */} +
+ {[ + { label: "Total Capacity", value: totalCapacity.toLocaleString(), sub: "agents" }, + { label: "Active Agents", value: totalActive.toLocaleString(), sub: "running" }, + { label: "Fleet Health", value: `${Math.round(nodes.reduce((s,n)=>s+n.uptime_pct,0)/nodes.length)}%`, sub: "avg uptime" }, + ].map(({ label, value, sub }) => ( +
+

{label}

+

{value}

+

{sub}

+
+ ))} +
+ + {/* Node cards */} +
+ {nodes.map((node) => ( +
+
+
+
+ +

{node.hostname}

+ + {node.role} + +
+

{node.ip}

+
+
+

{node.agent_capacity.toLocaleString()}

+

agent capacity

+
+
+ +
+
+

Services

+
+ {node.services.map((s) => ( + {s} + ))} +
+
+
+

Ollama Models

+
+ {node.ollama_models.length > 0 + ? node.ollama_models.map((m) => ( + {m} + )) + : None configured} +
+
+
+ +
+ Uptime: {node.uptime_pct}% + {node.tunnel_active && ⚡ Cloudflare Tunnel active} +
+
+ ))} +
+
+ ); +}