# ChainOfThought
URL: /docs/primitives/chain-of-thought
Collapsible accordion for grouping reasoning steps and tool calls.
The ChainOfThought primitive groups consecutive reasoning and tool-call parts into a collapsible accordion. Reasoning models emit reasoning tokens and tool calls before producing a final answer. This primitive lets you collapse those intermediate steps behind a "Thinking" toggle.
Grouped Chain of Thought currently plugs into `MessagePrimitive.Parts` via `components.ChainOfThought`. If you're wiring grouped CoT, use that API.
```tsx
import {
AuiIf,
ChainOfThoughtPrimitive,
MessagePrimitive,
} from "@assistant-ui/react";
function AssistantMessage() {
return (
{({ part }) => {
if (part.type === "text") return ;
return null;
}}
);
}
function ChainOfThought() {
return (
Thinking
!s.chainOfThought.collapsed}>
(
{text}
),
tools: {
Fallback: ({ toolName, status }) => (
{toolName}
{status.type === "running" ? "running..." : "done"}
),
},
}}
/>
);
}
```
Quick Start \[#quick-start]
Render your normal message parts with `MessagePrimitive.Parts`, then place a `ChainOfThought` component alongside them inside the same `MessagePrimitive.Root`:
```tsx
import {
ChainOfThoughtPrimitive,
MessagePrimitive,
} from "@assistant-ui/react";
{({ part }) => {
if (part.type === "text") return ;
return null;
}}
function MyChainOfThought() {
return (
Thinking
);
}
```
`Root` renders a `
`, `AccordionTrigger` renders a `
` that toggles the collapsed state, and `Parts` renders the grouped reasoning and tool-call parts.
Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).
Core Concepts \[#core-concepts]
How Grouping Works \[#how-grouping-works]
`ChainOfThoughtPrimitive.Parts` reads the current message's grouped reasoning and tool-call context. In practice, render your normal text/image/data parts with `MessagePrimitive.Parts`, and render `ChainOfThoughtPrimitive` separately where you want the collapsible reasoning block to appear.
Collapsed State \[#collapsed-state]
The accordion starts collapsed by default. `AccordionTrigger` toggles between collapsed and expanded. Use `AuiIf` to conditionally render parts based on the collapsed state:
```tsx
import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
Thinking
!s.chainOfThought.collapsed}>
```
Chevron Indicators \[#chevron-indicators]
Use `AuiIf` to show directional icons that reflect the current state:
```tsx
import { AuiIf, ChainOfThoughtPrimitive } from "@assistant-ui/react";
import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
s.chainOfThought.collapsed}>
!s.chainOfThought.collapsed}>
Thinking
```
Parts Components \[#parts-components]
`ChainOfThoughtPrimitive.Parts` accepts a `components` prop to control how each part type renders:
```tsx
(
{text}
),
tools: {
Fallback: ({ toolName, status }) => (
{status.type === "running" ? `Running ${toolName}...` : `${toolName} completed`}
),
},
Layout: ({ children }) => (
{children}
),
}}
/>
```
| Prop | Type | Description |
| --------------------------- | ---------------------------------- | --------------------------------- |
| `components.Reasoning` | `FC<{ text: string }>` | Renders reasoning parts |
| `components.tools.Fallback` | `ToolCallMessagePartComponent` | Fallback for tool-call parts |
| `components.Layout` | `ComponentType` | Wrapper around each rendered part |
Parts \[#parts]
Root \[#root]
Container for the chain-of-thought disclosure UI. Renders a `` element unless `asChild` is set.
```tsx
...
```
AccordionTrigger \[#accordiontrigger]
Trigger that toggles the collapsed state. Renders a `
` element unless `asChild` is set.
```tsx
Thinking
```
Parts \[#parts-1]
Renders reasoning and tool-call parts. This component does not track collapsed state internally, so control visibility with `AuiIf` as shown in the patterns below.
```tsx
(
{text}
),
tools: {
Fallback: ({ toolName, status }) => (
{status.type === "running" ? `Running ${toolName}...` : `${toolName} completed`}
),
},
}}
/>
```
Patterns \[#patterns]
Minimal Accordion \[#minimal-accordion]
```tsx
function ChainOfThought() {
return (
Thinking
!s.chainOfThought.collapsed}>
(
{text}
),
}}
/>
);
}
```
With Tool Calls \[#with-tool-calls]
```tsx
function ChainOfThought() {
return (
Thinking
!s.chainOfThought.collapsed}>
(
{text}
),
tools: {
Fallback: ({ toolName, status }) => (
{toolName}
{status.type === "running" ? "running..." : "done"}
),
},
Layout: ({ children }) => (
{children}
),
}}
/>
);
}
```
Relationship to Components \[#relationship-to-components]
The [Chain of Thought guide](/docs/guides/chain-of-thought) covers end-to-end setup including backend configuration with reasoning models. See the complete [with-chain-of-thought example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-chain-of-thought) for a full working implementation.
API Reference \[#api-reference]
For the complete guide including backend configuration, see [Chain of Thought](/docs/guides/chain-of-thought). For prop details, see the [ChainOfThoughtPrimitive source](https://github.com/assistant-ui/assistant-ui/tree/main/packages/react/src/primitives/chainOfThought).
Related:
* [Chain of Thought Guide](/docs/guides/chain-of-thought)
* [MessagePrimitive](/docs/primitives/message)