Thinking Since v4.1.0

A collapsible reasoning panel that opens while the model thinks, then collapses and reports how long it took. Built on Trace, so it sits naturally among agent activity rows.

Usage

import {
BuiThinking,
BuiThinkingContent,
BuiThinkingIcon,
BuiThinkingLabel,
BuiThinkingPanel,
BuiThinkingTrigger,
} from '@/bui/ui/thinking';
<div buiThinking [streaming]="thinking()">
<button buiThinkingTrigger>
<mat-icon buiThinkingIcon svgIcon="brain" />
<span buiThinkingLabel></span>
</button>
<ng-template buiThinkingPanel>
<div buiThinkingContent>{{ reasoning() }}</div>
</ng-template>
</div>

Example

Bind streaming to the reasoning phase of the reply. The panel expands when streaming starts and collapses when it ends, and the trigger toggles it at any time. Swap the icon for a spinner while the model thinks for a stronger cue.

Which invoices need attention first?

<div buiMessage>
<div buiMessageContent>
<div buiThinking [streaming]="thinking()">
<button buiThinkingTrigger>
@if (thinking()) {
<mat-progress-spinner buiThinkingIcon mode="indeterminate" diameter="16" />
} @else {
<mat-icon buiThinkingIcon svgIcon="brain" />
}
<span buiThinkingLabel></span>
</button>
<ng-template buiThinkingPanel>
<div buiThinkingContent>{{ reasoning() }}</div>
</ng-template>
</div>

<p>{{ answer() }}</p>
</div>
</div>

Label

The label shimmers while streaming. Left empty, it reads Thinking while streaming and Thought for 4s once done, counting the seconds between the start and the end of streaming.

Any content projected into buiThinkingLabel replaces both texts. Angular decides once whether a slot has projected content, so even a conditional block that renders nothing counts as content and the fallback never returns. A custom label therefore renders its finished text itself. The elapsed seconds are available on the root through exportAs.

<div buiThinking #thinking="buiThinking" [streaming]="streaming()">
<button buiThinkingTrigger>
<mat-icon buiThinkingIcon svgIcon="receipt-text" />
<span buiThinkingLabel>
@if (streaming()) {
Reviewing open invoices
} @else {
Reviewed 14 invoices in {{ thinking.elapsed() }}s
}
</span>
</button>
<ng-template buiThinkingPanel>
<div buiThinkingContent>{{ reasoning() }}</div>
</ng-template>
</div>

Duration

A message restored from history never streams on the page, so there is nothing to measure. Pass the stored duration in seconds and the label reports it instead of the elapsed time.

Start with the client that has two overdue invoices. Both are more than 30 days overdue and make up nearly half of your outstanding balance. The other two clients are current, with their remaining invoices due within ten days.

<div buiThinking [duration]="message.thinkingSeconds">
<button buiThinkingTrigger>
<mat-icon buiThinkingIcon svgIcon="brain" />
<span buiThinkingLabel></span>
</button>
<ng-template buiThinkingPanel>
<div buiThinkingContent>{{ message.reasoning }}</div>
</ng-template>
</div>

Expand

expand decides how streaming drives the panel. The trigger toggles it in every mode.

auto
Opens while streaming and collapses when done. The default.
open
Opens while streaming and stays open after.
manual
Never opens or collapses on its own.
<div buiThinking expand="open" [streaming]="thinking()">
...
</div>

API Reference

buiThinking

Root. Tracks streaming and drives the expanded state.

InputTypeDefaultDescription
streamingbooleanfalseWhether the model is reasoning.
durationnumber — Seconds shown in the label instead of the measured time.
expand'auto' | 'open' | 'manual''auto'How streaming opens and collapses the panel.
expandedbooleanfalseTwo-way binding for the expanded state, with (expandedChange).
elapsedSignal<number>0Read only. Seconds the last streaming phase took.

buiThinkingTrigger

The button that toggles the panel. Draws the chevron after its content.

buiThinkingIcon

Leading icon slot, such as a brain or a progress spinner.

buiThinkingLabel

Label slot. Shows the projected content, or the built in text when empty.

buiThinkingPanel

Goes on an ng-template. Creates the content on open and destroys it on close.

buiThinkingContent

The reasoning, with a rail beside it.