Skip to content

Commit 6ba1e8f

Browse files
committed
fix message builder to handle text only flat input
1 parent 577a127 commit 6ba1e8f

File tree

1 file changed

+26
-36
lines changed

1 file changed

+26
-36
lines changed

src/inferencesh/models/llm.py

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)