Class: SwarmCLI::Formatters::HumanFormatter

Inherits:
Object
  • Object
show all
Defined in:
lib/swarm_cli/formatters/human_formatter.rb

Overview

HumanFormatter creates beautiful, detailed real-time output using reusable UI components. Shows everything: agent thinking, tool calls with arguments, results, responses. Uses clean component architecture for maintainability and testability.

Modes:

  • :non_interactive - Full headers, task prompt, complete summary (for single execution)
  • :interactive - Minimal output for REPL (headers shown in welcome screen)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output: $stdout, quiet: false, truncate: false, verbose: false, mode: :non_interactive) ⇒ HumanFormatter

Returns a new instance of HumanFormatter.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 15

def initialize(output: $stdout, quiet: false, truncate: false, verbose: false, mode: :non_interactive)
  @output = output
  @quiet = quiet
  @truncate = truncate
  @verbose = verbose
  @mode = mode

  # Initialize Pastel with TTY detection
  @pastel = Pastel.new(enabled: output.tty?)

  # Initialize state managers
  @color_cache = SwarmCLI::UI::State::AgentColorCache.new
  @depth_tracker = SwarmCLI::UI::State::DepthTracker.new
  @usage_tracker = SwarmCLI::UI::State::UsageTracker.new
  @spinner_manager = SwarmCLI::UI::State::SpinnerManager.new

  # Initialize components
  @divider = SwarmCLI::UI::Components::Divider.new(pastel: @pastel, terminal_width: TTY::Screen.width)
  @agent_badge = SwarmCLI::UI::Components::AgentBadge.new(pastel: @pastel, color_cache: @color_cache)
  @content_block = SwarmCLI::UI::Components::ContentBlock.new(pastel: @pastel)
  @panel = SwarmCLI::UI::Components::Panel.new(pastel: @pastel)

  # Initialize event renderer
  @event_renderer = SwarmCLI::UI::Renderers::EventRenderer.new(
    pastel: @pastel,
    agent_badge: @agent_badge,
    depth_tracker: @depth_tracker,
  )

  # Track last context percentage for warnings
  @last_context_percentage = {}

  # Start time tracking
  @start_time = nil
end

Instance Attribute Details

#spinner_managerObject (readonly)

Returns the value of attribute spinner_manager.



13
14
15
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 13

def spinner_manager
  @spinner_manager
end

Instance Method Details

#on_error(error:, duration: nil) ⇒ Object

Called when swarm execution fails



126
127
128
129
130
131
132
133
134
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 126

def on_error(error:, duration: nil)
  # Defensive: ensure all spinners are stopped before showing error
  @spinner_manager.stop_all

  @output.puts
  @output.puts @divider.full
  print_error(error)
  @output.puts @divider.full
end

#on_log(entry) ⇒ Object

Called for each log entry from SwarmSDK



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 66

def on_log(entry)
  return if @quiet

  case entry[:type]
  when "user_prompt"
    handle_user_request(entry)
  when "agent_step"
    handle_agent_step(entry)
  when "agent_stop"
    handle_agent_stop(entry)
  when "tool_call"
    handle_tool_call(entry)
  when "tool_result"
    handle_tool_result(entry)
  when "agent_delegation"
    handle_agent_delegation(entry)
  when "delegation_result"
    handle_delegation_result(entry)
  when "context_limit_warning"
    handle_context_warning(entry)
  when "model_lookup_warning"
    handle_model_lookup_warning(entry)
  when "compression_started"
    handle_compression_started(entry)
  when "compression_completed"
    handle_compression_completed(entry)
  when "hook_executed"
    handle_hook_executed(entry)
  when "breakpoint_enter"
    handle_breakpoint_enter(entry)
  when "breakpoint_exit"
    handle_breakpoint_exit(entry)
  when "llm_retry_attempt"
    handle_llm_retry_attempt(entry)
  when "llm_retry_exhausted"
    handle_llm_retry_exhausted(entry)
  when "llm_request_failed"
    handle_llm_request_failed(entry)
  end
end

#on_start(config_path:, swarm_name:, lead_agent:, prompt:) ⇒ Object

Called when swarm execution starts



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 52

def on_start(config_path:, swarm_name:, lead_agent:, prompt:)
  @start_time = Time.now

  # Only show headers in non-interactive mode
  if @mode == :non_interactive
    print_header(swarm_name, lead_agent)
    print_prompt(prompt)
    @output.puts @divider.full
    @output.puts @pastel.bold("#{SwarmCLI::UI::Icons::INFO} Execution Log:")
    @output.puts
  end
end

#on_success(result:) ⇒ Object

Called when swarm execution completes successfully



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/swarm_cli/formatters/human_formatter.rb', line 108

def on_success(result:)
  # Defensive: ensure all spinners are stopped before showing result
  @spinner_manager.stop_all

  if @mode == :non_interactive
    # Full result display with summary
    @output.puts
    @output.puts @divider.full
  end

  # Print result (handles mode internally)
  print_result(result)

  # Only print summary in non-interactive mode
  print_summary(result) if @mode == :non_interactive
end