Class: Space::Architect::Research::Renderer

Inherits:
Object
  • Object
show all
Defined in:
lib/space_architect/research/renderer.rb

Overview

Pure, testable verbosity-gated renderer for stream-json events.

Levels (§5.3 ladder):

0 (quiet)  — nothing
1 (default) — lifecycle + terminal line only
2 (-v)     — + assistant text
3 (-vv)    — + tool-call names
4 (-vvv)   — + tool-call inputs and results

–thinking: + assistant thinking blocks (any level > 0) –jsonl: emit raw lane-tagged jsonl instead of human text

Instance Method Summary collapse

Constructor Details

#initialize(level:, thinking: false, jsonl: false) ⇒ Renderer

Returns a new instance of Renderer.



17
18
19
20
21
# File 'lib/space_architect/research/renderer.rb', line 17

def initialize(level:, thinking: false, jsonl: false)
  @level    = level
  @thinking = thinking
  @jsonl    = jsonl
end

Instance Method Details

#lifecycle?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/space_architect/research/renderer.rb', line 79

def lifecycle?
  @level >= 1 && !@jsonl
end

#render(lane:, events:, alive:) ⇒ Object

Render a batch of events for a lane. alive: true → lane still in flight (lifecycle prefix) alive: false → lane finished (terminal line included) Returns a String (may be empty).



27
28
29
30
31
32
33
34
35
36
37
38
39
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
77
# File 'lib/space_architect/research/renderer.rb', line 27

def render(lane:, events:, alive:)
  return "" if @level == 0 && !@jsonl

  if @jsonl
    return events.map { |ev| "[#{lane}] #{JSON.generate(ev)}" }.join("\n").then { |s| s.empty? ? s : "#{s}\n" }
  end

  lines = []
  terminal = nil

  events.each do |ev|
    case ev["type"]
    when "assistant"
      Array(ev.dig("message", "content")).each do |block|
        case block["type"]
        when "thinking"
          lines << "[#{lane}] #{block['thinking'].to_s.strip}" if @thinking && @level >= 1
        when "text"
          lines << "[#{lane}] #{block['text'].to_s.strip}" if @level >= 2
        when "tool_use"
          if @level >= 3
            name_line = "[#{lane}] tool: #{block['name']}"
            if @level >= 4
              input = block["input"]
              name_line += " #{JSON.generate(input)}" if input && !input.empty?
            end
            lines << name_line
          end
        end
      end
    when "user"
      Array(ev.dig("message", "content")).each do |block|
        next unless block["type"] == "tool_result"
        next unless @level >= 4

        content = block["content"]
        lines << "[#{lane}] tool_result: #{content.to_s.strip}"
      end
    when "result"
      terminal = ev
    end
  end

  if terminal
    lines << terminal_line(lane, terminal)
  elsif alive && @level >= 1 && events.empty?
    lines << "[#{lane}] running"
  end

  lines.reject(&:empty?).join("\n").then { |s| s.empty? ? s : "#{s}\n" }
end