google-genai 1.55.0__py3-none-any.whl → 1.56.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. google/genai/_interactions/_base_client.py +8 -2
  2. google/genai/_interactions/resources/interactions.py +6 -6
  3. google/genai/_interactions/types/__init__.py +2 -0
  4. google/genai/_interactions/types/audio_content.py +0 -1
  5. google/genai/_interactions/types/audio_content_param.py +0 -1
  6. google/genai/_interactions/types/code_execution_call_content.py +0 -1
  7. google/genai/_interactions/types/code_execution_call_content_param.py +0 -1
  8. google/genai/_interactions/types/code_execution_result_content.py +0 -1
  9. google/genai/_interactions/types/code_execution_result_content_param.py +0 -1
  10. google/genai/_interactions/types/content_delta.py +7 -23
  11. google/genai/_interactions/types/deep_research_agent_config.py +0 -1
  12. google/genai/_interactions/types/deep_research_agent_config_param.py +0 -1
  13. google/genai/_interactions/types/document_content.py +3 -2
  14. google/genai/_interactions/types/document_content_param.py +3 -2
  15. google/genai/{tests/__init__.py → _interactions/types/document_mime_type.py} +5 -3
  16. google/genai/{tests/afc/__init__.py → _interactions/types/document_mime_type_param.py} +8 -4
  17. google/genai/_interactions/types/dynamic_agent_config.py +0 -1
  18. google/genai/_interactions/types/dynamic_agent_config_param.py +0 -1
  19. google/genai/_interactions/types/file_search_result_content.py +0 -1
  20. google/genai/_interactions/types/file_search_result_content_param.py +0 -1
  21. google/genai/_interactions/types/function_call_content.py +0 -1
  22. google/genai/_interactions/types/function_call_content_param.py +0 -1
  23. google/genai/_interactions/types/function_result_content.py +1 -2
  24. google/genai/_interactions/types/function_result_content_param.py +1 -2
  25. google/genai/_interactions/types/google_search_call_content.py +0 -1
  26. google/genai/_interactions/types/google_search_call_content_param.py +0 -1
  27. google/genai/_interactions/types/google_search_result_content.py +0 -1
  28. google/genai/_interactions/types/google_search_result_content_param.py +0 -1
  29. google/genai/_interactions/types/image_content.py +1 -2
  30. google/genai/_interactions/types/image_content_param.py +1 -2
  31. google/genai/_interactions/types/mcp_server_tool_call_content.py +0 -1
  32. google/genai/_interactions/types/mcp_server_tool_call_content_param.py +0 -1
  33. google/genai/_interactions/types/mcp_server_tool_result_content.py +1 -2
  34. google/genai/_interactions/types/mcp_server_tool_result_content_param.py +1 -2
  35. google/genai/_interactions/types/text_content.py +0 -1
  36. google/genai/_interactions/types/text_content_param.py +0 -1
  37. google/genai/_interactions/types/thinking_level.py +1 -1
  38. google/genai/_interactions/types/thought_content.py +0 -1
  39. google/genai/_interactions/types/thought_content_param.py +0 -1
  40. google/genai/_interactions/types/url_context_call_content.py +0 -1
  41. google/genai/_interactions/types/url_context_call_content_param.py +0 -1
  42. google/genai/_interactions/types/url_context_result_content.py +0 -1
  43. google/genai/_interactions/types/url_context_result_content_param.py +0 -1
  44. google/genai/_interactions/types/video_content.py +1 -2
  45. google/genai/_interactions/types/video_content_param.py +1 -2
  46. google/genai/_live_converters.py +2 -30
  47. google/genai/client.py +3 -1
  48. google/genai/models.py +2 -29
  49. google/genai/tunings.py +1 -27
  50. google/genai/types.py +20 -22
  51. google/genai/version.py +1 -1
  52. {google_genai-1.55.0.dist-info → google_genai-1.56.0.dist-info}/METADATA +224 -22
  53. google_genai-1.56.0.dist-info/RECORD +162 -0
  54. google/genai/tests/afc/test_convert_if_exist_pydantic_model.py +0 -309
  55. google/genai/tests/afc/test_convert_number_values_for_function_call_args.py +0 -63
  56. google/genai/tests/afc/test_find_afc_incompatible_tool_indexes.py +0 -240
  57. google/genai/tests/afc/test_generate_content_stream_afc.py +0 -530
  58. google/genai/tests/afc/test_generate_content_stream_afc_thoughts.py +0 -77
  59. google/genai/tests/afc/test_get_function_map.py +0 -176
  60. google/genai/tests/afc/test_get_function_response_parts.py +0 -277
  61. google/genai/tests/afc/test_get_max_remote_calls_for_afc.py +0 -130
  62. google/genai/tests/afc/test_invoke_function_from_dict_args.py +0 -241
  63. google/genai/tests/afc/test_raise_error_for_afc_incompatible_config.py +0 -159
  64. google/genai/tests/afc/test_should_append_afc_history.py +0 -53
  65. google/genai/tests/afc/test_should_disable_afc.py +0 -214
  66. google/genai/tests/batches/__init__.py +0 -17
  67. google/genai/tests/batches/test_cancel.py +0 -77
  68. google/genai/tests/batches/test_create.py +0 -78
  69. google/genai/tests/batches/test_create_with_bigquery.py +0 -113
  70. google/genai/tests/batches/test_create_with_file.py +0 -82
  71. google/genai/tests/batches/test_create_with_gcs.py +0 -125
  72. google/genai/tests/batches/test_create_with_inlined_requests.py +0 -255
  73. google/genai/tests/batches/test_delete.py +0 -86
  74. google/genai/tests/batches/test_embedding.py +0 -157
  75. google/genai/tests/batches/test_get.py +0 -78
  76. google/genai/tests/batches/test_list.py +0 -79
  77. google/genai/tests/caches/__init__.py +0 -17
  78. google/genai/tests/caches/constants.py +0 -29
  79. google/genai/tests/caches/test_create.py +0 -210
  80. google/genai/tests/caches/test_create_custom_url.py +0 -105
  81. google/genai/tests/caches/test_delete.py +0 -54
  82. google/genai/tests/caches/test_delete_custom_url.py +0 -52
  83. google/genai/tests/caches/test_get.py +0 -94
  84. google/genai/tests/caches/test_get_custom_url.py +0 -52
  85. google/genai/tests/caches/test_list.py +0 -68
  86. google/genai/tests/caches/test_update.py +0 -70
  87. google/genai/tests/caches/test_update_custom_url.py +0 -58
  88. google/genai/tests/chats/__init__.py +0 -1
  89. google/genai/tests/chats/test_get_history.py +0 -597
  90. google/genai/tests/chats/test_send_message.py +0 -844
  91. google/genai/tests/chats/test_validate_response.py +0 -90
  92. google/genai/tests/client/__init__.py +0 -17
  93. google/genai/tests/client/test_async_stream.py +0 -427
  94. google/genai/tests/client/test_client_close.py +0 -197
  95. google/genai/tests/client/test_client_initialization.py +0 -1687
  96. google/genai/tests/client/test_client_requests.py +0 -355
  97. google/genai/tests/client/test_custom_client.py +0 -77
  98. google/genai/tests/client/test_http_options.py +0 -178
  99. google/genai/tests/client/test_replay_client_equality.py +0 -168
  100. google/genai/tests/client/test_retries.py +0 -846
  101. google/genai/tests/client/test_upload_errors.py +0 -136
  102. google/genai/tests/common/__init__.py +0 -17
  103. google/genai/tests/common/test_common.py +0 -954
  104. google/genai/tests/conftest.py +0 -162
  105. google/genai/tests/documents/__init__.py +0 -17
  106. google/genai/tests/documents/test_delete.py +0 -51
  107. google/genai/tests/documents/test_get.py +0 -85
  108. google/genai/tests/documents/test_list.py +0 -72
  109. google/genai/tests/errors/__init__.py +0 -1
  110. google/genai/tests/errors/test_api_error.py +0 -417
  111. google/genai/tests/file_search_stores/__init__.py +0 -17
  112. google/genai/tests/file_search_stores/test_create.py +0 -66
  113. google/genai/tests/file_search_stores/test_delete.py +0 -64
  114. google/genai/tests/file_search_stores/test_get.py +0 -94
  115. google/genai/tests/file_search_stores/test_import_file.py +0 -112
  116. google/genai/tests/file_search_stores/test_list.py +0 -57
  117. google/genai/tests/file_search_stores/test_upload_to_file_search_store.py +0 -141
  118. google/genai/tests/files/__init__.py +0 -17
  119. google/genai/tests/files/test_delete.py +0 -46
  120. google/genai/tests/files/test_download.py +0 -85
  121. google/genai/tests/files/test_get.py +0 -46
  122. google/genai/tests/files/test_list.py +0 -72
  123. google/genai/tests/files/test_upload.py +0 -255
  124. google/genai/tests/imports/test_no_optional_imports.py +0 -28
  125. google/genai/tests/interactions/test_integration.py +0 -80
  126. google/genai/tests/live/__init__.py +0 -16
  127. google/genai/tests/live/test_live.py +0 -2177
  128. google/genai/tests/live/test_live_music.py +0 -362
  129. google/genai/tests/live/test_live_response.py +0 -163
  130. google/genai/tests/live/test_send_client_content.py +0 -147
  131. google/genai/tests/live/test_send_realtime_input.py +0 -268
  132. google/genai/tests/live/test_send_tool_response.py +0 -222
  133. google/genai/tests/local_tokenizer/__init__.py +0 -17
  134. google/genai/tests/local_tokenizer/test_local_tokenizer.py +0 -343
  135. google/genai/tests/local_tokenizer/test_local_tokenizer_loader.py +0 -235
  136. google/genai/tests/mcp/__init__.py +0 -17
  137. google/genai/tests/mcp/test_has_mcp_tool_usage.py +0 -89
  138. google/genai/tests/mcp/test_mcp_to_gemini_tools.py +0 -191
  139. google/genai/tests/mcp/test_parse_config_for_mcp_sessions.py +0 -201
  140. google/genai/tests/mcp/test_parse_config_for_mcp_usage.py +0 -130
  141. google/genai/tests/mcp/test_set_mcp_usage_header.py +0 -72
  142. google/genai/tests/models/__init__.py +0 -17
  143. google/genai/tests/models/constants.py +0 -8
  144. google/genai/tests/models/test_compute_tokens.py +0 -120
  145. google/genai/tests/models/test_count_tokens.py +0 -159
  146. google/genai/tests/models/test_delete.py +0 -107
  147. google/genai/tests/models/test_edit_image.py +0 -264
  148. google/genai/tests/models/test_embed_content.py +0 -94
  149. google/genai/tests/models/test_function_call_streaming.py +0 -442
  150. google/genai/tests/models/test_generate_content.py +0 -2502
  151. google/genai/tests/models/test_generate_content_cached_content.py +0 -132
  152. google/genai/tests/models/test_generate_content_config_zero_value.py +0 -103
  153. google/genai/tests/models/test_generate_content_from_apikey.py +0 -44
  154. google/genai/tests/models/test_generate_content_http_options.py +0 -40
  155. google/genai/tests/models/test_generate_content_image_generation.py +0 -143
  156. google/genai/tests/models/test_generate_content_mcp.py +0 -343
  157. google/genai/tests/models/test_generate_content_media_resolution.py +0 -97
  158. google/genai/tests/models/test_generate_content_model.py +0 -139
  159. google/genai/tests/models/test_generate_content_part.py +0 -821
  160. google/genai/tests/models/test_generate_content_thought.py +0 -76
  161. google/genai/tests/models/test_generate_content_tools.py +0 -1761
  162. google/genai/tests/models/test_generate_images.py +0 -191
  163. google/genai/tests/models/test_generate_videos.py +0 -759
  164. google/genai/tests/models/test_get.py +0 -104
  165. google/genai/tests/models/test_list.py +0 -233
  166. google/genai/tests/models/test_recontext_image.py +0 -189
  167. google/genai/tests/models/test_segment_image.py +0 -148
  168. google/genai/tests/models/test_update.py +0 -95
  169. google/genai/tests/models/test_upscale_image.py +0 -157
  170. google/genai/tests/operations/__init__.py +0 -17
  171. google/genai/tests/operations/test_get.py +0 -38
  172. google/genai/tests/public_samples/__init__.py +0 -17
  173. google/genai/tests/public_samples/test_gemini_text_only.py +0 -34
  174. google/genai/tests/pytest_helper.py +0 -229
  175. google/genai/tests/shared/__init__.py +0 -16
  176. google/genai/tests/shared/batches/__init__.py +0 -14
  177. google/genai/tests/shared/batches/test_create_delete.py +0 -57
  178. google/genai/tests/shared/batches/test_create_get_cancel.py +0 -56
  179. google/genai/tests/shared/batches/test_list.py +0 -40
  180. google/genai/tests/shared/caches/__init__.py +0 -14
  181. google/genai/tests/shared/caches/test_create_get_delete.py +0 -67
  182. google/genai/tests/shared/caches/test_create_update_get.py +0 -71
  183. google/genai/tests/shared/caches/test_list.py +0 -40
  184. google/genai/tests/shared/chats/__init__.py +0 -14
  185. google/genai/tests/shared/chats/test_send_message.py +0 -48
  186. google/genai/tests/shared/chats/test_send_message_stream.py +0 -50
  187. google/genai/tests/shared/files/__init__.py +0 -14
  188. google/genai/tests/shared/files/test_list.py +0 -41
  189. google/genai/tests/shared/files/test_upload_get_delete.py +0 -54
  190. google/genai/tests/shared/models/__init__.py +0 -14
  191. google/genai/tests/shared/models/test_compute_tokens.py +0 -41
  192. google/genai/tests/shared/models/test_count_tokens.py +0 -40
  193. google/genai/tests/shared/models/test_edit_image.py +0 -67
  194. google/genai/tests/shared/models/test_embed.py +0 -40
  195. google/genai/tests/shared/models/test_generate_content.py +0 -39
  196. google/genai/tests/shared/models/test_generate_content_stream.py +0 -54
  197. google/genai/tests/shared/models/test_generate_images.py +0 -40
  198. google/genai/tests/shared/models/test_generate_videos.py +0 -38
  199. google/genai/tests/shared/models/test_list.py +0 -37
  200. google/genai/tests/shared/models/test_recontext_image.py +0 -55
  201. google/genai/tests/shared/models/test_segment_image.py +0 -52
  202. google/genai/tests/shared/models/test_upscale_image.py +0 -52
  203. google/genai/tests/shared/tunings/__init__.py +0 -16
  204. google/genai/tests/shared/tunings/test_create.py +0 -46
  205. google/genai/tests/shared/tunings/test_create_get_cancel.py +0 -56
  206. google/genai/tests/shared/tunings/test_list.py +0 -39
  207. google/genai/tests/tokens/__init__.py +0 -16
  208. google/genai/tests/tokens/test_create.py +0 -154
  209. google/genai/tests/transformers/__init__.py +0 -17
  210. google/genai/tests/transformers/test_blobs.py +0 -71
  211. google/genai/tests/transformers/test_bytes.py +0 -15
  212. google/genai/tests/transformers/test_duck_type.py +0 -96
  213. google/genai/tests/transformers/test_function_responses.py +0 -72
  214. google/genai/tests/transformers/test_schema.py +0 -653
  215. google/genai/tests/transformers/test_t_batch.py +0 -286
  216. google/genai/tests/transformers/test_t_content.py +0 -160
  217. google/genai/tests/transformers/test_t_contents.py +0 -398
  218. google/genai/tests/transformers/test_t_part.py +0 -85
  219. google/genai/tests/transformers/test_t_parts.py +0 -87
  220. google/genai/tests/transformers/test_t_tool.py +0 -157
  221. google/genai/tests/transformers/test_t_tools.py +0 -195
  222. google/genai/tests/tunings/__init__.py +0 -16
  223. google/genai/tests/tunings/test_cancel.py +0 -39
  224. google/genai/tests/tunings/test_end_to_end.py +0 -106
  225. google/genai/tests/tunings/test_get.py +0 -67
  226. google/genai/tests/tunings/test_list.py +0 -75
  227. google/genai/tests/tunings/test_tune.py +0 -268
  228. google/genai/tests/types/__init__.py +0 -16
  229. google/genai/tests/types/test_bytes_internal.py +0 -271
  230. google/genai/tests/types/test_bytes_type.py +0 -152
  231. google/genai/tests/types/test_future.py +0 -101
  232. google/genai/tests/types/test_optional_types.py +0 -36
  233. google/genai/tests/types/test_part_type.py +0 -616
  234. google/genai/tests/types/test_schema_from_json_schema.py +0 -417
  235. google/genai/tests/types/test_schema_json_schema.py +0 -468
  236. google/genai/tests/types/test_types.py +0 -2903
  237. google_genai-1.55.0.dist-info/RECORD +0 -345
  238. /google/genai/{tests/interactions/__init__.py → _interactions/py.typed} +0 -0
  239. {google_genai-1.55.0.dist-info → google_genai-1.56.0.dist-info}/WHEEL +0 -0
  240. {google_genai-1.55.0.dist-info → google_genai-1.56.0.dist-info}/licenses/LICENSE +0 -0
  241. {google_genai-1.55.0.dist-info → google_genai-1.56.0.dist-info}/top_level.txt +0 -0
@@ -1,597 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
- #
15
-
16
-
17
- from unittest import mock
18
-
19
- import pytest
20
-
21
- from ... import chats
22
- from ... import client
23
- from ... import models
24
- from ... import types
25
-
26
- AFC_HISTORY = [
27
- types.Content(
28
- role='user',
29
- parts=[types.Part.from_text(text='afc input')],
30
- ),
31
- types.Content(
32
- role='model',
33
- parts=[
34
- types.Part(
35
- function_call=types.FunctionCall(
36
- name='foo', args={'bar': 'baz'}
37
- )
38
- )
39
- ],
40
- ),
41
- ]
42
-
43
-
44
- pytest_plugins = 'pytest_asyncio'
45
-
46
-
47
- @pytest.fixture
48
- def mock_api_client(vertexai=False):
49
- api_client = mock.MagicMock(spec=client.ApiClient)
50
- api_client.api_key = 'TEST_API_KEY'
51
- api_client._host = lambda: 'test_host'
52
- api_client._http_options = {'headers': {}} # Ensure headers exist
53
- api_client.vertexai = vertexai
54
- return api_client
55
-
56
-
57
- @pytest.fixture
58
- def mock_generate_content_invalid_content():
59
- with mock.patch.object(
60
- models.Models, 'generate_content'
61
- ) as mock_generate_content:
62
- mock_generate_content.return_value = types.GenerateContentResponse(
63
- candidates=[
64
- types.Candidate(
65
- content=types.Content(
66
- role='model',
67
- parts=[types.Part(text='')],
68
- )
69
- )
70
- ]
71
- )
72
- yield mock_generate_content
73
-
74
-
75
- @pytest.fixture
76
- def mock_generate_content_empty_content():
77
- with mock.patch.object(
78
- models.Models, 'generate_content'
79
- ) as mock_generate_content:
80
- mock_generate_content.return_value = types.GenerateContentResponse(
81
- candidates=[]
82
- )
83
- yield mock_generate_content
84
-
85
-
86
- @pytest.fixture
87
- def mock_generate_content_stream_invalid_content():
88
- with mock.patch.object(
89
- models.Models, 'generate_content_stream'
90
- ) as mock_generate_content:
91
- mock_generate_content.return_value = [
92
- types.GenerateContentResponse(
93
- candidates=[
94
- types.Candidate(
95
- content=types.Content(
96
- role='model',
97
- parts=[types.Part(text='')],
98
- )
99
- )
100
- ]
101
- )
102
- ]
103
- yield mock_generate_content
104
-
105
-
106
- @pytest.fixture
107
- def mock_generate_content_stream_empty_content():
108
- with mock.patch.object(
109
- models.Models, 'generate_content_stream'
110
- ) as mock_generate_content:
111
- mock_generate_content.return_value = [
112
- types.GenerateContentResponse(candidates=[])
113
- ]
114
- yield mock_generate_content
115
-
116
-
117
- @pytest.fixture
118
- def mock_generate_content_afc_history():
119
- with mock.patch.object(
120
- models.Models, 'generate_content'
121
- ) as mock_generate_content:
122
- mock_generate_content.return_value = types.GenerateContentResponse(
123
- candidates=[
124
- types.Candidate(
125
- content=types.Content(
126
- role='model',
127
- parts=[types.Part.from_text(text='afc output')],
128
- )
129
- )
130
- ],
131
- automatic_function_calling_history=AFC_HISTORY,
132
- )
133
- yield mock_generate_content
134
-
135
-
136
- @pytest.fixture
137
- def mock_generate_content_stream_afc_history():
138
- with mock.patch.object(
139
- models.Models, 'generate_content_stream'
140
- ) as mock_generate_content:
141
- mock_generate_content.return_value = [
142
- types.GenerateContentResponse(
143
- candidates=[
144
- types.Candidate(
145
- content=types.Content(
146
- role='model',
147
- parts=[types.Part.from_text(text='afc output')],
148
- ),
149
- finish_reason=types.FinishReason.STOP,
150
- )
151
- ],
152
- automatic_function_calling_history=AFC_HISTORY,
153
- )
154
- ]
155
- yield mock_generate_content
156
-
157
-
158
- def test_history_start_with_valid_model_content():
159
- history = [
160
- types.Content(
161
- role='model',
162
- parts=[types.Part.from_text(text='Hello there! how can I help you?')],
163
- ),
164
- types.Content(role='user', parts=[types.Part.from_text(text='Hello')]),
165
- ]
166
-
167
- models_module = models.Models(mock_api_client)
168
- chats_module = chats.Chats(modules=models_module)
169
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
170
-
171
- assert chat.get_history() == history
172
- assert chat.get_history(curated=True) == history
173
-
174
-
175
- def test_history_start_with_invalid_model_content():
176
- history = [
177
- types.Content(
178
- role='model',
179
- parts=[],
180
- ),
181
- types.Content(role='user', parts=[types.Part.from_text(text='Hello')]),
182
- ]
183
-
184
- models_module = models.Models(mock_api_client)
185
- chats_module = chats.Chats(modules=models_module)
186
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
187
-
188
- assert chat.get_history() == history
189
- assert chat.get_history(curated=True) == [types.Content(role='user', parts=[types.Part.from_text(text='Hello')])]
190
-
191
-
192
- def test_history_with_consecutive_valid_user_inputs():
193
- history = [
194
- types.Content(
195
- role='user',
196
- parts=[types.Part.from_text(text='user input 1')],
197
- ),
198
- types.Content(
199
- role='user',
200
- parts=[types.Part.from_text(text='user input 2')],
201
- ),
202
- ]
203
-
204
- models_module = models.Models(mock_api_client)
205
- chats_module = chats.Chats(modules=models_module)
206
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
207
-
208
- assert chat.get_history() == history
209
- assert chat.get_history(curated=True) == history
210
-
211
-
212
- def test_history_with_valid_and_invalid_user_inputs():
213
- history = [
214
- types.Content(
215
- role='user',
216
- parts=[types.Part.from_text(text='user input 1')],
217
- ),
218
- types.Content(
219
- role='user',
220
- parts=[], # invalid content
221
- ),
222
- types.Content(
223
- role='user',
224
- parts=[types.Part.from_text(text='user input 2')],
225
- ),
226
- ]
227
-
228
- models_module = models.Models(mock_api_client)
229
- chats_module = chats.Chats(modules=models_module)
230
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
231
-
232
- assert chat.get_history() == history
233
- assert chat.get_history(curated=True) == history
234
-
235
-
236
- def test_history_with_consecutive_valid_model_outputs():
237
- history = [
238
- types.Content(
239
- role='model',
240
- parts=[types.Part.from_text(text='model output 1')],
241
- ),
242
- types.Content(
243
- role='model',
244
- parts=[types.Part.from_text(text='model output 2')],
245
- ),
246
- ]
247
-
248
- models_module = models.Models(mock_api_client)
249
- chats_module = chats.Chats(modules=models_module)
250
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
251
-
252
- assert chat.get_history() == history
253
- assert chat.get_history(curated=True) == history
254
-
255
-
256
- def test_history_with_valid_and_invalid_model_output():
257
- history = [
258
- types.Content(
259
- role='model',
260
- parts=[types.Part.from_text(text='model output 1')],
261
- ),
262
- types.Content(
263
- role='model',
264
- parts=[], # invalid content
265
- ),
266
- types.Content(
267
- role='model',
268
- parts=[types.Part.from_text(text='model output 2')],
269
- ),
270
- ]
271
-
272
- models_module = models.Models(mock_api_client)
273
- chats_module = chats.Chats(modules=models_module)
274
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
275
-
276
- assert chat.get_history() == history
277
- assert chat.get_history(curated=True) == []
278
-
279
-
280
- def test_history_end_with_user_input():
281
- history = [
282
- types.Content(
283
- role='user',
284
- parts=[types.Part.from_text(text='user input 1')],
285
- ),
286
- types.Content(
287
- role='model',
288
- parts=[types.Part.from_text(text='model output')],
289
- ),
290
- types.Content(
291
- role='user',
292
- parts=[types.Part.from_text(text='user input 2')],
293
- ),
294
- ]
295
-
296
- models_module = models.Models(mock_api_client)
297
- chats_module = chats.Chats(modules=models_module)
298
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
299
-
300
- assert chat.get_history() == history
301
- assert chat.get_history(curated=True) == history
302
-
303
-
304
- def test_unrecognized_role_in_history():
305
- history = [
306
- types.Content(role='user', parts=[types.Part.from_text(text='Hello')]),
307
- types.Content(
308
- role='invalid_role',
309
- parts=[types.Part.from_text(text='Hello there! how can I help you?')],
310
- ),
311
- ]
312
-
313
- models_module = models.Models(mock_api_client)
314
- chats_module = chats.Chats(modules=models_module)
315
- with pytest.raises(ValueError) as e:
316
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
317
-
318
- assert 'Role must be user or model' in str(e)
319
-
320
-
321
- def test_sync_chat_create():
322
- history = [
323
- types.Content(
324
- role='user', parts=[types.Part.from_text(text='user input turn 1')]
325
- ),
326
- types.Content(
327
- role='model',
328
- parts=[types.Part.from_text(text='model output turn 1')],
329
- ),
330
- types.Content(
331
- role='model',
332
- parts=[types.Part.from_text(text='model output turn 1')],
333
- ),
334
- types.Content(
335
- role='model',
336
- parts=[types.Part.from_text(text='user input turn 2')],
337
- ),
338
- ]
339
-
340
- models_module = models.Models(mock_api_client)
341
- chats_module = chats.Chats(modules=models_module)
342
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
343
-
344
- assert chat.get_history() == history
345
- assert chat.get_history(curated=True) == history
346
-
347
-
348
- def test_async_chat_create():
349
- history = [
350
- types.Content(
351
- role='user', parts=[types.Part.from_text(text='user input turn 1')]
352
- ),
353
- types.Content(
354
- role='model',
355
- parts=[types.Part.from_text(text='model output turn 1')],
356
- ),
357
- types.Content(
358
- role='model',
359
- parts=[types.Part.from_text(text='model output turn 1')],
360
- ),
361
- types.Content(
362
- role='model',
363
- parts=[types.Part.from_text(text='user input turn 2')],
364
- ),
365
- types.Content(
366
- role='model',
367
- parts=[types.Part.from_text(text='model output turn 2')],
368
- ),
369
- ]
370
-
371
- models_module = models.AsyncModels(mock_api_client)
372
- chats_module = chats.AsyncChats(modules=models_module)
373
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
374
-
375
- assert chat.get_history() == history
376
- assert chat.get_history(curated=True) == history
377
-
378
-
379
- def test_sync_chat_create_with_history_dict():
380
- history = [
381
- {'role': 'user', 'parts': [{'text': 'user input turn 1'}]},
382
- {'role': 'model', 'parts': [{'text': 'model output turn 1'}]},
383
- {'role': 'user', 'parts': [{'text': 'user input turn 2'}]},
384
- {'role': 'model', 'parts': [{'text': 'model output turn 2'}]},
385
- ]
386
- models_module = models.Models(mock_api_client)
387
- chats_module = chats.Chats(modules=models_module)
388
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
389
-
390
- expected_history = [
391
- types.Content(
392
- role='user', parts=[types.Part.from_text(text='user input turn 1')]
393
- ),
394
- types.Content(
395
- role='model',
396
- parts=[types.Part.from_text(text='model output turn 1')],
397
- ),
398
- types.Content(
399
- role='user', parts=[types.Part.from_text(text='user input turn 2')]
400
- ),
401
- types.Content(
402
- role='model',
403
- parts=[types.Part.from_text(text='model output turn 2')],
404
- ),
405
- ]
406
- assert chat.get_history() == expected_history
407
- assert chat.get_history(curated=True) == expected_history
408
-
409
-
410
- def test_async_chat_create_with_history_dict():
411
- history = [
412
- {'role': 'user', 'parts': [{'text': 'user input turn 1'}]},
413
- {'role': 'model', 'parts': [{'text': 'model output turn 1'}]},
414
- {'role': 'user', 'parts': [{'text': 'user input turn 2'}]},
415
- {'role': 'model', 'parts': [{'text': 'model output turn 2'}]},
416
- ]
417
- models_module = models.AsyncModels(mock_api_client)
418
- chats_module = chats.AsyncChats(modules=models_module)
419
- chat = chats_module.create(model='gemini-2.5-flash', history=history)
420
-
421
- expected_history = [
422
- types.Content(
423
- role='user', parts=[types.Part.from_text(text='user input turn 1')]
424
- ),
425
- types.Content(
426
- role='model',
427
- parts=[types.Part.from_text(text='model output turn 1')],
428
- ),
429
- types.Content(
430
- role='user', parts=[types.Part.from_text(text='user input turn 2')]
431
- ),
432
- types.Content(
433
- role='model',
434
- parts=[types.Part.from_text(text='model output turn 2')],
435
- ),
436
- ]
437
- assert chat.get_history() == expected_history
438
- assert chat.get_history(curated=True) == expected_history
439
-
440
-
441
- def test_history_with_invalid_turns():
442
- valid_input = types.Content(
443
- role='user', parts=[types.Part.from_text(text='Hello')]
444
- )
445
- valid_output = [
446
- types.Content(
447
- role='model',
448
- parts=[types.Part.from_text(text='Hello there! how can I help you?')],
449
- ),
450
- types.Content(
451
- role='model',
452
- parts=[types.Part.from_text(text='Hello there! how can I help you?')],
453
- ),
454
- ]
455
- invalid_input = types.Content(
456
- role='user',
457
- parts=[
458
- types.Part.from_text(text='a input will be rejected by the model')
459
- ],
460
- )
461
- invalid_output = types.Content(
462
- role='model',
463
- parts=[],
464
- )
465
- comprehensive_history = []
466
- comprehensive_history.append(valid_input)
467
- comprehensive_history.extend(valid_output)
468
- comprehensive_history.append(invalid_input)
469
- comprehensive_history.append(invalid_output)
470
- curated_history = []
471
- curated_history.append(valid_input)
472
- curated_history.extend(valid_output)
473
-
474
- models_module = models.Models(mock_api_client)
475
- chats_module = chats.Chats(modules=models_module)
476
- chat = chats_module.create(
477
- model='gemini-2.5-flash', history=comprehensive_history
478
- )
479
-
480
- assert chat.get_history() == comprehensive_history
481
- assert chat.get_history(curated=True) == curated_history
482
-
483
-
484
- def test_chat_with_invalid_content(mock_generate_content_invalid_content):
485
- models_module = models.Models(mock_api_client)
486
- chats_module = chats.Chats(modules=models_module)
487
- chat = chats_module.create(model='gemini-2.5-flash')
488
-
489
- chat.send_message('Hello')
490
-
491
- expected_comprehensive_history = [
492
- types.UserContent(parts=[types.Part.from_text(text='Hello')]),
493
- types.Content(
494
- parts=[types.Part(text='')],
495
- role='model',
496
- ),
497
- ]
498
- assert chat.get_history() == expected_comprehensive_history
499
- assert not chat.get_history(curated=True)
500
-
501
-
502
- def test_chat_with_empty_content(mock_generate_content_empty_content):
503
- models_module = models.Models(mock_api_client)
504
- chats_module = chats.Chats(modules=models_module)
505
- chat = chats_module.create(model='gemini-2.5-flash')
506
-
507
- chat.send_message('Hello')
508
-
509
- expected_comprehensive_history = [
510
- types.UserContent(parts=[types.Part.from_text(text='Hello')]),
511
- types.Content(
512
- parts=[],
513
- role='model',
514
- ),
515
- ]
516
- assert chat.get_history() == expected_comprehensive_history
517
- assert not chat.get_history(curated=True)
518
-
519
-
520
- def test_chat_stream_with_invalid_content(
521
- mock_generate_content_stream_invalid_content,
522
- ):
523
- models_module = models.Models(mock_api_client)
524
- chats_module = chats.Chats(modules=models_module)
525
- chat = chats_module.create(model='gemini-2.5-flash')
526
-
527
- chunks = chat.send_message_stream('Hello')
528
- for chunk in chunks:
529
- pass
530
-
531
- expected_comprehensive_history = [
532
- types.UserContent(parts=[types.Part.from_text(text='Hello')]),
533
- types.Content(
534
- parts=[types.Part(text='')],
535
- role='model',
536
- ),
537
- ]
538
- assert chat.get_history() == expected_comprehensive_history
539
- assert not chat.get_history(curated=True)
540
-
541
-
542
- def test_chat_stream_with_empty_content(
543
- mock_generate_content_stream_empty_content,
544
- ):
545
- models_module = models.Models(mock_api_client)
546
- chats_module = chats.Chats(modules=models_module)
547
- chat = chats_module.create(model='gemini-2.5-flash')
548
-
549
- chunks = chat.send_message_stream('Hello')
550
- for chunk in chunks:
551
- pass
552
-
553
- expected_comprehensive_history = [
554
- types.UserContent(parts=[types.Part.from_text(text='Hello')]),
555
- types.Content(
556
- parts=[],
557
- role='model',
558
- ),
559
- ]
560
- assert chat.get_history() == expected_comprehensive_history
561
- assert not chat.get_history(curated=True)
562
-
563
-
564
- def test_chat_with_afc_history(mock_generate_content_afc_history):
565
- models_module = models.Models(mock_api_client)
566
- chats_module = chats.Chats(modules=models_module)
567
- chat = chats_module.create(model='gemini-2.5-flash')
568
-
569
- chat.send_message('Hello')
570
-
571
- expected_history = AFC_HISTORY + [
572
- types.Content(
573
- role='model',
574
- parts=[types.Part.from_text(text='afc output')],
575
- ),
576
- ]
577
- assert chat.get_history() == expected_history
578
- assert chat.get_history(curated=True) == expected_history
579
-
580
-
581
- def test_chat_stream_with_afc_history(mock_generate_content_stream_afc_history):
582
- models_module = models.Models(mock_api_client)
583
- chats_module = chats.Chats(modules=models_module)
584
- chat = chats_module.create(model='gemini-2.5-flash')
585
-
586
- chunks = chat.send_message_stream('Hello')
587
- for chunk in chunks:
588
- pass
589
-
590
- expected_history = AFC_HISTORY + [
591
- types.Content(
592
- role='model',
593
- parts=[types.Part.from_text(text='afc output')],
594
- ),
595
- ]
596
- assert chat.get_history() == expected_history
597
- assert chat.get_history(curated=True) == expected_history