Class: Ragdoll::ImageToTextService
- Inherits:
-
Object
- Object
- Ragdoll::ImageToTextService
show all
- Defined in:
- app/services/ragdoll/image_to_text_service.rb
Defined Under Namespace
Classes: DescriptionError
Constant Summary
collapse
- DEFAULT_OPTIONS =
{
model: "gemma3",
provider: :ollama,
assume_model_exists: true,
temperature: 0.2,
detail_level: :comprehensive
}.freeze
- DEFAULT_FALLBACK_OPTIONS =
{
model: "smollm2",
provider: :ollama,
assume_model_exists: true,
temperature: 0.4
}.freeze
- DETAIL_LEVELS =
{
minimal: "Provide a brief, one-sentence description of the image.",
standard: "Describe the main elements, objects, and overall composition of the image.",
comprehensive: "Provide a detailed description including objects, people, settings, colors, mood, style, and any text visible in the image.",
analytical: "Analyze the image thoroughly, describing composition, lighting, subjects, background, context, and any symbolic or artistic elements."
}.freeze
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(primary: DEFAULT_OPTIONS, fallback: DEFAULT_FALLBACK_OPTIONS, **options) ⇒ ImageToTextService
Returns a new instance of ImageToTextService.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'app/services/ragdoll/image_to_text_service.rb', line 37
def initialize(primary: DEFAULT_OPTIONS, fallback: DEFAULT_FALLBACK_OPTIONS, **options)
@options = DEFAULT_OPTIONS.merge(options)
@detail_level = @options[:detail_level] || :comprehensive
configure_ruby_llm_globally
primary_opts = primary.dup
primary_temp = primary_opts.delete(:temperature) || 0.2
@primary_prompt = build_prompt(@detail_level)
begin
@primary = RubyLLM.chat(**primary_opts).with_temperature(primary_temp)
rescue StandardError => e
puts "❌ ImageToTextService: Primary model creation failed: #{e.message}"
@primary = nil
end
fallback_opts = fallback.dup
fallback_temp = fallback_opts.delete(:temperature) || 0.4
begin
@fallback = RubyLLM.chat(**fallback_opts).with_temperature(fallback_temp)
rescue StandardError => e
puts "❌ ImageToTextService: Fallback model creation failed: #{e.message}"
@fallback = nil
end
if @primary.nil? && @fallback.nil?
puts "⚠️ ImageToTextService: WARNING - No models available! Service will return metadata-based descriptions only."
end
end
|
Class Method Details
.convert(file_path, **options) ⇒ Object
33
34
35
|
# File 'app/services/ragdoll/image_to_text_service.rb', line 33
def self.convert(file_path, **options)
new(**options).convert(file_path)
end
|
Instance Method Details
#convert(file_path) ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'app/services/ragdoll/image_to_text_service.rb', line 71
def convert(file_path)
return "" unless File.exist?(file_path)
return "" unless image_file?(file_path)
start_time = Time.now
@image_path = file_path
begin
@image = Magick::Image.read(@image_path).first
image_data = prepare_image_data
return generate_fallback_description unless image_data
rescue StandardError => e
puts "❌ ImageToTextService: Failed to read image: #{e.message}"
return generate_fallback_description
end
if @primary
description = attempt_vision_description(image_data)
if description && !description.empty?
elapsed = Time.now - start_time
puts "✅ ImageToTextService: Vision description generated (#{elapsed.round(2)}s)"
return description
end
end
if @fallback
description = attempt_fallback_description
if description && !description.empty?
elapsed = Time.now - start_time
puts "✅ ImageToTextService: Fallback description generated (#{elapsed.round(2)}s)"
return description
end
end
elapsed = Time.now - start_time
puts "🔚 ImageToTextService: Using metadata-based description (#{elapsed.round(2)}s)"
generate_fallback_description
end
|
114
115
116
|
# File 'app/services/ragdoll/image_to_text_service.rb', line 114
def supported_formats
%w[.jpg .jpeg .png .gif .bmp .webp .svg .ico .tiff .tif]
end
|