Class: TUI::Decorators::BaseDecorator

Inherits:
Object
  • Object
show all
Includes:
Formatting
Defined in:
lib/tui/decorators/base_decorator.rb

Overview

Client-side decorator layer for per-tool TUI rendering.

Mirrors the server’s Draper architecture but with a different specialization axis: server decorators are uniform per EVENT TYPE (tool_call, tool_result, message), while client decorators are unique per TOOL NAME (bash, read_file, web_get) — determining how each tool looks on screen.

The factory dispatches on the tool field in the structured data hash received from the server. Unknown tools fall back to generic rendering provided by this base class.

Examples:

Render a tool call

decorator = TUI::Decorators::BaseDecorator.for(data)
lines = decorator.render(tui)

Constant Summary collapse

ICON =

wrench

"\u{1F527}"
CHECKMARK =
"\u2713"
RETURN_ARROW =
"\u21A9"
ERROR_ICON =
"\u274C"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Formatting

#format_ns_timestamp, #format_token_label, #token_count_color

Constructor Details

#initialize(data) ⇒ BaseDecorator

Returns a new instance of BaseDecorator.



32
33
34
# File 'lib/tui/decorators/base_decorator.rb', line 32

def initialize(data)
  @data = data
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



30
31
32
# File 'lib/tui/decorators/base_decorator.rb', line 30

def data
  @data
end

Class Method Details

.for(data) ⇒ BaseDecorator

Factory returning the per-tool decorator for the given data hash.

Parameters:

  • data (Hash)

    structured event data with string keys (“role”, “tool”, “content”, etc.)

Returns:



41
42
43
44
# File 'lib/tui/decorators/base_decorator.rb', line 41

def self.for(data)
  tool = resolve_tool(data)
  decorator_for(tool).new(data)
end

Instance Method Details

#colorString

Unified color for all tool call headers. Keeps tool invocations visually distinct from conversation messages (user/assistant/thought).

Returns:

  • (String)


122
123
124
# File 'lib/tui/decorators/base_decorator.rb', line 122

def color
  "magenta"
end

#iconString

Icon for this tool type. Subclasses override with tool-specific icons.

Returns:

  • (String)


115
116
117
# File 'lib/tui/decorators/base_decorator.rb', line 115

def icon
  ICON
end

#render(tui) ⇒ Array<RatatuiRuby::Widgets::Line>

Renders the event, dispatching by role to the appropriate method.

Parameters:

  • tui (RatatuiRuby)

    TUI rendering API

Returns:

  • (Array<RatatuiRuby::Widgets::Line>)


50
51
52
53
54
55
56
# File 'lib/tui/decorators/base_decorator.rb', line 50

def render(tui)
  case data["role"].to_s
  when "tool_call" then render_call(tui)
  when "tool_response" then render_response(tui)
  when "think" then render_think(tui)
  end
end

#render_call(tui) ⇒ Array<RatatuiRuby::Widgets::Line>

Generic tool call rendering — icon, tool name, and indented input. Subclasses override for tool-specific presentation.

Parameters:

  • tui (RatatuiRuby)

    TUI rendering API

Returns:

  • (Array<RatatuiRuby::Widgets::Line>)


63
64
65
66
67
68
69
70
71
# File 'lib/tui/decorators/base_decorator.rb', line 63

def render_call(tui)
  style = tui.style(fg: color)
  header = build_call_header
  lines = [tui.line(spans: [tui.span(content: header, style: style)])]
  data["input"].to_s.split("\n", -1).each do |line|
    lines << tui.line(spans: [tui.span(content: "  #{line}", style: style)])
  end
  lines
end

#render_response(tui) ⇒ Array<RatatuiRuby::Widgets::Line>

Generic tool response rendering — success/failure indicator and content. Token counts get their own color-coded span so expensive responses visually jump out in debug mode. Subclasses override for tool-specific presentation.

Parameters:

  • tui (RatatuiRuby)

    TUI rendering API

Returns:

  • (Array<RatatuiRuby::Widgets::Line>)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/tui/decorators/base_decorator.rb', line 80

def render_response(tui)
  indicator = (data["success"] == false) ? ERROR_ICON : CHECKMARK
  tool_id = data["tool_use_id"]
  tokens = data["tokens"]
  style = tui.style(fg: response_color)

  meta_parts = []
  meta_parts << "[#{tool_id}]" if tool_id
  meta_parts << indicator
  prefix = "  #{RETURN_ARROW} #{meta_parts.join(" ")} "

  content_lines = data["content"].to_s.split("\n", -1)
  first_line_spans = [tui.span(content: prefix, style: style)]
  if tokens
    tok_label = format_token_label(tokens, data["estimated"])
    first_line_spans << tui.span(content: "#{tok_label} ", style: tui.style(fg: token_count_color(tokens)))
  end
  first_line_spans << tui.span(content: content_lines.first.to_s, style: style)

  lines = [tui.line(spans: first_line_spans)]
  content_lines.drop(1).each { |line| lines << tui.line(spans: [tui.span(content: "    #{line}", style: style)]) }
  lines
end

#render_think(tui) ⇒ Array<RatatuiRuby::Widgets::Line>

Think rendering — delegated to ThinkDecorator, but base provides a fallback that renders as a generic tool call.

Parameters:

  • tui (RatatuiRuby)

    TUI rendering API

Returns:

  • (Array<RatatuiRuby::Widgets::Line>)


109
110
111
# File 'lib/tui/decorators/base_decorator.rb', line 109

def render_think(tui)
  render_call(tui)
end

#response_colorString

Color for tool response content. Subclasses override for tool-specific colors.

Returns:

  • (String)


128
129
130
# File 'lib/tui/decorators/base_decorator.rb', line 128

def response_color
  "white"
end