@@ -147,51 +147,41 @@ def build_messages(
147147 transform_user_message : Optional [Callable [[str ], str ]] = None
148148) -> List [Dict [str , Any ]]:
149149 """Build messages for LLaMA.cpp chat completion.
150-
151- Args:
152- input_data: The input data
153- transform_user_message: Optional function to transform user message text before building messages
154- """
155- messages = [
156- {
157- "role" : "system" ,
158- "content" : [{"type" : "text" , "text" : input_data .system_prompt }],
159- }
160- ]
161150
162- # Add context messages
163- for msg in input_data . context :
164- message_content = []
165- text = msg . text
166- if transform_user_message and msg . role == ContextMessageRole . USER :
167- text = transform_user_message (text )
151+ If any message includes image content, builds OpenAI-style multipart format.
152+ Otherwise, uses plain string-only format.
153+ """
154+ def render_message ( msg : ContextMessage , allow_multipart : bool ) -> str | List [ dict ]:
155+ parts = []
156+ text = transform_user_message (msg . text ) if transform_user_message and msg . role == ContextMessageRole . USER else msg . text
168157 if text :
169- message_content .append ({"type" : "text" , "text" : text })
170- if hasattr ( msg , 'image' ) and msg .image :
158+ parts .append ({"type" : "text" , "text" : text })
159+ if msg .image :
171160 if msg .image .path :
172161 image_data_uri = image_to_base64_data_uri (msg .image .path )
173- message_content .append ({"type" : "image_url" , "image_url" : {"url" : image_data_uri }})
162+ parts .append ({"type" : "image_url" , "image_url" : {"url" : image_data_uri }})
174163 elif msg .image .uri :
175- message_content .append ({"type" : "image_url" , "image_url" : {"url" : msg .image .uri }})
164+ parts .append ({"type" : "image_url" , "image_url" : {"url" : msg .image .uri }})
165+ if allow_multipart :
166+ return parts
167+ if len (parts ) == 1 and parts [0 ]["type" ] == "text" :
168+ return parts [0 ]["text" ]
169+ raise ValueError ("Image content requires multipart support" )
170+
171+ multipart = any (m .image for m in input_data .context ) or input_data .image is not None
172+ messages = [{"role" : "system" , "content" : input_data .system_prompt }]
173+
174+ for msg in input_data .context :
176175 messages .append ({
177176 "role" : msg .role ,
178- "content" : message_content
177+ "content" : render_message ( msg , allow_multipart = multipart )
179178 })
180179
181- # Add user message
182- user_content = []
183- text = input_data .text
184- if transform_user_message :
185- text = transform_user_message (text )
186- if text :
187- user_content .append ({"type" : "text" , "text" : text })
188- if hasattr (input_data , 'image' ) and input_data .image :
189- if input_data .image .path :
190- image_data_uri = image_to_base64_data_uri (input_data .image .path )
191- user_content .append ({"type" : "image_url" , "image_url" : {"url" : image_data_uri }})
192- elif input_data .image .uri :
193- user_content .append ({"type" : "image_url" , "image_url" : {"url" : input_data .image .uri }})
194- messages .append ({"role" : "user" , "content" : user_content })
180+ user_msg = ContextMessage (role = ContextMessageRole .USER , text = input_data .text , image = input_data .image )
181+ messages .append ({
182+ "role" : "user" ,
183+ "content" : render_message (user_msg , allow_multipart = multipart )
184+ })
195185
196186 return messages
197187
0 commit comments