Context Since v4.1.0

A popover that shows context window usage and its breakdown.

Context is a recipe and adds no Core code. A popover opens from a ring drawn with two determinate mat-progress-spinners, and lists the tokens used against the limit with a mat-progress-bar and the input, output and reasoning breakdown. It sits in the prompt input chin next to the model selector.

Example

The ring fills as the conversation grows, so usage reads at a glance. Open it for the numbers.

<div buiPopover class="w-64" position="top-end">
<button
matIconButton
buiPopoverTrigger
type="button"
class="small [--icon-button-padding:0.375rem] [--icon-button-progress-spinner-size:1rem]"
aria-label="Context used"
>
<div class="relative flex items-center justify-center">
<mat-progress-spinner
class="absolute [--progress-spinner-indicator-color:var(--color-neutral-a4)]"
mode="determinate"
strokeWidth="14"
value="100"
/>
<mat-progress-spinner
class="[--progress-spinner-indicator-color:var(--color-primary-9)]"
mode="determinate"
strokeWidth="14"
[value]="(used / usage.limit) * 100"
/>
</div>
</button>
<ng-template buiPopoverPortal>
<div buiPopoverContent class="gap-y-3 [--popover-border-radius:var(--radius-xl)]">
<div class="flex items-center justify-between">
<div buiPopoverTitle>Context</div>
<span class="text-neutral-a11 tabular-nums">
{{ used / 1000 }}K / {{ usage.limit / 1000 }}K
</span>
</div>
<mat-progress-bar
class="[--progress-bar-height:0.375rem]"
mode="determinate"
aria-label="Context used"
[value]="(used / usage.limit) * 100"
/>
<div class="flex flex-col gap-y-1">
<div class="flex justify-between">
<span class="text-neutral-a11">Input</span>
<span class="tabular-nums">{{ usage.input / 1000 }}K</span>
</div>
<div class="flex justify-between">
<span class="text-neutral-a11">Output</span>
<span class="tabular-nums">{{ usage.output / 1000 }}K</span>
</div>
<div class="flex justify-between">
<span class="text-neutral-a11">Reasoning</span>
<span class="tabular-nums">{{ usage.reasoning / 1000 }}K</span>
</div>
</div>
</div>
</ng-template>
</div>
import { MatIconButton } from '@angular/material/button';
import { MatProgressBar } from '@angular/material/progress-bar';
import { MatProgressSpinner } from '@angular/material/progress-spinner';
import {
BuiPopover,
BuiPopoverContent,
BuiPopoverPortal,
BuiPopoverTitle,
BuiPopoverTrigger,
} from '@/bui/ui/popover';

Data

The popover reads token counts for the conversation and the model's context limit. Most providers return the counts with each response; update them after every turn.

readonly usage = {
input: 31_200,
output: 8_400,
reasoning: 2_400,
limit: 100_000,
};

readonly used = this.usage.input + this.usage.output + this.usage.reasoning;