Module: RubyLLM::Protocols::ChatCompletions::Images
- Defined in:
- lib/ruby_llm/protocols/chat_completions/images.rb
Overview
Image generation methods for the OpenAI API integration
Class Method Summary collapse
- .attachments?(value) ⇒ Boolean
- .blank_attachment?(value) ⇒ Boolean
- .build_image_reference(source) ⇒ Object
- .build_image_references(sources) ⇒ Object
- .build_upload_part(source) ⇒ Object
- .build_upload_parts(sources) ⇒ Object
- .editing?(with, mask) ⇒ Boolean
- .images_url(with: nil, mask: nil) ⇒ Object
- .json_image_references?(model) ⇒ Boolean
- .parse_image_response(response, model:) ⇒ Object
- .parse_image_responses(response, model:) ⇒ Object
- .render_edit_payload(prompt, model:, size:, with:, mask:, provider_options:, count: nil) ⇒ Object
- .render_image_payload(prompt, model:, size:, count: nil, with: nil, mask: nil, provider_options: {}) ⇒ Object
-
.single_upload_part(parts) ⇒ Object
Retries only rewind upload parts at the top level of the payload, so a lone image rides there instead of inside an array.
- .validate_paint_inputs!(with:, mask:) ⇒ Object
Class Method Details
.attachments?(value) ⇒ Boolean
117 118 119 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 117 def (value) Array(value).any? { |item| !(item) } end |
.blank_attachment?(value) ⇒ Boolean
121 122 123 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 121 def (value) value.nil? || (value.is_a?(String) && value.strip.empty?) end |
.build_image_reference(source) ⇒ Object
82 83 84 85 86 87 88 89 90 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 82 def build_image_reference(source) = Attachment.new(source, config: @config) return { file_id: .provider_file_id } if .provider_file? return { image_url: .source.to_s } if .url? raise UnsupportedAttachmentError, .mime_type unless .image? { image_url: .for_llm } end |
.build_image_references(sources) ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 74 def build_image_references(sources) Array(sources).filter_map do |source| next if (source) build_image_reference(source) end end |
.build_upload_part(source) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 106 def build_upload_part(source) = Attachment.new(source, config: @config) raise UnsupportedAttachmentError, .mime_type unless .image? Faraday::UploadIO.new(StringIO.new(.content), .mime_type, .filename) end |
.build_upload_parts(sources) ⇒ Object
92 93 94 95 96 97 98 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 92 def build_upload_parts(sources) Array(sources).filter_map do |source| next if (source) build_upload_part(source) end end |
.editing?(with, mask) ⇒ Boolean
113 114 115 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 113 def editing?(with, mask) (with) || !mask.nil? end |
.images_url(with: nil, mask: nil) ⇒ Object
13 14 15 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 13 def images_url(with: nil, mask: nil) editing?(with, mask) ? 'images/edits' : 'images/generations' end |
.json_image_references?(model) ⇒ Boolean
70 71 72 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 70 def json_image_references?(model) model.match?(/\A(gpt-image|chatgpt-image)/) end |
.parse_image_response(response, model:) ⇒ Object
29 30 31 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 29 def parse_image_response(response, model:) parse_image_responses(response, model:).first end |
.parse_image_responses(response, model:) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 33 def parse_image_responses(response, model:) data = response.body entries = Array(data['data']) raise Error, 'Unexpected response format from OpenAI image API' if entries.empty? entries.map.with_index do |image_data, index| Image.new( url: image_data['url'], mime_type: 'image/png', # DALL-E typically returns PNGs revised_prompt: image_data['revised_prompt'], model: model, data: image_data['b64_json'], usage: index.zero? ? (data['usage'] || {}) : {} ) end end |
.render_edit_payload(prompt, model:, size:, with:, mask:, provider_options:, count: nil) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 57 def render_edit_payload(prompt, model:, size:, with:, mask:, provider_options:, count: nil) payload = { model: model, prompt: prompt, n: count || 1 } if json_image_references?(model) payload[:images] = build_image_references(with) payload[:mask] = build_image_reference(mask) if mask payload[:size] = size if size else payload[:image] = single_upload_part(build_upload_parts(with)) payload[:mask] = build_upload_part(mask) if mask end payload.merge() end |
.render_image_payload(prompt, model:, size:, count: nil, with: nil, mask: nil, provider_options: {}) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 17 def render_image_payload(prompt, model:, size:, count: nil, with: nil, mask: nil, provider_options: {}) return render_edit_payload(prompt, model:, size:, count:, with:, mask:, provider_options:) if editing?(with, mask) { model: model, prompt: prompt, n: count || 1, size: size }.merge() end |
.single_upload_part(parts) ⇒ Object
Retries only rewind upload parts at the top level of the payload, so a lone image rides there instead of inside an array.
102 103 104 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 102 def single_upload_part(parts) parts.one? ? parts.first : parts end |
.validate_paint_inputs!(with:, mask:) ⇒ Object
51 52 53 54 55 |
# File 'lib/ruby_llm/protocols/chat_completions/images.rb', line 51 def validate_paint_inputs!(with:, mask:) return unless editing?(with, mask) raise ArgumentError, 'with: is required when mask: is provided' if mask && !(with) end |