Fork Horse repository, listed by its owner. Publisher snapshot.

packages/forkhorse-dashboard/src/usage.tsx

Snapshot at 34e3175

Containing directory

4,516 bytes · textView raw
1import { Badge, Tooltip } from "@cloudflare/kumo";
2import type { ReactNode } from "react";
3import type { Brand, TokenBudgetState, Usage, UsageSources } from "./contracts.ts";
4import { relativeTime } from "./time.ts";
5import { tokenNumber, totalTokens, usageTooltip, usageValues } from "./usage.ts";
6
7function SourceFigure({
8  value, agent, brand, split = false, compact = false, focusable = true, budget, children,
9}: {
10  value: Usage;
11  agent: string;
12  brand: Brand;
13  split?: boolean;
14  compact?: boolean;
15  focusable?: boolean;
16  budget?: number | null;
17  children?: ReactNode;
18}) {
19  const fullDetails = `${totalTokens(value).toLocaleString("en-US")} tokens: ${value.inputTokens.toLocaleString("en-US")} in · ${value.outputTokens.toLocaleString("en-US")} out · ${value.source}${value.model ? ` · ${value.model} (reported)` : ""} · as of ${relativeTime(value.at)}. ${usageTooltip(value, agent, brand)}`;
20  return (
21    <span className={`usage-source caption tabular${compact ? " usage-compact" : ""}`}>
22      <Tooltip content={compact ? fullDetails : usageTooltip(value, agent, brand)} render={<span className={`usage-figure${split ? " usage-split" : ""}`} tabIndex={compact ? (focusable ? 0 : -1) : undefined} aria-label={compact ? fullDetails : undefined} />}>
23        {compact ? `${tokenNumber(totalTokens(value))} ${value.source}` : (
24          <>
25            {split ? <>
26              <span>{tokenNumber(value.inputTokens)} in ·</span>{" "}
27              <span>{tokenNumber(value.outputTokens)} out ·</span>{" "}
28              <span>{value.source} by {agent}</span>
29            </> : <>
30              {budget != null ? `${tokenNumber(totalTokens(value))} / ${tokenNumber(budget)} tokens` : `${tokenNumber(totalTokens(value))} tokens`}
31              {` · ${value.source}`}
32            </>}
33          </>
34        )}
35      </Tooltip>
36      {!compact && <>
37        {children}
38        <span className="usage-freshness caption muted">as of {relativeTime(value.at)}</span>
39        {split && value.model && <span className="usage-model caption muted">{value.model} (reported)</span>}
40      </>}
41    </span>
42  );
43}
44export function UsageFigures({
45  usage, agent, brand, split = false, compact = false, focusable = true,
46}: {
47  usage?: UsageSources;
48  agent: string;
49  brand: Brand;
50  split?: boolean;
51  compact?: boolean;
52  focusable?: boolean;
53}) {
54  const values = usageValues(usage);
55  if (!values.length) return <span className="caption text-color-kumo-subtle usage-missing">Not reported</span>;
56  return (
57    <span className="usage-figures">
58      {values.map((value) => <SourceFigure key={value.source} value={value} agent={agent} brand={brand} split={split} compact={compact} focusable={focusable} />)}
59    </span>
60  );
61}
62export function BudgetUsage({
63  usage, budget, status, agent, brand,
64}: {
65  usage?: UsageSources;
66  budget?: number | null;
67  status?: TokenBudgetState;
68  agent: string;
69  brand: Brand;
70}) {
71  if (budget == null) return <UsageFigures usage={usage} agent={agent} brand={brand} />;
72  // Core chooses metered first and owns the boundary state; never combine the sources.
73  const value = usage?.metered ?? usage?.reported;
74  const unchecked = !value || status === "unchecked" || status === undefined;
75  const warning = (
76    <Tooltip content={value ? "Budget status unavailable." : `${agent} hasn't reported usage.`} render={<span />}>
77      <Badge appearance="dot" variant="neutral" className="caption status-dot status-warning">Budget unchecked</Badge>
78    </Tooltip>
79  );
80  const label = status === "over" ? "Over budget" : status === "near" ? "Near budget" : "Within budget";
81  return (
82    <div className="budget-usage">
83      {!value ? <><UsageFigures usage={usage} agent={agent} brand={brand} />{warning}</> :
84        usageValues(usage).map((source) => (
85          <SourceFigure key={source.source} value={source} budget={budget} agent={agent} brand={brand}>
86            {source === value && (unchecked ? warning :
87              <span className={`token-budget token-budget-${status}`}>
88                <meter min={0} max={budget} value={totalTokens(value)} aria-label={`${label} (${value.source})`}
89                  aria-valuetext={`${totalTokens(value).toLocaleString("en-US")} of ${budget.toLocaleString("en-US")} tokens (${value.source})`} />
90                <span className="caption token-budget-state">{status !== "within" && <span aria-hidden="true">● </span>}{label}</span>
91              </span>
92            )}
93          </SourceFigure>
94        ))}
95    </div>
96  );
97}
98