11from __future__ import annotations as _annotations
22
33from collections .abc import Hashable , Sequence
4- from dataclasses import dataclass
4+ from dataclasses import dataclass , field
55from typing import Literal
66
77import pytest
1313
1414def stream_text_deltas (
1515 case : Case ,
16- ) -> tuple [list [ModelResponseStreamEvent ], list [ModelResponseStreamEvent ], list [ModelResponsePart ], str ]:
16+ ) -> tuple [list [ModelResponseStreamEvent ], list [ModelResponseStreamEvent ], list [ModelResponsePart ]]:
1717 """Helper to stream chunks through manager and return all events + final parts."""
1818 manager = ModelResponsePartsManager ()
1919 events_before_flushing : list [ModelResponseStreamEvent ] = []
@@ -32,14 +32,7 @@ def stream_text_deltas(
3232 for event in manager .final_flush ():
3333 all_events .append (event )
3434
35- parts = manager .get_parts ()
36- leftover_closing_bufffer = ''
37- for part in parts :
38- if isinstance (part , ThinkingPart ):
39- leftover_closing_bufffer = part .closing_tag_buffer
40- break
41-
42- return events_before_flushing , all_events , parts , leftover_closing_bufffer
35+ return events_before_flushing , all_events , manager .get_parts ()
4336
4437
4538@dataclass
@@ -51,7 +44,7 @@ class Case:
5144 expected_events_before_flushing : Sequence [ModelResponseStreamEvent ] | Literal ['same-as-expected-events' ] = (
5245 'same-as-expected-events'
5346 )
54- leftover_closing_bufffer : str = ''
47+ leftover_closing_bufffer : list [ str ] = field ( default_factory = list )
5548 vendor_part_id : Hashable | None = 'content'
5649 ignore_leading_whitespace : bool = False
5750 thinking_tags : tuple [str , str ] | None = ('<think>' , '</think>' )
@@ -66,7 +59,7 @@ class Case:
6659 PartStartEvent (index = 0 , part = ThinkingPart ('con' )),
6760 PartDeltaEvent (index = 0 , delta = ThinkingPartDelta (content_delta = 'tent' )),
6861 ],
69- leftover_closing_bufffer = '</th' , # a full ['</th', 'ink>'] would leave the buffer empty
62+ leftover_closing_bufffer = [ '</th' ] , # a full ['</th', 'ink>'] would leave the buffer empty
7063 ),
7164 Case (
7265 name = 'full_split_on_both_sides_clean' ,
@@ -274,7 +267,7 @@ class Case:
274267 expected_events = [
275268 PartStartEvent (index = 0 , part = ThinkingPart ('content' )),
276269 ],
277- leftover_closing_bufffer = '</th' ,
270+ leftover_closing_bufffer = [ '</th' ] ,
278271 ),
279272 Case (
280273 name = 'existing_thinking_partial_closing' ,
@@ -283,7 +276,7 @@ class Case:
283276 expected_events = [
284277 PartStartEvent (index = 0 , part = ThinkingPart ('content' )),
285278 ],
286- leftover_closing_bufffer = '</th' ,
279+ leftover_closing_bufffer = [ '</th' ] ,
287280 ),
288281 Case (
289282 name = 'existing_thinking_buffer_completes_partial_closing' ,
@@ -301,7 +294,7 @@ class Case:
301294 PartStartEvent (index = 0 , part = ThinkingPart ('content' )),
302295 PartDeltaEvent (index = 0 , delta = ThinkingPartDelta (content_delta = 'more' )),
303296 ],
304- leftover_closing_bufffer = '</th' ,
297+ leftover_closing_bufffer = [ '</th' ] ,
305298 ),
306299 Case (
307300 name = 'existing_thinking_buffer_multi_partial_closing_completes' ,
@@ -529,7 +522,7 @@ def test_thinking_parts_parametrized(case: Case) -> None:
529522 """
530523 Parametrized coverage for all cases described in the report.
531524 """
532- events_before_flushing , events , final_parts , leftover_closing_bufffer = stream_text_deltas (case )
525+ events_before_flushing , events , final_parts = stream_text_deltas (case )
533526
534527 # Parts observed from final state (after all deltas have been applied)
535528 assert final_parts == case .expected_parts , f'\n Observed: { final_parts } \n Expected: { case .expected_parts } '
@@ -547,6 +540,10 @@ def test_thinking_parts_parametrized(case: Case) -> None:
547540 f'\n Observed: { events_before_flushing } \n Expected: { case .expected_events_before_flushing } '
548541 )
549542
543+ leftover_closing_bufffer = [
544+ part .closing_tag_buffer for part in final_parts if isinstance (part , ThinkingPart ) and part .closing_tag_buffer
545+ ]
546+
550547 assert leftover_closing_bufffer == case .leftover_closing_bufffer , (
551548 f'\n Observed: { leftover_closing_bufffer } \n Expected: { case .leftover_closing_bufffer } '
552549 )
0 commit comments