google-genai 1.29.0__tar.gz → 1.31.0__tar.gz

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 (41) hide show
  1. {google_genai-1.29.0/google_genai.egg-info → google_genai-1.31.0}/PKG-INFO +1 -1
  2. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_api_client.py +41 -37
  3. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_automatic_function_calling_util.py +12 -0
  4. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_live_converters.py +51 -6
  5. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_tokens_converters.py +26 -3
  6. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_transformers.py +51 -0
  7. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/batches.py +166 -3
  8. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/caches.py +51 -6
  9. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/chats.py +1 -0
  10. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/files.py +1 -0
  11. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/live.py +92 -88
  12. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/models.py +416 -16
  13. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/operations.py +1 -0
  14. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/tokens.py +1 -0
  15. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/tunings.py +315 -43
  16. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/types.py +1518 -421
  17. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/version.py +1 -1
  18. {google_genai-1.29.0 → google_genai-1.31.0/google_genai.egg-info}/PKG-INFO +1 -1
  19. {google_genai-1.29.0 → google_genai-1.31.0}/pyproject.toml +1 -1
  20. {google_genai-1.29.0 → google_genai-1.31.0}/LICENSE +0 -0
  21. {google_genai-1.29.0 → google_genai-1.31.0}/MANIFEST.in +0 -0
  22. {google_genai-1.29.0 → google_genai-1.31.0}/README.md +0 -0
  23. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/__init__.py +0 -0
  24. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_adapters.py +0 -0
  25. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_api_module.py +0 -0
  26. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_base_url.py +0 -0
  27. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_common.py +0 -0
  28. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_extra_utils.py +0 -0
  29. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_mcp_utils.py +0 -0
  30. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_replay_api_client.py +0 -0
  31. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/_test_api_client.py +0 -0
  32. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/client.py +0 -0
  33. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/errors.py +0 -0
  34. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/live_music.py +0 -0
  35. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/pagers.py +0 -0
  36. {google_genai-1.29.0 → google_genai-1.31.0}/google/genai/py.typed +0 -0
  37. {google_genai-1.29.0 → google_genai-1.31.0}/google_genai.egg-info/SOURCES.txt +0 -0
  38. {google_genai-1.29.0 → google_genai-1.31.0}/google_genai.egg-info/dependency_links.txt +0 -0
  39. {google_genai-1.29.0 → google_genai-1.31.0}/google_genai.egg-info/requires.txt +0 -0
  40. {google_genai-1.29.0 → google_genai-1.31.0}/google_genai.egg-info/top_level.txt +0 -0
  41. {google_genai-1.29.0 → google_genai-1.31.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.29.0
3
+ Version: 1.31.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -91,7 +91,7 @@ class EphemeralTokenAPIKeyError(ValueError):
91
91
 
92
92
  # This method checks for the API key in the environment variables. Google API
93
93
  # key is precedenced over Gemini API key.
94
- def _get_env_api_key() -> Optional[str]:
94
+ def get_env_api_key() -> Optional[str]:
95
95
  """Gets the API key from environment variables, prioritizing GOOGLE_API_KEY.
96
96
 
97
97
  Returns:
@@ -108,7 +108,7 @@ def _get_env_api_key() -> Optional[str]:
108
108
  return env_google_api_key or env_gemini_api_key or None
109
109
 
110
110
 
111
- def _append_library_version_headers(headers: dict[str, str]) -> None:
111
+ def append_library_version_headers(headers: dict[str, str]) -> None:
112
112
  """Appends the telemetry header to the headers dict."""
113
113
  library_label = f'google-genai-sdk/{version.__version__}'
114
114
  language_label = 'gl-python/' + sys.version.split()[0]
@@ -131,7 +131,7 @@ def _append_library_version_headers(headers: dict[str, str]) -> None:
131
131
  headers['x-goog-api-client'] = version_header_value
132
132
 
133
133
 
134
- def _patch_http_options(
134
+ def patch_http_options(
135
135
  options: HttpOptions, patch_options: HttpOptions
136
136
  ) -> HttpOptions:
137
137
  copy_option = options.model_copy()
@@ -155,11 +155,11 @@ def _patch_http_options(
155
155
  setattr(copy_option, key, getattr(options, key))
156
156
 
157
157
  if copy_option.headers is not None:
158
- _append_library_version_headers(copy_option.headers)
158
+ append_library_version_headers(copy_option.headers)
159
159
  return copy_option
160
160
 
161
161
 
162
- def _populate_server_timeout_header(
162
+ def populate_server_timeout_header(
163
163
  headers: dict[str, str], timeout_in_seconds: Optional[Union[float, int]]
164
164
  ) -> None:
165
165
  """Populates the server timeout header in the headers dict."""
@@ -167,7 +167,7 @@ def _populate_server_timeout_header(
167
167
  headers['X-Server-Timeout'] = str(math.ceil(timeout_in_seconds))
168
168
 
169
169
 
170
- def _join_url_path(base_url: str, path: str) -> str:
170
+ def join_url_path(base_url: str, path: str) -> str:
171
171
  parsed_base = urlparse(base_url)
172
172
  base_path = (
173
173
  parsed_base.path[:-1]
@@ -178,7 +178,7 @@ def _join_url_path(base_url: str, path: str) -> str:
178
178
  return urlunparse(parsed_base._replace(path=base_path + '/' + path))
179
179
 
180
180
 
181
- def _load_auth(*, project: Union[str, None]) -> Tuple[Credentials, str]:
181
+ def load_auth(*, project: Union[str, None]) -> Tuple[Credentials, str]:
182
182
  """Loads google auth credentials and project id."""
183
183
  credentials, loaded_project_id = google.auth.default( # type: ignore[no-untyped-call]
184
184
  scopes=['https://www.googleapis.com/auth/cloud-platform'],
@@ -195,12 +195,12 @@ def _load_auth(*, project: Union[str, None]) -> Tuple[Credentials, str]:
195
195
  return credentials, project
196
196
 
197
197
 
198
- def _refresh_auth(credentials: Credentials) -> Credentials:
198
+ def refresh_auth(credentials: Credentials) -> Credentials:
199
199
  credentials.refresh(Request()) # type: ignore[no-untyped-call]
200
200
  return credentials
201
201
 
202
202
 
203
- def _get_timeout_in_seconds(
203
+ def get_timeout_in_seconds(
204
204
  timeout: Optional[Union[float, int]],
205
205
  ) -> Optional[float]:
206
206
  """Converts the timeout to seconds."""
@@ -346,9 +346,10 @@ class HttpResponse:
346
346
 
347
347
  async def _aiter_response_stream(self) -> AsyncIterator[str]:
348
348
  """Asynchronously iterates over chunks retrieved from the API."""
349
- if not isinstance(
350
- self.response_stream, (httpx.Response, aiohttp.ClientResponse)
351
- ):
349
+ is_valid_response = isinstance(self.response_stream, httpx.Response) or (
350
+ has_aiohttp and isinstance(self.response_stream, aiohttp.ClientResponse)
351
+ )
352
+ if not is_valid_response:
352
353
  raise TypeError(
353
354
  'Expected self.response_stream to be an httpx.Response or'
354
355
  ' aiohttp.ClientResponse object, but got'
@@ -383,7 +384,9 @@ class HttpResponse:
383
384
  chunk = ''
384
385
 
385
386
  # aiohttp.ClientResponse uses a content stream that we read line by line.
386
- elif isinstance(self.response_stream, aiohttp.ClientResponse):
387
+ elif has_aiohttp and isinstance(
388
+ self.response_stream, aiohttp.ClientResponse
389
+ ):
387
390
  while True:
388
391
  # Read a line from the stream. This returns bytes.
389
392
  line_bytes = await self.response_stream.content.readline()
@@ -431,6 +434,7 @@ class HttpResponse:
431
434
  f'Failed to parse response as JSON. Raw response: {response}'
432
435
  ) from e
433
436
 
437
+
434
438
  # Default retry options.
435
439
  # The config is based on https://cloud.google.com/storage/docs/retry-strategy.
436
440
  # By default, the client will retry 4 times with approximately 1.0, 2.0, 4.0,
@@ -450,7 +454,7 @@ _RETRY_HTTP_STATUS_CODES = (
450
454
  )
451
455
 
452
456
 
453
- def _retry_args(options: Optional[HttpRetryOptions]) -> _common.StringDict:
457
+ def retry_args(options: Optional[HttpRetryOptions]) -> _common.StringDict:
454
458
  """Returns the retry args for the given http retry options.
455
459
 
456
460
  Args:
@@ -570,7 +574,7 @@ class BaseApiClient:
570
574
  # Retrieve implicitly set values from the environment.
571
575
  env_project = os.environ.get('GOOGLE_CLOUD_PROJECT', None)
572
576
  env_location = os.environ.get('GOOGLE_CLOUD_LOCATION', None)
573
- env_api_key = _get_env_api_key()
577
+ env_api_key = get_env_api_key()
574
578
  self.project = project or env_project
575
579
  self.location = location or env_location
576
580
  self.api_key = api_key or env_api_key
@@ -627,13 +631,13 @@ class BaseApiClient:
627
631
  and not self.api_key
628
632
  and not validated_http_options.base_url
629
633
  ):
630
- credentials, self.project = _load_auth(project=None)
634
+ credentials, self.project = load_auth(project=None)
631
635
  if not self._credentials:
632
636
  self._credentials = credentials
633
637
 
634
638
  has_sufficient_auth = (self.project and self.location) or self.api_key
635
639
 
636
- if (not has_sufficient_auth and not validated_http_options.base_url):
640
+ if not has_sufficient_auth and not validated_http_options.base_url:
637
641
  # Skip sufficient auth check if base url is provided in http options.
638
642
  raise ValueError(
639
643
  'Project and location or API key must be set when using the Vertex '
@@ -666,12 +670,12 @@ class BaseApiClient:
666
670
  self._http_options.headers['x-goog-api-key'] = self.api_key
667
671
  # Update the http options with the user provided http options.
668
672
  if http_options:
669
- self._http_options = _patch_http_options(
673
+ self._http_options = patch_http_options(
670
674
  self._http_options, validated_http_options
671
675
  )
672
676
  else:
673
677
  if self._http_options.headers is not None:
674
- _append_library_version_headers(self._http_options.headers)
678
+ append_library_version_headers(self._http_options.headers)
675
679
 
676
680
  client_args, async_client_args = self._ensure_httpx_ssl_ctx(
677
681
  self._http_options
@@ -685,7 +689,7 @@ class BaseApiClient:
685
689
  )
686
690
  self._websocket_ssl_ctx = self._ensure_websocket_ssl_ctx(self._http_options)
687
691
 
688
- retry_kwargs = _retry_args(self._http_options.retry_options)
692
+ retry_kwargs = retry_args(self._http_options.retry_options)
689
693
  self._retry = tenacity.Retrying(**retry_kwargs)
690
694
  self._async_retry = tenacity.AsyncRetrying(**retry_kwargs)
691
695
 
@@ -885,14 +889,14 @@ class BaseApiClient:
885
889
  """Retrieves the access token for the credentials."""
886
890
  with self._sync_auth_lock:
887
891
  if not self._credentials:
888
- self._credentials, project = _load_auth(project=self.project)
892
+ self._credentials, project = load_auth(project=self.project)
889
893
  if not self.project:
890
894
  self.project = project
891
895
 
892
896
  if self._credentials:
893
897
  if self._credentials.expired or not self._credentials.token:
894
898
  # Only refresh when it needs to. Default expiration is 3600 seconds.
895
- _refresh_auth(self._credentials)
899
+ refresh_auth(self._credentials)
896
900
  if not self._credentials.token:
897
901
  raise RuntimeError('Could not resolve API token from the environment')
898
902
  return self._credentials.token # type: ignore[no-any-return]
@@ -908,7 +912,7 @@ class BaseApiClient:
908
912
  if not self._credentials:
909
913
  # Double check that the credentials are not set before loading them.
910
914
  self._credentials, project = await asyncio.to_thread(
911
- _load_auth, project=self.project
915
+ load_auth, project=self.project
912
916
  )
913
917
  if not self.project:
914
918
  self.project = project
@@ -919,7 +923,7 @@ class BaseApiClient:
919
923
  async with self._async_auth_lock:
920
924
  if self._credentials.expired or not self._credentials.token:
921
925
  # Double check that the credentials expired before refreshing.
922
- await asyncio.to_thread(_refresh_auth, self._credentials)
926
+ await asyncio.to_thread(refresh_auth, self._credentials)
923
927
 
924
928
  if not self._credentials.token:
925
929
  raise RuntimeError('Could not resolve API token from the environment')
@@ -942,12 +946,12 @@ class BaseApiClient:
942
946
  # patch the http options with the user provided settings.
943
947
  if http_options:
944
948
  if isinstance(http_options, HttpOptions):
945
- patched_http_options = _patch_http_options(
949
+ patched_http_options = patch_http_options(
946
950
  self._http_options,
947
951
  http_options,
948
952
  )
949
953
  else:
950
- patched_http_options = _patch_http_options(
954
+ patched_http_options = patch_http_options(
951
955
  self._http_options, HttpOptions.model_validate(http_options)
952
956
  )
953
957
  else:
@@ -989,7 +993,7 @@ class BaseApiClient:
989
993
  request_dict, patched_http_options.extra_body
990
994
  )
991
995
 
992
- url = _join_url_path(
996
+ url = join_url_path(
993
997
  base_url,
994
998
  versioned_path,
995
999
  )
@@ -999,11 +1003,11 @@ class BaseApiClient:
999
1003
  'Ephemeral tokens can only be used with the live API.'
1000
1004
  )
1001
1005
 
1002
- timeout_in_seconds = _get_timeout_in_seconds(patched_http_options.timeout)
1006
+ timeout_in_seconds = get_timeout_in_seconds(patched_http_options.timeout)
1003
1007
 
1004
1008
  if patched_http_options.headers is None:
1005
1009
  raise ValueError('Request headers must be set.')
1006
- _populate_server_timeout_header(
1010
+ populate_server_timeout_header(
1007
1011
  patched_http_options.headers, timeout_in_seconds
1008
1012
  )
1009
1013
  return HttpRequest(
@@ -1075,7 +1079,7 @@ class BaseApiClient:
1075
1079
  )
1076
1080
  # Support per request retry options.
1077
1081
  if parameter_model.retry_options:
1078
- retry_kwargs = _retry_args(parameter_model.retry_options)
1082
+ retry_kwargs = retry_args(parameter_model.retry_options)
1079
1083
  retry = tenacity.Retrying(**retry_kwargs)
1080
1084
  return retry(self._request_once, http_request, stream) # type: ignore[no-any-return]
1081
1085
 
@@ -1235,7 +1239,7 @@ class BaseApiClient:
1235
1239
  )
1236
1240
  # Support per request retry options.
1237
1241
  if parameter_model.retry_options:
1238
- retry_kwargs = _retry_args(parameter_model.retry_options)
1242
+ retry_kwargs = retry_args(parameter_model.retry_options)
1239
1243
  retry = tenacity.AsyncRetrying(**retry_kwargs)
1240
1244
  return await retry(self._async_request_once, http_request, stream) # type: ignore[no-any-return]
1241
1245
  return await self._async_retry( # type: ignore[no-any-return]
@@ -1394,13 +1398,13 @@ class BaseApiClient:
1394
1398
  if isinstance(self._http_options, dict)
1395
1399
  else self._http_options.timeout
1396
1400
  )
1397
- timeout_in_seconds = _get_timeout_in_seconds(timeout)
1401
+ timeout_in_seconds = get_timeout_in_seconds(timeout)
1398
1402
  upload_headers = {
1399
1403
  'X-Goog-Upload-Command': upload_command,
1400
1404
  'X-Goog-Upload-Offset': str(offset),
1401
1405
  'Content-Length': str(chunk_size),
1402
1406
  }
1403
- _populate_server_timeout_header(upload_headers, timeout_in_seconds)
1407
+ populate_server_timeout_header(upload_headers, timeout_in_seconds)
1404
1408
  retry_count = 0
1405
1409
  while retry_count < MAX_RETRY_COUNT:
1406
1410
  response = self._httpx_client.request(
@@ -1554,13 +1558,13 @@ class BaseApiClient:
1554
1558
  if isinstance(self._http_options, dict)
1555
1559
  else self._http_options.timeout
1556
1560
  )
1557
- timeout_in_seconds = _get_timeout_in_seconds(timeout)
1561
+ timeout_in_seconds = get_timeout_in_seconds(timeout)
1558
1562
  upload_headers = {
1559
1563
  'X-Goog-Upload-Command': upload_command,
1560
1564
  'X-Goog-Upload-Offset': str(offset),
1561
1565
  'Content-Length': str(chunk_size),
1562
1566
  }
1563
- _populate_server_timeout_header(upload_headers, timeout_in_seconds)
1567
+ populate_server_timeout_header(upload_headers, timeout_in_seconds)
1564
1568
 
1565
1569
  retry_count = 0
1566
1570
  response = None
@@ -1630,13 +1634,13 @@ class BaseApiClient:
1630
1634
  if isinstance(self._http_options, dict)
1631
1635
  else self._http_options.timeout
1632
1636
  )
1633
- timeout_in_seconds = _get_timeout_in_seconds(timeout)
1637
+ timeout_in_seconds = get_timeout_in_seconds(timeout)
1634
1638
  upload_headers = {
1635
1639
  'X-Goog-Upload-Command': upload_command,
1636
1640
  'X-Goog-Upload-Offset': str(offset),
1637
1641
  'Content-Length': str(chunk_size),
1638
1642
  }
1639
- _populate_server_timeout_header(upload_headers, timeout_in_seconds)
1643
+ populate_server_timeout_header(upload_headers, timeout_in_seconds)
1640
1644
 
1641
1645
  retry_count = 0
1642
1646
  client_response = None
@@ -30,6 +30,18 @@ if sys.version_info >= (3, 10):
30
30
  else:
31
31
  VersionedUnionType = typing._UnionGenericAlias # type: ignore[attr-defined]
32
32
 
33
+
34
+ __all__ = [
35
+ '_py_builtin_type_to_schema_type',
36
+ '_raise_for_unsupported_param',
37
+ '_handle_params_as_deferred_annotations',
38
+ '_add_unevaluated_items_to_fixed_len_tuple_schema',
39
+ '_is_builtin_primitive_or_compound',
40
+ '_is_default_value_compatible',
41
+ '_parse_schema_from_parameter',
42
+ '_get_required_fields',
43
+ ]
44
+
33
45
  _py_builtin_type_to_schema_type = {
34
46
  str: types.Type.STRING,
35
47
  int: types.Type.INTEGER,
@@ -16,6 +16,7 @@
16
16
  # Code generated by the Google Gen AI SDK generator DO NOT EDIT.
17
17
 
18
18
  from typing import Any, Optional, Union
19
+
19
20
  from . import _transformers as t
20
21
  from ._api_client import BaseApiClient
21
22
  from ._common import get_value_by_path as getv
@@ -312,6 +313,11 @@ def _GoogleSearch_to_mldev(
312
313
  _Interval_to_mldev(getv(from_object, ['time_range_filter']), to_object),
313
314
  )
314
315
 
316
+ if getv(from_object, ['exclude_domains']) is not None:
317
+ raise ValueError(
318
+ 'exclude_domains parameter is not supported in Gemini API.'
319
+ )
320
+
315
321
  return to_object
316
322
 
317
323
 
@@ -359,6 +365,17 @@ def _UrlContext_to_mldev(
359
365
  return to_object
360
366
 
361
367
 
368
+ def _ToolComputerUse_to_mldev(
369
+ from_object: Union[dict[str, Any], object],
370
+ parent_object: Optional[dict[str, Any]] = None,
371
+ ) -> dict[str, Any]:
372
+ to_object: dict[str, Any] = {}
373
+ if getv(from_object, ['environment']) is not None:
374
+ setv(to_object, ['environment'], getv(from_object, ['environment']))
375
+
376
+ return to_object
377
+
378
+
362
379
  def _Tool_to_mldev(
363
380
  from_object: Union[dict[str, Any], object],
364
381
  parent_object: Optional[dict[str, Any]] = None,
@@ -408,12 +425,18 @@ def _Tool_to_mldev(
408
425
  _UrlContext_to_mldev(getv(from_object, ['url_context']), to_object),
409
426
  )
410
427
 
428
+ if getv(from_object, ['computer_use']) is not None:
429
+ setv(
430
+ to_object,
431
+ ['computerUse'],
432
+ _ToolComputerUse_to_mldev(
433
+ getv(from_object, ['computer_use']), to_object
434
+ ),
435
+ )
436
+
411
437
  if getv(from_object, ['code_execution']) is not None:
412
438
  setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
413
439
 
414
- if getv(from_object, ['computer_use']) is not None:
415
- setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
416
-
417
440
  return to_object
418
441
 
419
442
 
@@ -1444,6 +1467,9 @@ def _GoogleSearch_to_vertex(
1444
1467
  ),
1445
1468
  )
1446
1469
 
1470
+ if getv(from_object, ['exclude_domains']) is not None:
1471
+ setv(to_object, ['excludeDomains'], getv(from_object, ['exclude_domains']))
1472
+
1447
1473
  return to_object
1448
1474
 
1449
1475
 
@@ -1487,6 +1513,8 @@ def _EnterpriseWebSearch_to_vertex(
1487
1513
  parent_object: Optional[dict[str, Any]] = None,
1488
1514
  ) -> dict[str, Any]:
1489
1515
  to_object: dict[str, Any] = {}
1516
+ if getv(from_object, ['exclude_domains']) is not None:
1517
+ setv(to_object, ['excludeDomains'], getv(from_object, ['exclude_domains']))
1490
1518
 
1491
1519
  return to_object
1492
1520
 
@@ -1566,6 +1594,17 @@ def _UrlContext_to_vertex(
1566
1594
  return to_object
1567
1595
 
1568
1596
 
1597
+ def _ToolComputerUse_to_vertex(
1598
+ from_object: Union[dict[str, Any], object],
1599
+ parent_object: Optional[dict[str, Any]] = None,
1600
+ ) -> dict[str, Any]:
1601
+ to_object: dict[str, Any] = {}
1602
+ if getv(from_object, ['environment']) is not None:
1603
+ setv(to_object, ['environment'], getv(from_object, ['environment']))
1604
+
1605
+ return to_object
1606
+
1607
+
1569
1608
  def _Tool_to_vertex(
1570
1609
  from_object: Union[dict[str, Any], object],
1571
1610
  parent_object: Optional[dict[str, Any]] = None,
@@ -1625,12 +1664,18 @@ def _Tool_to_vertex(
1625
1664
  _UrlContext_to_vertex(getv(from_object, ['url_context']), to_object),
1626
1665
  )
1627
1666
 
1667
+ if getv(from_object, ['computer_use']) is not None:
1668
+ setv(
1669
+ to_object,
1670
+ ['computerUse'],
1671
+ _ToolComputerUse_to_vertex(
1672
+ getv(from_object, ['computer_use']), to_object
1673
+ ),
1674
+ )
1675
+
1628
1676
  if getv(from_object, ['code_execution']) is not None:
1629
1677
  setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
1630
1678
 
1631
- if getv(from_object, ['computer_use']) is not None:
1632
- setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
1633
-
1634
1679
  return to_object
1635
1680
 
1636
1681
 
@@ -16,6 +16,7 @@
16
16
  # Code generated by the Google Gen AI SDK generator DO NOT EDIT.
17
17
 
18
18
  from typing import Any, Optional, Union
19
+
19
20
  from . import _transformers as t
20
21
  from ._api_client import BaseApiClient
21
22
  from ._common import get_value_by_path as getv
@@ -312,6 +313,11 @@ def _GoogleSearch_to_mldev(
312
313
  _Interval_to_mldev(getv(from_object, ['time_range_filter']), to_object),
313
314
  )
314
315
 
316
+ if getv(from_object, ['exclude_domains']) is not None:
317
+ raise ValueError(
318
+ 'exclude_domains parameter is not supported in Gemini API.'
319
+ )
320
+
315
321
  return to_object
316
322
 
317
323
 
@@ -359,6 +365,17 @@ def _UrlContext_to_mldev(
359
365
  return to_object
360
366
 
361
367
 
368
+ def _ToolComputerUse_to_mldev(
369
+ from_object: Union[dict[str, Any], object],
370
+ parent_object: Optional[dict[str, Any]] = None,
371
+ ) -> dict[str, Any]:
372
+ to_object: dict[str, Any] = {}
373
+ if getv(from_object, ['environment']) is not None:
374
+ setv(to_object, ['environment'], getv(from_object, ['environment']))
375
+
376
+ return to_object
377
+
378
+
362
379
  def _Tool_to_mldev(
363
380
  from_object: Union[dict[str, Any], object],
364
381
  parent_object: Optional[dict[str, Any]] = None,
@@ -408,12 +425,18 @@ def _Tool_to_mldev(
408
425
  _UrlContext_to_mldev(getv(from_object, ['url_context']), to_object),
409
426
  )
410
427
 
428
+ if getv(from_object, ['computer_use']) is not None:
429
+ setv(
430
+ to_object,
431
+ ['computerUse'],
432
+ _ToolComputerUse_to_mldev(
433
+ getv(from_object, ['computer_use']), to_object
434
+ ),
435
+ )
436
+
411
437
  if getv(from_object, ['code_execution']) is not None:
412
438
  setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
413
439
 
414
- if getv(from_object, ['computer_use']) is not None:
415
- setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
416
-
417
440
  return to_object
418
441
 
419
442
 
@@ -28,6 +28,7 @@ import types as builtin_types
28
28
  import typing
29
29
  from typing import Any, GenericAlias, List, Optional, Sequence, Union # type: ignore[attr-defined]
30
30
  from ._mcp_utils import mcp_to_gemini_tool
31
+ from ._common import get_value_by_path as getv
31
32
 
32
33
  if typing.TYPE_CHECKING:
33
34
  import PIL.Image
@@ -1224,3 +1225,53 @@ def t_tool_response(
1224
1225
  f'Could not convert input (type "{type(input)}") to '
1225
1226
  '`types.LiveClientToolResponse`'
1226
1227
  ) from e
1228
+
1229
+
1230
+ def t_metrics(
1231
+ metrics: list[types.MetricSubclass]
1232
+ ) -> list[dict[str, Any]]:
1233
+ """Prepares the metric payload for the evaluation request.
1234
+
1235
+ Args:
1236
+ request_dict: The dictionary containing the request details.
1237
+ resolved_metrics: A list of resolved metric objects.
1238
+
1239
+ Returns:
1240
+ The updated request dictionary with the prepared metric payload.
1241
+ """
1242
+ metrics_payload = []
1243
+
1244
+ for metric in metrics:
1245
+ metric_payload_item: dict[str, Any] = {}
1246
+ metric_payload_item['aggregation_metrics'] = [
1247
+ 'AVERAGE',
1248
+ 'STANDARD_DEVIATION',
1249
+ ]
1250
+
1251
+ metric_name = getv(metric, ['name']).lower()
1252
+
1253
+ if metric_name == 'exact_match':
1254
+ metric_payload_item['exact_match_spec'] = {}
1255
+ elif metric_name == 'bleu':
1256
+ metric_payload_item['bleu_spec'] = {}
1257
+ elif metric_name.startswith('rouge'):
1258
+ rouge_type = metric_name.replace("_", "")
1259
+ metric_payload_item['rouge_spec'] = {'rouge_type': rouge_type}
1260
+
1261
+ elif hasattr(metric, 'prompt_template') and metric.prompt_template:
1262
+ pointwise_spec = {'metric_prompt_template': metric.prompt_template}
1263
+ system_instruction = getv(metric, ['judge_model_system_instruction'])
1264
+ if system_instruction:
1265
+ pointwise_spec['system_instruction'] = system_instruction
1266
+ return_raw_output = getv(metric, ['return_raw_output'])
1267
+ if return_raw_output:
1268
+ pointwise_spec['custom_output_format_config'] = { # type: ignore[assignment]
1269
+ 'return_raw_output': return_raw_output
1270
+ }
1271
+ metric_payload_item['pointwise_metric_spec'] = pointwise_spec
1272
+ else:
1273
+ raise ValueError(
1274
+ 'Unsupported metric type or invalid metric name:' f' {metric_name}'
1275
+ )
1276
+ metrics_payload.append(metric_payload_item)
1277
+ return metrics_payload