Documents
reasoning
reasoning
Type
External
Status
Published
Created
Mar 17, 2026
Updated
May 5, 2026
Updated by
Dosu Bot
Source
View

import { ReasoningSample, ReasoningGroupSample } from "@/components/docs/samples/reasoning";

Getting Started#

Add reasoning#

<InstallCommand shadcn={["reasoning"]} />

This adds a /components/assistant-ui/reasoning.tsx file to your project.

Use in your application#

Previously, reasoning parts were rendered via components.Reasoning and grouped via components.ReasoningGroup on MessagePrimitive.Parts. Both are deprecated; MessagePrimitive.GroupedParts is the supported replacement, and the highlighted lines below show the new pieces.

Render reasoning parts through MessagePrimitive.GroupedParts. Group consecutive reasoning parts with "group-reasoning", then compose ReasoningRoot, ReasoningTrigger, ReasoningContent, and ReasoningText around the grouped children.

While reasoning is streaming, part.status.type === "running". Pass that to defaultOpen so the accordion auto-opens during streaming and lets the user collapse it once the model moves on.

import { MessagePrimitive } from "@assistant-ui/react";
import { MarkdownText } from "@/components/assistant-ui/markdown-text";
import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
import {
  Reasoning,
  ReasoningContent,
  ReasoningRoot,
  ReasoningText,
  ReasoningTrigger,
} from "@/components/assistant-ui/reasoning"; // [!code ++]

const AssistantMessage: FC = () => {
  return (
    <MessagePrimitive.Root className="...">
      <div className="...">
        <MessagePrimitive.GroupedParts // [!code ++]
          groupBy={(part) => { // [!code ++]
            if (part.type === "reasoning") return ["group-reasoning"]; // [!code ++]
            return null; // [!code ++]
          }} // [!code ++]
        > // [!code ++]
          {({ part, children }) => { // [!code ++]
            switch (part.type) { // [!code ++]
              case "group-reasoning": { // [!code ++]
                const running = part.status.type === "running"; // [!code ++]
                return ( // [!code ++]
                  <ReasoningRoot defaultOpen={running}> // [!code ++]
                    <ReasoningTrigger active={running} /> // [!code ++]
                    <ReasoningContent aria-busy={running}> // [!code ++]
                      <ReasoningText>{children}</ReasoningText> // [!code ++]
                    </ReasoningContent> // [!code ++]
                  </ReasoningRoot> // [!code ++]
                ); // [!code ++]
              } // [!code ++]
              case "text": // [!code ++]
                return <MarkdownText />; // [!code ++]
              case "reasoning": // [!code ++]
                return <Reasoning {...part} />; // [!code ++]
              case "tool-call": // [!code ++]
                return part.toolUI ?? <ToolFallback {...part} />; // [!code ++]
              default: // [!code ++]
                return null; // [!code ++]
            } // [!code ++]
          }} // [!code ++]
        </MessagePrimitive.GroupedParts> // [!code ++]
      </div>
      <AssistantActionBar />
      <BranchPicker className="..." />
    </MessagePrimitive.Root>
  );
};

GroupedParts calls your render function for both group nodes and leaf parts. The case "group-reasoning" branch renders the collapsible shell and must render {children}; that is where the individual reasoning parts get placed. The case "reasoning" branch renders each individual reasoning part inside that shell and must not render children. Removing either case breaks rendering.

How It Works#

The component consists of two parts:

  1. Reasoning: Renders individual reasoning message part content (with markdown support)
  2. Composable group pieces (ReasoningRoot, ReasoningTrigger, ReasoningContent, ReasoningText): Wrap grouped reasoning children in a collapsible container

Consecutive reasoning parts are grouped by MessagePrimitive.GroupedParts. Use the composable API below to control the grouped layout.

When using the composable API, ReasoningText is a plain container. Add <MarkdownText /> for markdown rendering.

Variants#

Use the variant prop on ReasoningRoot to change the visual style:

<ReasoningRoot variant="outline">...</ReasoningRoot>
<ReasoningRoot variant="ghost">...</ReasoningRoot>
<ReasoningRoot variant="muted">...</ReasoningRoot>
VariantDescription
outlineRounded border (default)
ghostNo additional styling
mutedMuted background

Legacy ReasoningGroup#

ReasoningGroup is kept for existing code that still uses the deprecated components.ReasoningGroup prop on MessagePrimitive.Parts. New code should use MessagePrimitive.GroupedParts and compose the root/trigger/content pieces directly.

import { ReasoningGroup } from "@/components/assistant-ui/reasoning";

const ReasoningGroupImpl: ReasoningGroupComponent = ({
  children,
  startIndex,
  endIndex,
}) => {
  const isReasoningStreaming = useAuiState((s) => {
    if (s.message.status?.type !== "running") return false;
    const lastIndex = s.message.parts.length - 1;
    if (lastIndex < 0) return false;
    const lastType = s.message.parts[lastIndex]?.type;
    if (lastType !== "reasoning") return false;
    return lastIndex >= startIndex && lastIndex <= endIndex;
  });

  return (
    <ReasoningRoot defaultOpen={isReasoningStreaming}>
      <ReasoningTrigger active={isReasoningStreaming} />
      <ReasoningContent aria-busy={isReasoningStreaming}>
        <ReasoningText>{children}</ReasoningText>
      </ReasoningContent>
    </ReasoningRoot>
  );
};

API Reference#

Composable API#

All sub-components are exported for custom layouts:

ComponentDescription
ReasoningRootCollapsible container with scroll lock
ReasoningTriggerButton with icon, label, and shimmer
ReasoningContentAnimated collapsible content wrapper
ReasoningTextText wrapper with slide/fade animation
ReasoningFadeGradient fade overlay at bottom
import {
  ReasoningRoot,
  ReasoningTrigger,
  ReasoningContent,
  ReasoningText,
  ReasoningFade,
} from "@/components/assistant-ui/reasoning";

<ReasoningRoot variant="muted">
  <ReasoningTrigger active={isStreaming} />
  <ReasoningContent>
    <ReasoningText>{children}</ReasoningText>
  </ReasoningContent>
</ReasoningRoot>
  • ToolGroup - Similar grouping pattern for tool calls
  • PartGrouping - Advanced grouping options for message parts
reasoning | Dosu