fix(llm): improve message handling to support LLMs without content/tool_calls

This commit improves the message handling in the LLM class to gracefully handle
messages without 'content' or 'tool_calls' fields. Previously, the system would
raise a ValueError when encountering such messages, causing crashes when working
with models like Google's Gemini that sometimes return messages with different
structures.

Key changes:
- Reordered message processing to check for Message objects first
- Changed validation approach to silently skip malformed messages instead of crashing
- Removed the strict ValueError when content/tool_calls are missing

This change maintains compatibility with correctly formatted messages while
improving robustness when working with various LLM providers.
This commit is contained in:
a-holm 2025-03-14 21:01:13 +01:00
parent 3671e1d866
commit 350b0038ee

View File

@ -84,14 +84,15 @@ class LLM:
formatted_messages = [] formatted_messages = []
for message in messages: for message in messages:
if isinstance(message, Message):
message = message.to_dict()
if isinstance(message, dict): if isinstance(message, dict):
# If message is already a dict, ensure it has required fields # If message is a dict, ensure it has required fields
if "role" not in message: if "role" not in message:
raise ValueError("Message dict must contain 'role' field") raise ValueError("Message dict must contain 'role' field")
if "content" in message or "tool_calls" in message:
formatted_messages.append(message) formatted_messages.append(message)
elif isinstance(message, Message): # else: do not include the message
# If message is a Message object, convert it to dict
formatted_messages.append(message.to_dict())
else: else:
raise TypeError(f"Unsupported message type: {type(message)}") raise TypeError(f"Unsupported message type: {type(message)}")
@ -99,10 +100,6 @@ class LLM:
for msg in formatted_messages: for msg in formatted_messages:
if msg["role"] not in ROLE_VALUES: if msg["role"] not in ROLE_VALUES:
raise ValueError(f"Invalid role: {msg['role']}") raise ValueError(f"Invalid role: {msg['role']}")
if "content" not in msg and "tool_calls" not in msg:
raise ValueError(
"Message must contain either 'content' or 'tool_calls'"
)
return formatted_messages return formatted_messages