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#
Pass the Reasoning and ReasoningGroup components to the MessagePrimitive.Parts component:
import { MessagePrimitive } from "@assistant-ui/react";
import { Reasoning } from "@/components/assistant-ui/reasoning";
const AssistantMessage: FC = () => {
return (
<MessagePrimitive.Root className="...">
<div className="...">
<MessagePrimitive.Parts>
{({ part }) => {
if (part.type === "reasoning") return <Reasoning {...part} />;
return null;
}}
</MessagePrimitive.Parts>
</div>
<AssistantActionBar />
<BranchPicker className="..." />
</MessagePrimitive.Root>
);
};
How It Works#
The component consists of two parts:
Reasoning: Renders individual reasoning message part content (with markdown support)ReasoningGroup: Wraps consecutive reasoning parts in a collapsible container
Consecutive reasoning parts are automatically grouped together by the ReasoningGroup component.
When using the composable API,
Reasoning.Textis a plain container. Add<MarkdownText />for markdown rendering.
Variants#
Use the variant prop on Reasoning.Root to change the visual style:
<Reasoning.Root variant="outline">...</Reasoning.Root>
<Reasoning.Root variant="ghost">...</Reasoning.Root>
<Reasoning.Root variant="muted">...</Reasoning.Root>
| Variant | Description |
|---|---|
outline | Rounded border (default) |
ghost | No additional styling |
muted | Muted background |
ReasoningGroup#
ReasoningGroup wraps consecutive reasoning parts in a collapsible container. It auto-expands during streaming.
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:
| Component | Description |
|---|---|
Reasoning.Root | Collapsible container with scroll lock |
Reasoning.Trigger | Button with icon, label, and shimmer |
Reasoning.Content | Animated collapsible content wrapper |
Reasoning.Text | Text wrapper with slide/fade animation |
Reasoning.Fade | Gradient fade overlay at bottom |
import {
Reasoning,
ReasoningRoot,
ReasoningTrigger,
ReasoningContent,
ReasoningText,
ReasoningFade,
} from "@/components/assistant-ui/reasoning";
// Compound component syntax
<Reasoning.Root variant="muted">
<Reasoning.Trigger active={isStreaming} />
<Reasoning.Content>
<Reasoning.Text>{children}</Reasoning.Text>
</Reasoning.Content>
</Reasoning.Root>
Related Components#
- ToolGroup - Similar grouping pattern for tool calls
- PartGrouping - Experimental API for grouping message parts