# TUI — Actor Thought Blocks Actor thought blocks display the reasoning traces produced by actors that support extended thinking (e.g. Claude's extended thinking mode). Thought blocks are rendered in the conversation stream with muted styling and can be expanded or collapsed by the user. Introduced in v3.7.0 (issue #1001). See also [`tui.md`](tui.md) for the overall TUI architecture. --- ## Overview When an actor emits a reasoning trace, the TUI wraps it in a `ThoughtBlockWidget`. By default the widget shows at most 10 lines with a truncation indicator; pressing `Space` expands it to show the full content. ``` ▶ [Thinking — 3 more lines hidden] I need to consider the edge cases for the validation logic. First, let me check whether the input can be None... The schema requires a non-empty string, so... [Space to expand] ``` After expanding: ``` ▼ [Thinking] I need to consider the edge cases for the validation logic. First, let me check whether the input can be None... The schema requires a non-empty string, so... I should also handle the case where the string is whitespace-only. The validator strips whitespace before checking length. ... ``` --- ## ThoughtBlock Domain Model **Module**: `cleveragents.domain.models.thought.thought_block` `ThoughtBlock` is a plain Python dataclass that holds the content and display state of a single reasoning trace. ### Fields | Field | Type | Default | Description | |-------|------|---------|-------------| | `content` | `str` | — | Full text content of the thought | | `max_lines` | `int` | `10` | Maximum lines shown when collapsed | | `expanded` | `bool` | `False` | Whether the block is currently expanded | ### Methods | Method | Returns | Description | |--------|---------|-------------| | `lines()` | `list[str]` | All content lines | | `visible_lines()` | `list[str]` | Lines visible in the current state (up to `max_lines` when collapsed) | | `is_truncated()` | `bool` | `True` when content is truncated in collapsed state | | `hidden_line_count()` | `int` | Number of lines hidden when collapsed | | `toggle()` | `None` | Toggle expanded/collapsed state | | `expand()` | `None` | Expand to show full content | | `collapse()` | `None` | Collapse to `max_lines` | ### Usage Example ```python from cleveragents.domain.models.thought.thought_block import ThoughtBlock block = ThoughtBlock( content="Line 1\nLine 2\nLine 3\n...\nLine 15", max_lines=10, ) print(block.is_truncated()) # True (15 lines > 10) print(block.hidden_line_count()) # 5 print(len(block.visible_lines())) # 10 block.toggle() print(block.expanded) # True print(len(block.visible_lines())) # 15 (all lines) ``` --- ## ThoughtBlockWidget **Module**: `cleveragents.tui.widgets.thought_block` `ThoughtBlockWidget` is a Textual `Static` subclass that renders a `ThoughtBlock` domain model with muted styling. ### CSS Classes | Class | Applied when | |-------|-------------| | `thought-block` | Always (base muted styling) | | `thought-block--collapsed` | Block is collapsed | | `thought-block--expanded` | Block is expanded | ### Indicators | Indicator | Meaning | |-----------|---------| | `▶` | Block is collapsed; press `Space` to expand | | `▼` | Block is expanded; press `Space` to collapse | ### Methods | Method | Returns | Description | |--------|---------|-------------| | `toggle()` | `None` | Toggle expanded/collapsed state and re-render | | `expand()` | `None` | Expand the block | | `collapse()` | `None` | Collapse the block | ### Keyboard Binding The `Space` key is bound to `toggle()` when the widget is focused within the conversation stream. ### Usage Example ```python from cleveragents.domain.models.thought.thought_block import ThoughtBlock from cleveragents.tui.widgets.thought_block import ThoughtBlockWidget block = ThoughtBlock(content="I need to think about this...\n" * 20) widget = ThoughtBlockWidget(block) # Programmatically expand widget.expand() ``` --- ## Integration with the Conversation Stream The main TUI conversation widget creates a `ThoughtBlockWidget` whenever an actor message contains a reasoning trace. Thought blocks appear inline in the conversation, visually distinguished from regular message content by the `thought-block` CSS class (rendered in a muted/dimmed colour). --- ## Related Documentation - [TUI Reference](tui.md) — overall TUI architecture - [Actor Runtime](actor_runtime.md) — actor execution model - [Async Architecture](async_architecture.md) — how actor responses are streamed