fix: reintroduce helpful error message in ChatMessage deserialization (#9748)

* fix: reintroduce helpful error message in  deserialization

* fix fmt
This commit is contained in:
Stefano Fiorucci 2025-08-28 15:27:09 +02:00 committed by GitHub
parent 41b7ed4f47
commit 95dafdc20b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 3 deletions

View File

@ -209,7 +209,17 @@ def _deserialize_content_part(part: dict[str, Any]) -> ChatMessageContentT:
if serialization_key in part:
return cls.from_dict(part[serialization_key])
raise ValueError(f"Unsupported content part in the serialized ChatMessage: `{part}`")
# NOTE: this verbose error message provides guidance to LLMs when creating invalid messages during agent runs
msg = (
f"Unsupported content part in the serialized ChatMessage: {part}. "
"The `content` field of the serialized ChatMessage must be a list of dictionaries, where each "
"dictionary contains one of these keys: 'text', 'image', 'reasoning', 'tool_call', or 'tool_call_result'. "
"Valid formats: [{'text': 'Hello'}, {'image': {'base64_image': '...', ...}}, "
"{'reasoning': {'reasoning_text': 'I think...', 'extra': {...}}}, "
"{'tool_call': {'tool_name': 'search', 'arguments': {}, 'id': 'call_123'}}, "
"{'tool_call_result': {'result': 'data', 'origin': {...}, 'error': false}}]"
)
raise ValueError(msg)
def _serialize_content_part(part: ChatMessageContentT) -> dict[str, Any]:
@ -530,6 +540,8 @@ class ChatMessage: # pylint: disable=too-many-public-methods # it's OK since we
:returns:
The created object.
"""
# NOTE: this verbose error message provides guidance to LLMs when creating invalid messages during agent runs
if not "role" in data and not "_role" in data:
raise ValueError(
"The `role` field is required in the message dictionary. "

View File

@ -0,0 +1,8 @@
---
fixes:
- |
Reintroduce verbose error message when deserializing a `ChatMessage` with invalid content parts.
While LLMs may still generate messages in the wrong format, this error provides guidance on the expected structure,
making retries easier and more reliable during agent runs.
The error message was unintentionally removed during a previous refactoring.

View File

@ -398,11 +398,11 @@ class TestChatMessage:
def test_from_dict_with_invalid_content_type(self):
data = {"role": "assistant", "content": [{"text": "Hello"}, "invalid"]}
with pytest.raises(ValueError, match="Unsupported content part in the serialized ChatMessage"):
with pytest.raises(ValueError, match=r"Unsupported content part.*Valid formats.*"):
ChatMessage.from_dict(data)
data = {"role": "assistant", "content": [{"text": "Hello"}, {"invalid": "invalid"}]}
with pytest.raises(ValueError, match="Unsupported content part in the serialized ChatMessage"):
with pytest.raises(ValueError, match=r"Unsupported content part.*Valid formats.*"):
ChatMessage.from_dict(data)
def test_from_dict_with_missing_role(self):