55import pytest
66
77from haystack import Pipeline , component
8- from haystack .dataclasses import ComponentInfo , FinishReason , StreamingChunk , ToolCall , ToolCallDelta , ToolCallResult
8+ from haystack .dataclasses import (
9+ ComponentInfo ,
10+ ReasoningContent ,
11+ StreamingChunk ,
12+ ToolCall ,
13+ ToolCallDelta ,
14+ ToolCallResult ,
15+ )
916
1017
1118@component
@@ -75,17 +82,30 @@ def test_create_chunk_with_content_and_tool_call_result():
7582 )
7683
7784
85+ def test_create_chunk_with_content_and_reasoning ():
86+ with pytest .raises (ValueError , match = "Only one of `content`, `tool_call`, `tool_call_result`" ):
87+ StreamingChunk (
88+ content = "Test content" , meta = {"key" : "value" }, reasoning = ReasoningContent (reasoning_text = "thinking" )
89+ )
90+
91+
92+ def test_reasoning_and_no_index ():
93+ with pytest .raises (
94+ ValueError , match = "If `tool_call`, `tool_call_result` or `reasoning` is set, `index` must also be set."
95+ ):
96+ StreamingChunk (content = "" , meta = {"key" : "value" }, reasoning = ReasoningContent (reasoning_text = "thinking" ))
97+
98+
7899def test_component_info_from_component ():
79- component = ExampleComponent ()
80- component_info = ComponentInfo .from_component (component )
100+ component_info = ComponentInfo .from_component (ExampleComponent ())
81101 assert component_info .type == "test_streaming_chunk.ExampleComponent"
82102
83103
84104def test_component_info_from_component_with_name_from_pipeline ():
85105 pipeline = Pipeline ()
86- component = ExampleComponent ()
87- pipeline .add_component ("pipeline_component" , component )
88- component_info = ComponentInfo .from_component (component )
106+ comp = ExampleComponent ()
107+ pipeline .add_component ("pipeline_component" , comp )
108+ component_info = ComponentInfo .from_component (comp )
89109 assert component_info .type == "test_streaming_chunk.ExampleComponent"
90110 assert component_info .name == "pipeline_component"
91111
@@ -139,8 +159,7 @@ def test_finish_reason_tool_call_results():
139159
140160def test_to_dict_tool_call_result ():
141161 """Test the to_dict method for StreamingChunk with tool_call_result."""
142- component = ExampleComponent ()
143- component_info = ComponentInfo .from_component (component )
162+ component_info = ComponentInfo .from_component (ExampleComponent ())
144163 tool_call_result = ToolCallResult (
145164 result = "output" , origin = ToolCall (id = "123" , tool_name = "test_tool" , arguments = {"arg1" : "value1" }), error = False
146165 )
@@ -165,12 +184,12 @@ def test_to_dict_tool_call_result():
165184 assert d ["tool_call_result" ]["origin" ]["id" ] == "123"
166185 assert d ["tool_call_result" ]["origin" ]["arguments" ]["arg1" ] == "value1"
167186 assert d ["finish_reason" ] == "tool_call_results"
187+ assert d ["reasoning" ] is None
168188
169189
170190def test_to_dict_tool_calls ():
171191 """Test the to_dict method for StreamingChunk with tool_calls."""
172- component = ExampleComponent ()
173- component_info = ComponentInfo .from_component (component )
192+ component_info = ComponentInfo .from_component (ExampleComponent ())
174193 tool_calls = [
175194 ToolCallDelta (id = "123" , tool_name = "test_tool" , arguments = '{"arg1": "value1"}' , index = 0 ),
176195 ToolCallDelta (id = "456" , tool_name = "another_tool" , arguments = '{"arg2": "value2"}' , index = 1 ),
@@ -197,6 +216,34 @@ def test_to_dict_tool_calls():
197216 assert d ["tool_calls" ][1 ]["id" ] == "456"
198217 assert d ["tool_calls" ][1 ]["index" ] == 1
199218 assert d ["finish_reason" ] == "tool_calls"
219+ assert d ["reasoning" ] is None
220+
221+
222+ def test_to_dict_reasoning ():
223+ """Test the to_dict method for StreamingChunk with reasoning."""
224+ component_info = ComponentInfo .from_component (ExampleComponent ())
225+ reasoning = ReasoningContent (reasoning_text = "thinking" , extra = {"step" : 1 })
226+
227+ chunk = StreamingChunk (
228+ content = "" ,
229+ meta = {"key" : "value" },
230+ index = 0 ,
231+ component_info = component_info ,
232+ reasoning = reasoning ,
233+ finish_reason = "stop" ,
234+ )
235+
236+ d = chunk .to_dict ()
237+
238+ assert d ["content" ] == ""
239+ assert d ["meta" ] == {"key" : "value" }
240+ assert d ["index" ] == 0
241+ assert d ["component_info" ]["type" ] == "test_streaming_chunk.ExampleComponent"
242+ assert d ["reasoning" ]["reasoning_text" ] == "thinking"
243+ assert d ["reasoning" ]["extra" ]["step" ] == 1
244+ assert d ["finish_reason" ] == "stop"
245+ assert d ["tool_calls" ] is None
246+ assert d ["tool_call_result" ] is None
200247
201248
202249def test_from_dict_tool_call_result ():
@@ -227,6 +274,7 @@ def test_from_dict_tool_call_result():
227274 assert chunk .tool_call_result .result == "output"
228275 assert chunk .tool_call_result .error is False
229276 assert chunk .tool_call_result .origin .id == "123"
277+ assert chunk .reasoning is None
230278
231279
232280def test_from_dict_tool_calls ():
@@ -253,3 +301,32 @@ def test_from_dict_tool_calls():
253301 assert chunk .tool_calls [0 ].tool_name == "test_tool"
254302 assert chunk .tool_calls [0 ].index == 0
255303 assert chunk .finish_reason == "tool_calls"
304+ assert chunk .reasoning is None
305+
306+
307+ def test_from_dict_reasoning ():
308+ """Test the from_dict method for StreamingChunk with reasoning."""
309+ component_info = {"type" : "test_streaming_chunk.ExampleComponent" , "name" : "test_component" }
310+ reasoning = {"reasoning_text" : "thinking" , "extra" : {"step" : 1 }}
311+
312+ data = {
313+ "content" : "" ,
314+ "meta" : {"key" : "value" },
315+ "index" : 0 ,
316+ "component_info" : component_info ,
317+ "reasoning" : reasoning ,
318+ "finish_reason" : "stop" ,
319+ }
320+
321+ chunk = StreamingChunk .from_dict (data )
322+
323+ assert chunk .content == ""
324+ assert chunk .meta == {"key" : "value" }
325+ assert chunk .index == 0
326+ assert chunk .component_info .type == "test_streaming_chunk.ExampleComponent"
327+ assert chunk .component_info .name == "test_component"
328+ assert chunk .reasoning .reasoning_text == "thinking"
329+ assert chunk .reasoning .extra ["step" ] == 1
330+ assert chunk .finish_reason == "stop"
331+ assert chunk .tool_calls is None
332+ assert chunk .tool_call_result is None
0 commit comments