@@ -288,6 +288,86 @@ def test_to_openai_dict_format_invalid():
288288 message .to_openai_dict_format ()
289289
290290
291+ def test_from_openai_dict_format_user_message ():
292+ openai_msg = {"role" : "user" , "content" : "Hello, how are you?" , "name" : "John" }
293+ message = ChatMessage .from_openai_dict_format (openai_msg )
294+ assert message .role .value == "user"
295+ assert message .text == "Hello, how are you?"
296+ assert message .name == "John"
297+
298+
299+ def test_from_openai_dict_format_system_message ():
300+ openai_msg = {"role" : "system" , "content" : "You are a helpful assistant" }
301+ message = ChatMessage .from_openai_dict_format (openai_msg )
302+ assert message .role .value == "system"
303+ assert message .text == "You are a helpful assistant"
304+
305+
306+ def test_from_openai_dict_format_assistant_message_with_content ():
307+ openai_msg = {"role" : "assistant" , "content" : "I can help with that" }
308+ message = ChatMessage .from_openai_dict_format (openai_msg )
309+ assert message .role .value == "assistant"
310+ assert message .text == "I can help with that"
311+
312+
313+ def test_from_openai_dict_format_assistant_message_with_tool_calls ():
314+ openai_msg = {
315+ "role" : "assistant" ,
316+ "content" : None ,
317+ "tool_calls" : [{"id" : "call_123" , "function" : {"name" : "get_weather" , "arguments" : '{"location": "Berlin"}' }}],
318+ }
319+ message = ChatMessage .from_openai_dict_format (openai_msg )
320+ assert message .role .value == "assistant"
321+ assert message .text is None
322+ assert len (message .tool_calls ) == 1
323+ tool_call = message .tool_calls [0 ]
324+ assert tool_call .id == "call_123"
325+ assert tool_call .tool_name == "get_weather"
326+ assert tool_call .arguments == {"location" : "Berlin" }
327+
328+
329+ def test_from_openai_dict_format_tool_message ():
330+ openai_msg = {"role" : "tool" , "content" : "The weather is sunny" , "tool_call_id" : "call_123" }
331+ message = ChatMessage .from_openai_dict_format (openai_msg )
332+ assert message .role .value == "tool"
333+ assert message .tool_call_result .result == "The weather is sunny"
334+ assert message .tool_call_result .origin .id == "call_123"
335+
336+
337+ def test_from_openai_dict_format_tool_without_id ():
338+ openai_msg = {"role" : "tool" , "content" : "The weather is sunny" }
339+ message = ChatMessage .from_openai_dict_format (openai_msg )
340+ assert message .role .value == "tool"
341+ assert message .tool_call_result .result == "The weather is sunny"
342+ assert message .tool_call_result .origin .id is None
343+
344+
345+ def test_from_openai_dict_format_missing_role ():
346+ with pytest .raises (ValueError ):
347+ ChatMessage .from_openai_dict_format ({"content" : "test" })
348+
349+
350+ def test_from_openai_dict_format_missing_content ():
351+ with pytest .raises (ValueError ):
352+ ChatMessage .from_openai_dict_format ({"role" : "user" })
353+
354+
355+ def test_from_openai_dict_format_invalid_tool_calls ():
356+ openai_msg = {"role" : "assistant" , "tool_calls" : [{"invalid" : "format" }]}
357+ with pytest .raises (ValueError ):
358+ ChatMessage .from_openai_dict_format (openai_msg )
359+
360+
361+ def test_from_openai_dict_format_unsupported_role ():
362+ with pytest .raises (ValueError ):
363+ ChatMessage .from_openai_dict_format ({"role" : "invalid" , "content" : "test" })
364+
365+
366+ def test_from_openai_dict_format_assistant_missing_content_and_tool_calls ():
367+ with pytest .raises (ValueError ):
368+ ChatMessage .from_openai_dict_format ({"role" : "assistant" , "irrelevant" : "irrelevant" })
369+
370+
291371@pytest .mark .integration
292372def test_apply_chat_templating_on_chat_message ():
293373 messages = [ChatMessage .from_system ("You are good assistant" ), ChatMessage .from_user ("I have a question" )]
0 commit comments