Module: Kward::CLITranscriptFormatter

Defined in:
lib/kward/cli_transcript_formatter.rb

Overview

Formats conversation messages for terminal transcript display.

Class Method Summary collapse

Class Method Details

.content_part_text(part) ⇒ Object



88
89
90
91
92
93
94
95
96
97
# File 'lib/kward/cli_transcript_formatter.rb', line 88

def content_part_text(part)
  type = MessageAccess.value(part, :type)
  if type == "text"
    MessageAccess.value(part, :text)
  elsif type == "image"
    path = MessageAccess.value(part, :path)
    media_type = MessageAccess.value(part, :media_type) || MessageAccess.value(part, :mimeType) || "image"
    "[#{media_type}#{path ? ": #{path}" : ""}]"
  end
end

.content_text(content) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/kward/cli_transcript_formatter.rb', line 27

def content_text(content)
  case content
  when Array
    content.filter_map { |part| content_part_text(part) }.join("\n")
  else
    content.to_s
  end
end

.decoded_image_size(data) ⇒ Object



113
114
115
116
117
118
119
# File 'lib/kward/cli_transcript_formatter.rb', line 113

def decoded_image_size(data)
  return nil if data.to_s.empty?

  Base64.decode64(data.to_s.gsub(/\s+/, "")).bytesize
rescue ArgumentError
  nil
end

.display_text(message) ⇒ Object



36
37
38
39
40
41
# File 'lib/kward/cli_transcript_formatter.rb', line 36

def display_text(message)
  display_content = MessageAccess.display_content(message)
  return display_content.to_s unless display_content.nil?

  content_text(MessageAccess.content(message))
end

.full_text(message) ⇒ Object



84
85
86
# File 'lib/kward/cli_transcript_formatter.rb', line 84

def full_text(message)
  MessageText.full_text(message)
end

.image_part_reference(part) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/kward/cli_transcript_formatter.rb', line 99

def image_part_reference(part)
  data = MessageAccess.value(part, :data)
  path = MessageAccess.value(part, :path)
  media_type = MessageAccess.value(part, :media_type) || MessageAccess.value(part, :mimeType) || "image"
  {
    status: :attached,
    type: "image",
    label: path.to_s.empty? ? "pasted image" : File.basename(path),
    media_type: media_type,
    size_bytes: decoded_image_size(data),
    path: path
  }
end

.image_parts(message) ⇒ Object



65
66
67
68
69
70
# File 'lib/kward/cli_transcript_formatter.rb', line 65

def image_parts(message)
  content = MessageAccess.content(message)
  return [] unless content.is_a?(Array)

  content.select { |part| MessageAccess.value(part, :type) == "image" }
end

.image_references(message) ⇒ Object



72
73
74
# File 'lib/kward/cli_transcript_formatter.rb', line 72

def image_references(message)
  image_parts(message).map { |part| image_part_reference(part) }
end

.reasoning(message) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/kward/cli_transcript_formatter.rb', line 12

def reasoning(message)
  direct = MessageAccess.value(message, :reasoning_summary)
  return direct.to_s unless direct.to_s.empty?

  content = MessageAccess.content(message)
  return "" unless content.is_a?(Array)

  content.filter_map do |part|
    type = MessageAccess.value(part, :type)
    next unless ["thinking", "reasoning"].include?(type)

    MessageAccess.value(part, :thinking) || MessageAccess.value(part, :reasoning) || MessageAccess.value(part, :text)
  end.join("\n")
end

.synthetic_tool_call(name, id) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/kward/cli_transcript_formatter.rb', line 76

def synthetic_tool_call(name, id)
  {
    "id" => id || "restored_tool",
    "type" => "function",
    "function" => { "name" => name || "tool", "arguments" => "{}" }
  }
end

.user_display_text(message) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/kward/cli_transcript_formatter.rb', line 43

def user_display_text(message)
  display_content = MessageAccess.display_content(message)
  return display_content.to_s unless display_content.nil?

  content = MessageAccess.content(message)
  return content.to_s unless content.is_a?(Array)

  text = content.filter_map do |part|
    next unless MessageAccess.value(part, :type) == "text"

    MessageAccess.value(part, :text)
  end.join("\n")
  ImageAttachments.display_text_without_references(text, ImageAttachments.references_from_text(text).select { |reference| reference[:status] == :attached })
end

.user_transcript_input(message) ⇒ Object



58
59
60
61
62
63
# File 'lib/kward/cli_transcript_formatter.rb', line 58

def user_transcript_input(message)
  content = MessageAccess.content(message)
  return content.to_s unless content.is_a?(Array)

  user_display_text(message)
end