/** * UsageSection — personal usage statistics */ const { html } = window; const { useState, useEffect } = hooks; function esc(s) { return s == null ? '' : String(s); } function fmt(n) { return n == null ? '0' : n.toLocaleString(); } export function UsageSection() { const [usage, setUsage] = useState(null); useEffect(() => { // Use the generic API escape hatch since there's no dedicated namespace sw.api.get('/api/v1/profile/usage').then(data => { setUsage(data); }).catch(() => setUsage({})); }, []); if (usage === null) { return html`
Loading usage\u2026
`; } const totals = usage.totals || usage; const byModel = usage.by_model || []; return html`

Totals

${[ ['Requests', totals.request_count], ['Input Tokens', totals.input_tokens], ['Output Tokens', totals.output_tokens], ['Total Tokens', totals.total_tokens], ].map(([label, val]) => html`
${label}
${fmt(val)}
`)}
${byModel.length > 0 && html`

By Model

${byModel.map(m => html` `)}
ModelRequestsTokens
${esc(m.model_id || m.model)} ${fmt(m.request_count)} ${fmt(m.total_tokens)}
`} `; }