React UI Base
Loading...

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

PropTypeDefaultDescription
messageTamboThreadMessageundefinedSource message. If omitted, read from a parent Message.Root context.
defaultExpandedbooleantrueInitial expanded state.
autoCollapsebooleantrueCollapse automatically when the message content arrives and reasoning is complete.
isLoadingbooleanundefinedLoading 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.

PropTypeDefaultDescription
forceMountbooleanfalseKeep 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 Content
  • data-loading on StatusText (present when loading)