repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
The Living OS cockpit
stars
latest
clone command
git clone gitlawb://did:key:z6Mku78K...XywC/living-os-cockp...git clone gitlawb://did:key:z6Mku78K.../living-os-cockp...59751530feat: surface worker supervisor health in live work5h ago| #1 | 'use client'; |
| #2 | import useSWR from 'swr'; |
| #3 | import { swrFetcher } from '@/lib/client-api'; |
| #4 | import BrainSwapPanel from '@/components/BrainSwapPanel'; |
| #5 | |
| #6 | const fetcher = swrFetcher; |
| #7 | |
| #8 | function formatUsdc(value?: number | null): string { |
| #9 | if (typeof value !== 'number' || !Number.isFinite(value)) return '-'; |
| #10 | if (value === 0) return '$0.00'; |
| #11 | if (value < 1) return `$${value.toFixed(4)}`; |
| #12 | return `$${value.toFixed(2)}`; |
| #13 | } |
| #14 | |
| #15 | function formatDiem(value?: number | null): string { |
| #16 | if (typeof value !== 'number' || !Number.isFinite(value)) return '0.0000'; |
| #17 | return value.toFixed(4); |
| #18 | } |
| #19 | |
| #20 | function formatCountdown(seconds?: number | null): string { |
| #21 | if (typeof seconds !== 'number' || !Number.isFinite(seconds)) return '--:--'; |
| #22 | const clamped = Math.max(0, Math.floor(seconds)); |
| #23 | const hours = Math.floor(clamped / 3600); |
| #24 | const minutes = Math.floor((clamped % 3600) / 60); |
| #25 | return `${hours}h ${minutes.toString().padStart(2, '0')}m`; |
| #26 | } |
| #27 | |
| #28 | export default function SovereignInfra() { |
| #29 | const { data: spend } = useSWR('/api/spend', fetcher, { refreshInterval: 10000 }); |
| #30 | const { data: antseed } = useSWR('/api/antseed', fetcher, { refreshInterval: 30000 }); |
| #31 | const balance = antseed?.buyerBalance; |
| #32 | const budget = spend?.budget_diem ?? spend?.dailyCapacityUsd ?? 6.03; |
| #33 | const spent = spend?.spent_diem ?? spend?.today?.usd ?? 0; |
| #34 | const percent = Math.min(100, spend?.percent_used ?? spend?.todayBurnPercent ?? 0); |
| #35 | const items = (spend?.items ?? []).slice(-10).reverse(); |
| #36 | const notifications = (spend?.notifications ?? []).slice(-3).reverse(); |
| #37 | |
| #38 | return ( |
| #39 | <div className="space-y-3 text-sm"> |
| #40 | <div> |
| #41 | <div className="text-[color:var(--gold-2)] text-xs uppercase tracking-wider mb-1.5">DIEM epoch compute</div> |
| #42 | <div className="flex justify-between mb-1"> |
| #43 | <span className="text-[color:var(--text-2)]">Spend since 5PM PT</span> |
| #44 | <span className="font-mono">{formatDiem(spent)} / {Number(budget).toFixed(2)} DIEM</span> |
| #45 | </div> |
| #46 | <div className="w-full bg-[color:var(--bg-3)] rounded-full h-2 overflow-hidden"> |
| #47 | <div |
| #48 | className="h-2 rounded-full transition-all" |
| #49 | style={{ |
| #50 | width: `${percent}%`, |
| #51 | background: 'linear-gradient(90deg, var(--gold-2), var(--gold-1))', |
| #52 | }} |
| #53 | /> |
| #54 | </div> |
| #55 | <div className="mt-1 grid grid-cols-2 gap-2 text-[10px] text-[color:var(--text-3)]"> |
| #56 | <span>{spend?.calls ?? spend?.today?.messages ?? 0} debits - {percent.toFixed(1)}% used</span> |
| #57 | <span className="text-right">reset in {formatCountdown(spend?.epoch?.seconds_until_reset)}</span> |
| #58 | </div> |
| #59 | <div className="mt-2 rounded-md border border-[color:var(--border)] bg-black/10 p-2"> |
| #60 | <div className="mb-1 flex items-center justify-between"> |
| #61 | <span className="text-[10px] uppercase tracking-wider text-[color:var(--text-3)]">Epoch breakdown</span> |
| #62 | <span className="font-mono text-[10px] text-[color:var(--text-3)]">{spend?.epoch?.timezone ?? 'America/Los_Angeles'}</span> |
| #63 | </div> |
| #64 | <div className="max-h-32 space-y-1 overflow-y-auto pr-1"> |
| #65 | {items.length ? items.map((item: any) => ( |
| #66 | <div key={item.call_id ?? `${item.timestamp}-${item.model}`} className="grid grid-cols-[1fr_auto] gap-2 text-[10px]"> |
| #67 | <span className="truncate text-[color:var(--text-2)]">{item.task ?? 'unknown'} - {item.model ?? 'unknown'}</span> |
| #68 | <span className="font-mono text-[color:var(--gold-1)]">{formatDiem(item.diem_debited)}</span> |
| #69 | </div> |
| #70 | )) : ( |
| #71 | <div className="text-[10px] text-[color:var(--text-3)]">No DIEM debits recorded in this epoch yet.</div> |
| #72 | )} |
| #73 | </div> |
| #74 | </div> |
| #75 | {notifications.length ? ( |
| #76 | <div className="mt-2 space-y-1"> |
| #77 | {notifications.map((note: any) => ( |
| #78 | <div key={`${note.epoch_id}-${note.threshold_percent}-${note.timestamp}`} className="rounded-md border border-[color:var(--gold-2)]/30 bg-[color:var(--gold-2)]/10 p-2 text-[10px] text-[color:var(--text-2)]"> |
| #79 | <span className="text-[color:var(--gold-1)]">{note.threshold_percent}% ping:</span>{' '} |
| #80 | {formatDiem(note.since_last_ping_diem)} DIEM since last ping, cumulative {formatDiem(note.cumulative_diem)}. |
| #81 | </div> |
| #82 | ))} |
| #83 | </div> |
| #84 | ) : null} |
| #85 | </div> |
| #86 | |
| #87 | <div className="divider-gold" /> |
| #88 | |
| #89 | <div className="grid grid-cols-2 gap-2 text-xs"> |
| #90 | <div> |
| #91 | <div className="text-[color:var(--text-3)]">DIEM staked</div> |
| #92 | <div className="text-[color:var(--gold-1)] font-mono text-base">6.03</div> |
| #93 | </div> |
| #94 | <div> |
| #95 | <div className="text-[color:var(--text-3)]">VVV</div> |
| #96 | <div className="text-[color:var(--text-1)] font-mono text-base">halving Jul</div> |
| #97 | </div> |
| #98 | </div> |
| #99 | |
| #100 | <div className="divider-gold" /> |
| #101 | |
| #102 | <BrainSwapPanel /> |
| #103 | |
| #104 | <div className="divider-gold" /> |
| #105 | |
| #106 | <div> |
| #107 | <div className="text-[color:var(--gold-2)] text-xs uppercase tracking-wider mb-1.5">AntSeed</div> |
| #108 | <div className="space-y-1 text-xs"> |
| #109 | <div className="flex justify-between"> |
| #110 | <span className="text-[color:var(--text-2)]">Seller state</span> |
| #111 | <span className={antseed?.state === 'seeding' ? 'text-green-400' : 'text-amber-400'}> |
| #112 | {antseed?.state ?? '-'} |
| #113 | </span> |
| #114 | </div> |
| #115 | <div className="flex justify-between"> |
| #116 | <span className="text-[color:var(--text-2)]">Channels</span> |
| #117 | <span className="font-mono">{antseed?.activeChannels ?? 0} {antseed?.channelStatus ?? 'idle'}</span> |
| #118 | </div> |
| #119 | <div className="flex justify-between"> |
| #120 | <span className="text-[color:var(--text-2)]">Earned today</span> |
| #121 | <span className="font-mono">${antseed?.earningsToday ?? '0'}</span> |
| #122 | </div> |
| #123 | <div className="flex justify-between"> |
| #124 | <span className="text-[color:var(--text-2)]">Deposit available</span> |
| #125 | <span className="font-mono">{formatUsdc(balance?.depositsAvailable)}</span> |
| #126 | </div> |
| #127 | <div className="flex justify-between"> |
| #128 | <span className="text-[color:var(--text-2)]">Wallet USDC</span> |
| #129 | <span className="font-mono">{formatUsdc(balance?.walletUsdc)}</span> |
| #130 | </div> |
| #131 | <div className="flex justify-between"> |
| #132 | <span className="text-[color:var(--text-2)]">Uptime</span> |
| #133 | <span className="font-mono">{antseed?.uptime ?? '-'}</span> |
| #134 | </div> |
| #135 | </div> |
| #136 | </div> |
| #137 | </div> |
| #138 | ); |
| #139 | } |
| #140 |