// Sacred Valley card: AI Usage — Claude Code token usage + local (OpenClaw/Ollama) // performance, summarised from the Homelab Monitor via /api/ai-usage. import { el, mount } from '../../dom.js'; import { api } from '../../api.js'; let body; const fmt = (n) => { n = Number(n) || 0; if (n >= 1e6) return (n / 1e6).toFixed(1) + 'M'; if (n >= 1e3) return (n / 1e3).toFixed(1) + 'k'; return String(n); }; const dur = (ms) => ms == null ? '—' : (ms >= 1000 ? (ms / 1000).toFixed(1) + 's' : Math.round(ms) + 'ms'); const mono = (t, color) => el('span', { style: { fontFamily: 'var(--font-mono)', ...(color ? { color } : {}) } }, t); async function load() { if (!body) return; try { const u = await api.get('/api/ai-usage'); if (!u.ok) { mount(body, el('span', { class: 'muted' }, 'Monitor unreachable (' + (u.url || '') + ')')); return; } const c = u.claude, l = u.local; mount(body, el('div', { class: 'aiu-sec' }, el('div', { class: 'aiu-h' }, 'Claude Code'), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'today'), mono(`${fmt(c.today.input)}↑ ${fmt(c.today.output)}↓`)), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'cache · turns'), mono(`${fmt(c.today.cache)} · ${c.today.turns}`)), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'week'), mono(`${fmt(c.week.input + c.week.output)} tok`)), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'top model'), mono((c.top_model || '—').replace(/^claude-/, ''), 'var(--accent)')) ), el('div', { class: 'aiu-sec' }, el('div', { class: 'aiu-h' }, 'Local · OpenClaw'), l.top ? el('div', {}, el('div', { class: 'sv-row' }, el('span', { class: 'k' }, l.top.model), mono(`${dur(l.top.p50_ms)} p50 · ${dur(l.top.p95_ms)} p95`)), el('div', { class: 'sv-row' }, el('span', { class: 'k' }, 'runs · err'), mono(`${l.runs} · ${(l.top.error_rate * 100).toFixed(0)}%`))) : el('span', { class: 'muted' }, 'No local runs yet') ), el('a', { class: 'aiu-link', href: 'http://192.168.1.212:8080/', target: '_blank', rel: 'noopener' }, 'Full dashboard ↗') ); } catch { mount(body, el('span', { class: 'muted' }, 'No usage data')); } } export default { id: 'ai-usage', title: 'AI Usage', size: 'm', mount(e) { body = e; load(); }, start() {}, stop() { body = null; } };