# Chain of thought

Package: @commenda/pathfinder@0.1.0
Page: /docs/components/chain-of-thought
Figma: https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=601-225

```tsx
import { ChainOfThought } from '@commenda/pathfinder/chain-of-thought';

<ChainOfThought
  isStreaming={isReasoningStreaming}
  duration={elapsedSeconds}
  steps={[
    { id: 'summary', type: 'reasoning', content: summary },
    {
      id: toolCallId,
      type: 'tool',
      tool: { name: 'list_entities', status: 'running' },
    },
  ]}
/>;
```


## Usage [#usage]

```tsx
import { ChainOfThought } from '@commenda/pathfinder/chain-of-thought';

<ChainOfThought
  isStreaming={isReasoningStreaming}
  duration={elapsedSeconds}
  steps={[
    { id: 'summary', type: 'reasoning', content: summary },
    {
      id: toolCallId,
      type: 'tool',
      tool: { name: 'list_entities', status: 'running' },
    },
  ]}
/>;
```

## Live activity [#live-activity]


```tsx
import { ChainOfThought } from '@commenda/pathfinder/chain-of-thought';

<ChainOfThought
  isStreaming={isReasoningStreaming}
  duration={elapsedSeconds}
  steps={[
    { id: 'summary', type: 'reasoning', content: summary },
    {
      id: toolCallId,
      type: 'tool',
      tool: { name: 'list_entities', status: 'running' },
    },
  ]}
/>;
```


Use Start/Finish activity to exercise streaming updates. New run resets disclosure intent.

## API reference [#api-reference]

| Prop | Type | Requirement | Behavior |
| --- | --- | --- | --- |
| `steps` | `readonly ChainOfThoughtStep[]` | required | Required ordered list with stable unique IDs |
| `isStreaming` | `boolean` | optional | Live label and elapsed summary |
| `duration` | `number` | optional | Live label and elapsed summary |
| `label` | `string` | optional | Live label and elapsed summary |
| `disclosureConfig` | `ActivityDisclosureConfig` | optional | Outer disclosure; each tool has independent configuration |
| `className` | `string` | optional | Layout override |

### disclosureConfig fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `open` | `boolean` | No |  |
| `defaultOpen` | `boolean` | No |  |
| `onOpenChange` | `((open: boolean) => void)` | No |  |

## Step model [#step-model]

```tsx
type ChainOfThoughtStep =
  | { id: string; type: 'reasoning'; content: ReactNode }
  | { id: string; type: 'tool'; tool: ToolCallProps };
```

Update a step in place using the same ID. Several tool steps may be running concurrently; the host determines when the overall reasoning part ends. An empty list creates an empty disclosure without fabricated progress.

## Design rules [#design-rules]

- **CHAIN-01:** IDs must be unique and stable across streaming updates and reordering. Use toolCallId for tool steps.
- **CHAIN-02:** Figma 600:29113 / 600:32905: 12px between prose groups, 4px between consecutive tool rows; preserve source order and do not invent steps.
- **CHAIN-03:** History starts closed, live starts open and closes after the next part plus 1s. Manual expansion stays respected; each nested tool retains its own disclosure.

`disclosureConfig.onOpenChange` reports user toggle requests. A controlled `open` value delegates timing and persistence to the host. Automatic collapse also preserves a panel containing keyboard focus.

## Accessibility and integration [#accessibility-and-integration]

Disclosure buttons support Enter and Space, preserve focus, and expose `aria-expanded`. Payload copy buttons are outside the disclosure trigger. Pointer disclosure uses the existing 200ms height transition; keyboard and reduced-motion interaction are immediate. Long text wraps while code scrolls inside its own region. Use one meaningful ThinkingIndicator status per active response rather than announcing every streamed token or tool payload.

The application owns requests, cancellation, approval, retries, durations, and history persistence. No AI SDK provider is required. See [AI content integration](/docs/guides/ai-content) for migration mappings; consumer migration is outside this phase.
