Components
RunMeter
Tokens, estimated cost from your rates, time to first token and the prompt-cache hit rate.
Example
Run
mock-agent-1- Tokens
- 41.1k
- Est. cost
- $0.056
- Input 38.7k(28.8k cached)
- Output 2.41k(96 reasoning)
- TTFT
- 684ms
- Total
- 21.8s
- Cache hit
- 74%
$0.032 input · $0.024 output · $2.5/$10 per 1M
Pass totalUsage from streamText through message metadata, and timing from useRunTiming(status). Cost is an estimate from the pricing you supply.
Interactive, and the same on the components page. Try the keyboard below on it.
Installation
npm i @dgesteves/agent-ui-kit aiimport { RunMeter, useRunTiming } from '@dgesteves/agent-ui-kit';
// Once per app (with Tailwind v4: @import '@dgesteves/agent-ui-kit/tailwind.css'; in your CSS)
import '@dgesteves/agent-ui-kit/styles.css';npx shadcn@latest add @agent-ui-kit/run-meterimport { RunMeter } from '@/components/agent-ui/run-meter';
import { useRunTiming } from '@/components/agent-ui/lib/hooks';The styles are once per app; Getting started has the Tailwind v4 and plain CSS options.
Usage
const timing = useRunTiming(status);
<RunMeter
variant="expanded"
usage={last?.metadata?.usage}
pricing={{ input: 2.5, cachedInput: 0.25, output: 10 }} // USD per million tokens
ttftMs={timing.ttftMs}
durationMs={timing.activeMs}
live={status === 'streaming'}
/>API reference
Generated from the types the package ships, so it matches the version you install.
RunMeter
Token usage, estimated cost and latency for an agent run.
compact is a single inline strip for headers; expanded is a card with a
token breakdown bar and the prompt-cache hit rate.
Props
usageRunUsagepricingModelPricingUsed to estimate cost when
costis not given.costnumberExplicit cost in USD, e.g. reported by your gateway.
ttftMsnumberTime to first token, ms.
durationMsnumberTotal (active) run time, ms.
livebooleanDefaultfalseThe run is in progress: values are live.
modelstringvariant'compact' | 'expanded'Default'compact'titleReactNodeDefault'Run'Heading for the expanded variant.
headingLevelHeadingLevelDefault3Heading level for the expanded variant's title.
Other props go to the root <div>: className (merged with tailwind-merge), id, aria-*, data-* and event handlers.
ModelPricing
USD per million tokens.
inputrequirednumberoutputrequirednumbercachedInputnumberPrice for cache-read input tokens. Defaults to
input.cacheWritenumberPrice for input tokens written to the prompt cache (e.g. 1.25x input on Anthropic). Defaults to
input.
RunUsage
Token usage, compatible with the AI SDK LanguageModelUsage shape.
type RunUsage = {
inputTokens?: number | undefined;
outputTokens?: number | undefined;
totalTokens?: number | undefined;
inputTokenDetails?: Partial<LanguageModelUsage['inputTokenDetails']> | undefined;
outputTokenDetails?: Partial<LanguageModelUsage['outputTokenDetails']> | undefined;
};Accessibility
- The compact strip is a group named "Run metrics" with one visually hidden sentence, such as "20.9k input tokens, 255 output tokens, estimated cost $0.025, …", instead of a run of loose numbers.
- The expanded card has a heading (
title, atheadingLevel) and a labelled token breakdown list. - Numbers tween as they change, except with
prefers-reduced-motion.
Theming
Every color, radius and font is a CSS variable, so the overrides in Theming apply, on :root or scoped to any element. These hooks are read from the component's markup.
- Slots (data-slot)
- run-meter
- State attributes
- data-varianton
run-meter'compact' | 'expanded' - Tokens it uses
- --aui-accent--aui-accent-fg--aui-border--aui-chart-input--aui-chart-output--aui-fg--aui-fg-muted--aui-fg-subtle--aui-font-mono--aui-font-sans--aui-radius--aui-ring--aui-surface--aui-surface-2
/* Only this component, and only inside .settings-panel */
.settings-panel [data-slot='run-meter'] {
--aui-radius: 4px;
}
[data-slot='run-meter'][data-variant='compact'] {
outline: 1px solid var(--aui-accent);
}