google-genai 1.54.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 (137) hide show
  1. google/genai/__init__.py +1 -0
  2. google/genai/_interactions/__init__.py +117 -0
  3. google/genai/_interactions/_base_client.py +2025 -0
  4. google/genai/_interactions/_client.py +511 -0
  5. google/genai/_interactions/_compat.py +234 -0
  6. google/genai/_interactions/_constants.py +29 -0
  7. google/genai/_interactions/_exceptions.py +122 -0
  8. google/genai/_interactions/_files.py +139 -0
  9. google/genai/_interactions/_models.py +873 -0
  10. google/genai/_interactions/_qs.py +165 -0
  11. google/genai/_interactions/_resource.py +58 -0
  12. google/genai/_interactions/_response.py +847 -0
  13. google/genai/_interactions/_streaming.py +354 -0
  14. google/genai/_interactions/_types.py +276 -0
  15. google/genai/_interactions/_utils/__init__.py +79 -0
  16. google/genai/_interactions/_utils/_compat.py +61 -0
  17. google/genai/_interactions/_utils/_datetime_parse.py +151 -0
  18. google/genai/_interactions/_utils/_logs.py +40 -0
  19. google/genai/_interactions/_utils/_proxy.py +80 -0
  20. google/genai/_interactions/_utils/_reflection.py +57 -0
  21. google/genai/_interactions/_utils/_resources_proxy.py +39 -0
  22. google/genai/_interactions/_utils/_streams.py +27 -0
  23. google/genai/_interactions/_utils/_sync.py +73 -0
  24. google/genai/_interactions/_utils/_transform.py +472 -0
  25. google/genai/_interactions/_utils/_typing.py +172 -0
  26. google/genai/_interactions/_utils/_utils.py +437 -0
  27. google/genai/_interactions/_version.py +18 -0
  28. google/genai/_interactions/py.typed +0 -0
  29. google/genai/_interactions/resources/__init__.py +34 -0
  30. google/genai/_interactions/resources/interactions.py +1350 -0
  31. google/genai/_interactions/types/__init__.py +109 -0
  32. google/genai/_interactions/types/allowed_tools.py +33 -0
  33. google/genai/_interactions/types/allowed_tools_param.py +35 -0
  34. google/genai/_interactions/types/annotation.py +42 -0
  35. google/genai/_interactions/types/annotation_param.py +42 -0
  36. google/genai/_interactions/types/audio_content.py +37 -0
  37. google/genai/_interactions/types/audio_content_param.py +44 -0
  38. google/genai/_interactions/types/audio_mime_type.py +25 -0
  39. google/genai/_interactions/types/audio_mime_type_param.py +27 -0
  40. google/genai/_interactions/types/code_execution_call_arguments.py +33 -0
  41. google/genai/_interactions/types/code_execution_call_arguments_param.py +32 -0
  42. google/genai/_interactions/types/code_execution_call_content.py +36 -0
  43. google/genai/_interactions/types/code_execution_call_content_param.py +36 -0
  44. google/genai/_interactions/types/code_execution_result_content.py +41 -0
  45. google/genai/_interactions/types/code_execution_result_content_param.py +40 -0
  46. google/genai/_interactions/types/content_delta.py +342 -0
  47. google/genai/_interactions/types/content_start.py +79 -0
  48. google/genai/_interactions/types/content_stop.py +35 -0
  49. google/genai/_interactions/types/deep_research_agent_config.py +32 -0
  50. google/genai/_interactions/types/deep_research_agent_config_param.py +31 -0
  51. google/genai/_interactions/types/document_content.py +37 -0
  52. google/genai/_interactions/types/document_content_param.py +44 -0
  53. google/genai/_interactions/types/document_mime_type.py +23 -0
  54. google/genai/_interactions/types/document_mime_type_param.py +25 -0
  55. google/genai/_interactions/types/dynamic_agent_config.py +43 -0
  56. google/genai/_interactions/types/dynamic_agent_config_param.py +32 -0
  57. google/genai/_interactions/types/error_event.py +46 -0
  58. google/genai/_interactions/types/file_search_result_content.py +45 -0
  59. google/genai/_interactions/types/file_search_result_content_param.py +45 -0
  60. google/genai/_interactions/types/function.py +38 -0
  61. google/genai/_interactions/types/function_call_content.py +38 -0
  62. google/genai/_interactions/types/function_call_content_param.py +38 -0
  63. google/genai/_interactions/types/function_param.py +37 -0
  64. google/genai/_interactions/types/function_result_content.py +51 -0
  65. google/genai/_interactions/types/function_result_content_param.py +53 -0
  66. google/genai/_interactions/types/generation_config.py +57 -0
  67. google/genai/_interactions/types/generation_config_param.py +59 -0
  68. google/genai/_interactions/types/google_search_call_arguments.py +29 -0
  69. google/genai/_interactions/types/google_search_call_arguments_param.py +31 -0
  70. google/genai/_interactions/types/google_search_call_content.py +36 -0
  71. google/genai/_interactions/types/google_search_call_content_param.py +36 -0
  72. google/genai/_interactions/types/google_search_result.py +35 -0
  73. google/genai/_interactions/types/google_search_result_content.py +42 -0
  74. google/genai/_interactions/types/google_search_result_content_param.py +43 -0
  75. google/genai/_interactions/types/google_search_result_param.py +35 -0
  76. google/genai/_interactions/types/image_content.py +40 -0
  77. google/genai/_interactions/types/image_content_param.py +47 -0
  78. google/genai/_interactions/types/image_mime_type.py +23 -0
  79. google/genai/_interactions/types/image_mime_type_param.py +25 -0
  80. google/genai/_interactions/types/interaction.py +165 -0
  81. google/genai/_interactions/types/interaction_create_params.py +212 -0
  82. google/genai/_interactions/types/interaction_event.py +37 -0
  83. google/genai/_interactions/types/interaction_get_params.py +46 -0
  84. google/genai/_interactions/types/interaction_sse_event.py +32 -0
  85. google/genai/_interactions/types/interaction_status_update.py +37 -0
  86. google/genai/_interactions/types/mcp_server_tool_call_content.py +41 -0
  87. google/genai/_interactions/types/mcp_server_tool_call_content_param.py +41 -0
  88. google/genai/_interactions/types/mcp_server_tool_result_content.py +51 -0
  89. google/genai/_interactions/types/mcp_server_tool_result_content_param.py +53 -0
  90. google/genai/_interactions/types/model.py +36 -0
  91. google/genai/_interactions/types/model_param.py +38 -0
  92. google/genai/_interactions/types/speech_config.py +35 -0
  93. google/genai/_interactions/types/speech_config_param.py +35 -0
  94. google/genai/_interactions/types/text_content.py +36 -0
  95. google/genai/_interactions/types/text_content_param.py +37 -0
  96. google/genai/_interactions/types/thinking_level.py +22 -0
  97. google/genai/_interactions/types/thought_content.py +40 -0
  98. google/genai/_interactions/types/thought_content_param.py +46 -0
  99. google/genai/_interactions/types/tool.py +100 -0
  100. google/genai/_interactions/types/tool_choice.py +26 -0
  101. google/genai/_interactions/types/tool_choice_config.py +28 -0
  102. google/genai/_interactions/types/tool_choice_config_param.py +29 -0
  103. google/genai/_interactions/types/tool_choice_param.py +28 -0
  104. google/genai/_interactions/types/tool_choice_type.py +22 -0
  105. google/genai/_interactions/types/tool_param.py +97 -0
  106. google/genai/_interactions/types/turn.py +76 -0
  107. google/genai/_interactions/types/turn_param.py +73 -0
  108. google/genai/_interactions/types/url_context_call_arguments.py +29 -0
  109. google/genai/_interactions/types/url_context_call_arguments_param.py +31 -0
  110. google/genai/_interactions/types/url_context_call_content.py +36 -0
  111. google/genai/_interactions/types/url_context_call_content_param.py +36 -0
  112. google/genai/_interactions/types/url_context_result.py +33 -0
  113. google/genai/_interactions/types/url_context_result_content.py +42 -0
  114. google/genai/_interactions/types/url_context_result_content_param.py +43 -0
  115. google/genai/_interactions/types/url_context_result_param.py +32 -0
  116. google/genai/_interactions/types/usage.py +106 -0
  117. google/genai/_interactions/types/usage_param.py +106 -0
  118. google/genai/_interactions/types/video_content.py +40 -0
  119. google/genai/_interactions/types/video_content_param.py +47 -0
  120. google/genai/_interactions/types/video_mime_type.py +36 -0
  121. google/genai/_interactions/types/video_mime_type_param.py +38 -0
  122. google/genai/_live_converters.py +33 -30
  123. google/genai/_tokens_converters.py +5 -0
  124. google/genai/batches.py +7 -0
  125. google/genai/client.py +226 -1
  126. google/genai/interactions.py +17 -0
  127. google/genai/live.py +4 -3
  128. google/genai/models.py +14 -29
  129. google/genai/tunings.py +1 -27
  130. google/genai/types.py +92 -22
  131. google/genai/version.py +1 -1
  132. {google_genai-1.54.0.dist-info → google_genai-1.56.0.dist-info}/METADATA +226 -22
  133. google_genai-1.56.0.dist-info/RECORD +162 -0
  134. google_genai-1.54.0.dist-info/RECORD +0 -41
  135. {google_genai-1.54.0.dist-info → google_genai-1.56.0.dist-info}/WHEEL +0 -0
  136. {google_genai-1.54.0.dist-info → google_genai-1.56.0.dist-info}/licenses/LICENSE +0 -0
  137. {google_genai-1.54.0.dist-info → google_genai-1.56.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,36 @@
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
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17
+
18
+ from typing import Union
19
+ from typing_extensions import Literal, TypeAlias
20
+
21
+ __all__ = ["VideoMimeType"]
22
+
23
+ VideoMimeType: TypeAlias = Union[
24
+ Literal[
25
+ "video/mp4",
26
+ "video/mpeg",
27
+ "video/mov",
28
+ "video/avi",
29
+ "video/x-flv",
30
+ "video/mpg",
31
+ "video/webm",
32
+ "video/wmv",
33
+ "video/3gpp",
34
+ ],
35
+ str,
36
+ ]
@@ -0,0 +1,38 @@
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
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Union
21
+ from typing_extensions import Literal, TypeAlias
22
+
23
+ __all__ = ["VideoMimeTypeParam"]
24
+
25
+ VideoMimeTypeParam: TypeAlias = Union[
26
+ Literal[
27
+ "video/mp4",
28
+ "video/mpeg",
29
+ "video/mov",
30
+ "video/avi",
31
+ "video/x-flv",
32
+ "video/mpg",
33
+ "video/webm",
34
+ "video/wmv",
35
+ "video/3gpp",
36
+ ],
37
+ str,
38
+ ]
@@ -226,13 +226,7 @@ def _GenerationConfig_to_vertex(
226
226
  setv(to_object, ['seed'], getv(from_object, ['seed']))
227
227
 
228
228
  if getv(from_object, ['speech_config']) is not None:
229
- setv(
230
- to_object,
231
- ['speechConfig'],
232
- _SpeechConfig_to_vertex(
233
- getv(from_object, ['speech_config']), to_object
234
- ),
235
- )
229
+ setv(to_object, ['speechConfig'], getv(from_object, ['speech_config']))
236
230
 
237
231
  if getv(from_object, ['stop_sequences']) is not None:
238
232
  setv(to_object, ['stopSequences'], getv(from_object, ['stop_sequences']))
@@ -534,6 +528,11 @@ def _LiveClientSetup_to_mldev(
534
528
  if getv(from_object, ['proactivity']) is not None:
535
529
  setv(to_object, ['proactivity'], getv(from_object, ['proactivity']))
536
530
 
531
+ if getv(from_object, ['explicit_vad_signal']) is not None:
532
+ raise ValueError(
533
+ 'explicit_vad_signal parameter is not supported in Gemini API.'
534
+ )
535
+
537
536
  return to_object
538
537
 
539
538
 
@@ -603,6 +602,13 @@ def _LiveClientSetup_to_vertex(
603
602
  if getv(from_object, ['proactivity']) is not None:
604
603
  setv(to_object, ['proactivity'], getv(from_object, ['proactivity']))
605
604
 
605
+ if getv(from_object, ['explicit_vad_signal']) is not None:
606
+ setv(
607
+ to_object,
608
+ ['explicitVadSignal'],
609
+ getv(from_object, ['explicit_vad_signal']),
610
+ )
611
+
606
612
  return to_object
607
613
 
608
614
 
@@ -753,6 +759,11 @@ def _LiveConnectConfig_to_mldev(
753
759
  getv(from_object, ['proactivity']),
754
760
  )
755
761
 
762
+ if getv(from_object, ['explicit_vad_signal']) is not None:
763
+ raise ValueError(
764
+ 'explicit_vad_signal parameter is not supported in Gemini API.'
765
+ )
766
+
756
767
  return to_object
757
768
 
758
769
 
@@ -825,10 +836,7 @@ def _LiveConnectConfig_to_vertex(
825
836
  setv(
826
837
  parent_object,
827
838
  ['setup', 'generationConfig', 'speechConfig'],
828
- _SpeechConfig_to_vertex(
829
- t.t_live_speech_config(getv(from_object, ['speech_config'])),
830
- to_object,
831
- ),
839
+ t.t_live_speech_config(getv(from_object, ['speech_config'])),
832
840
  )
833
841
 
834
842
  if getv(from_object, ['thinking_config']) is not None:
@@ -904,6 +912,13 @@ def _LiveConnectConfig_to_vertex(
904
912
  getv(from_object, ['proactivity']),
905
913
  )
906
914
 
915
+ if getv(from_object, ['explicit_vad_signal']) is not None:
916
+ setv(
917
+ parent_object,
918
+ ['setup', 'explicitVadSignal'],
919
+ getv(from_object, ['explicit_vad_signal']),
920
+ )
921
+
907
922
  return to_object
908
923
 
909
924
 
@@ -1176,6 +1191,13 @@ def _LiveServerMessage_from_vertex(
1176
1191
  getv(from_object, ['sessionResumptionUpdate']),
1177
1192
  )
1178
1193
 
1194
+ if getv(from_object, ['voiceActivityDetectionSignal']) is not None:
1195
+ setv(
1196
+ to_object,
1197
+ ['voice_activity_detection_signal'],
1198
+ getv(from_object, ['voiceActivityDetectionSignal']),
1199
+ )
1200
+
1179
1201
  return to_object
1180
1202
 
1181
1203
 
@@ -1260,25 +1282,6 @@ def _SessionResumptionConfig_to_mldev(
1260
1282
  return to_object
1261
1283
 
1262
1284
 
1263
- def _SpeechConfig_to_vertex(
1264
- from_object: Union[dict[str, Any], object],
1265
- parent_object: Optional[dict[str, Any]] = None,
1266
- ) -> dict[str, Any]:
1267
- to_object: dict[str, Any] = {}
1268
- if getv(from_object, ['voice_config']) is not None:
1269
- setv(to_object, ['voiceConfig'], getv(from_object, ['voice_config']))
1270
-
1271
- if getv(from_object, ['language_code']) is not None:
1272
- setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
1273
-
1274
- if getv(from_object, ['multi_speaker_voice_config']) is not None:
1275
- raise ValueError(
1276
- 'multi_speaker_voice_config parameter is not supported in Vertex AI.'
1277
- )
1278
-
1279
- return to_object
1280
-
1281
-
1282
1285
  def _Tool_to_mldev(
1283
1286
  from_object: Union[dict[str, Any], object],
1284
1287
  parent_object: Optional[dict[str, Any]] = None,
@@ -355,6 +355,11 @@ def _LiveConnectConfig_to_mldev(
355
355
  getv(from_object, ['proactivity']),
356
356
  )
357
357
 
358
+ if getv(from_object, ['explicit_vad_signal']) is not None:
359
+ raise ValueError(
360
+ 'explicit_vad_signal parameter is not supported in Gemini API.'
361
+ )
362
+
358
363
  return to_object
359
364
 
360
365
 
google/genai/batches.py CHANGED
@@ -1006,6 +1006,13 @@ def _GenerateContentConfig_to_mldev(
1006
1006
  _ImageConfig_to_mldev(getv(from_object, ['image_config']), to_object),
1007
1007
  )
1008
1008
 
1009
+ if getv(from_object, ['enable_enhanced_civic_answers']) is not None:
1010
+ setv(
1011
+ to_object,
1012
+ ['enableEnhancedCivicAnswers'],
1013
+ getv(from_object, ['enable_enhanced_civic_answers']),
1014
+ )
1015
+
1009
1016
  return to_object
1010
1017
 
1011
1018
 
google/genai/client.py CHANGED
@@ -16,7 +16,7 @@
16
16
  import asyncio
17
17
  import os
18
18
  from types import TracebackType
19
- from typing import Optional, Union
19
+ from typing import Optional, Union, cast
20
20
 
21
21
  import google.auth
22
22
  import pydantic
@@ -36,6 +36,20 @@ from .tokens import AsyncTokens, Tokens
36
36
  from .tunings import AsyncTunings, Tunings
37
37
  from .types import HttpOptions, HttpOptionsDict, HttpRetryOptions
38
38
 
39
+ import warnings
40
+ import httpx
41
+
42
+ from ._api_client import has_aiohttp
43
+
44
+ from . import _common
45
+
46
+ from ._interactions import AsyncGeminiNextGenAPIClient, DEFAULT_MAX_RETRIES, DefaultAioHttpClient, GeminiNextGenAPIClient
47
+ from ._interactions._models import FinalRequestOptions
48
+ from ._interactions._types import Headers
49
+ from ._interactions._utils import is_given
50
+ from ._interactions.resources import AsyncInteractionsResource as AsyncNextGenInteractionsResource, InteractionsResource as NextGenInteractionsResource
51
+ _interactions_experimental_warned = False
52
+
39
53
 
40
54
  class AsyncClient:
41
55
  """Client for making asynchronous (non-blocking) requests."""
@@ -52,6 +66,114 @@ class AsyncClient:
52
66
  self._live = AsyncLive(self._api_client)
53
67
  self._tokens = AsyncTokens(self._api_client)
54
68
  self._operations = AsyncOperations(self._api_client)
69
+ self._nextgen_client_instance: Optional[AsyncGeminiNextGenAPIClient] = None
70
+
71
+ @property
72
+ def _nextgen_client(self) -> AsyncGeminiNextGenAPIClient:
73
+ if self._nextgen_client_instance is not None:
74
+ return self._nextgen_client_instance
75
+
76
+ http_opts = self._api_client._http_options
77
+
78
+ if http_opts.extra_body:
79
+ warnings.warn(
80
+ 'extra_body properties are not supported in `.interactions` yet',
81
+ category=UserWarning,
82
+ stacklevel=5,
83
+ )
84
+
85
+ retry_opts = http_opts.retry_options
86
+ if retry_opts is not None and (
87
+ retry_opts.initial_delay is not None
88
+ or retry_opts.max_delay is not None
89
+ or retry_opts.exp_base is not None
90
+ or retry_opts.jitter is not None
91
+ or retry_opts.http_status_codes is not None
92
+ ):
93
+ warnings.warn(
94
+ 'Granular retry options are not supported in `.interactions` yet',
95
+ category=UserWarning,
96
+ stacklevel=5,
97
+ )
98
+
99
+ http_client: httpx.AsyncClient = self._api_client._async_httpx_client
100
+
101
+ async_client_args = self._api_client._http_options.async_client_args or {}
102
+ has_custom_transport = 'transport' in async_client_args
103
+
104
+ if has_aiohttp and not has_custom_transport:
105
+ warnings.warn(
106
+ 'Async interactions client cannot use aiohttp, fallingback to httpx.',
107
+ category=UserWarning,
108
+ stacklevel=5,
109
+ )
110
+
111
+ if retry_opts is not None and retry_opts.attempts is not None:
112
+ max_retries = retry_opts.attempts
113
+ else:
114
+ max_retries = DEFAULT_MAX_RETRIES + 1
115
+
116
+ self._nextgen_client_instance = AsyncGeminiNextGenAPIClient(
117
+ base_url=http_opts.base_url,
118
+ api_key=self._api_client.api_key,
119
+ api_version=http_opts.api_version,
120
+ default_headers=http_opts.headers,
121
+ http_client=http_client,
122
+ # uSDk expects ms, nextgen uses a httpx Timeout -> expects seconds.
123
+ timeout=http_opts.timeout / 1000 if http_opts.timeout else None,
124
+ max_retries=max_retries,
125
+ )
126
+
127
+ client = self._nextgen_client_instance
128
+ if self._api_client.vertexai:
129
+ client._is_vertex = True
130
+ client._vertex_project = self._api_client.project
131
+ client._vertex_location = self._api_client.location
132
+
133
+ async def prepare_options(options: FinalRequestOptions) -> FinalRequestOptions:
134
+ headers = {}
135
+ if is_given(options.headers):
136
+ headers = {**options.headers}
137
+
138
+ headers['Authorization'] = f'Bearer {await self._api_client._async_access_token()}'
139
+ if (
140
+ self._api_client._credentials
141
+ and self._api_client._credentials.quota_project_id
142
+ ):
143
+ headers['x-goog-user-project'] = (
144
+ self._api_client._credentials.quota_project_id
145
+ )
146
+ options.headers = headers
147
+
148
+ return options
149
+
150
+ if self._api_client.project or self._api_client.location:
151
+ client._prepare_options = prepare_options # type: ignore[method-assign]
152
+
153
+ def validate_headers(headers: Headers, custom_headers: Headers) -> None:
154
+ return
155
+
156
+ client._validate_headers = validate_headers # type: ignore[method-assign]
157
+ return self._nextgen_client_instance
158
+
159
+ @property
160
+ def interactions(self) -> AsyncNextGenInteractionsResource:
161
+ global _interactions_experimental_warned
162
+ if not _interactions_experimental_warned:
163
+ _interactions_experimental_warned = True
164
+ warnings.warn(
165
+ 'Interactions usage is experimental and may change in future versions.',
166
+ category=UserWarning,
167
+ stacklevel=1,
168
+ )
169
+ return self._nextgen_client.interactions
170
+
171
+ @property
172
+ def _has_nextgen_client(self) -> bool:
173
+ return (
174
+ hasattr(self, '_nextgen_client_instance') and
175
+ self._nextgen_client_instance is not None
176
+ )
55
177
 
56
178
  @property
57
179
  def models(self) -> AsyncModels:
@@ -120,6 +242,9 @@ class AsyncClient:
120
242
  """
121
243
  await self._api_client.aclose()
122
244
 
245
+ if self._has_nextgen_client:
246
+ await self._nextgen_client.close()
247
+
123
248
  async def __aenter__(self) -> 'AsyncClient':
124
249
  return self
125
250
 
@@ -287,6 +412,7 @@ class Client:
287
412
  self._files = Files(self._api_client)
288
413
  self._tokens = Tokens(self._api_client)
289
414
  self._operations = Operations(self._api_client)
415
+ self._nextgen_client_instance: Optional[GeminiNextGenAPIClient] = None
290
416
 
291
417
  @staticmethod
292
418
  def _get_api_client(
@@ -324,6 +450,102 @@ class Client:
324
450
  http_options=http_options,
325
451
  )
326
452
 
453
+ @property
454
+ def _nextgen_client(self) -> GeminiNextGenAPIClient:
455
+ if self._nextgen_client_instance is not None:
456
+ return self._nextgen_client_instance
457
+
458
+ http_opts = self._api_client._http_options
459
+
460
+ if http_opts.extra_body:
461
+ warnings.warn(
462
+ 'extra_body properties are not supported in `.interactions` yet',
463
+ category=UserWarning,
464
+ stacklevel=5,
465
+ )
466
+
467
+ retry_opts = http_opts.retry_options
468
+ if retry_opts is not None and (
469
+ retry_opts.initial_delay is not None
470
+ or retry_opts.max_delay is not None
471
+ or retry_opts.exp_base is not None
472
+ or retry_opts.jitter is not None
473
+ or retry_opts.http_status_codes is not None
474
+ ):
475
+ warnings.warn(
476
+ 'Granular retry options are not supported in `.interactions` yet',
477
+ category=UserWarning,
478
+ stacklevel=5,
479
+ )
480
+
481
+ if retry_opts is not None and retry_opts.attempts is not None:
482
+ max_retries = retry_opts.attempts
483
+ else:
484
+ max_retries = DEFAULT_MAX_RETRIES + 1
485
+
486
+ self._nextgen_client_instance = GeminiNextGenAPIClient(
487
+ base_url=http_opts.base_url,
488
+ api_key=self._api_client.api_key,
489
+ api_version=http_opts.api_version,
490
+ default_headers=http_opts.headers,
491
+ http_client=self._api_client._httpx_client,
492
+ # uSDk expects ms, nextgen uses a httpx Timeout -> expects seconds.
493
+ timeout=http_opts.timeout / 1000 if http_opts.timeout else None,
494
+ max_retries=max_retries,
495
+ )
496
+
497
+ client = self._nextgen_client_instance
498
+ if self.vertexai:
499
+ client._is_vertex = True
500
+ client._vertex_project = self._api_client.project
501
+ client._vertex_location = self._api_client.location
502
+
503
+ def prepare_options(options: FinalRequestOptions) -> FinalRequestOptions:
504
+ headers = {}
505
+ if is_given(options.headers):
506
+ headers = {**options.headers}
507
+ options.headers = headers
508
+
509
+ headers['Authorization'] = f'Bearer {self._api_client._access_token()}'
510
+ if (
511
+ self._api_client._credentials
512
+ and self._api_client._credentials.quota_project_id
513
+ ):
514
+ headers['x-goog-user-project'] = (
515
+ self._api_client._credentials.quota_project_id
516
+ )
517
+
518
+ return options
519
+
520
+ if self._api_client.project or self._api_client.location:
521
+ client._prepare_options = prepare_options # type: ignore[method-assign]
522
+
523
+ def validate_headers(headers: Headers, custom_headers: Headers) -> None:
524
+ return
525
+
526
+ client._validate_headers = validate_headers # type: ignore[method-assign]
527
+
528
+ return self._nextgen_client_instance
529
+
530
+ @property
531
+ def interactions(self) -> NextGenInteractionsResource:
532
+ global _interactions_experimental_warned
533
+ if not _interactions_experimental_warned:
534
+ _interactions_experimental_warned = True
535
+ warnings.warn(
536
+ 'Interactions usage is experimental and may change in future versions.',
537
+ category=UserWarning,
538
+ stacklevel=2,
539
+ )
540
+ return self._nextgen_client.interactions
541
+
542
+ @property
543
+ def _has_nextgen_client(self) -> bool:
544
+ return (
545
+ hasattr(self, '_nextgen_client_instance') and
546
+ self._nextgen_client_instance is not None
547
+ )
548
+
327
549
  @property
328
550
  def chats(self) -> Chats:
329
551
  return Chats(modules=self.models)
@@ -396,6 +618,9 @@ class Client:
396
618
  """
397
619
  self._api_client.close()
398
620
 
621
+ if self._has_nextgen_client:
622
+ self._nextgen_client.close()
623
+
399
624
  def __enter__(self) -> 'Client':
400
625
  return self
401
626
 
@@ -0,0 +1,17 @@
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
+ """Expose stainless types."""
16
+
17
+ from ._interactions.types import *
google/genai/live.py CHANGED
@@ -975,8 +975,9 @@ class AsyncLive(_api_module.BaseModule):
975
975
  ).model_dump(exclude_none=True),
976
976
  )
977
977
  )
978
- del request_dict['config']
979
978
 
979
+ del request_dict['config']
980
+ request_dict = _common.encode_unserializable_types(request_dict)
980
981
  setv(request_dict, ['setup', 'model'], transformed_model)
981
982
 
982
983
  request = json.dumps(request_dict)
@@ -998,7 +999,7 @@ class AsyncLive(_api_module.BaseModule):
998
999
  )
999
1000
  )
1000
1001
  del request_dict['config']
1001
-
1002
+ request_dict = _common.encode_unserializable_types(request_dict)
1002
1003
  setv(request_dict, ['setup', 'model'], transformed_model)
1003
1004
 
1004
1005
  request = json.dumps(request_dict)
@@ -1061,7 +1062,7 @@ class AsyncLive(_api_module.BaseModule):
1061
1062
  )
1062
1063
  )
1063
1064
  del request_dict['config']
1064
-
1065
+ request_dict = _common.encode_unserializable_types(request_dict)
1065
1066
  if (
1066
1067
  getv(
1067
1068
  request_dict, ['setup', 'generationConfig', 'responseModalities']
google/genai/models.py CHANGED
@@ -1110,6 +1110,13 @@ def _GenerateContentConfig_to_mldev(
1110
1110
  _ImageConfig_to_mldev(getv(from_object, ['image_config']), to_object),
1111
1111
  )
1112
1112
 
1113
+ if getv(from_object, ['enable_enhanced_civic_answers']) is not None:
1114
+ setv(
1115
+ to_object,
1116
+ ['enableEnhancedCivicAnswers'],
1117
+ getv(from_object, ['enable_enhanced_civic_answers']),
1118
+ )
1119
+
1113
1120
  return to_object
1114
1121
 
1115
1122
 
@@ -1251,9 +1258,7 @@ def _GenerateContentConfig_to_vertex(
1251
1258
  setv(
1252
1259
  to_object,
1253
1260
  ['speechConfig'],
1254
- _SpeechConfig_to_vertex(
1255
- t.t_speech_config(getv(from_object, ['speech_config'])), to_object
1256
- ),
1261
+ t.t_speech_config(getv(from_object, ['speech_config'])),
1257
1262
  )
1258
1263
 
1259
1264
  if getv(from_object, ['audio_timestamp']) is not None:
@@ -1269,6 +1274,11 @@ def _GenerateContentConfig_to_vertex(
1269
1274
  _ImageConfig_to_vertex(getv(from_object, ['image_config']), to_object),
1270
1275
  )
1271
1276
 
1277
+ if getv(from_object, ['enable_enhanced_civic_answers']) is not None:
1278
+ raise ValueError(
1279
+ 'enable_enhanced_civic_answers parameter is not supported in Vertex AI.'
1280
+ )
1281
+
1272
1282
  return to_object
1273
1283
 
1274
1284
 
@@ -2434,13 +2444,7 @@ def _GenerationConfig_to_vertex(
2434
2444
  setv(to_object, ['seed'], getv(from_object, ['seed']))
2435
2445
 
2436
2446
  if getv(from_object, ['speech_config']) is not None:
2437
- setv(
2438
- to_object,
2439
- ['speechConfig'],
2440
- _SpeechConfig_to_vertex(
2441
- getv(from_object, ['speech_config']), to_object
2442
- ),
2443
- )
2447
+ setv(to_object, ['speechConfig'], getv(from_object, ['speech_config']))
2444
2448
 
2445
2449
  if getv(from_object, ['stop_sequences']) is not None:
2446
2450
  setv(to_object, ['stopSequences'], getv(from_object, ['stop_sequences']))
@@ -3415,25 +3419,6 @@ def _SegmentImageSource_to_vertex(
3415
3419
  return to_object
3416
3420
 
3417
3421
 
3418
- def _SpeechConfig_to_vertex(
3419
- from_object: Union[dict[str, Any], object],
3420
- parent_object: Optional[dict[str, Any]] = None,
3421
- ) -> dict[str, Any]:
3422
- to_object: dict[str, Any] = {}
3423
- if getv(from_object, ['voice_config']) is not None:
3424
- setv(to_object, ['voiceConfig'], getv(from_object, ['voice_config']))
3425
-
3426
- if getv(from_object, ['language_code']) is not None:
3427
- setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
3428
-
3429
- if getv(from_object, ['multi_speaker_voice_config']) is not None:
3430
- raise ValueError(
3431
- 'multi_speaker_voice_config parameter is not supported in Vertex AI.'
3432
- )
3433
-
3434
- return to_object
3435
-
3436
-
3437
3422
  def _ToolConfig_to_mldev(
3438
3423
  from_object: Union[dict[str, Any], object],
3439
3424
  parent_object: Optional[dict[str, Any]] = None,
google/genai/tunings.py CHANGED
@@ -674,13 +674,7 @@ def _GenerationConfig_to_vertex(
674
674
  setv(to_object, ['seed'], getv(from_object, ['seed']))
675
675
 
676
676
  if getv(from_object, ['speech_config']) is not None:
677
- setv(
678
- to_object,
679
- ['speechConfig'],
680
- _SpeechConfig_to_vertex(
681
- getv(from_object, ['speech_config']), to_object, root_object
682
- ),
683
- )
677
+ setv(to_object, ['speechConfig'], getv(from_object, ['speech_config']))
684
678
 
685
679
  if getv(from_object, ['stop_sequences']) is not None:
686
680
  setv(to_object, ['stopSequences'], getv(from_object, ['stop_sequences']))
@@ -861,26 +855,6 @@ def _ListTuningJobsResponse_from_vertex(
861
855
  return to_object
862
856
 
863
857
 
864
- def _SpeechConfig_to_vertex(
865
- from_object: Union[dict[str, Any], object],
866
- parent_object: Optional[dict[str, Any]] = None,
867
- root_object: Optional[Union[dict[str, Any], object]] = None,
868
- ) -> dict[str, Any]:
869
- to_object: dict[str, Any] = {}
870
- if getv(from_object, ['voice_config']) is not None:
871
- setv(to_object, ['voiceConfig'], getv(from_object, ['voice_config']))
872
-
873
- if getv(from_object, ['language_code']) is not None:
874
- setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
875
-
876
- if getv(from_object, ['multi_speaker_voice_config']) is not None:
877
- raise ValueError(
878
- 'multi_speaker_voice_config parameter is not supported in Vertex AI.'
879
- )
880
-
881
- return to_object
882
-
883
-
884
858
  def _TunedModel_from_mldev(
885
859
  from_object: Union[dict[str, Any], object],
886
860
  parent_object: Optional[dict[str, Any]] = None,