@@ -22,28 +22,9 @@ def render_payload(messages, tools:, temperature:, model:, stream: nil)
22
22
Array ( tools )
23
23
end
24
24
25
- # Ensure messages are properly processed to handle nil values
26
- processed_messages = messages . map { |m | render_message ( m ) }
27
-
28
- # Use the debugging helper for vision models to diagnose image issues
29
- if supports_vision? ( model )
30
- debug_image_handling ( messages , processed_messages )
31
- end
32
-
33
- # Debug any nil values in content arrays for vision models
34
- if ENV [ "DEBUG" ] && supports_vision? ( model )
35
- processed_messages . each_with_index do |msg , idx |
36
- if msg [ :content ] . is_a? ( Array ) && msg [ :content ] . any? ( &:nil? )
37
- RubyLLM . logger . debug "WARNING: Nil values detected in content array for message #{ idx } "
38
- RubyLLM . logger . debug "Original content before processing: #{ messages [ idx ] . content . inspect } "
39
- RubyLLM . logger . debug "Processed content: #{ msg [ :content ] . inspect } "
40
- end
41
- end
42
- end
43
-
44
25
payload = {
45
26
model : model ,
46
- messages : processed_messages ,
27
+ messages : messages . map { | m | render_message ( m ) } ,
47
28
temperature : temperature ,
48
29
stream : stream ,
49
30
tools : tools_array &.any? ? tools_array . map { |t | render_tool ( t ) } : nil ,
@@ -63,13 +44,7 @@ def render_message(message)
63
44
result [ :role ] = message . role
64
45
65
46
# Handle content (text or multimodal)
66
- if message . content . nil?
67
- # If content is nil, provide a simple empty message
68
- result [ :content ] = ""
69
- elsif message . content . is_a? ( Array )
70
- # Log detailed information for debugging
71
- RubyLLM . logger . debug "Processing array content in message: #{ message . content . inspect } " if ENV [ "DEBUG" ]
72
-
47
+ if message . content . is_a? ( Array )
73
48
# Filter out any nil values and ensure the array is not empty
74
49
filtered_content = message . content . compact
75
50
if filtered_content . empty?
@@ -112,37 +87,17 @@ def format_multimodal_content(content)
112
87
# As a workaround, we filter out nil values below, but this doesn't solve the root issue
113
88
# which requires changes to the core library's Content handling.
114
89
115
- # Filter out nil values and perform additional validation
90
+ # Filter out nil values
116
91
filtered_content = content . compact
117
92
118
- if filtered_content . empty?
119
- RubyLLM . logger . warn "WARNING: All items in the content array were nil or empty"
120
- # Return a simple text message to avoid API errors
121
- return [ { type : "text" , text : "Please provide content for this message." } ]
122
- end
93
+ RubyLLM . logger . debug "Filtered content: #{ filtered_content . inspect } "
123
94
124
- # Filter out any malformed image items (those without required data)
125
- validated_content = filtered_content . map do |item |
95
+ filtered_content . map do |item |
126
96
if item . is_a? ( Hash ) && item [ :type ] == "image"
127
- if item [ :url ] . nil? && ( item [ :data ] . nil? || item [ :data ] . empty? )
128
- RubyLLM . logger . warn "WARNING: Skipping malformed image item: #{ item . inspect } "
129
- nil
130
- else
131
- format_image_content ( item )
132
- end
97
+ format_image_content ( item )
133
98
else
134
99
item
135
100
end
136
- end . compact
137
-
138
- RubyLLM . logger . debug "Validated multimodal content: #{ validated_content . inspect } "
139
-
140
- # If all content was filtered out, provide a fallback
141
- if validated_content . empty?
142
- RubyLLM . logger . warn "WARNING: All content was filtered out due to validation"
143
- [ { type : "text" , text : "Please provide valid content for this message." } ]
144
- else
145
- validated_content
146
101
end
147
102
end
148
103
@@ -163,45 +118,24 @@ def format_image_content(image)
163
118
# NOTE: This method is currently not getting properly formatted images from the Content class
164
119
# in vision-related tests. Debug logs show this method isn't being called with valid image data.
165
120
166
- # Basic validation - return nil for invalid image data
167
- return nil unless image . is_a? ( Hash )
168
-
169
- # Log detailed information about image formatting attempts in debug mode
170
- RubyLLM . logger . debug "Formatting image: #{ image . inspect } " if ENV [ "DEBUG" ]
171
-
172
- result = nil
173
-
174
- if image [ :url ] && !image [ :url ] . empty?
175
- result = {
121
+ if image [ :url ]
122
+ {
176
123
type : "image" ,
177
124
source : {
178
125
type : "url" ,
179
126
url : image [ :url ] ,
180
127
} ,
181
128
}
182
- elsif image [ :data ] && ! image [ :data ] . empty?
183
- result = {
129
+ elsif image [ :data ]
130
+ {
184
131
type : "image" ,
185
132
source : {
186
133
type : "base64" ,
187
134
media_type : image [ :media_type ] || "image/jpeg" ,
188
135
data : image [ :data ] ,
189
136
} ,
190
137
}
191
- elsif image [ :source ] && image [ :source ] . is_a? ( Hash )
192
- # The image may already be in the correct format for Mistral
193
- # Just do some basic validation
194
- if ( image [ :source ] [ :type ] == "url" && image [ :source ] [ :url ] ) ||
195
- ( image [ :source ] [ :type ] == "base64" && image [ :source ] [ :data ] )
196
- result = image
197
- end
198
- end
199
-
200
- if result . nil?
201
- RubyLLM . logger . warn "WARNING: Unable to format image: #{ image . inspect } "
202
138
end
203
-
204
- result
205
139
end
206
140
207
141
def render_tool_call ( tool_call )
@@ -280,53 +214,6 @@ def parse_tool_arguments(args)
280
214
args
281
215
end
282
216
end
283
-
284
- # Helper method to check if a model supports vision capabilities
285
- def supports_vision? ( model_id )
286
- Mistral . capabilities . supports_vision? ( model_id )
287
- end
288
-
289
- # Debugging helper to assist with troubleshooting image handling issues
290
- # This is a comprehensive method that logs detailed information about the content
291
- # being processed to help identify issues with image handling.
292
- def debug_image_handling ( messages , formatted_messages )
293
- return unless ENV [ "DEBUG" ]
294
-
295
- RubyLLM . logger . debug "==== IMAGE HANDLING DIAGNOSTICS ===="
296
-
297
- messages . each_with_index do |msg , i |
298
- next unless msg . content . is_a? ( Array )
299
-
300
- RubyLLM . logger . debug "Message #{ i } : Original content array:"
301
- msg . content . each_with_index do |item , j |
302
- if item . nil?
303
- RubyLLM . logger . debug " Item #{ j } : NIL VALUE"
304
- elsif item . is_a? ( Hash ) && item [ :type ] == "image"
305
- has_url = item [ :url ] && !item [ :url ] . empty?
306
- has_data = item [ :data ] && !item [ :data ] . empty?
307
- has_source = item [ :source ] && item [ :source ] . is_a? ( Hash )
308
-
309
- details = [ ]
310
- details << "url=#{ item [ :url ] . to_s [ 0 ..30 ] } ..." if has_url
311
- details << "data_size=#{ item [ :data ] . to_s . size rescue "N/A" } " if has_data
312
- details << "source=#{ item [ :source ] . inspect } " if has_source
313
-
314
- RubyLLM . logger . debug " Item #{ j } : IMAGE - #{ details . join ( ", " ) } "
315
- else
316
- RubyLLM . logger . debug " Item #{ j } : #{ item . class } - #{ item . inspect [ 0 ..100 ] } ..."
317
- end
318
- end
319
-
320
- if formatted_messages && formatted_messages [ i ] && formatted_messages [ i ] [ :content ] . is_a? ( Array )
321
- RubyLLM . logger . debug "Message #{ i } : Formatted content array:"
322
- formatted_messages [ i ] [ :content ] . each_with_index do |item , j |
323
- RubyLLM . logger . debug " Item #{ j } : #{ item . inspect [ 0 ..100 ] } ..."
324
- end
325
- end
326
- end
327
-
328
- RubyLLM . logger . debug "==== END DIAGNOSTICS ===="
329
- end
330
217
end
331
218
end
332
219
end
0 commit comments