Module: Gemlings::UI

Defined in:
lib/gemlings/ui.rb

Defined Under Namespace

Modules: Styles Classes: NullStyle, Spinner, StatusLine

Constant Summary collapse

SPINNER_FRAMES =
%w[⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏].freeze

Class Method Summary collapse

Class Method Details

.code(source) ⇒ Object



161
162
163
164
165
166
# File 'lib/gemlings/ui.rb', line 161

def code(source)
  puts
  highlighted = rouge_formatter.format(rouge_lexer.lex(source))
  highlighted.each_line { |line| puts "  #{line.rstrip}" }
  puts
end

.error(text) ⇒ Object



172
173
174
# File 'lib/gemlings/ui.rb', line 172

def error(text)
  puts Styles.error.render("Error: ") + text
end

.final_answer(text) ⇒ Object



202
203
204
205
# File 'lib/gemlings/ui.rb', line 202

def final_answer(text)
  puts
  puts Styles.final_answer.render("Final answer: ") + text.to_s
end

.observation(text) ⇒ Object



168
169
170
# File 'lib/gemlings/ui.rb', line 168

def observation(text)
  puts Styles.label.render("Result: ") + truncate(text, 200)
end

.plan(text) ⇒ Object



180
181
182
183
184
# File 'lib/gemlings/ui.rb', line 180

def plan(text)
  label = Styles.plan_label.render(" Plan ")
  body = Styles.plan_box.render(text)
  puts "\n#{label}\n#{body}\n"
end

.run_summary(total_steps:, total_duration:, total_tokens:) ⇒ Object



196
197
198
199
200
# File 'lib/gemlings/ui.rb', line 196

def run_summary(total_steps:, total_duration:, total_tokens:)
  parts = ["#{total_steps} #{total_steps == 1 ? "step" : "steps"}", format("%.1fs total", total_duration)]
  parts << total_tokens.to_s if total_tokens.total_tokens > 0
  puts Styles.dim.render(parts.join(" | "))
end

.spinner(message) ⇒ Object



207
208
209
# File 'lib/gemlings/ui.rb', line 207

def spinner(message)
  Spinner.new(message)
end

.status(message) ⇒ Object



176
177
178
# File 'lib/gemlings/ui.rb', line 176

def status(message)
  StatusLine.new(message)
end

.step_metrics(duration:, token_usage:) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'lib/gemlings/ui.rb', line 186

def step_metrics(duration:, token_usage:)
  parts = []
  parts << format("%.1fs", duration) if duration > 0
  parts << token_usage.to_s if token_usage
  return if parts.empty?

  puts Styles.dim.render(parts.join(" | "))
  puts
end

.stream_end ⇒ Object



215
216
217
# File 'lib/gemlings/ui.rb', line 215

def stream_end
  $stderr.print "\n"
end

.stream_token(text) ⇒ Object



211
212
213
# File 'lib/gemlings/ui.rb', line 211

def stream_token(text)
  $stderr.print text
end

.thought(text) ⇒ Object



157
158
159
# File 'lib/gemlings/ui.rb', line 157

def thought(text)
  puts Styles.label.render("Thought: ") + text
end

.welcome ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/gemlings/ui.rb', line 219

def welcome
  if LIPGLOSS_AVAILABLE
    title = Lipgloss::Style.new
      .bold(true)
      .foreground("#7B61FF")
      .render("gemlings")

    version = Styles.dim.render("v#{VERSION}")
    puts "#{title} #{version}"
    puts Styles.dim.render("Code-first AI agents for Ruby")
  else
    puts "gemlings v#{VERSION}"
    puts "Code-first AI agents for Ruby"
  end
  puts
end