@@ -90,12 +90,7 @@ async def test_translate_event_with_empty_parts(self, translator, mock_adk_event
90
90
91
91
@pytest .mark .asyncio
92
92
async def test_translate_function_calls_detection (self , translator , mock_adk_event ):
93
- """Test function calls detection by asserting tool events are emitted.
94
-
95
- This avoids brittle checks on debug log wording and instead
96
- verifies that function calls result in ToolCall events.
97
- """
98
- # Mock event with one function call
93
+ """Test that function calls produce ToolCall events."""
99
94
mock_function_call = MagicMock ()
100
95
mock_function_call .name = "test_function"
101
96
mock_function_call .id = "call_123"
@@ -106,17 +101,10 @@ async def test_translate_function_calls_detection(self, translator, mock_adk_eve
106
101
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
107
102
events .append (event )
108
103
109
- # Expect a START, ARGS, END sequence for the function call
110
- types = [e .type for e in events ]
111
- type_names = [str (t ).split ('.' )[- 1 ] for t in types ]
112
- assert type_names == [
113
- "TOOL_CALL_START" ,
114
- "TOOL_CALL_ARGS" ,
115
- "TOOL_CALL_END" ,
116
- ]
117
- # And the tool_call_id should match the mocked id
118
- ids = [getattr (e , 'tool_call_id' , None ) for e in events ]
119
- assert all (tc_id == "call_123" for tc_id in ids )
104
+ type_names = [str (event .type ).split ('.' )[- 1 ] for event in events ]
105
+ assert type_names == ["TOOL_CALL_START" , "TOOL_CALL_ARGS" , "TOOL_CALL_END" ]
106
+ ids = [getattr (event , 'tool_call_id' , None ) for event in events ]
107
+ assert ids == ["call_123" , "call_123" , "call_123" ]
120
108
121
109
@pytest .mark .asyncio
122
110
async def test_translate_function_responses_handling (self , translator , mock_adk_event ):
@@ -195,7 +183,7 @@ async def test_translate_text_content_basic(self, translator, mock_adk_event_wit
195
183
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
196
184
events .append (event )
197
185
198
- assert len (events ) == 3 # START, CONTENT, END
186
+ assert len (events ) == 3 # START, CONTENT , END
199
187
assert isinstance (events [0 ], TextMessageStartEvent )
200
188
assert isinstance (events [1 ], TextMessageContentEvent )
201
189
assert isinstance (events [2 ], TextMessageEndEvent )
@@ -222,10 +210,9 @@ async def test_translate_text_content_multiple_parts(self, translator, mock_adk_
222
210
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
223
211
events .append (event )
224
212
225
- assert len (events ) == 3 # START, CONTENT, END
213
+ assert len (events ) == 3 # START, CONTENT , END
226
214
assert isinstance (events [1 ], TextMessageContentEvent )
227
215
assert events [1 ].delta == "First partSecond part" # Joined without newlines
228
- assert isinstance (events [2 ], TextMessageEndEvent )
229
216
230
217
@pytest .mark .asyncio
231
218
async def test_translate_text_content_partial_streaming (self , translator , mock_adk_event_with_content ):
@@ -237,6 +224,10 @@ async def test_translate_text_content_partial_streaming(self, translator, mock_a
237
224
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
238
225
events .append (event )
239
226
227
+ # The translator keeps streaming open; forcing a close should yield END
228
+ async for event in translator .force_close_streaming_message ():
229
+ events .append (event )
230
+
240
231
assert len (events ) == 3 # START, CONTENT, END (forced close)
241
232
assert isinstance (events [0 ], TextMessageStartEvent )
242
233
assert isinstance (events [1 ], TextMessageContentEvent )
@@ -306,7 +297,7 @@ async def test_translate_text_content_final_response_from_agent_callback(self, t
306
297
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
307
298
events .append (event )
308
299
309
- assert len (events ) == 3 # START, CONTENT, END (non-streaming final response)
300
+ assert len (events ) == 3 # START, CONTENT , END
310
301
assert isinstance (events [0 ], TextMessageStartEvent )
311
302
assert isinstance (events [1 ], TextMessageContentEvent )
312
303
assert events [1 ].delta == mock_adk_event_with_content .content .parts [0 ].text
@@ -362,9 +353,8 @@ async def test_translate_text_content_mixed_text_parts(self, translator, mock_ad
362
353
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
363
354
events .append (event )
364
355
365
- assert len (events ) == 3 # START, CONTENT, END
356
+ assert len (events ) == 3 # START, CONTENT , END
366
357
assert events [1 ].delta == "Valid textMore text"
367
- assert isinstance (events [2 ], TextMessageEndEvent )
368
358
369
359
@pytest .mark .asyncio
370
360
async def test_translate_function_calls_basic (self , translator , mock_adk_event ):
@@ -650,24 +640,21 @@ async def test_streaming_state_management(self, translator, mock_adk_event_with_
650
640
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
651
641
events1 .append (event )
652
642
653
- assert len (events1 ) == 3 # START, CONTENT, END (forced close at translate completion)
643
+ assert len (events1 ) == 3 # START, CONTENT, END
654
644
message_id = events1 [0 ].message_id
655
645
656
- # Stream is closed after forced END
646
+ # streaming is stoped after TextMessageEndEvent
657
647
assert translator ._is_streaming is False
658
- assert translator ._streaming_message_id is None
648
+ # since the streaming is stopped
649
+ assert translator ._streaming_message_id == None
659
650
660
- # Second event should start a new stream with a new message ID
651
+ # Second event should continue streaming (same message ID)
661
652
events2 = []
662
653
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
663
654
events2 .append (event )
664
655
665
- assert len (events2 ) == 3 # START, CONTENT, END
666
- assert isinstance (events2 [0 ], TextMessageStartEvent )
667
- assert events2 [0 ].message_id != message_id
668
- assert isinstance (events2 [2 ], TextMessageEndEvent )
669
- assert translator ._is_streaming is False
670
- assert translator ._streaming_message_id is None
656
+ assert len (events2 ) == 3 # New Streaming (START , CONTENT ,END)
657
+ assert events2 [0 ].message_id != message_id # Same message ID
671
658
672
659
@pytest .mark .asyncio
673
660
async def test_complex_event_with_multiple_features (self , translator , mock_adk_event ):
@@ -691,8 +678,8 @@ async def test_complex_event_with_multiple_features(self, translator, mock_adk_e
691
678
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
692
679
events .append (event )
693
680
694
- # Should have text events, state delta, custom event, and END
695
- assert len (events ) == 5 # START, CONTENT, STATE_DELTA, CUSTOM, END
681
+ # Should have text events, state delta, and custom event
682
+ assert len (events ) == 5 # START, CONTENT, STATE_DELTA, CUSTOM , END
696
683
697
684
# Check event types
698
685
event_types = [type (event ) for event in events ]
@@ -771,8 +758,8 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
771
758
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
772
759
events1 .append (event )
773
760
774
- assert len (events1 ) == 3 # START, CONTENT, END (forced close )
775
- assert translator ._is_streaming is False
761
+ assert len (events1 ) == 2 # START, CONTENT (stream remains open )
762
+ assert translator ._is_streaming is True
776
763
message_id = events1 [0 ].message_id
777
764
778
765
# Second partial event (should continue streaming)
@@ -783,13 +770,11 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
783
770
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
784
771
events2 .append (event )
785
772
786
- assert len (events2 ) == 3 # New START, CONTENT, END for continuation
787
- assert isinstance (events2 [0 ], TextMessageStartEvent )
788
- assert isinstance (events2 [1 ], TextMessageContentEvent )
789
- assert isinstance (events2 [2 ], TextMessageEndEvent )
790
- assert translator ._is_streaming is False
791
- new_message_id = events2 [0 ].message_id
792
- assert new_message_id != message_id
773
+ assert len (events2 ) == 1 # Additional CONTENT chunk
774
+ assert isinstance (events2 [0 ], TextMessageContentEvent )
775
+ assert events2 [0 ].message_id == message_id # Same stream continues
776
+ assert translator ._is_streaming is True
777
+ assert translator ._streaming_message_id == message_id
793
778
794
779
# Final event (should end streaming - requires is_final_response=True)
795
780
mock_adk_event_with_content .partial = False
@@ -800,7 +785,9 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
800
785
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
801
786
events3 .append (event )
802
787
803
- assert len (events3 ) == 0 # Already emitted END in previous translate
788
+ assert len (events3 ) == 1 # Final END to close the stream
789
+ assert isinstance (events3 [0 ], TextMessageEndEvent )
790
+ assert events3 [0 ].message_id == message_id
804
791
805
792
# Should reset streaming state
806
793
assert translator ._is_streaming is False
0 commit comments