- CHANGELOG.md: extend [3.7.0] section with 15 new entries covering PermissionsScreen, ThoughtBlock, UKO runtime services, ACMS Phase 2 protocol aliases, DevcontainerHandler protocol completion, DatabaseResourceHandler CRUD/checkpoint, estimation lifecycle hook, user_identity domain events, PLAN_APPLIED/PLAN_CANCELLED enrichment, server serve subcommand, async audit refactor, and CLI flag fixes - README.md: extend Highlights with permissions screen, thought blocks, UKO runtime, database handler, and estimation lifecycle - docs/reference/uko_runtime.md: new reference for UKOQueryInterface, UKOInferenceEngine, and UKOGraphPersistence (issue #891) - docs/reference/tui_permissions.md: new reference for PermissionsScreen, PermissionRequestService, and all domain models (issue #996) - docs/reference/tui_thought_block.md: new reference for ThoughtBlock domain model and ThoughtBlockWidget (issue #1001) - docs/reference/database_handler.md: new reference for DatabaseResourceHandler CRUD and checkpoint methods (issue #1241) - docs/reference/devcontainer_resources.md: add DevcontainerHandler protocol methods section (delete, list_children, diff, create_sandbox) (issue #1242) - docs/reference/tui.md: extend architecture table and add Permissions Screen and Actor Thought Blocks sections ISSUES CLOSED: #1393
4.5 KiB
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 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
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
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 — overall TUI architecture
- Actor Runtime — actor execution model
- Async Architecture — how actor responses are streamed