66
77import pytest
88
9- from haystack .dataclasses .chat_message import ChatMessage , ChatRole , TextContent , ToolCall , ToolCallResult
9+ from haystack .dataclasses .chat_message import (
10+ ChatMessage ,
11+ ChatRole ,
12+ ReasoningContent ,
13+ TextContent ,
14+ ToolCall ,
15+ ToolCallResult ,
16+ )
1017from haystack .dataclasses .image_content import ImageContent
1118
1219
@@ -80,9 +87,28 @@ def test_text_content_from_dict(self):
8087 tc = TextContent .from_dict ({"text" : "Hello" })
8188 assert tc .text == "Hello"
8289
90+ def test_reasoning_content_init (self ):
91+ rc = ReasoningContent (reasoning_text = "Let me think about it..." )
92+
93+ assert rc .reasoning_text == "Let me think about it..."
94+ assert rc .extra == {}
95+
96+ rc = ReasoningContent (reasoning_text = "Let me think about it..." , extra = {"key" : "value" })
97+ assert rc .reasoning_text == "Let me think about it..."
98+ assert rc .extra == {"key" : "value" }
99+
100+ def test_reasoning_content_to_dict (self ):
101+ rc = ReasoningContent (reasoning_text = "Let me think about it..." , extra = {"key" : "value" })
102+ assert rc .to_dict () == {"reasoning_text" : "Let me think about it..." , "extra" : {"key" : "value" }}
103+
104+ def test_reasoning_content_from_dict (self ):
105+ rc = ReasoningContent .from_dict ({"reasoning_text" : "Let me think about it..." , "extra" : {"key" : "value" }})
106+ assert rc .reasoning_text == "Let me think about it..."
107+ assert rc .extra == {"key" : "value" }
108+
83109
84110class TestChatMessage :
85- def test_from_assistant_with_valid_content (self ):
111+ def test_from_assistant_with_text (self ):
86112 text = "Hello, how can I assist you?"
87113 message = ChatMessage .from_assistant (text )
88114
@@ -99,6 +125,8 @@ def test_from_assistant_with_valid_content(self):
99125 assert not message .tool_call_result
100126 assert not message .images
101127 assert not message .image
128+ assert not message .reasonings
129+ assert not message .reasoning
102130
103131 def test_from_assistant_with_tool_calls (self ):
104132 tool_calls = [
@@ -120,6 +148,53 @@ def test_from_assistant_with_tool_calls(self):
120148 assert not message .tool_call_result
121149 assert not message .images
122150 assert not message .image
151+ assert not message .reasoning
152+ assert not message .reasonings
153+
154+ def test_from_assistant_with_reasoning_object (self ):
155+ reasoning = ReasoningContent (reasoning_text = "Let me think about it..." , extra = {"key" : "value" })
156+ text = "After thinking about it, I can say that the answer is 42."
157+ message = ChatMessage .from_assistant (text = text , reasoning = reasoning )
158+
159+ assert message .role == ChatRole .ASSISTANT
160+ assert message ._content == [reasoning , TextContent (text = text )]
161+
162+ assert message .texts == [text ]
163+ assert message .text == text
164+ assert message .reasoning == reasoning
165+ assert message .reasonings == [reasoning ]
166+
167+ assert not message .tool_calls
168+ assert not message .tool_call
169+ assert not message .tool_call_results
170+ assert not message .tool_call_result
171+ assert not message .images
172+ assert not message .image
173+
174+ def test_from_assistant_with_reasoning_string (self ):
175+ reasoning = "Let me think about it..."
176+ text = "After thinking about it, I can say that the answer is 42."
177+ message = ChatMessage .from_assistant (text = text , reasoning = reasoning )
178+
179+ expected_reasoning_content = ReasoningContent (reasoning_text = reasoning )
180+ assert message .role == ChatRole .ASSISTANT
181+ assert message ._content == [expected_reasoning_content , TextContent (text = text )]
182+
183+ assert message .texts == [text ]
184+ assert message .text == text
185+ assert message .reasoning == expected_reasoning_content
186+ assert message .reasonings == [expected_reasoning_content ]
187+
188+ assert not message .tool_calls
189+ assert not message .tool_call
190+ assert not message .tool_call_results
191+ assert not message .tool_call_result
192+ assert not message .images
193+ assert not message .image
194+
195+ def test_from_assistant_with_invalid_reasoning (self ):
196+ with pytest .raises (TypeError ):
197+ ChatMessage .from_assistant (text = "text" , reasoning = 123 )
123198
124199 def test_from_user_with_valid_content (self ):
125200 text = "I have a question."
@@ -138,6 +213,8 @@ def test_from_user_with_valid_content(self):
138213 assert not message .tool_call_result
139214 assert not message .images
140215 assert not message .image
216+ assert not message .reasonings
217+ assert not message .reasoning
141218
142219 def test_from_user_with_name (self ):
143220 text = "I have a question."
@@ -207,6 +284,8 @@ def test_from_system_with_valid_content(self):
207284 assert not message .tool_call_result
208285 assert not message .images
209286 assert not message .image
287+ assert not message .reasonings
288+ assert not message .reasoning
210289
211290 def test_from_tool_with_valid_content (self ):
212291 tool_result = "Tool result"
@@ -227,6 +306,8 @@ def test_from_tool_with_valid_content(self):
227306 assert not message .text
228307 assert not message .images
229308 assert not message .image
309+ assert not message .reasonings
310+ assert not message .reasoning
230311
231312 def test_multiple_text_segments (self ):
232313 texts = [TextContent (text = "Hello" ), TextContent (text = "World" )]
@@ -266,10 +347,13 @@ def test_serde(self, base64_image_string):
266347 meta = {"key" : "value" },
267348 validation = True ,
268349 )
350+ reasoning_content = ReasoningContent (reasoning_text = "Let me think about it..." , extra = {"key" : "value" })
269351 meta = {"some" : "info" }
270352
271353 message = ChatMessage (
272- _role = role , _content = [text_content , tool_call , tool_call_result , image_content ], _meta = meta
354+ _role = role ,
355+ _content = [text_content , tool_call , tool_call_result , image_content , reasoning_content ],
356+ _meta = meta ,
273357 )
274358
275359 serialized_message = message .to_dict ()
@@ -293,6 +377,7 @@ def test_serde(self, base64_image_string):
293377 "validation" : True ,
294378 }
295379 },
380+ {"reasoning" : {"reasoning_text" : "Let me think about it..." , "extra" : {"key" : "value" }}},
296381 ],
297382 "role" : "assistant" ,
298383 "name" : None ,
0 commit comments