Module: SwarmCLI::V3::EventRenderer
- Defined in:
- lib/swarm_cli/v3/event_renderer.rb
Overview
Stateless formatter for V3 agent events.
Converts event hashes (emitted by SwarmSDK::V3::EventStream) into styled terminal strings. Returns nil for unrecognized event types so the caller can silently skip them.
Constant Summary collapse
- TOOL_EMOJIS =
{ "Read" => "\u{1F4D6}", "Write" => "\u{270F}\u{FE0F}", "Edit" => "\u{1F527}", "Bash" => "\u{1F4BB}", "Grep" => "\u{1F50D}", "Glob" => "\u{1F4C2}", "Think" => "\u{1F4AD}", "Reboot" => "\u{1F504}", "Clock" => "\u{1F550}", "SubTask" => "\u{1F41D}", }.freeze
Class Method Summary collapse
-
.format(event) ⇒ String?
Format an event hash into a styled terminal string.
-
.format_activity(event) ⇒ String?
Format a memory event as a short activity status string.
-
.format_defrag_progress(event) ⇒ String?
Format a defrag progress event for activity indicator display.
-
.format_tool_args(args) ⇒ String
Format tool arguments as a compact key: value string.
-
.format_tool_result(text, max_lines: 3, max_line_length: 100) ⇒ String
Format tool result preview with multiline support.
-
.truncate(text, max) ⇒ String
Truncate text to a maximum length, replacing newlines with return arrows.
Class Method Details
.format(event) ⇒ String?
Format an event hash into a styled terminal string.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 40 def format(event) case event[:type] when "tool_call" emoji = TOOL_EMOJIS[event[:tool]] || "\u{1F527}" args = format_tool_args(event[:arguments]) " #{emoji} #{ANSIColors.dim("#{event[:tool]}(#{args})")}" when "tool_result" format_tool_result(event[:result_preview]) when "subtask_spawned" ANSIColors.magenta(" \u{1F41D} SubTask spawned: #{event[:title]} (depth: #{event[:depth]})") when "subtask_completed" ANSIColors.green(" \u{2705} SubTask completed: #{event[:title]}") when "subtask_failed" ANSIColors.red(" \u{274C} SubTask failed: #{event[:title]} \u{2014} #{event[:error]}") when "memory_retrieval", "memory_wait_ingestion", "memory_eviction" label = event[:type].sub("memory_", "").tr("_", " ") ANSIColors.dim(" \u{1F9E0} #{label} (#{event[:elapsed_ms]}ms)") when "tool_skipped" ANSIColors.yellow(" \u{23ED}\u{FE0F} #{event[:tool]} skipped (steering)") when "steering_injected" ANSIColors.yellow(" \u{1F3AF} Steering injected (#{event[:message_count]} message#{"s" if event[:message_count] != 1})") when "follow_up_injected" ANSIColors.cyan(" \u{1F4CB} Follow-up processing (#{event[:message_count]} message#{"s" if event[:message_count] != 1})") when "memory_defrag_start" ANSIColors.cyan(" \u{1F9F9} Starting defrag (#{event[:total_cards]} cards, #{event[:total_clusters]} clusters)") when "memory_defrag_complete" ANSIColors.green(" \u{2705} Defrag complete in #{event[:elapsed_ms]}ms") when "loop_started" ANSIColors.cyan(" \u{1F504} Starting refinement (max #{event[:max_iterations]} iterations)") when "loop_iteration_completed" delta = event[:delta_score] ? " (similarity: #{(event[:delta_score] * 100).round(1)}%)" : "" ANSIColors.dim(" \u{1F504} Iteration #{event[:iteration]} complete#{delta}") when "loop_completed" label = event[:converged] ? "converged" : "#{event[:iterations]} iterations" ANSIColors.green(" \u{2705} Refinement complete (#{label})") end end |
.format_activity(event) ⇒ String?
Format a memory event as a short activity status string.
Used by the activity indicator to show memory operations inline on the “Working…” line rather than as separate output lines.
96 97 98 99 100 101 102 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 96 def format_activity(event) case event[:type] when "memory_retrieval", "memory_wait_ingestion", "memory_eviction" label = event[:type].sub("memory_", "").tr("_", " ") "\u{1F9E0} #{label}: #{event[:elapsed_ms]}ms" end end |
.format_defrag_progress(event) ⇒ String?
Format a defrag progress event for activity indicator display.
82 83 84 85 86 87 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 82 def format_defrag_progress(event) return unless event[:type] == "memory_defrag_progress" pct = (event[:overall_current].to_f / event[:overall_total] * 100).round "\u{1F9F9} [#{pct}%] #{event[:description]}" end |
.format_tool_args(args) ⇒ String
Format tool arguments as a compact key: value string.
157 158 159 160 161 162 163 164 165 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 157 def format_tool_args(args) return "" if args.nil? || args.empty? pairs = args.map do |k, v| val = v.is_a?(String) ? "\"#{truncate(v, 50)}\"" : truncate(v.inspect, 50) "#{k}: #{val}" end truncate(pairs.join(", "), 120) end |
.format_tool_result(text, max_lines: 3, max_line_length: 100) ⇒ String
Format tool result preview with multiline support.
Shows up to 3 lines, truncates long lines, and indicates when content is truncated. Each line is indented and dimmed.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 113 def format_tool_result(text, max_lines: 3, max_line_length: 100) return ANSIColors.dim(" \u{21B3} (empty)") if text.nil? || text.to_s.strip.empty? lines = text.to_s.lines.map(&:chomp) truncated_vertically = lines.size > max_lines # Take first max_lines display_lines = lines.first(max_lines) # Truncate each line horizontally formatted = display_lines.map do |line| truncated_line = if line.length > max_line_length "#{line[0...max_line_length]}\u{2026}" else line end ANSIColors.dim(" \u{21B3} #{truncated_line}") end # Add ellipsis indicator if truncated vertically if truncated_vertically remaining = lines.size - max_lines formatted << ANSIColors.dim(" \u{21B3} \u{2026} (#{remaining} more line#{"s" if remaining != 1})") end formatted.join("\n") end |
.truncate(text, max) ⇒ String
Truncate text to a maximum length, replacing newlines with return arrows.
146 147 148 149 150 151 |
# File 'lib/swarm_cli/v3/event_renderer.rb', line 146 def truncate(text, max) return "" if text.nil? text = text.to_s.tr("\n", "\u{21B5}") text.length > max ? "#{text[0...max]}\u{2026}" : text end |