(
(
{
className,
provider,
modelName,
displayName,
usedTokens,
contextWindow,
breakdown,
hitRatePct,
inputTokens,
outputTokens,
...props
},
ref,
) => {
const icon = getProviderIcon(provider);
const name = displayName || modelName;
// Inline pill: provider icon + model name + "X / Y tokens used".
// The "tokens used" tail renders as soon as `contextWindow` is known
// (typically from the leading metadata frame). `usedTokens` lags by a
// tick — it only becomes non-null after the first `message_start`
// usage frame. Showing "— / 200K tokens used" early gives users the
// model's capacity context without waiting for the first byte.
const inline = (
{icon && (
{icon}
)}
{name}
{contextWindow != null && (
{usedTokens != null ? formatTokenCount(usedTokens) : '—'}/{formatTokenCount(contextWindow)} tokens used
)}
);
// Without a breakdown there's no story to tell on hover — return the
// bare inline so we don't add a stray pointer cursor / accessibility
// chrome on chat surfaces that don't capture cross-call usage.
if (!hasAnyBreakdownRow(breakdown)) return inline;
return (
{inline}
Token breakdown
{/* Answer-call row — uses the SAME pretty model name as the
inline pill, plus the input/output split that doesn't fit
in the inline view. */}
{breakdown!.haikuRewriter && (
)}
{breakdown!.haikuClassifier && (
)}
{breakdown!.haikuSummarizer && (
)}
{typeof hitRatePct === 'number' && hitRatePct > 0 && (
Prompt-cache hit: {hitRatePct}% of answer input
)}
);
},
);
function BreakdownRow({
label,
input,
output,
isAnswer,
}: {
label: string;
input?: number;
output?: number;
isAnswer?: boolean;
}) {
return (
{label}
{input != null ? formatTokenCount(input) : '—'} in / {output != null ? formatTokenCount(output) : '—'} out
);
}
ModelDisplay.displayName = 'ModelDisplay';
export interface ModelDisplaySkeletonProps extends React.HTMLAttributes {
/** Also render the right-aligned "tokens used" tail placeholder. The token
* tail only appears once `contextWindow` is known, so the default skeleton
* shows just the left part (provider icon + model name). */
showTokens?: boolean;
}
/**
* Loading placeholder for the {@link ModelDisplay} inline pill. Mirrors its
* layout (provider icon + model name) so the footer doesn't shift when the
* real model metadata resolves. The "tokens used" tail is opt-in via
* `showTokens`, matching ModelDisplay (which only renders it once the context
* window is known).
*/
const ModelDisplaySkeleton = React.forwardRef(
({ className, showTokens = false, ...props }, ref) => (
{/* provider icon */}
{/* model name */}
{/* "X / Y tokens used" tail — only when tokens are expected */}
{showTokens && }
),
);
ModelDisplaySkeleton.displayName = 'ModelDisplaySkeleton';
export { ModelDisplay, ModelDisplaySkeleton };