@@ -195,17 +195,18 @@ async def test_translate_text_content_basic(self, translator, mock_adk_event_wit
195
195
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
196
196
events .append (event )
197
197
198
- assert len (events ) == 3 # START, CONTENT , END
198
+ assert len (events ) == 2 # START, CONTENT
199
199
assert isinstance (events [0 ], TextMessageStartEvent )
200
200
assert isinstance (events [1 ], TextMessageContentEvent )
201
- assert isinstance (events [2 ], TextMessageEndEvent )
202
201
203
202
# Check content
204
203
assert events [1 ].delta == "Test content"
205
204
206
205
# Check message IDs are consistent
207
206
message_id = events [0 ].message_id
208
207
assert events [1 ].message_id == message_id
208
+ # No END event emitted for non-final, non-turn-complete content
209
+ assert all (not isinstance (event , TextMessageEndEvent ) for event in events )
209
210
210
211
@pytest .mark .asyncio
211
212
async def test_translate_text_content_multiple_parts (self , translator , mock_adk_event ):
@@ -222,9 +223,10 @@ async def test_translate_text_content_multiple_parts(self, translator, mock_adk_
222
223
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
223
224
events .append (event )
224
225
225
- assert len (events ) == 3 # START, CONTENT , END
226
+ assert len (events ) == 2 # START, CONTENT
226
227
assert isinstance (events [1 ], TextMessageContentEvent )
227
228
assert events [1 ].delta == "First partSecond part" # Joined without newlines
229
+ assert all (not isinstance (event , TextMessageEndEvent ) for event in events )
228
230
229
231
@pytest .mark .asyncio
230
232
async def test_translate_text_content_partial_streaming (self , translator , mock_adk_event_with_content ):
@@ -236,9 +238,10 @@ async def test_translate_text_content_partial_streaming(self, translator, mock_a
236
238
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
237
239
events .append (event )
238
240
239
- assert len (events ) == 3 # START, CONTENT , END
241
+ assert len (events ) == 2 # START, CONTENT
240
242
assert isinstance (events [0 ], TextMessageStartEvent )
241
243
assert isinstance (events [1 ], TextMessageContentEvent )
244
+ assert all (not isinstance (event , TextMessageEndEvent ) for event in events )
242
245
243
246
@pytest .mark .asyncio
244
247
async def test_translate_text_content_final_response_callable (self , translator , mock_adk_event_with_content ):
@@ -304,7 +307,7 @@ async def test_translate_text_content_final_response_from_agent_callback(self, t
304
307
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
305
308
events .append (event )
306
309
307
- assert len (events ) == 3 # START, CONTENT , END
310
+ assert len (events ) == 3 # START, CONTENT, END (non-streaming final response)
308
311
assert isinstance (events [0 ], TextMessageStartEvent )
309
312
assert isinstance (events [1 ], TextMessageContentEvent )
310
313
assert events [1 ].delta == mock_adk_event_with_content .content .parts [0 ].text
@@ -360,8 +363,9 @@ async def test_translate_text_content_mixed_text_parts(self, translator, mock_ad
360
363
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
361
364
events .append (event )
362
365
363
- assert len (events ) == 3 # START, CONTENT , END
366
+ assert len (events ) == 2 # START, CONTENT
364
367
assert events [1 ].delta == "Valid textMore text"
368
+ assert all (not isinstance (event , TextMessageEndEvent ) for event in events )
365
369
366
370
@pytest .mark .asyncio
367
371
async def test_translate_function_calls_basic (self , translator , mock_adk_event ):
@@ -647,21 +651,23 @@ async def test_streaming_state_management(self, translator, mock_adk_event_with_
647
651
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
648
652
events1 .append (event )
649
653
650
- assert len (events1 ) == 3 # START, CONTENT, END
654
+ assert len (events1 ) == 2 # START, CONTENT (stream stays open)
651
655
message_id = events1 [0 ].message_id
652
656
653
- # streaming is stoped after TextMessageEndEvent
654
- assert translator ._is_streaming is False
655
- # since the streaming is stopped
656
- assert translator ._streaming_message_id == None
657
+ # Stream remains active until completion signal
658
+ assert translator ._is_streaming is True
659
+ assert translator ._streaming_message_id == message_id
657
660
658
- # Second event should continue streaming ( same message ID )
661
+ # Second event should append to the same stream (content only )
659
662
events2 = []
660
663
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
661
664
events2 .append (event )
662
665
663
- assert len (events2 ) == 3 # New Streaming (START , CONTENT ,END)
664
- assert events2 [0 ].message_id != message_id # Same message ID
666
+ assert len (events2 ) == 1 # CONTENT only
667
+ assert isinstance (events2 [0 ], TextMessageContentEvent )
668
+ assert events2 [0 ].message_id == message_id
669
+ assert translator ._is_streaming is True
670
+ assert translator ._streaming_message_id == message_id
665
671
666
672
@pytest .mark .asyncio
667
673
async def test_complex_event_with_multiple_features (self , translator , mock_adk_event ):
@@ -685,16 +691,16 @@ async def test_complex_event_with_multiple_features(self, translator, mock_adk_e
685
691
async for event in translator .translate (mock_adk_event , "thread_1" , "run_1" ):
686
692
events .append (event )
687
693
688
- # Should have text events, state delta, and custom event
689
- assert len (events ) == 5 # START, CONTENT, STATE_DELTA, CUSTOM , END
694
+ # Should have text events, state delta, and custom event (stream remains open)
695
+ assert len (events ) == 4 # START, CONTENT, STATE_DELTA, CUSTOM
690
696
691
697
# Check event types
692
698
event_types = [type (event ) for event in events ]
693
699
assert TextMessageStartEvent in event_types
694
700
assert TextMessageContentEvent in event_types
695
701
assert StateDeltaEvent in event_types
696
702
assert CustomEvent in event_types
697
- assert TextMessageEndEvent in event_types
703
+ assert TextMessageEndEvent not in event_types
698
704
699
705
@pytest .mark .asyncio
700
706
async def test_event_logging_coverage (self , translator , mock_adk_event_with_content ):
@@ -765,8 +771,8 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
765
771
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
766
772
events1 .append (event )
767
773
768
- assert len (events1 ) == 3 # START, CONTENT , END
769
- assert translator ._is_streaming is False
774
+ assert len (events1 ) == 2 # START, CONTENT
775
+ assert translator ._is_streaming is True
770
776
message_id = events1 [0 ].message_id
771
777
772
778
# Second partial event (should continue streaming)
@@ -777,9 +783,11 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
777
783
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
778
784
events2 .append (event )
779
785
780
- assert len (events2 ) == 3 # Will start from begining (START , CONTENT , END)
781
- assert isinstance (events2 [1 ], TextMessageContentEvent )
782
- assert events2 [0 ].message_id != message_id # Not the same message ID Because its a new streaming
786
+ assert len (events2 ) == 1 # Additional CONTENT chunk
787
+ assert isinstance (events2 [0 ], TextMessageContentEvent )
788
+ assert events2 [0 ].message_id == message_id # Same stream continues
789
+ assert translator ._is_streaming is True
790
+ assert translator ._streaming_message_id == message_id
783
791
784
792
# Final event (should end streaming - requires is_final_response=True)
785
793
mock_adk_event_with_content .partial = False
@@ -790,7 +798,9 @@ async def test_partial_streaming_continuation(self, translator, mock_adk_event_w
790
798
async for event in translator .translate (mock_adk_event_with_content , "thread_1" , "run_1" ):
791
799
events3 .append (event )
792
800
793
- assert len (events3 ) == 0 # No more message (turn Complete)
801
+ assert len (events3 ) == 1 # Final END to close the stream
802
+ assert isinstance (events3 [0 ], TextMessageEndEvent )
803
+ assert events3 [0 ].message_id == message_id
794
804
795
805
# Should reset streaming state
796
806
assert translator ._is_streaming is False
0 commit comments