ReasoningInfo
Compose reasoning status and expandable reasoning steps for assistant messages.
ReasoningInfo
ReasoningInfo in @tambo-ai/react-ui-base exposes reasoning-state behavior with unstyled trigger/content parts.
Demo
import { ReasoningInfo } from "@tambo-ai/react-ui-base/reasoning-info";import type { TamboThreadMessage } from "@tambo-ai/react";import { ChevronDown } from "lucide-react";// message.reasoning is a string[] of reasoning steps// message.reasoningDurationMS is the total thinking timeexport function DemoReasoningInfo({ message }: { message: TamboThreadMessage }) { return ( <ReasoningInfo.Root message={message} isLoading={false} autoCollapse={false}> <ReasoningInfo.Trigger className="flex items-center gap-2 text-sm text-neutral-600 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-100"> <ChevronDown className="h-3.5 w-3.5" /> <ReasoningInfo.StatusText /> </ReasoningInfo.Trigger> <ReasoningInfo.Content className="mt-2 max-h-48 overflow-y-auto rounded-lg border border-neutral-200 bg-neutral-50 p-3 dark:border-neutral-700 dark:bg-neutral-800"> <ReasoningInfo.Steps className="space-y-2 text-sm text-neutral-700 dark:text-neutral-300" /> </ReasoningInfo.Content> </ReasoningInfo.Root> );}Anatomy
<ReasoningInfo.Root message={message}>
<ReasoningInfo.StatusText />
<ReasoningInfo.Trigger />
<ReasoningInfo.Content>
<ReasoningInfo.Steps />
</ReasoningInfo.Content>
</ReasoningInfo.Root>Examples
Custom Step Renderer
<ReasoningInfo.Steps>
{({ steps, showStepNumbers }) =>
steps.map((step, i) => (
<li key={i}>
{showStepNumbers && <span>{i + 1}.</span>} {step}
</li>
))
}
</ReasoningInfo.Steps>Custom Status Text
<ReasoningInfo.StatusText>
{({ text, isLoading, stepCount }) => (
<span>
{isLoading ? "Thinking..." : text}
{stepCount > 1 && ` (${stepCount} steps)`}
</span>
)}
</ReasoningInfo.StatusText>API reference
Root
| Prop | Type | Default | Description |
|---|---|---|---|
message | TamboThreadMessage | undefined | Source message. If omitted, read from a parent Message.Root context. |
defaultExpanded | boolean | true | Initial expanded state. |
autoCollapse | boolean | true | Collapse automatically when the message content arrives and reasoning is complete. |
isLoading | boolean | undefined | Loading flag. If omitted, read from a parent Message.Root context. |
Render state: isExpanded, isLoading, statusText, reasoningCount.
Returns null when the message has no reasoning data.
StatusText
Displays a computed status label (e.g. "Thinking", "Thought for 5 seconds").
Render state: text, isLoading, stepCount.
Default children render text plus a step count suffix when there are multiple steps.
Trigger
Toggles reasoning visibility.
Render state: isExpanded.
Content
Collapsible container for reasoning details. Includes auto-scroll behavior.
| Prop | Type | Default | Description |
|---|---|---|---|
forceMount | boolean | false | Keep mounted regardless of expanded state (for animations). |
Render state: isExpanded.
Steps
Provides reasoning step data for rendering.
Render state: steps (string[]), showStepNumbers (true when steps.length > 1).
showStepNumbers is computed, not a prop.
Accessibility
- Use semantic list markup for custom step renderers.
- Ensure trigger text reflects expand/collapse state.
Styling Hooks
data-slot="reasoning-info"(Root)data-slot="reasoning-info-status-text"data-slot="reasoning-info-trigger"data-slot="reasoning-info-content"data-slot="reasoning-info-steps"data-state="open" | "closed"on Trigger and Contentdata-loadingon StatusText (present when loading)