Module: RubyLLM::Providers::OpenAI::Images

Included in:
RubyLLM::Providers::OpenAI
Defined in:
lib/ruby_llm/providers/openai/images.rb

Overview

Image generation methods for the OpenAI API integration

Class Method Summary collapse

Class Method Details

.attachments?(value) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/ruby_llm/providers/openai/images.rb', line 80

def attachments?(value)
  Array(value).any? { |item| !blank_attachment?(item) }
end

.blank_attachment?(value) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/ruby_llm/providers/openai/images.rb', line 84

def blank_attachment?(value)
  value.nil? || (value.is_a?(String) && value.strip.empty?)
end

.build_upload_part(source) ⇒ Object



69
70
71
72
73
74
# File 'lib/ruby_llm/providers/openai/images.rb', line 69

def build_upload_part(source)
  attachment = Attachment.new(source)
  raise UnsupportedAttachmentError, attachment.mime_type unless attachment.image?

  Faraday::UploadIO.new(StringIO.new(attachment.content), attachment.mime_type, attachment.filename)
end

.build_upload_parts(sources) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/ruby_llm/providers/openai/images.rb', line 61

def build_upload_parts(sources)
  Array(sources).filter_map do |source|
    next if blank_attachment?(source)

    build_upload_part(source)
  end
end

.editing?(with, mask) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/ruby_llm/providers/openai/images.rb', line 76

def editing?(with, mask)
  attachments?(with) || !mask.nil?
end

.images_url(with: nil, mask: nil) ⇒ Object



13
14
15
# File 'lib/ruby_llm/providers/openai/images.rb', line 13

def images_url(with: nil, mask: nil)
  editing?(with, mask) ? 'images/edits' : 'images/generations'
end

.parse_image_response(response, model:) ⇒ Object

Raises:



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/ruby_llm/providers/openai/images.rb', line 28

def parse_image_response(response, model:)
  data = response.body
  image_data = Array(data['data']).first

  raise Error.new(nil, 'Unexpected response format from OpenAI image API') unless image_data

  Image.new(
    url: image_data['url'],
    mime_type: 'image/png', # DALL-E typically returns PNGs
    revised_prompt: image_data['revised_prompt'],
    model_id: model,
    data: image_data['b64_json'],
    usage: data['usage'] || {}
  )
end

.render_edit_payload(prompt, model:, with:, mask:, params:) ⇒ Object



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

def render_edit_payload(prompt, model:, with:, mask:, params:)
  payload = params.merge(
    model: model,
    prompt: prompt,
    image: build_upload_parts(with),
    n: 1
  )
  payload[:mask] = build_upload_part(mask) if mask
  payload
end

.render_image_payload(prompt, model:, size:, with: nil, mask: nil, params: {}) ⇒ Object

rubocop:disable Metrics/ParameterLists



17
18
19
20
21
22
23
24
25
26
# File 'lib/ruby_llm/providers/openai/images.rb', line 17

def render_image_payload(prompt, model:, size:, with: nil, mask: nil, params: {}) # rubocop:disable Metrics/ParameterLists
  return render_edit_payload(prompt, model:, with:, mask:, params:) if editing?(with, mask)

  {
    model: model,
    prompt: prompt,
    n: 1,
    size: size
  }.merge(params)
end

.validate_paint_inputs!(with:, mask:) ⇒ Object

Raises:

  • (ArgumentError)


44
45
46
47
48
# File 'lib/ruby_llm/providers/openai/images.rb', line 44

def validate_paint_inputs!(with:, mask:)
  return unless editing?(with, mask)

  raise ArgumentError, 'with: is required when mask: is provided' if mask && !attachments?(with)
end