Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit a6fa619

Browse files
authored
FEATURE: enforce jpg/png for all images (#1309)
This ensures webp / gif are converted to png prior to sending to LLMs given webp and gif are not evenly supported. png/jpg is universally supported and are the only supported format. longer term we need to add support for audio/video/pdf which is supported by some models. * more specs
1 parent b2a6ee9 commit a6fa619

File tree

5 files changed

+44
-2
lines changed

5 files changed

+44
-2
lines changed

lib/completions/upload_encoder.rb

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ def self.encode(upload_ids:, max_pixels:)
1010
next if upload.blank?
1111
next if upload.width.to_i == 0 || upload.height.to_i == 0
1212

13+
desired_extension = upload.extension
14+
desired_extension = "png" if upload.extension == "gif"
15+
desired_extension = "png" if upload.extension == "webp"
16+
desired_extension = "jpeg" if upload.extension == "jpg"
17+
18+
# this keeps it very simple format wise given everyone supports png and jpg
19+
next if !%w[jpeg png].include?(desired_extension)
20+
1321
original_pixels = upload.width * upload.height
1422

1523
image = upload
@@ -20,12 +28,15 @@ def self.encode(upload_ids:, max_pixels:)
2028
new_width = (ratio * upload.width).to_i
2129
new_height = (ratio * upload.height).to_i
2230

23-
image = upload.get_optimized_image(new_width, new_height)
31+
image = upload.get_optimized_image(new_width, new_height, format: desired_extension)
32+
elsif upload.extension != desired_extension
33+
image =
34+
upload.get_optimized_image(upload.width, upload.height, format: desired_extension)
2435
end
2536

2637
next if !image
2738

28-
mime_type = MiniMime.lookup_by_filename(upload.original_filename).content_type
39+
mime_type = MiniMime.lookup_by_filename("test.#{desired_extension}").content_type
2940

3041
path = Discourse.store.path_for(image)
3142
if path.blank?

spec/fixtures/images/1x1.gif

43 Bytes
Loading

spec/fixtures/images/1x1.jpg

160 Bytes
Loading

spec/fixtures/images/1x1.webp

44 Bytes
Loading
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe DiscourseAi::Completions::UploadEncoder do
4+
let(:gif) { plugin_file_from_fixtures("1x1.gif") }
5+
let(:jpg) { plugin_file_from_fixtures("1x1.jpg") }
6+
let(:webp) { plugin_file_from_fixtures("1x1.webp") }
7+
8+
it "automatically converts gifs to pngs" do
9+
upload = UploadCreator.new(gif, "1x1.gif").create_for(Discourse.system_user.id)
10+
encoded = described_class.encode(upload_ids: [upload.id], max_pixels: 1_048_576)
11+
expect(encoded.length).to eq(1)
12+
expect(encoded[0][:base64]).to be_present
13+
expect(encoded[0][:mime_type]).to eq("image/png")
14+
end
15+
16+
it "automatically converts webp to pngs" do
17+
upload = UploadCreator.new(webp, "1x1.webp").create_for(Discourse.system_user.id)
18+
encoded = described_class.encode(upload_ids: [upload.id], max_pixels: 1_048_576)
19+
expect(encoded.length).to eq(1)
20+
expect(encoded[0][:base64]).to be_present
21+
expect(encoded[0][:mime_type]).to eq("image/png")
22+
end
23+
24+
it "supports jpg" do
25+
upload = UploadCreator.new(jpg, "1x1.jpg").create_for(Discourse.system_user.id)
26+
encoded = described_class.encode(upload_ids: [upload.id], max_pixels: 1_048_576)
27+
expect(encoded.length).to eq(1)
28+
expect(encoded[0][:base64]).to be_present
29+
expect(encoded[0][:mime_type]).to eq("image/jpeg")
30+
end
31+
end

0 commit comments

Comments
 (0)