google-genai 1.16.0__tar.gz → 1.17.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.16.0/google_genai.egg-info → google_genai-1.17.0}/PKG-INFO +2 -2
  2. {google_genai-1.16.0 → google_genai-1.17.0}/README.md +1 -1
  3. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_automatic_function_calling_util.py +1 -0
  4. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_extra_utils.py +3 -6
  5. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_live_converters.py +106 -31
  6. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_mcp_utils.py +3 -6
  7. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_replay_api_client.py +51 -1
  8. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_tokens_converters.py +54 -6
  9. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_transformers.py +20 -2
  10. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/caches.py +60 -6
  11. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/live.py +23 -1
  12. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/models.py +314 -14
  13. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/tunings.py +6 -0
  14. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/types.py +316 -154
  15. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/version.py +1 -1
  16. {google_genai-1.16.0 → google_genai-1.17.0/google_genai.egg-info}/PKG-INFO +2 -2
  17. {google_genai-1.16.0 → google_genai-1.17.0}/pyproject.toml +1 -1
  18. {google_genai-1.16.0 → google_genai-1.17.0}/LICENSE +0 -0
  19. {google_genai-1.16.0 → google_genai-1.17.0}/MANIFEST.in +0 -0
  20. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/__init__.py +0 -0
  21. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_adapters.py +0 -0
  22. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_api_client.py +0 -0
  23. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_api_module.py +0 -0
  24. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_base_url.py +0 -0
  25. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_common.py +0 -0
  26. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/_test_api_client.py +0 -0
  27. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/batches.py +0 -0
  28. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/chats.py +0 -0
  29. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/client.py +0 -0
  30. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/errors.py +0 -0
  31. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/files.py +0 -0
  32. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/live_music.py +0 -0
  33. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/operations.py +0 -0
  34. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/pagers.py +0 -0
  35. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/py.typed +0 -0
  36. {google_genai-1.16.0 → google_genai-1.17.0}/google/genai/tokens.py +0 -0
  37. {google_genai-1.16.0 → google_genai-1.17.0}/google_genai.egg-info/SOURCES.txt +0 -0
  38. {google_genai-1.16.0 → google_genai-1.17.0}/google_genai.egg-info/dependency_links.txt +0 -0
  39. {google_genai-1.16.0 → google_genai-1.17.0}/google_genai.egg-info/requires.txt +0 -0
  40. {google_genai-1.16.0 → google_genai-1.17.0}/google_genai.egg-info/top_level.txt +0 -0
  41. {google_genai-1.16.0 → google_genai-1.17.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.16.0
3
+ Version: 1.17.0
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -148,7 +148,7 @@ Pydantic model types are available in the `types` module.
148
148
 
149
149
  ## Models
150
150
 
151
- The `client.models` modules exposes model inferencing and model getters.
151
+ The `client.models` module exposes model inferencing and model getters.
152
152
  See the 'Create a client' section above to initialize a client.
153
153
 
154
154
  ### Generate Content
@@ -117,7 +117,7 @@ Pydantic model types are available in the `types` module.
117
117
 
118
118
  ## Models
119
119
 
120
- The `client.models` modules exposes model inferencing and model getters.
120
+ The `client.models` module exposes model inferencing and model getters.
121
121
  See the 'Create a client' section above to initialize a client.
122
122
 
123
123
  ### Generate Content
@@ -37,6 +37,7 @@ _py_builtin_type_to_schema_type = {
37
37
  bool: types.Type.BOOLEAN,
38
38
  list: types.Type.ARRAY,
39
39
  dict: types.Type.OBJECT,
40
+ None: types.Type.NULL,
40
41
  }
41
42
 
42
43
 
@@ -502,10 +502,7 @@ async def parse_config_for_mcp_sessions(
502
502
  mcp_to_genai_tool_adapters[function_declaration.name] = (
503
503
  mcp_to_genai_tool_adapter
504
504
  )
505
- if McpClientSession is not None:
506
- parsed_config_copy.tools.extend(
507
- tool
508
- for tool in parsed_config.tools
509
- if not isinstance(tool, McpClientSession)
510
- )
505
+ else:
506
+ parsed_config_copy.tools.append(tool)
507
+
511
508
  return parsed_config_copy, mcp_to_genai_tool_adapters
@@ -281,6 +281,42 @@ def _Blob_to_vertex(
281
281
  return to_object
282
282
 
283
283
 
284
+ def _FileData_to_mldev(
285
+ api_client: BaseApiClient,
286
+ from_object: Union[dict[str, Any], object],
287
+ parent_object: Optional[dict[str, Any]] = None,
288
+ ) -> dict[str, Any]:
289
+ to_object: dict[str, Any] = {}
290
+ if getv(from_object, ['display_name']) is not None:
291
+ raise ValueError('display_name parameter is not supported in Gemini API.')
292
+
293
+ if getv(from_object, ['file_uri']) is not None:
294
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
295
+
296
+ if getv(from_object, ['mime_type']) is not None:
297
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
298
+
299
+ return to_object
300
+
301
+
302
+ def _FileData_to_vertex(
303
+ api_client: BaseApiClient,
304
+ from_object: Union[dict[str, Any], object],
305
+ parent_object: Optional[dict[str, Any]] = None,
306
+ ) -> dict[str, Any]:
307
+ to_object: dict[str, Any] = {}
308
+ if getv(from_object, ['display_name']) is not None:
309
+ setv(to_object, ['displayName'], getv(from_object, ['display_name']))
310
+
311
+ if getv(from_object, ['file_uri']) is not None:
312
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
313
+
314
+ if getv(from_object, ['mime_type']) is not None:
315
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
316
+
317
+ return to_object
318
+
319
+
284
320
  def _Part_to_mldev(
285
321
  api_client: BaseApiClient,
286
322
  from_object: Union[dict[str, Any], object],
@@ -308,6 +344,15 @@ def _Part_to_mldev(
308
344
  ),
309
345
  )
310
346
 
347
+ if getv(from_object, ['file_data']) is not None:
348
+ setv(
349
+ to_object,
350
+ ['fileData'],
351
+ _FileData_to_mldev(
352
+ api_client, getv(from_object, ['file_data']), to_object
353
+ ),
354
+ )
355
+
311
356
  if getv(from_object, ['code_execution_result']) is not None:
312
357
  setv(
313
358
  to_object,
@@ -318,9 +363,6 @@ def _Part_to_mldev(
318
363
  if getv(from_object, ['executable_code']) is not None:
319
364
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
320
365
 
321
- if getv(from_object, ['file_data']) is not None:
322
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
323
-
324
366
  if getv(from_object, ['function_call']) is not None:
325
367
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
326
368
 
@@ -364,6 +406,15 @@ def _Part_to_vertex(
364
406
  ),
365
407
  )
366
408
 
409
+ if getv(from_object, ['file_data']) is not None:
410
+ setv(
411
+ to_object,
412
+ ['fileData'],
413
+ _FileData_to_vertex(
414
+ api_client, getv(from_object, ['file_data']), to_object
415
+ ),
416
+ )
417
+
367
418
  if getv(from_object, ['code_execution_result']) is not None:
368
419
  setv(
369
420
  to_object,
@@ -374,9 +425,6 @@ def _Part_to_vertex(
374
425
  if getv(from_object, ['executable_code']) is not None:
375
426
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
376
427
 
377
- if getv(from_object, ['file_data']) is not None:
378
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
379
-
380
428
  if getv(from_object, ['function_call']) is not None:
381
429
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
382
430
 
@@ -2345,13 +2393,6 @@ def _LiveMusicGenerationConfig_to_mldev(
2345
2393
  getv(from_object, ['only_bass_and_drums']),
2346
2394
  )
2347
2395
 
2348
- if getv(from_object, ['music_generation_mode']) is not None:
2349
- setv(
2350
- to_object,
2351
- ['musicGenerationMode'],
2352
- getv(from_object, ['music_generation_mode']),
2353
- )
2354
-
2355
2396
  return to_object
2356
2397
 
2357
2398
 
@@ -2396,11 +2437,6 @@ def _LiveMusicGenerationConfig_to_vertex(
2396
2437
  'only_bass_and_drums parameter is not supported in Vertex AI.'
2397
2438
  )
2398
2439
 
2399
- if getv(from_object, ['music_generation_mode']) is not None:
2400
- raise ValueError(
2401
- 'music_generation_mode parameter is not supported in Vertex AI.'
2402
- )
2403
-
2404
2440
  return to_object
2405
2441
 
2406
2442
 
@@ -2653,6 +2689,40 @@ def _Blob_from_vertex(
2653
2689
  return to_object
2654
2690
 
2655
2691
 
2692
+ def _FileData_from_mldev(
2693
+ api_client: BaseApiClient,
2694
+ from_object: Union[dict[str, Any], object],
2695
+ parent_object: Optional[dict[str, Any]] = None,
2696
+ ) -> dict[str, Any]:
2697
+ to_object: dict[str, Any] = {}
2698
+
2699
+ if getv(from_object, ['fileUri']) is not None:
2700
+ setv(to_object, ['file_uri'], getv(from_object, ['fileUri']))
2701
+
2702
+ if getv(from_object, ['mimeType']) is not None:
2703
+ setv(to_object, ['mime_type'], getv(from_object, ['mimeType']))
2704
+
2705
+ return to_object
2706
+
2707
+
2708
+ def _FileData_from_vertex(
2709
+ api_client: BaseApiClient,
2710
+ from_object: Union[dict[str, Any], object],
2711
+ parent_object: Optional[dict[str, Any]] = None,
2712
+ ) -> dict[str, Any]:
2713
+ to_object: dict[str, Any] = {}
2714
+ if getv(from_object, ['displayName']) is not None:
2715
+ setv(to_object, ['display_name'], getv(from_object, ['displayName']))
2716
+
2717
+ if getv(from_object, ['fileUri']) is not None:
2718
+ setv(to_object, ['file_uri'], getv(from_object, ['fileUri']))
2719
+
2720
+ if getv(from_object, ['mimeType']) is not None:
2721
+ setv(to_object, ['mime_type'], getv(from_object, ['mimeType']))
2722
+
2723
+ return to_object
2724
+
2725
+
2656
2726
  def _Part_from_mldev(
2657
2727
  api_client: BaseApiClient,
2658
2728
  from_object: Union[dict[str, Any], object],
@@ -2680,6 +2750,15 @@ def _Part_from_mldev(
2680
2750
  ),
2681
2751
  )
2682
2752
 
2753
+ if getv(from_object, ['fileData']) is not None:
2754
+ setv(
2755
+ to_object,
2756
+ ['file_data'],
2757
+ _FileData_from_mldev(
2758
+ api_client, getv(from_object, ['fileData']), to_object
2759
+ ),
2760
+ )
2761
+
2683
2762
  if getv(from_object, ['codeExecutionResult']) is not None:
2684
2763
  setv(
2685
2764
  to_object,
@@ -2690,9 +2769,6 @@ def _Part_from_mldev(
2690
2769
  if getv(from_object, ['executableCode']) is not None:
2691
2770
  setv(to_object, ['executable_code'], getv(from_object, ['executableCode']))
2692
2771
 
2693
- if getv(from_object, ['fileData']) is not None:
2694
- setv(to_object, ['file_data'], getv(from_object, ['fileData']))
2695
-
2696
2772
  if getv(from_object, ['functionCall']) is not None:
2697
2773
  setv(to_object, ['function_call'], getv(from_object, ['functionCall']))
2698
2774
 
@@ -2736,6 +2812,15 @@ def _Part_from_vertex(
2736
2812
  ),
2737
2813
  )
2738
2814
 
2815
+ if getv(from_object, ['fileData']) is not None:
2816
+ setv(
2817
+ to_object,
2818
+ ['file_data'],
2819
+ _FileData_from_vertex(
2820
+ api_client, getv(from_object, ['fileData']), to_object
2821
+ ),
2822
+ )
2823
+
2739
2824
  if getv(from_object, ['codeExecutionResult']) is not None:
2740
2825
  setv(
2741
2826
  to_object,
@@ -2746,9 +2831,6 @@ def _Part_from_vertex(
2746
2831
  if getv(from_object, ['executableCode']) is not None:
2747
2832
  setv(to_object, ['executable_code'], getv(from_object, ['executableCode']))
2748
2833
 
2749
- if getv(from_object, ['fileData']) is not None:
2750
- setv(to_object, ['file_data'], getv(from_object, ['fileData']))
2751
-
2752
2834
  if getv(from_object, ['functionCall']) is not None:
2753
2835
  setv(to_object, ['function_call'], getv(from_object, ['functionCall']))
2754
2836
 
@@ -3676,13 +3758,6 @@ def _LiveMusicGenerationConfig_from_mldev(
3676
3758
  getv(from_object, ['onlyBassAndDrums']),
3677
3759
  )
3678
3760
 
3679
- if getv(from_object, ['musicGenerationMode']) is not None:
3680
- setv(
3681
- to_object,
3682
- ['music_generation_mode'],
3683
- getv(from_object, ['musicGenerationMode']),
3684
- )
3685
-
3686
3761
  return to_object
3687
3762
 
3688
3763
 
@@ -83,13 +83,10 @@ def set_mcp_usage_header(headers: dict[str, str]) -> None:
83
83
  version_label = version("mcp")
84
84
  except PackageNotFoundError:
85
85
  version_label = "0.0.0"
86
- # TODO: b/418827318 - Investigate weather the duplicate mcp label check is
87
- # necessary.
88
- mcp_label = f"mcp_used/{version_label}"
89
86
  existing_header = headers.get("x-goog-api-client", "")
90
- if mcp_label in existing_header:
91
- return
92
- headers["x-goog-api-client"] = (existing_header + f" {mcp_label}").lstrip()
87
+ headers["x-goog-api-client"] = (
88
+ existing_header + f" mcp_used/{version_label}"
89
+ ).lstrip()
93
90
 
94
91
 
95
92
  def _filter_to_supported_schema(schema: dict[str, Any]) -> dict[str, Any]:
@@ -18,6 +18,7 @@
18
18
  import base64
19
19
  import copy
20
20
  import datetime
21
+ import enum
21
22
  import inspect
22
23
  import io
23
24
  import json
@@ -37,6 +38,55 @@ from .types import HttpOptions, HttpOptionsOrDict
37
38
  from .types import GenerateVideosOperation
38
39
 
39
40
 
41
+ def to_snake_case(name: str) -> str:
42
+ """Converts a string from camelCase or PascalCase to snake_case."""
43
+
44
+ if not isinstance(name, str):
45
+ name = str(name)
46
+ s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
47
+ return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
48
+
49
+
50
+ def _normalize_json_case(obj: Any) -> Any:
51
+ if isinstance(obj, dict):
52
+ return {
53
+ to_snake_case(k): _normalize_json_case(v)
54
+ for k, v in obj.items()
55
+ }
56
+ elif isinstance(obj, list):
57
+ return [_normalize_json_case(item) for item in obj]
58
+ elif isinstance(obj, enum.Enum):
59
+ return obj.value
60
+ else:
61
+ return obj
62
+
63
+
64
+ def _equals_ignore_key_case(obj1: Any, obj2: Any) -> bool:
65
+ """Compares two Python objects for equality ignoring key casing.
66
+
67
+ Returns:
68
+ bool: True if the two objects are equal regardless of key casing
69
+ (camelCase vs. snake_case). For example, the following are considered equal:
70
+
71
+ {'my_key': 'my_value'}
72
+ {'myKey': 'my_value'}
73
+
74
+ This also considers enums and strings with the same value as equal.
75
+ For example, the following are considered equal:
76
+
77
+ {'type': <Type.STRING: 'STRING'>}}
78
+ {'type': 'STRING'}
79
+ """
80
+
81
+ normalized_obj_1 = _normalize_json_case(obj1)
82
+ normalized_obj_2 = _normalize_json_case(obj2)
83
+
84
+ if normalized_obj_1 == normalized_obj_2:
85
+ return True
86
+ else:
87
+ return False
88
+
89
+
40
90
  def _redact_version_numbers(version_string: str) -> str:
41
91
  """Redacts version numbers in the form x.y.z from a string."""
42
92
  return re.sub(r'\d+\.\d+\.\d+', '{VERSION_NUMBER}', version_string)
@@ -358,7 +408,7 @@ class ReplayApiClient(BaseApiClient):
358
408
 
359
409
  actual_request_body = [request_data_copy]
360
410
  expected_request_body = interaction.request.body_segments
361
- assert actual_request_body == expected_request_body, (
411
+ assert _equals_ignore_key_case(actual_request_body, expected_request_body), (
362
412
  'Request body mismatch:\n'
363
413
  f'Actual: {actual_request_body}\n'
364
414
  f'Expected: {expected_request_body}'
@@ -281,6 +281,42 @@ def _Blob_to_vertex(
281
281
  return to_object
282
282
 
283
283
 
284
+ def _FileData_to_mldev(
285
+ api_client: BaseApiClient,
286
+ from_object: Union[dict[str, Any], object],
287
+ parent_object: Optional[dict[str, Any]] = None,
288
+ ) -> dict[str, Any]:
289
+ to_object: dict[str, Any] = {}
290
+ if getv(from_object, ['display_name']) is not None:
291
+ raise ValueError('display_name parameter is not supported in Gemini API.')
292
+
293
+ if getv(from_object, ['file_uri']) is not None:
294
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
295
+
296
+ if getv(from_object, ['mime_type']) is not None:
297
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
298
+
299
+ return to_object
300
+
301
+
302
+ def _FileData_to_vertex(
303
+ api_client: BaseApiClient,
304
+ from_object: Union[dict[str, Any], object],
305
+ parent_object: Optional[dict[str, Any]] = None,
306
+ ) -> dict[str, Any]:
307
+ to_object: dict[str, Any] = {}
308
+ if getv(from_object, ['display_name']) is not None:
309
+ setv(to_object, ['displayName'], getv(from_object, ['display_name']))
310
+
311
+ if getv(from_object, ['file_uri']) is not None:
312
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
313
+
314
+ if getv(from_object, ['mime_type']) is not None:
315
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
316
+
317
+ return to_object
318
+
319
+
284
320
  def _Part_to_mldev(
285
321
  api_client: BaseApiClient,
286
322
  from_object: Union[dict[str, Any], object],
@@ -308,6 +344,15 @@ def _Part_to_mldev(
308
344
  ),
309
345
  )
310
346
 
347
+ if getv(from_object, ['file_data']) is not None:
348
+ setv(
349
+ to_object,
350
+ ['fileData'],
351
+ _FileData_to_mldev(
352
+ api_client, getv(from_object, ['file_data']), to_object
353
+ ),
354
+ )
355
+
311
356
  if getv(from_object, ['code_execution_result']) is not None:
312
357
  setv(
313
358
  to_object,
@@ -318,9 +363,6 @@ def _Part_to_mldev(
318
363
  if getv(from_object, ['executable_code']) is not None:
319
364
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
320
365
 
321
- if getv(from_object, ['file_data']) is not None:
322
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
323
-
324
366
  if getv(from_object, ['function_call']) is not None:
325
367
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
326
368
 
@@ -364,6 +406,15 @@ def _Part_to_vertex(
364
406
  ),
365
407
  )
366
408
 
409
+ if getv(from_object, ['file_data']) is not None:
410
+ setv(
411
+ to_object,
412
+ ['fileData'],
413
+ _FileData_to_vertex(
414
+ api_client, getv(from_object, ['file_data']), to_object
415
+ ),
416
+ )
417
+
367
418
  if getv(from_object, ['code_execution_result']) is not None:
368
419
  setv(
369
420
  to_object,
@@ -374,9 +425,6 @@ def _Part_to_vertex(
374
425
  if getv(from_object, ['executable_code']) is not None:
375
426
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
376
427
 
377
- if getv(from_object, ['file_data']) is not None:
378
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
379
-
380
428
  if getv(from_object, ['function_call']) is not None:
381
429
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
382
430
 
@@ -630,6 +630,21 @@ def handle_null_fields(schema: dict[str, Any]) -> None:
630
630
  del schema['anyOf']
631
631
 
632
632
 
633
+ def _raise_for_unsupported_schema_type(origin: Any) -> None:
634
+ """Raises an error if the schema type is unsupported."""
635
+ raise ValueError(f'Unsupported schema type: {origin}')
636
+
637
+
638
+ def _raise_for_unsupported_mldev_properties(schema: Any, client: _api_client.BaseApiClient) -> None:
639
+ if not client.vertexai and (
640
+ schema.get('additionalProperties')
641
+ or schema.get('additional_properties')
642
+ ):
643
+ raise ValueError(
644
+ 'additionalProperties is not supported in the Gemini API.'
645
+ )
646
+
647
+
633
648
  def process_schema(
634
649
  schema: dict[str, Any],
635
650
  client: _api_client.BaseApiClient,
@@ -700,6 +715,8 @@ def process_schema(
700
715
  if schema.get('title') == 'PlaceholderLiteralEnum':
701
716
  del schema['title']
702
717
 
718
+ _raise_for_unsupported_mldev_properties(schema, client)
719
+
703
720
  # Standardize spelling for relevant schema fields. For example, if a dict is
704
721
  # provided directly to response_schema, it may use `any_of` instead of `anyOf.
705
722
  # Otherwise, model_json_schema() uses `anyOf`.
@@ -818,8 +835,9 @@ def t_schema(
818
835
  return _process_enum(origin, client)
819
836
  if isinstance(origin, types.Schema):
820
837
  if dict(origin) == dict(types.Schema()):
821
- # response_schema value was coerced to an empty Schema instance because it did not adhere to the Schema field annotation
822
- raise ValueError(f'Unsupported schema type.')
838
+ # response_schema value was coerced to an empty Schema instance because
839
+ # it did not adhere to the Schema field annotation
840
+ _raise_for_unsupported_schema_type(origin)
823
841
  schema = origin.model_dump(exclude_unset=True)
824
842
  process_schema(schema, client)
825
843
  return types.Schema.model_validate(schema)
@@ -66,6 +66,24 @@ def _Blob_to_mldev(
66
66
  return to_object
67
67
 
68
68
 
69
+ def _FileData_to_mldev(
70
+ api_client: BaseApiClient,
71
+ from_object: Union[dict[str, Any], object],
72
+ parent_object: Optional[dict[str, Any]] = None,
73
+ ) -> dict[str, Any]:
74
+ to_object: dict[str, Any] = {}
75
+ if getv(from_object, ['display_name']) is not None:
76
+ raise ValueError('display_name parameter is not supported in Gemini API.')
77
+
78
+ if getv(from_object, ['file_uri']) is not None:
79
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
80
+
81
+ if getv(from_object, ['mime_type']) is not None:
82
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
83
+
84
+ return to_object
85
+
86
+
69
87
  def _Part_to_mldev(
70
88
  api_client: BaseApiClient,
71
89
  from_object: Union[dict[str, Any], object],
@@ -93,6 +111,15 @@ def _Part_to_mldev(
93
111
  ),
94
112
  )
95
113
 
114
+ if getv(from_object, ['file_data']) is not None:
115
+ setv(
116
+ to_object,
117
+ ['fileData'],
118
+ _FileData_to_mldev(
119
+ api_client, getv(from_object, ['file_data']), to_object
120
+ ),
121
+ )
122
+
96
123
  if getv(from_object, ['code_execution_result']) is not None:
97
124
  setv(
98
125
  to_object,
@@ -103,9 +130,6 @@ def _Part_to_mldev(
103
130
  if getv(from_object, ['executable_code']) is not None:
104
131
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
105
132
 
106
- if getv(from_object, ['file_data']) is not None:
107
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
108
-
109
133
  if getv(from_object, ['function_call']) is not None:
110
134
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
111
135
 
@@ -428,6 +452,9 @@ def _RetrievalConfig_to_mldev(
428
452
  _LatLng_to_mldev(api_client, getv(from_object, ['lat_lng']), to_object),
429
453
  )
430
454
 
455
+ if getv(from_object, ['language_code']) is not None:
456
+ setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
457
+
431
458
  return to_object
432
459
 
433
460
 
@@ -704,6 +731,24 @@ def _Blob_to_vertex(
704
731
  return to_object
705
732
 
706
733
 
734
+ def _FileData_to_vertex(
735
+ api_client: BaseApiClient,
736
+ from_object: Union[dict[str, Any], object],
737
+ parent_object: Optional[dict[str, Any]] = None,
738
+ ) -> dict[str, Any]:
739
+ to_object: dict[str, Any] = {}
740
+ if getv(from_object, ['display_name']) is not None:
741
+ setv(to_object, ['displayName'], getv(from_object, ['display_name']))
742
+
743
+ if getv(from_object, ['file_uri']) is not None:
744
+ setv(to_object, ['fileUri'], getv(from_object, ['file_uri']))
745
+
746
+ if getv(from_object, ['mime_type']) is not None:
747
+ setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
748
+
749
+ return to_object
750
+
751
+
707
752
  def _Part_to_vertex(
708
753
  api_client: BaseApiClient,
709
754
  from_object: Union[dict[str, Any], object],
@@ -731,6 +776,15 @@ def _Part_to_vertex(
731
776
  ),
732
777
  )
733
778
 
779
+ if getv(from_object, ['file_data']) is not None:
780
+ setv(
781
+ to_object,
782
+ ['fileData'],
783
+ _FileData_to_vertex(
784
+ api_client, getv(from_object, ['file_data']), to_object
785
+ ),
786
+ )
787
+
734
788
  if getv(from_object, ['code_execution_result']) is not None:
735
789
  setv(
736
790
  to_object,
@@ -741,9 +795,6 @@ def _Part_to_vertex(
741
795
  if getv(from_object, ['executable_code']) is not None:
742
796
  setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
743
797
 
744
- if getv(from_object, ['file_data']) is not None:
745
- setv(to_object, ['fileData'], getv(from_object, ['file_data']))
746
-
747
798
  if getv(from_object, ['function_call']) is not None:
748
799
  setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
749
800
 
@@ -1084,6 +1135,9 @@ def _RetrievalConfig_to_vertex(
1084
1135
  ),
1085
1136
  )
1086
1137
 
1138
+ if getv(from_object, ['language_code']) is not None:
1139
+ setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
1140
+
1087
1141
  return to_object
1088
1142
 
1089
1143
 
@@ -944,7 +944,7 @@ class AsyncLive(_api_module.BaseModule):
944
944
 
945
945
  parameter_model = await _t_live_connect_config(self._api_client, config)
946
946
 
947
- if self._api_client.api_key:
947
+ if self._api_client.api_key and not self._api_client.vertexai:
948
948
  api_key = self._api_client.api_key
949
949
  version = self._api_client._http_options.api_version
950
950
  if uri is None:
@@ -964,6 +964,28 @@ class AsyncLive(_api_module.BaseModule):
964
964
 
965
965
  setv(request_dict, ['setup', 'model'], transformed_model)
966
966
 
967
+ request = json.dumps(request_dict)
968
+ elif self._api_client.api_key and self._api_client.vertexai:
969
+ # Headers already contains api key for express mode.
970
+ api_key = self._api_client.api_key
971
+ version = self._api_client._http_options.api_version
972
+ if uri is None:
973
+ uri = f'{base_url}/ws/google.cloud.aiplatform.{version}.LlmBidiService/BidiGenerateContent'
974
+ headers = self._api_client._http_options.headers
975
+
976
+ request_dict = _common.convert_to_dict(
977
+ live_converters._LiveConnectParameters_to_vertex(
978
+ api_client=self._api_client,
979
+ from_object=types.LiveConnectParameters(
980
+ model=transformed_model,
981
+ config=parameter_model,
982
+ ).model_dump(exclude_none=True),
983
+ )
984
+ )
985
+ del request_dict['config']
986
+
987
+ setv(request_dict, ['setup', 'model'], transformed_model)
988
+
967
989
  request = json.dumps(request_dict)
968
990
  else:
969
991
  if not self._api_client._credentials: