Module: RubyLLM::Providers::Bedrock::Media

Included in:
RubyLLM::Providers::Bedrock
Defined in:
lib/ruby_llm/providers/bedrock/media.rb

Overview

Media formatting for Bedrock Converse content blocks.

Class Method Summary collapse

Class Method Details

.empty_content?(content) ⇒ Boolean



19
20
21
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 19

def empty_content?(content)
  content.nil? || (content.respond_to?(:empty?) && content.empty?)
end

.render_attachment(attachment, used_document_names:) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 37

def render_attachment(attachment, used_document_names:)
  case attachment.type
  when :image
    render_image_attachment(attachment)
  when :pdf
    render_document_attachment(attachment, used_document_names:)
  when :text
    { text: attachment.for_llm }
  else
    raise UnsupportedAttachmentError, attachment.mime_type
  end
end

.render_content(content, used_document_names: nil) ⇒ Object



10
11
12
13
14
15
16
17
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 10

def render_content(content, used_document_names: nil)
  return [] if empty_content?(content)
  return render_raw_content(content) if content.is_a?(RubyLLM::Content::Raw)
  return [{ text: content.to_json }] if content.is_a?(Hash) || content.is_a?(Array)
  return [{ text: content }] unless content.is_a?(RubyLLM::Content)

  render_content_object(content, used_document_names || {})
end

.render_content_object(content, used_document_names) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 23

def render_content_object(content, used_document_names)
  blocks = []
  blocks << { text: content.text } if content.text
  content.attachments.each do |attachment|
    blocks << render_attachment(attachment, used_document_names:)
  end
  blocks
end

.render_document_attachment(attachment, used_document_names:) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 61

def render_document_attachment(attachment, used_document_names:)
  document_name = unique_document_name(sanitize_document_name(attachment.filename), used_document_names)
  {
    document: {
      format: attachment.format,
      name: document_name,
      source: {
        bytes: attachment.encoded
      }
    }
  }
end

.render_image_attachment(attachment) ⇒ Object



50
51
52
53
54
55
56
57
58
59
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 50

def render_image_attachment(attachment)
  {
    image: {
      format: attachment.format,
      source: {
        bytes: attachment.encoded
      }
    }
  }
end

.render_raw_content(content) ⇒ Object



32
33
34
35
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 32

def render_raw_content(content)
  value = content.value
  value.is_a?(Array) ? value : [value]
end

.sanitize_document_name(filename) ⇒ Object



74
75
76
77
78
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 74

def sanitize_document_name(filename)
  base = File.basename(filename.to_s, '.*')
  safe = base.gsub(/[^a-zA-Z0-9_-]/, '_')
  safe.empty? ? 'document' : safe
end

.unique_document_name(base_name, used_names) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/ruby_llm/providers/bedrock/media.rb', line 80

def unique_document_name(base_name, used_names)
  count = used_names[base_name].to_i
  used_names[base_name] = count + 1
  return base_name if count.zero?

  "#{base_name}_#{count + 1}"
end