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,530 +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
- from unittest import mock
16
- import pytest
17
- from ... import _api_client
18
- from ... import _extra_utils
19
- from ... import client
20
- from ... import models
21
- from ... import types
22
-
23
-
24
- TEST_NO_AFC_PART = types.Part(
25
- text=(
26
- 'Okay, here is the weather in San Francisco'
27
- ' as of approximately 8:10 pm PST on May'
28
- ' 10, 2023. Please note that the weather'
29
- ' can change rapidly.'
30
- )
31
- )
32
-
33
- TEST_FUNCTION_CALL_PART = types.Part(
34
- function_call=types.FunctionCall(
35
- name='get_current_weather',
36
- args={'location': 'San Francisco'},
37
- )
38
- )
39
-
40
- TEST_FUNCTION_RESPONSE_PART = types.Part(
41
- function_response=types.FunctionResponse(
42
- name='get_current_weather',
43
- response={'result': 'sunny'},
44
- )
45
- )
46
-
47
- TEST_AFC_TEXT_PART = types.Part(text='San Francisco weather is sunny.')
48
-
49
- TEST_NO_AFC_CONTENT = types.Content(
50
- parts=[TEST_NO_AFC_PART],
51
- role='model',
52
- )
53
-
54
- TEST_FUNCTION_CALL_CONTENT = types.Content(
55
- parts=[TEST_FUNCTION_CALL_PART],
56
- role='model',
57
- )
58
-
59
- TEST_FUNCTION_RESPONSE_CONTENT = types.Content(
60
- parts=[TEST_FUNCTION_RESPONSE_PART],
61
- role='user',
62
- )
63
-
64
- TEST_AFC_TEXT_CONTENT = types.Content(
65
- parts=[TEST_AFC_TEXT_PART],
66
- role='model',
67
- )
68
-
69
- TEST_AFC_HISTORY = [
70
- types.Content(
71
- parts=[types.Part(text='what is the weather in San Francisco?')],
72
- role='user',
73
- ),
74
- TEST_FUNCTION_CALL_CONTENT,
75
- TEST_FUNCTION_RESPONSE_CONTENT,
76
- ]
77
-
78
-
79
- def get_current_weather(location: str) -> str:
80
- """Returns the current weather.
81
-
82
- Args:
83
- location: The location of a city and state, e.g. "San Francisco, CA".
84
- """
85
- return 'windy'
86
-
87
-
88
- async def get_current_weather_async(location: str) -> str:
89
- """Returns the current weather.
90
-
91
- Args:
92
- location: The location of a city and state, e.g. "San Francisco, CA".
93
- """
94
- return 'windy'
95
-
96
-
97
- def get_aqi_from_city(location: str) -> str:
98
- """Returns the aqi index of a city.
99
-
100
- Args:
101
- location: The city and State, e.g. San Francisco, CA.
102
- """
103
- return None
104
-
105
-
106
- @pytest.fixture
107
- def mock_api_client(vertexai=False):
108
- api_client = mock.MagicMock(spec=client.ApiClient)
109
- api_client.api_key = 'TEST_API_KEY'
110
- api_client._host = lambda: 'test_host'
111
- api_client._http_options = {'headers': {}} # Ensure headers exist
112
- api_client.vertexai = vertexai
113
- return api_client
114
-
115
-
116
- @pytest.fixture
117
- def mock_get_function_response_parts_none():
118
- with mock.patch.object(
119
- _extra_utils,
120
- 'get_function_response_parts',
121
- ) as mock_get_function_response_parts_none:
122
- mock_get_function_response_parts_none.return_value = None
123
- yield mock_get_function_response_parts_none
124
-
125
-
126
- @pytest.fixture
127
- def mock_get_function_response_parts_none_async():
128
- with mock.patch.object(
129
- _extra_utils,
130
- 'get_function_response_parts_async',
131
- ) as mock_get_function_response_parts_none_async:
132
- mock_get_function_response_parts_none_async.return_value = None
133
- yield mock_get_function_response_parts_none_async
134
-
135
-
136
- @pytest.fixture
137
- def mock_get_function_response_parts() -> list[types.Part]:
138
- with mock.patch.object(
139
- _extra_utils, 'get_function_response_parts'
140
- ) as mock_get_function_response_parts:
141
- mock_get_function_response_parts.side_effect = [
142
- [TEST_FUNCTION_RESPONSE_PART],
143
- [], # Breaks when the function response is not returned.
144
- ]
145
- yield mock_get_function_response_parts
146
-
147
-
148
- @pytest.fixture
149
- def mock_get_function_response_parts_async() -> list[types.Part]:
150
- with mock.patch.object(
151
- _extra_utils, 'get_function_response_parts_async'
152
- ) as mock_get_function_response_parts_async:
153
- mock_get_function_response_parts_async.side_effect = [
154
- [TEST_FUNCTION_RESPONSE_PART],
155
- [], # Breaks when the function response is not returned.
156
- ]
157
- yield mock_get_function_response_parts_async
158
-
159
-
160
- @pytest.fixture
161
- def mock_generate_content_stream_no_afc():
162
- with mock.patch.object(
163
- models.Models, '_generate_content_stream'
164
- ) as mock_stream_no_afc:
165
- mock_stream_no_afc.return_value = [
166
- types.GenerateContentResponse(
167
- candidates=[types.Candidate(content=TEST_NO_AFC_CONTENT)]
168
- )
169
- ]
170
- yield mock_stream_no_afc
171
-
172
-
173
- @pytest.fixture
174
- def mock_generate_content_stream_with_afc():
175
- with mock.patch.object(
176
- models.Models, '_generate_content_stream'
177
- ) as mock_stream_with_afc:
178
- mock_stream_with_afc.side_effect = [
179
- [
180
- types.GenerateContentResponse(
181
- candidates=[types.Candidate(content=TEST_FUNCTION_CALL_CONTENT)]
182
- )
183
- ],
184
- [
185
- types.GenerateContentResponse(
186
- candidates=[types.Candidate(content=TEST_AFC_TEXT_CONTENT)]
187
- )
188
- ],
189
- ]
190
- yield mock_stream_with_afc
191
-
192
-
193
- @pytest.fixture
194
- def mock_generate_content_stream_no_afc_async():
195
- with mock.patch.object(
196
- models.AsyncModels, '_generate_content_stream'
197
- ) as mock_stream_no_afc:
198
-
199
- async def async_generator():
200
- yield types.GenerateContentResponse(
201
- candidates=[types.Candidate(content=TEST_NO_AFC_CONTENT)]
202
- )
203
-
204
- mock_stream_no_afc.return_value = async_generator()
205
- yield mock_stream_no_afc
206
-
207
-
208
- @pytest.fixture
209
- def mock_generate_content_stream_with_afc_async():
210
- with mock.patch.object(
211
- models.AsyncModels, '_generate_content_stream'
212
- ) as mock_stream_with_afc:
213
-
214
- async def async_generator_1():
215
- yield types.GenerateContentResponse(
216
- candidates=[types.Candidate(content=TEST_FUNCTION_CALL_CONTENT)]
217
- )
218
-
219
- async def async_generator_2():
220
- yield types.GenerateContentResponse(
221
- candidates=[types.Candidate(content=TEST_AFC_TEXT_CONTENT)]
222
- )
223
-
224
- mock_stream_with_afc.side_effect = [
225
- async_generator_1(),
226
- async_generator_2(),
227
- ]
228
- yield mock_stream_with_afc
229
-
230
-
231
- def test_generate_content_stream_no_function_map(
232
- mock_generate_content_stream_no_afc,
233
- mock_get_function_response_parts_none,
234
- ):
235
- """Test when no function tools are provided.
236
-
237
- Expected to answer past weather.
238
- """
239
- models_instance = models.Models(api_client_=mock_api_client)
240
- stream = models_instance.generate_content_stream(
241
- model='test_model', contents='what is the weather in San Francisco?'
242
- )
243
- for chunk in stream:
244
- assert chunk.text == TEST_NO_AFC_PART.text
245
-
246
- assert mock_generate_content_stream_no_afc.call_count == 1
247
- assert mock_get_function_response_parts_none.call_count == 0
248
-
249
-
250
- def test_generate_content_stream_afc_disabled(
251
- mock_generate_content_stream_with_afc,
252
- mock_get_function_response_parts_none,
253
- ):
254
- """Test when function tools are provided but AFC is disabled.
255
-
256
- Expected to respond with function call.
257
- """
258
- models_instance = models.Models(api_client_=mock_api_client)
259
- stream = models_instance.generate_content_stream(
260
- model='test_model',
261
- contents='what is the weather in San Francisco?',
262
- config=types.GenerateContentConfig(
263
- tools=[get_current_weather],
264
- automatic_function_calling=types.AutomaticFunctionCallingConfig(
265
- disable=True
266
- ),
267
- ),
268
- )
269
- for chunk in stream:
270
- # Work as manual function calling.
271
- assert chunk.candidates[0].content.parts[0].function_call
272
-
273
- assert mock_generate_content_stream_with_afc.call_count == 1
274
- assert mock_get_function_response_parts_none.call_count == 0
275
-
276
-
277
- def test_generate_content_stream_no_function_response(
278
- mock_generate_content_stream_no_afc,
279
- mock_get_function_response_parts_none,
280
- ):
281
- """Test when function tools are provided and function responses are not returned.
282
-
283
- Expected to answer past weather.
284
- """
285
- models_instance = models.Models(api_client_=mock_api_client)
286
- config = types.GenerateContentConfig(tools=[get_aqi_from_city])
287
- stream = models_instance.generate_content_stream(
288
- model='test_model',
289
- contents='what is the weather in San Francisco?',
290
- config=config,
291
- )
292
- for chunk in stream:
293
- assert chunk.text == TEST_NO_AFC_PART.text
294
-
295
- assert mock_generate_content_stream_no_afc.call_count == 1
296
- assert mock_get_function_response_parts_none.call_count == 1
297
-
298
-
299
- def test_generate_content_stream_with_function_tools_used(
300
- mock_generate_content_stream_with_afc,
301
- mock_get_function_response_parts,
302
- ):
303
- """Test when function tools are provided and function responses are returned.
304
-
305
- Expected to answer weather based on function response.
306
- """
307
- models_instance = models.Models(api_client_=mock_api_client)
308
- config = types.GenerateContentConfig(tools=[get_current_weather])
309
- stream = models_instance.generate_content_stream(
310
- model='test_model',
311
- contents='what is the weather in San Francisco?',
312
- config=config,
313
- )
314
-
315
- chunk = None
316
- for chunk in stream:
317
- assert chunk.text == TEST_AFC_TEXT_PART.text
318
-
319
- assert mock_generate_content_stream_with_afc.call_count == 2
320
- assert mock_get_function_response_parts.call_count == 2
321
-
322
- assert chunk is not None
323
- for i in range(len(chunk.automatic_function_calling_history)):
324
- assert chunk.automatic_function_calling_history[i].model_dump(
325
- exclude_none=True
326
- ) == TEST_AFC_HISTORY[i].model_dump(exclude_none=True)
327
-
328
-
329
- def test_generate_content_stream_with_thought_summaries(
330
- mock_generate_content_stream_with_afc,
331
- mock_get_function_response_parts,
332
- ):
333
- """Test when function tools are provided and thought summaries are enabled.
334
-
335
- Expected to answer weather based on function response.
336
- """
337
- models_instance = models.Models(api_client_=mock_api_client)
338
- config = types.GenerateContentConfig(
339
- tools=[get_current_weather],
340
- thinking_config=types.ThinkingConfig(include_thoughts=True),
341
- )
342
- stream = models_instance.generate_content_stream(
343
- model='test_model',
344
- contents='what is the weather in San Francisco?',
345
- config=config,
346
- )
347
-
348
- chunk = None
349
- for chunk in stream:
350
- assert chunk.text == TEST_AFC_TEXT_PART.text
351
-
352
- assert mock_generate_content_stream_with_afc.call_count == 2
353
- assert mock_get_function_response_parts.call_count == 2
354
-
355
- assert chunk is not None
356
- for i in range(len(chunk.automatic_function_calling_history)):
357
- assert chunk.automatic_function_calling_history[i].model_dump(
358
- exclude_none=True
359
- ) == TEST_AFC_HISTORY[i].model_dump(exclude_none=True)
360
-
361
-
362
- @pytest.mark.asyncio
363
- async def test_generate_content_stream_no_function_map_async(
364
- mock_generate_content_stream_no_afc,
365
- mock_get_function_response_parts_none,
366
- ):
367
- """Test when no function tools are provided.
368
-
369
- Expected to answer past weather.
370
- """
371
- models_instance = models.Models(api_client_=mock_api_client)
372
- stream = models_instance.generate_content_stream(
373
- model='test_model', contents='what is the weather in San Francisco?'
374
- )
375
- for chunk in stream:
376
- assert chunk.text == TEST_NO_AFC_PART.text
377
-
378
- assert mock_generate_content_stream_no_afc.call_count == 1
379
- assert mock_get_function_response_parts_none.call_count == 0
380
-
381
-
382
- @pytest.mark.asyncio
383
- async def test_generate_content_stream_afc_disabled_async(
384
- mock_generate_content_stream_with_afc_async,
385
- mock_get_function_response_parts_none,
386
- ):
387
- """Test when function tools are provided but AFC is disabled.
388
-
389
- Expected to respond with function call.
390
- """
391
- models_instance = models.AsyncModels(api_client_=mock_api_client)
392
- stream = await models_instance.generate_content_stream(
393
- model='test_model',
394
- contents='what is the weather in San Francisco?',
395
- config=types.GenerateContentConfig(
396
- tools=[get_current_weather],
397
- automatic_function_calling=types.AutomaticFunctionCallingConfig(
398
- disable=True
399
- ),
400
- ),
401
- )
402
- async for chunk in stream:
403
- # Work as manual function calling.
404
- assert chunk.candidates[0].content.parts[0].function_call
405
-
406
- assert mock_generate_content_stream_with_afc_async.call_count == 1
407
- assert mock_get_function_response_parts_none.call_count == 0
408
-
409
-
410
- @pytest.mark.asyncio
411
- async def test_generate_content_stream_no_function_response_async(
412
- mock_generate_content_stream_no_afc_async,
413
- mock_get_function_response_parts_none_async,
414
- ):
415
- """Test when function tools are provided and function responses are not returned.
416
-
417
- Expected to answer past weather.
418
- """
419
- models_instance = models.AsyncModels(api_client_=mock_api_client)
420
- config = types.GenerateContentConfig(tools=[get_aqi_from_city])
421
- stream = await models_instance.generate_content_stream(
422
- model='test_model',
423
- contents='what is the weather in San Francisco?',
424
- config=config,
425
- )
426
- async for chunk in stream:
427
- assert chunk.text == TEST_NO_AFC_PART.text
428
-
429
- assert mock_generate_content_stream_no_afc_async.call_count == 1
430
-
431
- assert mock_get_function_response_parts_none_async.call_count == 1
432
-
433
-
434
- @pytest.mark.asyncio
435
- async def test_generate_content_stream_with_function_tools_used_async(
436
- mock_generate_content_stream_with_afc_async,
437
- mock_get_function_response_parts_async,
438
- ):
439
- """Test when function tools are provided and function responses are returned.
440
-
441
- Expected to answer weather based on function response.
442
- """
443
- models_instance = models.AsyncModels(api_client_=mock_api_client)
444
- config = types.GenerateContentConfig(tools=[get_current_weather])
445
- stream = await models_instance.generate_content_stream(
446
- model='test_model',
447
- contents='what is the weather in San Francisco?',
448
- config=config,
449
- )
450
-
451
- chunk = None
452
- async for chunk in stream:
453
- assert chunk.text == TEST_AFC_TEXT_PART.text
454
-
455
- assert mock_generate_content_stream_with_afc_async.call_count == 2
456
-
457
- assert mock_get_function_response_parts_async.call_count == 2
458
-
459
- assert chunk is not None
460
- for i in range(len(chunk.automatic_function_calling_history)):
461
- assert chunk.automatic_function_calling_history[i].model_dump(
462
- exclude_none=True
463
- ) == TEST_AFC_HISTORY[i].model_dump(exclude_none=True)
464
-
465
-
466
- @pytest.mark.asyncio
467
- async def test_generate_content_stream_with_function_async_function_used_async(
468
- mock_generate_content_stream_with_afc_async,
469
- mock_get_function_response_parts_async,
470
- ):
471
- """Test when function tools are provided and function responses are returned.
472
-
473
- Expected to answer weather based on function response.
474
- """
475
- models_instance = models.AsyncModels(api_client_=mock_api_client)
476
- config = types.GenerateContentConfig(tools=[get_current_weather_async])
477
- stream = await models_instance.generate_content_stream(
478
- model='test_model',
479
- contents='what is the weather in San Francisco?',
480
- config=config,
481
- )
482
-
483
- chunk = None
484
- async for chunk in stream:
485
- assert chunk.text == TEST_AFC_TEXT_PART.text
486
-
487
- assert mock_generate_content_stream_with_afc_async.call_count == 2
488
-
489
- assert mock_get_function_response_parts_async.call_count == 2
490
-
491
- assert chunk is not None
492
- for i in range(len(chunk.automatic_function_calling_history)):
493
- assert chunk.automatic_function_calling_history[i].model_dump(
494
- exclude_none=True
495
- ) == TEST_AFC_HISTORY[i].model_dump(exclude_none=True)
496
-
497
-
498
- @pytest.mark.asyncio
499
- async def test_generate_content_stream_with_thought_summaries_async(
500
- mock_generate_content_stream_with_afc_async,
501
- mock_get_function_response_parts_async,
502
- ):
503
- """Test when function tools are provided and thought summaries are enabled.
504
-
505
- Expected to answer weather based on function response.
506
- """
507
- models_instance = models.AsyncModels(api_client_=mock_api_client)
508
- config = types.GenerateContentConfig(
509
- tools=[get_current_weather],
510
- thinking_config=types.ThinkingConfig(include_thoughts=True),
511
- )
512
- stream = await models_instance.generate_content_stream(
513
- model='test_model',
514
- contents='what is the weather in San Francisco?',
515
- config=config,
516
- )
517
-
518
- chunk = None
519
- async for chunk in stream:
520
- assert chunk.text == TEST_AFC_TEXT_PART.text
521
-
522
- assert mock_generate_content_stream_with_afc_async.call_count == 2
523
-
524
- assert mock_get_function_response_parts_async.call_count == 2
525
-
526
- assert chunk is not None
527
- for i in range(len(chunk.automatic_function_calling_history)):
528
- assert chunk.automatic_function_calling_history[i].model_dump(
529
- exclude_none=True
530
- ) == TEST_AFC_HISTORY[i].model_dump(exclude_none=True)
@@ -1,77 +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
- import pytest
16
- from ... import types
17
- from .. import pytest_helper
18
-
19
-
20
- def get_current_weather(location: str) -> str:
21
- """Returns the current weather.
22
-
23
- Args:
24
- location: The location of a city and state, e.g. "San Francisco, CA".
25
- """
26
- return 'windy'
27
-
28
-
29
- pytestmark = pytest_helper.setup(
30
- file=__file__,
31
- globals_for_file=globals(),
32
- test_method='models.generate_content',
33
- )
34
- pytest_plugins = ('pytest_asyncio',)
35
-
36
-
37
- def test_generate_content_stream_with_function_and_thought_summaries(client):
38
- """Test when function tools are provided and thought summaries are enabled.
39
-
40
- Expected to answer weather based on function response.
41
- """
42
- config = types.GenerateContentConfig(
43
- tools=[get_current_weather],
44
- thinking_config=types.ThinkingConfig(include_thoughts=True),
45
- )
46
- stream = client.models.generate_content_stream(
47
- model='gemini-2.5-flash',
48
- contents='what is the weather in San Francisco, CA?',
49
- config=config,
50
- )
51
-
52
- chunk = None
53
- for chunk in stream:
54
- assert chunk is not None
55
-
56
-
57
- @pytest.mark.asyncio
58
- async def test_generate_content_stream_with_function_and_thought_summaries_async(
59
- client,
60
- ):
61
- """Test when function tools are provided and thought summaries are enabled.
62
-
63
- Expected to answer weather based on function response.
64
- """
65
- config = types.GenerateContentConfig(
66
- tools=[get_current_weather],
67
- thinking_config=types.ThinkingConfig(include_thoughts=True),
68
- )
69
- stream = await client.aio.models.generate_content_stream(
70
- model='gemini-2.5-flash',
71
- contents='what is the weather in San Francisco, CA?',
72
- config=config,
73
- )
74
-
75
- chunk = None
76
- async for chunk in stream:
77
- assert chunk is not None