# Reasoning

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

```tsx
import { Reasoning } from '@commenda/pathfinder/reasoning';
import { Markdown } from '@commenda/pathfinder/markdown';

<Reasoning isStreaming={isReasoningStreaming} duration={elapsedSeconds}>
  <Markdown content={summary} isStreaming={isReasoningStreaming} />
</Reasoning>;
```


## Usage [#usage]

```tsx
import { Reasoning } from '@commenda/pathfinder/reasoning';
import { Markdown } from '@commenda/pathfinder/markdown';

<Reasoning isStreaming={isReasoningStreaming} duration={elapsedSeconds}>
  <Markdown content={summary} isStreaming={isReasoningStreaming} />
</Reasoning>;
```

## Live activity [#live-activity]


```tsx
import { Reasoning } from '@commenda/pathfinder/reasoning';
import { Markdown } from '@commenda/pathfinder/markdown';

<Reasoning isStreaming={isReasoningStreaming} duration={elapsedSeconds}>
  <Markdown content={summary} isStreaming={isReasoningStreaming} />
</Reasoning>;
```


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

## API reference [#api-reference]

| Prop | Type | Requirement | Behavior |
| --- | --- | --- | --- |
| `children` | `ReactNode` | required | Required app-provided summary; compose Markdown explicitly |
| `isStreaming` | `boolean` | optional | Whether this reasoning part is live, not whether the whole answer is live |
| `duration` | `number` | optional | Supplied elapsed seconds; invalid values use “Thought process” |
| `label` | `string` | optional | Override the trigger for localization |
| `disclosureConfig` | `ActivityDisclosureConfig` | optional | Manual intent overrides automation; controlled open is entirely host-owned |
| `className` | `string` | optional | Layout override |

### disclosureConfig fields

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

## Design rules [#design-rules]

- **REASONING-01:** Only render summaries supplied by the application. Never invent or reconstruct private model reasoning.
- **REASONING-02:** Live content opens automatically. Stop isStreaming when the next message part arrives; collapse after 1s. A user toggle, explicit defaultOpen, or controlled open wins over automation. History starts closed. Use a new React key for a new run.
- **REASONING-03:** Copy13 pearl800, a pearl300 hairline rail, 12px header gap and 12px inset. Compose Pathfinder Markdown when needed; plain text stays lightweight.

`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.
