@@ -156,6 +156,43 @@ def mock_generate_content_stream_afc_history():
156156 yield mock_generate_content
157157
158158
159+ @pytest .fixture
160+ def mock_generate_content_stream_with_split_model_output ():
161+ with mock .patch .object (
162+ models .Models , 'generate_content_stream'
163+ ) as mock_generate_content :
164+ mock_generate_content .return_value = [
165+ types .GenerateContentResponse (
166+ candidates = [
167+ types .Candidate (
168+ content = types .Content (
169+ role = 'model' ,
170+ parts = [types .Part .from_text (text = 'reasoning' )],
171+ ),
172+ )
173+ ]
174+ ),
175+ types .GenerateContentResponse (
176+ candidates = [
177+ types .Candidate (
178+ content = types .Content (
179+ role = 'model' ,
180+ parts = [
181+ types .Part (
182+ function_call = types .FunctionCall (
183+ name = 'foo' , args = {'bar' : 'baz' }
184+ )
185+ )
186+ ],
187+ ),
188+ finish_reason = types .FinishReason .STOP ,
189+ )
190+ ]
191+ ),
192+ ]
193+ yield mock_generate_content
194+
195+
159196def test_history_start_with_valid_model_content ():
160197 history = [
161198 types .Content (
@@ -251,7 +288,15 @@ def test_history_with_consecutive_valid_model_outputs():
251288 chat = chats_module .create (model = 'gemini-2.5-flash' , history = history )
252289
253290 assert chat .get_history () == history
254- assert chat .get_history (curated = True ) == history
291+ assert chat .get_history (curated = True ) == [
292+ types .Content (
293+ role = 'model' ,
294+ parts = [
295+ types .Part .from_text (text = 'model output 1' ),
296+ types .Part .from_text (text = 'model output 2' ),
297+ ],
298+ ),
299+ ]
255300
256301
257302def test_history_with_valid_and_invalid_model_output ():
@@ -343,7 +388,19 @@ def test_sync_chat_create():
343388 chat = chats_module .create (model = 'gemini-2.5-flash' , history = history )
344389
345390 assert chat .get_history () == history
346- assert chat .get_history (curated = True ) == history
391+ assert chat .get_history (curated = True ) == [
392+ types .Content (
393+ role = 'user' , parts = [types .Part .from_text (text = 'user input turn 1' )]
394+ ),
395+ types .Content (
396+ role = 'model' ,
397+ parts = [
398+ types .Part .from_text (text = 'model output turn 1' ),
399+ types .Part .from_text (text = 'model output turn 1' ),
400+ types .Part .from_text (text = 'user input turn 2' ),
401+ ],
402+ ),
403+ ]
347404
348405
349406def test_async_chat_create ():
@@ -374,7 +431,20 @@ def test_async_chat_create():
374431 chat = chats_module .create (model = 'gemini-2.5-flash' , history = history )
375432
376433 assert chat .get_history () == history
377- assert chat .get_history (curated = True ) == history
434+ assert chat .get_history (curated = True ) == [
435+ types .Content (
436+ role = 'user' , parts = [types .Part .from_text (text = 'user input turn 1' )]
437+ ),
438+ types .Content (
439+ role = 'model' ,
440+ parts = [
441+ types .Part .from_text (text = 'model output turn 1' ),
442+ types .Part .from_text (text = 'model output turn 1' ),
443+ types .Part .from_text (text = 'user input turn 2' ),
444+ types .Part .from_text (text = 'model output turn 2' ),
445+ ],
446+ ),
447+ ]
378448
379449
380450def test_sync_chat_create_with_history_dict ():
@@ -470,7 +540,15 @@ def test_history_with_invalid_turns():
470540 comprehensive_history .append (invalid_output )
471541 curated_history = []
472542 curated_history .append (valid_input )
473- curated_history .extend (valid_output )
543+ curated_history .append (
544+ types .Content (
545+ role = 'model' ,
546+ parts = [
547+ valid_output [0 ].parts [0 ],
548+ valid_output [1 ].parts [0 ],
549+ ],
550+ )
551+ )
474552
475553 models_module = models .Models (mock_api_client )
476554 chats_module = chats .Chats (modules = models_module )
@@ -596,3 +674,48 @@ def test_chat_stream_with_afc_history(mock_generate_content_stream_afc_history):
596674 ]
597675 assert chat .get_history () == expected_history
598676 assert chat .get_history (curated = True ) == expected_history
677+
678+
679+ def test_chat_stream_merges_model_chunks_for_curated_history (
680+ mock_generate_content_stream_with_split_model_output ,
681+ ):
682+ models_module = models .Models (mock_api_client )
683+ chats_module = chats .Chats (modules = models_module )
684+ chat = chats_module .create (model = 'gemini-2.5-flash' )
685+
686+ for _ in chat .send_message_stream ('Hello' ):
687+ pass
688+
689+ expected_comprehensive_history = [
690+ types .UserContent (parts = [types .Part .from_text (text = 'Hello' )]),
691+ types .Content (
692+ role = 'model' ,
693+ parts = [types .Part .from_text (text = 'reasoning' )],
694+ ),
695+ types .Content (
696+ role = 'model' ,
697+ parts = [
698+ types .Part (
699+ function_call = types .FunctionCall (
700+ name = 'foo' , args = {'bar' : 'baz' }
701+ )
702+ )
703+ ],
704+ ),
705+ ]
706+ expected_curated_history = [
707+ types .UserContent (parts = [types .Part .from_text (text = 'Hello' )]),
708+ types .Content (
709+ role = 'model' ,
710+ parts = [
711+ types .Part .from_text (text = 'reasoning' ),
712+ types .Part (
713+ function_call = types .FunctionCall (
714+ name = 'foo' , args = {'bar' : 'baz' }
715+ )
716+ ),
717+ ],
718+ ),
719+ ]
720+ assert chat .get_history () == expected_comprehensive_history
721+ assert chat .get_history (curated = True ) == expected_curated_history
0 commit comments