google-genai 1.17.0__py3-none-any.whl → 1.19.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.
- google/genai/__init__.py +1 -2
- google/genai/_api_client.py +31 -1
- google/genai/_common.py +36 -1
- google/genai/_live_converters.py +35 -1
- google/genai/_tokens_converters.py +28 -8
- google/genai/_transformers.py +2 -1
- google/genai/caches.py +21 -1
- google/genai/chats.py +6 -3
- google/genai/live.py +18 -102
- google/genai/models.py +56 -5
- google/genai/tokens.py +7 -2
- google/genai/types.py +53 -13
- google/genai/version.py +1 -1
- {google_genai-1.17.0.dist-info → google_genai-1.19.0.dist-info}/METADATA +1 -1
- {google_genai-1.17.0.dist-info → google_genai-1.19.0.dist-info}/RECORD +18 -18
- {google_genai-1.17.0.dist-info → google_genai-1.19.0.dist-info}/WHEEL +0 -0
- {google_genai-1.17.0.dist-info → google_genai-1.19.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.17.0.dist-info → google_genai-1.19.0.dist-info}/top_level.txt +0 -0
google/genai/__init__.py
CHANGED
google/genai/_api_client.py
CHANGED
@@ -63,6 +63,31 @@ MAX_RETRY_COUNT = 3
|
|
63
63
|
INITIAL_RETRY_DELAY = 1 # second
|
64
64
|
DELAY_MULTIPLIER = 2
|
65
65
|
|
66
|
+
|
67
|
+
class EphemeralTokenAPIKeyError(ValueError):
|
68
|
+
"""Error raised when the API key is invalid."""
|
69
|
+
|
70
|
+
|
71
|
+
# This method checks for the API key in the environment variables. Google API
|
72
|
+
# key is precedenced over Gemini API key.
|
73
|
+
def _get_env_api_key() -> Optional[str]:
|
74
|
+
"""Gets the API key from environment variables, prioritizing GOOGLE_API_KEY.
|
75
|
+
|
76
|
+
Returns:
|
77
|
+
The API key string if found, otherwise None. Empty string is considered
|
78
|
+
invalid.
|
79
|
+
"""
|
80
|
+
env_google_api_key = os.environ.get('GOOGLE_API_KEY', None)
|
81
|
+
env_gemini_api_key = os.environ.get('GEMINI_API_KEY', None)
|
82
|
+
if env_google_api_key and env_gemini_api_key:
|
83
|
+
logger.warning(
|
84
|
+
'Both GOOGLE_API_KEY and GEMINI_API_KEY are set. Using'
|
85
|
+
' GOOGLE_API_KEY.'
|
86
|
+
)
|
87
|
+
|
88
|
+
return env_google_api_key or env_gemini_api_key or None
|
89
|
+
|
90
|
+
|
66
91
|
def _append_library_version_headers(headers: dict[str, str]) -> None:
|
67
92
|
"""Appends the telemetry header to the headers dict."""
|
68
93
|
library_label = f'google-genai-sdk/{version.__version__}'
|
@@ -366,7 +391,7 @@ class BaseApiClient:
|
|
366
391
|
# Retrieve implicitly set values from the environment.
|
367
392
|
env_project = os.environ.get('GOOGLE_CLOUD_PROJECT', None)
|
368
393
|
env_location = os.environ.get('GOOGLE_CLOUD_LOCATION', None)
|
369
|
-
env_api_key =
|
394
|
+
env_api_key = _get_env_api_key()
|
370
395
|
self.project = project or env_project
|
371
396
|
self.location = location or env_location
|
372
397
|
self.api_key = api_key or env_api_key
|
@@ -625,6 +650,11 @@ class BaseApiClient:
|
|
625
650
|
versioned_path,
|
626
651
|
)
|
627
652
|
|
653
|
+
if self.api_key and self.api_key.startswith('auth_tokens/'):
|
654
|
+
raise EphemeralTokenAPIKeyError(
|
655
|
+
'Ephemeral tokens can only be used with the live API.'
|
656
|
+
)
|
657
|
+
|
628
658
|
timeout_in_seconds = _get_timeout_in_seconds(patched_http_options.timeout)
|
629
659
|
|
630
660
|
if patched_http_options.headers is None:
|
google/genai/_common.py
CHANGED
@@ -20,7 +20,7 @@ import datetime
|
|
20
20
|
import enum
|
21
21
|
import functools
|
22
22
|
import typing
|
23
|
-
from typing import Any, Callable, Optional, Union
|
23
|
+
from typing import Any, Callable, Optional, Union, get_origin, get_args
|
24
24
|
import uuid
|
25
25
|
import warnings
|
26
26
|
|
@@ -154,6 +154,38 @@ def convert_to_dict(obj: object) -> Any:
|
|
154
154
|
return obj
|
155
155
|
|
156
156
|
|
157
|
+
def _is_struct_type(annotation: type) -> bool:
|
158
|
+
"""Checks if the given annotation is list[dict[str, typing.Any]]
|
159
|
+
or typing.List[typing.Dict[str, typing.Any]].
|
160
|
+
|
161
|
+
This maps to Struct type in the API.
|
162
|
+
"""
|
163
|
+
outer_origin = get_origin(annotation)
|
164
|
+
outer_args = get_args(annotation)
|
165
|
+
|
166
|
+
if outer_origin is not list: # Python 3.9+ normalizes list
|
167
|
+
return False
|
168
|
+
|
169
|
+
if not outer_args or len(outer_args) != 1:
|
170
|
+
return False
|
171
|
+
|
172
|
+
inner_annotation = outer_args[0]
|
173
|
+
|
174
|
+
inner_origin = get_origin(inner_annotation)
|
175
|
+
inner_args = get_args(inner_annotation)
|
176
|
+
|
177
|
+
if inner_origin is not dict: # Python 3.9+ normalizes to dict
|
178
|
+
return False
|
179
|
+
|
180
|
+
if not inner_args or len(inner_args) != 2:
|
181
|
+
# dict should have exactly two type arguments
|
182
|
+
return False
|
183
|
+
|
184
|
+
# Check if the dict arguments are str and typing.Any
|
185
|
+
key_type, value_type = inner_args
|
186
|
+
return key_type is str and value_type is typing.Any
|
187
|
+
|
188
|
+
|
157
189
|
def _remove_extra_fields(
|
158
190
|
model: Any, response: dict[str, object]
|
159
191
|
) -> None:
|
@@ -188,6 +220,9 @@ def _remove_extra_fields(
|
|
188
220
|
if isinstance(value, dict) and typing.get_origin(annotation) is not dict:
|
189
221
|
_remove_extra_fields(annotation, value)
|
190
222
|
elif isinstance(value, list):
|
223
|
+
if _is_struct_type(annotation):
|
224
|
+
continue
|
225
|
+
|
191
226
|
for item in value:
|
192
227
|
# assume a list of dict is list of BaseModel
|
193
228
|
if isinstance(item, dict):
|
google/genai/_live_converters.py
CHANGED
@@ -353,6 +353,13 @@ def _Part_to_mldev(
|
|
353
353
|
),
|
354
354
|
)
|
355
355
|
|
356
|
+
if getv(from_object, ['thought_signature']) is not None:
|
357
|
+
setv(
|
358
|
+
to_object,
|
359
|
+
['thoughtSignature'],
|
360
|
+
getv(from_object, ['thought_signature']),
|
361
|
+
)
|
362
|
+
|
356
363
|
if getv(from_object, ['code_execution_result']) is not None:
|
357
364
|
setv(
|
358
365
|
to_object,
|
@@ -415,6 +422,13 @@ def _Part_to_vertex(
|
|
415
422
|
),
|
416
423
|
)
|
417
424
|
|
425
|
+
if getv(from_object, ['thought_signature']) is not None:
|
426
|
+
setv(
|
427
|
+
to_object,
|
428
|
+
['thoughtSignature'],
|
429
|
+
getv(from_object, ['thought_signature']),
|
430
|
+
)
|
431
|
+
|
418
432
|
if getv(from_object, ['code_execution_result']) is not None:
|
419
433
|
setv(
|
420
434
|
to_object,
|
@@ -967,7 +981,13 @@ def _Tool_to_vertex(
|
|
967
981
|
)
|
968
982
|
|
969
983
|
if getv(from_object, ['url_context']) is not None:
|
970
|
-
|
984
|
+
setv(
|
985
|
+
to_object,
|
986
|
+
['urlContext'],
|
987
|
+
_UrlContext_to_vertex(
|
988
|
+
api_client, getv(from_object, ['url_context']), to_object
|
989
|
+
),
|
990
|
+
)
|
971
991
|
|
972
992
|
if getv(from_object, ['code_execution']) is not None:
|
973
993
|
setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
|
@@ -2759,6 +2779,13 @@ def _Part_from_mldev(
|
|
2759
2779
|
),
|
2760
2780
|
)
|
2761
2781
|
|
2782
|
+
if getv(from_object, ['thoughtSignature']) is not None:
|
2783
|
+
setv(
|
2784
|
+
to_object,
|
2785
|
+
['thought_signature'],
|
2786
|
+
getv(from_object, ['thoughtSignature']),
|
2787
|
+
)
|
2788
|
+
|
2762
2789
|
if getv(from_object, ['codeExecutionResult']) is not None:
|
2763
2790
|
setv(
|
2764
2791
|
to_object,
|
@@ -2821,6 +2848,13 @@ def _Part_from_vertex(
|
|
2821
2848
|
),
|
2822
2849
|
)
|
2823
2850
|
|
2851
|
+
if getv(from_object, ['thoughtSignature']) is not None:
|
2852
|
+
setv(
|
2853
|
+
to_object,
|
2854
|
+
['thought_signature'],
|
2855
|
+
getv(from_object, ['thoughtSignature']),
|
2856
|
+
)
|
2857
|
+
|
2824
2858
|
if getv(from_object, ['codeExecutionResult']) is not None:
|
2825
2859
|
setv(
|
2826
2860
|
to_object,
|
@@ -353,6 +353,13 @@ def _Part_to_mldev(
|
|
353
353
|
),
|
354
354
|
)
|
355
355
|
|
356
|
+
if getv(from_object, ['thought_signature']) is not None:
|
357
|
+
setv(
|
358
|
+
to_object,
|
359
|
+
['thoughtSignature'],
|
360
|
+
getv(from_object, ['thought_signature']),
|
361
|
+
)
|
362
|
+
|
356
363
|
if getv(from_object, ['code_execution_result']) is not None:
|
357
364
|
setv(
|
358
365
|
to_object,
|
@@ -415,6 +422,13 @@ def _Part_to_vertex(
|
|
415
422
|
),
|
416
423
|
)
|
417
424
|
|
425
|
+
if getv(from_object, ['thought_signature']) is not None:
|
426
|
+
setv(
|
427
|
+
to_object,
|
428
|
+
['thoughtSignature'],
|
429
|
+
getv(from_object, ['thought_signature']),
|
430
|
+
)
|
431
|
+
|
418
432
|
if getv(from_object, ['code_execution_result']) is not None:
|
419
433
|
setv(
|
420
434
|
to_object,
|
@@ -967,7 +981,13 @@ def _Tool_to_vertex(
|
|
967
981
|
)
|
968
982
|
|
969
983
|
if getv(from_object, ['url_context']) is not None:
|
970
|
-
|
984
|
+
setv(
|
985
|
+
to_object,
|
986
|
+
['urlContext'],
|
987
|
+
_UrlContext_to_vertex(
|
988
|
+
api_client, getv(from_object, ['url_context']), to_object
|
989
|
+
),
|
990
|
+
)
|
971
991
|
|
972
992
|
if getv(from_object, ['code_execution']) is not None:
|
973
993
|
setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
|
@@ -1585,7 +1605,7 @@ def _LiveConnectConfig_to_vertex(
|
|
1585
1605
|
return to_object
|
1586
1606
|
|
1587
1607
|
|
1588
|
-
def
|
1608
|
+
def _LiveConnectConstraints_to_mldev(
|
1589
1609
|
api_client: BaseApiClient,
|
1590
1610
|
from_object: Union[dict[str, Any], object],
|
1591
1611
|
parent_object: Optional[dict[str, Any]] = None,
|
@@ -1610,7 +1630,7 @@ def _LiveEphemeralParameters_to_mldev(
|
|
1610
1630
|
return to_object
|
1611
1631
|
|
1612
1632
|
|
1613
|
-
def
|
1633
|
+
def _LiveConnectConstraints_to_vertex(
|
1614
1634
|
api_client: BaseApiClient,
|
1615
1635
|
from_object: Union[dict[str, Any], object],
|
1616
1636
|
parent_object: Optional[dict[str, Any]] = None,
|
@@ -1645,13 +1665,13 @@ def _CreateAuthTokenConfig_to_mldev(
|
|
1645
1665
|
if getv(from_object, ['uses']) is not None:
|
1646
1666
|
setv(parent_object, ['uses'], getv(from_object, ['uses']))
|
1647
1667
|
|
1648
|
-
if getv(from_object, ['
|
1668
|
+
if getv(from_object, ['live_connect_constraints']) is not None:
|
1649
1669
|
setv(
|
1650
1670
|
parent_object,
|
1651
1671
|
['bidiGenerateContentSetup'],
|
1652
|
-
|
1672
|
+
_LiveConnectConstraints_to_mldev(
|
1653
1673
|
api_client,
|
1654
|
-
getv(from_object, ['
|
1674
|
+
getv(from_object, ['live_connect_constraints']),
|
1655
1675
|
to_object,
|
1656
1676
|
),
|
1657
1677
|
)
|
@@ -1684,9 +1704,9 @@ def _CreateAuthTokenConfig_to_vertex(
|
|
1684
1704
|
if getv(from_object, ['uses']) is not None:
|
1685
1705
|
raise ValueError('uses parameter is not supported in Vertex AI.')
|
1686
1706
|
|
1687
|
-
if getv(from_object, ['
|
1707
|
+
if getv(from_object, ['live_connect_constraints']) is not None:
|
1688
1708
|
raise ValueError(
|
1689
|
-
'
|
1709
|
+
'live_connect_constraints parameter is not supported in Vertex AI.'
|
1690
1710
|
)
|
1691
1711
|
|
1692
1712
|
if getv(from_object, ['lock_additional_fields']) is not None:
|
google/genai/_transformers.py
CHANGED
@@ -761,7 +761,8 @@ def process_schema(
|
|
761
761
|
schema_type = schema.get('type')
|
762
762
|
if isinstance(schema_type, Enum):
|
763
763
|
schema_type = schema_type.value
|
764
|
-
schema_type
|
764
|
+
if isinstance(schema_type, str):
|
765
|
+
schema_type = schema_type.upper()
|
765
766
|
|
766
767
|
# model_json_schema() returns a schema with a 'const' field when a Literal with one value is provided as a pydantic field
|
767
768
|
# For example `genre: Literal['action']` becomes: {'const': 'action', 'title': 'Genre', 'type': 'string'}
|
google/genai/caches.py
CHANGED
@@ -120,6 +120,13 @@ def _Part_to_mldev(
|
|
120
120
|
),
|
121
121
|
)
|
122
122
|
|
123
|
+
if getv(from_object, ['thought_signature']) is not None:
|
124
|
+
setv(
|
125
|
+
to_object,
|
126
|
+
['thoughtSignature'],
|
127
|
+
getv(from_object, ['thought_signature']),
|
128
|
+
)
|
129
|
+
|
123
130
|
if getv(from_object, ['code_execution_result']) is not None:
|
124
131
|
setv(
|
125
132
|
to_object,
|
@@ -785,6 +792,13 @@ def _Part_to_vertex(
|
|
785
792
|
),
|
786
793
|
)
|
787
794
|
|
795
|
+
if getv(from_object, ['thought_signature']) is not None:
|
796
|
+
setv(
|
797
|
+
to_object,
|
798
|
+
['thoughtSignature'],
|
799
|
+
getv(from_object, ['thought_signature']),
|
800
|
+
)
|
801
|
+
|
788
802
|
if getv(from_object, ['code_execution_result']) is not None:
|
789
803
|
setv(
|
790
804
|
to_object,
|
@@ -1078,7 +1092,13 @@ def _Tool_to_vertex(
|
|
1078
1092
|
)
|
1079
1093
|
|
1080
1094
|
if getv(from_object, ['url_context']) is not None:
|
1081
|
-
|
1095
|
+
setv(
|
1096
|
+
to_object,
|
1097
|
+
['urlContext'],
|
1098
|
+
_UrlContext_to_vertex(
|
1099
|
+
api_client, getv(from_object, ['url_context']), to_object
|
1100
|
+
),
|
1101
|
+
)
|
1082
1102
|
|
1083
1103
|
if getv(from_object, ['code_execution']) is not None:
|
1084
1104
|
setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
|
google/genai/chats.py
CHANGED
@@ -160,7 +160,7 @@ class _BaseChat:
|
|
160
160
|
# Because the AFC input contains the entire curated chat history in
|
161
161
|
# addition to the new user input, we need to truncate the AFC history
|
162
162
|
# to deduplicate the existing chat history.
|
163
|
-
automatic_function_calling_history[len(self._curated_history):]
|
163
|
+
automatic_function_calling_history[len(self._curated_history) :]
|
164
164
|
if automatic_function_calling_history
|
165
165
|
else [user_input]
|
166
166
|
)
|
@@ -328,7 +328,7 @@ class Chat(_BaseChat):
|
|
328
328
|
yield chunk
|
329
329
|
automatic_function_calling_history = (
|
330
330
|
chunk.automatic_function_calling_history
|
331
|
-
if chunk.automatic_function_calling_history
|
331
|
+
if chunk is not None and chunk.automatic_function_calling_history
|
332
332
|
else []
|
333
333
|
)
|
334
334
|
self.record_history(
|
@@ -495,9 +495,12 @@ class AsyncChat(_BaseChat):
|
|
495
495
|
self.record_history(
|
496
496
|
user_input=input_content,
|
497
497
|
model_output=output_contents,
|
498
|
-
automatic_function_calling_history=chunk.automatic_function_calling_history
|
498
|
+
automatic_function_calling_history=chunk.automatic_function_calling_history
|
499
|
+
if chunk is not None and chunk.automatic_function_calling_history
|
500
|
+
else [],
|
499
501
|
is_valid=is_valid,
|
500
502
|
)
|
503
|
+
|
501
504
|
return async_generator() # type: ignore[no-untyped-call, no-any-return]
|
502
505
|
|
503
506
|
|
google/genai/live.py
CHANGED
@@ -34,6 +34,7 @@ from . import _live_converters as live_converters
|
|
34
34
|
from . import _mcp_utils
|
35
35
|
from . import _transformers as t
|
36
36
|
from . import client
|
37
|
+
from . import errors
|
37
38
|
from . import types
|
38
39
|
from ._api_client import BaseApiClient
|
39
40
|
from ._common import get_value_by_path as getv
|
@@ -78,10 +79,6 @@ _FUNCTION_RESPONSE_REQUIRES_ID = (
|
|
78
79
|
' response of a ToolCall.FunctionalCalls in Google AI.'
|
79
80
|
)
|
80
81
|
|
81
|
-
|
82
|
-
_DUMMY_KEY = 'dummy_key'
|
83
|
-
|
84
|
-
|
85
82
|
class AsyncSession:
|
86
83
|
"""[Preview] AsyncSession."""
|
87
84
|
|
@@ -912,25 +909,10 @@ class AsyncLive(_api_module.BaseModule):
|
|
912
909
|
Yields:
|
913
910
|
An AsyncSession object.
|
914
911
|
"""
|
915
|
-
async with self._connect(
|
916
|
-
model=model,
|
917
|
-
config=config,
|
918
|
-
) as session:
|
919
|
-
yield session
|
920
|
-
|
921
|
-
@contextlib.asynccontextmanager
|
922
|
-
async def _connect(
|
923
|
-
self,
|
924
|
-
*,
|
925
|
-
model: Optional[str] = None,
|
926
|
-
config: Optional[types.LiveConnectConfigOrDict] = None,
|
927
|
-
uri: Optional[str] = None,
|
928
|
-
) -> AsyncIterator[AsyncSession]:
|
929
|
-
|
930
912
|
# TODO(b/404946570): Support per request http options.
|
931
913
|
if isinstance(config, dict):
|
932
914
|
config = types.LiveConnectConfig(**config)
|
933
|
-
if config and config.http_options
|
915
|
+
if config and config.http_options:
|
934
916
|
raise ValueError(
|
935
917
|
'google.genai.client.aio.live.connect() does not support'
|
936
918
|
' http_options at request-level in LiveConnectConfig yet. Please use'
|
@@ -945,10 +927,22 @@ class AsyncLive(_api_module.BaseModule):
|
|
945
927
|
parameter_model = await _t_live_connect_config(self._api_client, config)
|
946
928
|
|
947
929
|
if self._api_client.api_key and not self._api_client.vertexai:
|
948
|
-
api_key = self._api_client.api_key
|
949
930
|
version = self._api_client._http_options.api_version
|
950
|
-
|
951
|
-
|
931
|
+
api_key = self._api_client.api_key
|
932
|
+
method = 'BidiGenerateContent'
|
933
|
+
key_name = 'key'
|
934
|
+
if api_key.startswith('auth_tokens/'):
|
935
|
+
warnings.warn(
|
936
|
+
message=(
|
937
|
+
"The SDK's ephemeral token support is experimental, and may"
|
938
|
+
' change in future versions.'
|
939
|
+
),
|
940
|
+
category=errors.ExperimentalWarning,
|
941
|
+
)
|
942
|
+
method = 'BidiGenerateContentConstrained'
|
943
|
+
key_name = 'access_token'
|
944
|
+
|
945
|
+
uri = f'{base_url}/ws/google.ai.generativelanguage.{version}.GenerativeService.{method}?{key_name}={api_key}'
|
952
946
|
headers = self._api_client._http_options.headers
|
953
947
|
|
954
948
|
request_dict = _common.convert_to_dict(
|
@@ -969,8 +963,7 @@ class AsyncLive(_api_module.BaseModule):
|
|
969
963
|
# Headers already contains api key for express mode.
|
970
964
|
api_key = self._api_client.api_key
|
971
965
|
version = self._api_client._http_options.api_version
|
972
|
-
|
973
|
-
uri = f'{base_url}/ws/google.cloud.aiplatform.{version}.LlmBidiService/BidiGenerateContent'
|
966
|
+
uri = f'{base_url}/ws/google.cloud.aiplatform.{version}.LlmBidiService/BidiGenerateContent'
|
974
967
|
headers = self._api_client._http_options.headers
|
975
968
|
|
976
969
|
request_dict = _common.convert_to_dict(
|
@@ -1060,83 +1053,6 @@ class AsyncLive(_api_module.BaseModule):
|
|
1060
1053
|
yield AsyncSession(api_client=self._api_client, websocket=ws)
|
1061
1054
|
|
1062
1055
|
|
1063
|
-
@_common.experimental_warning(
|
1064
|
-
"The SDK's Live API connection with ephemeral token implementation is"
|
1065
|
-
' experimental, and may change in future versions.',
|
1066
|
-
)
|
1067
|
-
@contextlib.asynccontextmanager
|
1068
|
-
async def live_ephemeral_connect(
|
1069
|
-
access_token: str,
|
1070
|
-
model: Optional[str] = None,
|
1071
|
-
config: Optional[types.LiveConnectConfigOrDict] = None,
|
1072
|
-
) -> AsyncIterator[AsyncSession]:
|
1073
|
-
"""[Experimental] Connect to the live server using ephermeral token (Gemini Developer API only).
|
1074
|
-
|
1075
|
-
Note: the live API is currently in experimental.
|
1076
|
-
|
1077
|
-
Usage:
|
1078
|
-
|
1079
|
-
.. code-block:: python
|
1080
|
-
from google import genai
|
1081
|
-
|
1082
|
-
config = {}
|
1083
|
-
async with genai.live_ephemeral_connect(
|
1084
|
-
access_token='auth_tokens/12345',
|
1085
|
-
model='...',
|
1086
|
-
config=config,
|
1087
|
-
http_options=types.HttpOptions(api_version='v1beta'),
|
1088
|
-
) as session:
|
1089
|
-
await session.send_client_content(
|
1090
|
-
turns=types.Content(
|
1091
|
-
role='user',
|
1092
|
-
parts=[types.Part(text='hello!')]
|
1093
|
-
),
|
1094
|
-
turn_complete=True
|
1095
|
-
)
|
1096
|
-
|
1097
|
-
async for message in session.receive():
|
1098
|
-
print(message)
|
1099
|
-
|
1100
|
-
Args:
|
1101
|
-
access_token: The access token to use for the Live session. It can be
|
1102
|
-
generated by the `client.tokens.create` method.
|
1103
|
-
model: The model to use for the Live session.
|
1104
|
-
config: The configuration for the Live session.
|
1105
|
-
|
1106
|
-
Yields:
|
1107
|
-
An AsyncSession object.
|
1108
|
-
"""
|
1109
|
-
if isinstance(config, dict):
|
1110
|
-
config = types.LiveConnectConfig(**config)
|
1111
|
-
|
1112
|
-
http_options = config.http_options if config else None
|
1113
|
-
|
1114
|
-
base_url = (
|
1115
|
-
http_options.base_url
|
1116
|
-
if http_options and http_options.base_url
|
1117
|
-
else 'https://generativelanguage.googleapis.com/'
|
1118
|
-
)
|
1119
|
-
api_version = (
|
1120
|
-
http_options.api_version
|
1121
|
-
if http_options and http_options.api_version
|
1122
|
-
else 'v1beta'
|
1123
|
-
)
|
1124
|
-
internal_client = client.Client(
|
1125
|
-
api_key=_DUMMY_KEY, # Can't be None during initialization
|
1126
|
-
http_options=types.HttpOptions(
|
1127
|
-
base_url=base_url,
|
1128
|
-
api_version=api_version,
|
1129
|
-
),
|
1130
|
-
)
|
1131
|
-
websocket_base_url = internal_client._api_client._websocket_base_url()
|
1132
|
-
uri = f'{websocket_base_url}/ws/google.ai.generativelanguage.{api_version}.GenerativeService.BidiGenerateContentConstrained?access_token={access_token}'
|
1133
|
-
|
1134
|
-
async with internal_client.aio.live._connect(
|
1135
|
-
model=model, config=config, uri=uri
|
1136
|
-
) as session:
|
1137
|
-
yield session
|
1138
|
-
|
1139
|
-
|
1140
1056
|
async def _t_live_connect_config(
|
1141
1057
|
api_client: BaseApiClient,
|
1142
1058
|
config: Optional[types.LiveConnectConfigOrDict],
|
google/genai/models.py
CHANGED
@@ -123,6 +123,13 @@ def _Part_to_mldev(
|
|
123
123
|
),
|
124
124
|
)
|
125
125
|
|
126
|
+
if getv(from_object, ['thought_signature']) is not None:
|
127
|
+
setv(
|
128
|
+
to_object,
|
129
|
+
['thoughtSignature'],
|
130
|
+
getv(from_object, ['thought_signature']),
|
131
|
+
)
|
132
|
+
|
126
133
|
if getv(from_object, ['code_execution_result']) is not None:
|
127
134
|
setv(
|
128
135
|
to_object,
|
@@ -1415,7 +1422,11 @@ def _GenerateVideosConfig_to_mldev(
|
|
1415
1422
|
)
|
1416
1423
|
|
1417
1424
|
if getv(from_object, ['enhance_prompt']) is not None:
|
1418
|
-
|
1425
|
+
setv(
|
1426
|
+
parent_object,
|
1427
|
+
['parameters', 'enhancePrompt'],
|
1428
|
+
getv(from_object, ['enhance_prompt']),
|
1429
|
+
)
|
1419
1430
|
|
1420
1431
|
if getv(from_object, ['generate_audio']) is not None:
|
1421
1432
|
raise ValueError('generate_audio parameter is not supported in Gemini API.')
|
@@ -1548,6 +1559,13 @@ def _Part_to_vertex(
|
|
1548
1559
|
),
|
1549
1560
|
)
|
1550
1561
|
|
1562
|
+
if getv(from_object, ['thought_signature']) is not None:
|
1563
|
+
setv(
|
1564
|
+
to_object,
|
1565
|
+
['thoughtSignature'],
|
1566
|
+
getv(from_object, ['thought_signature']),
|
1567
|
+
)
|
1568
|
+
|
1551
1569
|
if getv(from_object, ['code_execution_result']) is not None:
|
1552
1570
|
setv(
|
1553
1571
|
to_object,
|
@@ -1967,7 +1985,13 @@ def _Tool_to_vertex(
|
|
1967
1985
|
)
|
1968
1986
|
|
1969
1987
|
if getv(from_object, ['url_context']) is not None:
|
1970
|
-
|
1988
|
+
setv(
|
1989
|
+
to_object,
|
1990
|
+
['urlContext'],
|
1991
|
+
_UrlContext_to_vertex(
|
1992
|
+
api_client, getv(from_object, ['url_context']), to_object
|
1993
|
+
),
|
1994
|
+
)
|
1971
1995
|
|
1972
1996
|
if getv(from_object, ['code_execution']) is not None:
|
1973
1997
|
setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
|
@@ -3441,6 +3465,13 @@ def _Part_from_mldev(
|
|
3441
3465
|
),
|
3442
3466
|
)
|
3443
3467
|
|
3468
|
+
if getv(from_object, ['thoughtSignature']) is not None:
|
3469
|
+
setv(
|
3470
|
+
to_object,
|
3471
|
+
['thought_signature'],
|
3472
|
+
getv(from_object, ['thoughtSignature']),
|
3473
|
+
)
|
3474
|
+
|
3444
3475
|
if getv(from_object, ['codeExecutionResult']) is not None:
|
3445
3476
|
setv(
|
3446
3477
|
to_object,
|
@@ -4138,6 +4169,13 @@ def _Part_from_vertex(
|
|
4138
4169
|
),
|
4139
4170
|
)
|
4140
4171
|
|
4172
|
+
if getv(from_object, ['thoughtSignature']) is not None:
|
4173
|
+
setv(
|
4174
|
+
to_object,
|
4175
|
+
['thought_signature'],
|
4176
|
+
getv(from_object, ['thoughtSignature']),
|
4177
|
+
)
|
4178
|
+
|
4141
4179
|
if getv(from_object, ['codeExecutionResult']) is not None:
|
4142
4180
|
setv(
|
4143
4181
|
to_object,
|
@@ -4266,6 +4304,15 @@ def _Candidate_from_vertex(
|
|
4266
4304
|
if getv(from_object, ['finishReason']) is not None:
|
4267
4305
|
setv(to_object, ['finish_reason'], getv(from_object, ['finishReason']))
|
4268
4306
|
|
4307
|
+
if getv(from_object, ['urlContextMetadata']) is not None:
|
4308
|
+
setv(
|
4309
|
+
to_object,
|
4310
|
+
['url_context_metadata'],
|
4311
|
+
_UrlContextMetadata_from_vertex(
|
4312
|
+
api_client, getv(from_object, ['urlContextMetadata']), to_object
|
4313
|
+
),
|
4314
|
+
)
|
4315
|
+
|
4269
4316
|
if getv(from_object, ['avgLogprobs']) is not None:
|
4270
4317
|
setv(to_object, ['avg_logprobs'], getv(from_object, ['avgLogprobs']))
|
4271
4318
|
|
@@ -6105,7 +6152,8 @@ class Models(_api_module.BaseModule):
|
|
6105
6152
|
)
|
6106
6153
|
yield chunk
|
6107
6154
|
if (
|
6108
|
-
|
6155
|
+
chunk is None
|
6156
|
+
or not chunk.candidates
|
6109
6157
|
or not chunk.candidates[0].content
|
6110
6158
|
or not chunk.candidates[0].content.parts
|
6111
6159
|
):
|
@@ -6120,7 +6168,7 @@ class Models(_api_module.BaseModule):
|
|
6120
6168
|
break
|
6121
6169
|
|
6122
6170
|
# Append function response parts to contents for the next request.
|
6123
|
-
if chunk.candidates is not None:
|
6171
|
+
if chunk is not None and chunk.candidates is not None:
|
6124
6172
|
func_call_content = chunk.candidates[0].content
|
6125
6173
|
func_response_content = types.Content(
|
6126
6174
|
role='user',
|
@@ -7609,7 +7657,8 @@ class AsyncModels(_api_module.BaseModule):
|
|
7609
7657
|
)
|
7610
7658
|
yield chunk
|
7611
7659
|
if (
|
7612
|
-
|
7660
|
+
chunk is None
|
7661
|
+
or not chunk.candidates
|
7613
7662
|
or not chunk.candidates[0].content
|
7614
7663
|
or not chunk.candidates[0].content.parts
|
7615
7664
|
):
|
@@ -7623,6 +7672,8 @@ class AsyncModels(_api_module.BaseModule):
|
|
7623
7672
|
if not func_response_parts:
|
7624
7673
|
break
|
7625
7674
|
|
7675
|
+
if chunk is None:
|
7676
|
+
continue
|
7626
7677
|
# Append function response parts to contents for the next request.
|
7627
7678
|
func_call_content = chunk.candidates[0].content
|
7628
7679
|
func_response_content = types.Content(
|
google/genai/tokens.py
CHANGED
@@ -143,6 +143,7 @@ class Tokens(_api_module.BaseModule):
|
|
143
143
|
Usage:
|
144
144
|
|
145
145
|
.. code-block:: python
|
146
|
+
|
146
147
|
# Case 1: If LiveEphemeralParameters is unset, unlock LiveConnectConfig
|
147
148
|
# when using the token in Live API sessions. Each session connection can
|
148
149
|
# use a different configuration.
|
@@ -154,6 +155,7 @@ class Tokens(_api_module.BaseModule):
|
|
154
155
|
auth_token = client.tokens.create(config=config)
|
155
156
|
|
156
157
|
.. code-block:: python
|
158
|
+
|
157
159
|
# Case 2: If LiveEphemeralParameters is set, lock all fields in
|
158
160
|
# LiveConnectConfig when using the token in Live API sessions. For
|
159
161
|
# example, changing `output_audio_transcription` in the Live API
|
@@ -170,7 +172,9 @@ class Tokens(_api_module.BaseModule):
|
|
170
172
|
),
|
171
173
|
)
|
172
174
|
)
|
173
|
-
|
175
|
+
|
176
|
+
.. code-block:: python
|
177
|
+
|
174
178
|
# Case 3: If LiveEphemeralParameters is set and lockAdditionalFields is
|
175
179
|
# empty, lock LiveConnectConfig with set fields (e.g.
|
176
180
|
# system_instruction in this example) when using the token in Live API
|
@@ -187,7 +191,8 @@ class Tokens(_api_module.BaseModule):
|
|
187
191
|
)
|
188
192
|
)
|
189
193
|
|
190
|
-
|
194
|
+
.. code-block:: python
|
195
|
+
|
191
196
|
# Case 4: If LiveEphemeralParameters is set and lockAdditionalFields is
|
192
197
|
# set, lock LiveConnectConfig with set and additional fields (e.g.
|
193
198
|
# system_instruction, temperature in this example) when using the token
|
google/genai/types.py
CHANGED
@@ -59,17 +59,21 @@ _is_mcp_imported = False
|
|
59
59
|
if typing.TYPE_CHECKING:
|
60
60
|
from mcp import types as mcp_types
|
61
61
|
from mcp import ClientSession as McpClientSession
|
62
|
+
from mcp.types import CallToolResult as McpCallToolResult
|
62
63
|
|
63
64
|
_is_mcp_imported = True
|
64
65
|
else:
|
65
66
|
McpClientSession: typing.Type = Any
|
67
|
+
McpCallToolResult: typing.Type = Any
|
66
68
|
try:
|
67
69
|
from mcp import types as mcp_types
|
68
70
|
from mcp import ClientSession as McpClientSession
|
71
|
+
from mcp.types import CallToolResult as McpCallToolResult
|
69
72
|
|
70
73
|
_is_mcp_imported = True
|
71
74
|
except ImportError:
|
72
75
|
McpClientSession = None
|
76
|
+
McpCallToolResult = None
|
73
77
|
|
74
78
|
logger = logging.getLogger('google_genai.types')
|
75
79
|
|
@@ -225,6 +229,8 @@ class FinishReason(_common.CaseInSensitiveEnum):
|
|
225
229
|
"""The function call generated by the model is invalid."""
|
226
230
|
IMAGE_SAFETY = 'IMAGE_SAFETY'
|
227
231
|
"""Token generation stopped because generated images have safety violations."""
|
232
|
+
UNEXPECTED_TOOL_CALL = 'UNEXPECTED_TOOL_CALL'
|
233
|
+
"""The tool call generated by the model is invalid."""
|
228
234
|
|
229
235
|
|
230
236
|
class HarmProbability(_common.CaseInSensitiveEnum):
|
@@ -843,6 +849,21 @@ class FunctionResponse(_common.BaseModel):
|
|
843
849
|
description="""Required. The function response in JSON object format. Use "output" key to specify function output and "error" key to specify error details (if any). If "output" and "error" keys are not specified, then whole "response" is treated as function output.""",
|
844
850
|
)
|
845
851
|
|
852
|
+
@classmethod
|
853
|
+
def from_mcp_response(
|
854
|
+
cls, *, name: str, response: McpCallToolResult
|
855
|
+
) -> 'FunctionResponse':
|
856
|
+
if not _is_mcp_imported:
|
857
|
+
raise ValueError(
|
858
|
+
'MCP response is not supported. Please ensure that the MCP library is'
|
859
|
+
' imported.'
|
860
|
+
)
|
861
|
+
|
862
|
+
if response.isError:
|
863
|
+
return cls(name=name, response={'error': 'MCP response is error.'})
|
864
|
+
else:
|
865
|
+
return cls(name=name, response={'result': response.content})
|
866
|
+
|
846
867
|
|
847
868
|
class FunctionResponseDict(TypedDict, total=False):
|
848
869
|
"""A function response."""
|
@@ -887,6 +908,10 @@ class Part(_common.BaseModel):
|
|
887
908
|
file_data: Optional[FileData] = Field(
|
888
909
|
default=None, description="""Optional. URI based data."""
|
889
910
|
)
|
911
|
+
thought_signature: Optional[bytes] = Field(
|
912
|
+
default=None,
|
913
|
+
description="""An opaque signature for the thought so it can be reused in subsequent requests.""",
|
914
|
+
)
|
890
915
|
code_execution_result: Optional[CodeExecutionResult] = Field(
|
891
916
|
default=None,
|
892
917
|
description="""Optional. Result of executing the [ExecutableCode].""",
|
@@ -984,6 +1009,9 @@ class PartDict(TypedDict, total=False):
|
|
984
1009
|
file_data: Optional[FileDataDict]
|
985
1010
|
"""Optional. URI based data."""
|
986
1011
|
|
1012
|
+
thought_signature: Optional[bytes]
|
1013
|
+
"""An opaque signature for the thought so it can be reused in subsequent requests."""
|
1014
|
+
|
987
1015
|
code_execution_result: Optional[CodeExecutionResultDict]
|
988
1016
|
"""Optional. Result of executing the [ExecutableCode]."""
|
989
1017
|
|
@@ -1916,12 +1944,16 @@ class FunctionDeclaration(_common.BaseModel):
|
|
1916
1944
|
from . import _automatic_function_calling_util
|
1917
1945
|
|
1918
1946
|
parameters_properties = {}
|
1947
|
+
annotation_under_future = typing.get_type_hints(callable)
|
1919
1948
|
for name, param in inspect.signature(callable).parameters.items():
|
1920
1949
|
if param.kind in (
|
1921
1950
|
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
1922
1951
|
inspect.Parameter.KEYWORD_ONLY,
|
1923
1952
|
inspect.Parameter.POSITIONAL_ONLY,
|
1924
1953
|
):
|
1954
|
+
# This snippet catches the case when type hints are stored as strings
|
1955
|
+
if isinstance(param.annotation, str):
|
1956
|
+
param = param.replace(annotation=annotation_under_future[name])
|
1925
1957
|
schema = _automatic_function_calling_util._parse_schema_from_parameter(
|
1926
1958
|
api_option, param, callable.__name__
|
1927
1959
|
)
|
@@ -1943,6 +1975,7 @@ class FunctionDeclaration(_common.BaseModel):
|
|
1943
1975
|
declaration.parameters
|
1944
1976
|
)
|
1945
1977
|
)
|
1978
|
+
# TODO: b/421991354 - Remove this check once the bug is fixed.
|
1946
1979
|
if api_option == 'GEMINI_API':
|
1947
1980
|
return declaration
|
1948
1981
|
|
@@ -1950,14 +1983,21 @@ class FunctionDeclaration(_common.BaseModel):
|
|
1950
1983
|
if return_annotation is inspect._empty:
|
1951
1984
|
return declaration
|
1952
1985
|
|
1986
|
+
return_value = inspect.Parameter(
|
1987
|
+
'return_value',
|
1988
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
1989
|
+
annotation=return_annotation,
|
1990
|
+
)
|
1991
|
+
|
1992
|
+
# This snippet catches the case when type hints are stored as strings
|
1993
|
+
if isinstance(return_value.annotation, str):
|
1994
|
+
return_value = return_value.replace(
|
1995
|
+
annotation=annotation_under_future['return']
|
1996
|
+
)
|
1953
1997
|
declaration.response = (
|
1954
1998
|
_automatic_function_calling_util._parse_schema_from_parameter(
|
1955
1999
|
api_option,
|
1956
|
-
|
1957
|
-
'return_value',
|
1958
|
-
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
1959
|
-
annotation=return_annotation,
|
1960
|
-
),
|
2000
|
+
return_value,
|
1961
2001
|
callable.__name__,
|
1962
2002
|
)
|
1963
2003
|
)
|
@@ -12492,8 +12532,8 @@ class AuthTokenDict(TypedDict, total=False):
|
|
12492
12532
|
AuthTokenOrDict = Union[AuthToken, AuthTokenDict]
|
12493
12533
|
|
12494
12534
|
|
12495
|
-
class
|
12496
|
-
"""Config for
|
12535
|
+
class LiveConnectConstraints(_common.BaseModel):
|
12536
|
+
"""Config for LiveConnectConstraints for Auth Token creation."""
|
12497
12537
|
|
12498
12538
|
model: Optional[str] = Field(
|
12499
12539
|
default=None,
|
@@ -12507,8 +12547,8 @@ class LiveEphemeralParameters(_common.BaseModel):
|
|
12507
12547
|
)
|
12508
12548
|
|
12509
12549
|
|
12510
|
-
class
|
12511
|
-
"""Config for
|
12550
|
+
class LiveConnectConstraintsDict(TypedDict, total=False):
|
12551
|
+
"""Config for LiveConnectConstraints for Auth Token creation."""
|
12512
12552
|
|
12513
12553
|
model: Optional[str]
|
12514
12554
|
"""ID of the model to configure in the ephemeral token for Live API.
|
@@ -12519,8 +12559,8 @@ class LiveEphemeralParametersDict(TypedDict, total=False):
|
|
12519
12559
|
"""Configuration specific to Live API connections created using this token."""
|
12520
12560
|
|
12521
12561
|
|
12522
|
-
|
12523
|
-
|
12562
|
+
LiveConnectConstraintsOrDict = Union[
|
12563
|
+
LiveConnectConstraints, LiveConnectConstraintsDict
|
12524
12564
|
]
|
12525
12565
|
|
12526
12566
|
|
@@ -12553,7 +12593,7 @@ class CreateAuthTokenConfig(_common.BaseModel):
|
|
12553
12593
|
then no limit is applied. Default is 1. Resuming a Live API session does
|
12554
12594
|
not count as a use.""",
|
12555
12595
|
)
|
12556
|
-
|
12596
|
+
live_connect_constraints: Optional[LiveConnectConstraints] = Field(
|
12557
12597
|
default=None,
|
12558
12598
|
description="""Configuration specific to Live API connections created using this token.""",
|
12559
12599
|
)
|
@@ -12589,7 +12629,7 @@ class CreateAuthTokenConfigDict(TypedDict, total=False):
|
|
12589
12629
|
then no limit is applied. Default is 1. Resuming a Live API session does
|
12590
12630
|
not count as a use."""
|
12591
12631
|
|
12592
|
-
|
12632
|
+
live_connect_constraints: Optional[LiveConnectConstraintsDict]
|
12593
12633
|
"""Configuration specific to Live API connections created using this token."""
|
12594
12634
|
|
12595
12635
|
lock_additional_fields: Optional[list[str]]
|
google/genai/version.py
CHANGED
@@ -1,35 +1,35 @@
|
|
1
|
-
google/genai/__init__.py,sha256=
|
1
|
+
google/genai/__init__.py,sha256=SYTxz3Ho06pP2TBlvDU0FkUJz8ytbR3MgEpS9HvVYq4,709
|
2
2
|
google/genai/_adapters.py,sha256=Kok38miNYJff2n--l0zEK_hbq0y2rWOH7k75J7SMYbQ,1744
|
3
|
-
google/genai/_api_client.py,sha256=
|
3
|
+
google/genai/_api_client.py,sha256=AOhv4_L9aTDzT6ALvH54s5ozPUPCx4w4ShLdh8qpXvM,38879
|
4
4
|
google/genai/_api_module.py,sha256=lj8eUWx8_LBGBz-49qz6_ywWm3GYp3d8Bg5JoOHbtbI,902
|
5
5
|
google/genai/_automatic_function_calling_util.py,sha256=IJkPq2fT9pYxYm5Pbu5-e0nBoZKoZla7yT4_txWRKLs,10324
|
6
6
|
google/genai/_base_url.py,sha256=E5H4dew14Y16qfnB3XRnjSCi19cJVlkaMNoM_8ip-PM,1597
|
7
|
-
google/genai/_common.py,sha256=
|
7
|
+
google/genai/_common.py,sha256=hDqunjaAL__GXZzhr37QGOCR6z6PMc_EfiRy_ukAxHo,11545
|
8
8
|
google/genai/_extra_utils.py,sha256=_w8hB9Ag7giRR94nIOBJFTLiLEufulPXkCZpJG1XY5g,19241
|
9
|
-
google/genai/_live_converters.py,sha256=
|
9
|
+
google/genai/_live_converters.py,sha256=8J0h9JUdkwkPFugFBAW4EKTMkZATMDZWgNkc9WOh2Hg,115488
|
10
10
|
google/genai/_mcp_utils.py,sha256=khECx-DMuHemKzOQQ3msWp7FivPeEOnl3n1lvWc_b5o,3833
|
11
11
|
google/genai/_replay_api_client.py,sha256=BrnKkdUVejpuHvqVHK0V4m4TjvL4LaBLHRMv6vw0vGE,21361
|
12
12
|
google/genai/_test_api_client.py,sha256=4ruFIy5_1qcbKqqIBu3HSQbpSOBrxiecBtDZaTGFR1s,4797
|
13
|
-
google/genai/_tokens_converters.py,sha256=
|
14
|
-
google/genai/_transformers.py,sha256=
|
13
|
+
google/genai/_tokens_converters.py,sha256=IUmpIC7nKjZzp_azavxXgeML35nYSC0KRkCnGG0iZao,51477
|
14
|
+
google/genai/_transformers.py,sha256=Ii8u54Ni8388jU8OAei5sixZAmFP3o-OKbxomzBul4o,35557
|
15
15
|
google/genai/batches.py,sha256=gyNb--psM7cqXEP5RsJ908ismvsFFlDNRxt7mCwhYgM,34943
|
16
|
-
google/genai/caches.py,sha256=
|
17
|
-
google/genai/chats.py,sha256=
|
16
|
+
google/genai/caches.py,sha256=Z1DiYwZUjY9zrCapfEFOz77lwfWyCsAbnrcMF2tr24g,68038
|
17
|
+
google/genai/chats.py,sha256=Hl08SbpSCMS0kYiBNGNzPI8q3rijGEW_up0g2Wun9cY,17044
|
18
18
|
google/genai/client.py,sha256=9AWoFL2g-OQFA4Zqpecg74b7h3i5Q9ZlXF4bFePV0zA,10759
|
19
19
|
google/genai/errors.py,sha256=nLAVglUGuPdLqLcnN_VCifoi7V17u9BQ9AfxUdRzZLg,4795
|
20
20
|
google/genai/files.py,sha256=PB5Rh5WiLOPHcqPR1inGyhqL9PiE0BFHSL4Dz9HKtl8,39516
|
21
|
-
google/genai/live.py,sha256=
|
21
|
+
google/genai/live.py,sha256=ZpXHO7AFayOz2viISxs34rlG85dFH9qk-5-qOC9pcZE,39375
|
22
22
|
google/genai/live_music.py,sha256=lO-nDz2gEJ8bYesJC1Aru4IrsV7raEePf4sH3QQT6yI,7119
|
23
|
-
google/genai/models.py,sha256=
|
23
|
+
google/genai/models.py,sha256=B9T4g7VLUiaZbUADKJG1UrVlvwQziZbUSgOXo3yj4oA,239463
|
24
24
|
google/genai/operations.py,sha256=wWGngU4N3U2y_JteBkwqTmoNncehk2NcZgPyHaVulfI,20304
|
25
25
|
google/genai/pagers.py,sha256=nyVYxp92rS-UaewO_oBgP593knofeLU6yOn6RolNoGQ,6797
|
26
26
|
google/genai/py.typed,sha256=RsMFoLwBkAvY05t6izop4UHZtqOPLiKp3GkIEizzmQY,40
|
27
|
-
google/genai/tokens.py,sha256=
|
27
|
+
google/genai/tokens.py,sha256=31HRdGkuN1VkHn21qKBwa6PeiLFGMN-aFldPIGo9WxE,12188
|
28
28
|
google/genai/tunings.py,sha256=aEKTVfpn6rYWEKu0CRaS93mo2iLQtX5K3nSqX6UB_jM,49500
|
29
|
-
google/genai/types.py,sha256=
|
30
|
-
google/genai/version.py,sha256=
|
31
|
-
google_genai-1.
|
32
|
-
google_genai-1.
|
33
|
-
google_genai-1.
|
34
|
-
google_genai-1.
|
35
|
-
google_genai-1.
|
29
|
+
google/genai/types.py,sha256=SjZ9GaMEHn_YoOHnCLQm0Sl9AsnYPqBVbExlF6l9fo4,437412
|
30
|
+
google/genai/version.py,sha256=4Bj2qKIYUQDZnSbV8me-05HqXSvijhv-sXzln7K77wA,627
|
31
|
+
google_genai-1.19.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
32
|
+
google_genai-1.19.0.dist-info/METADATA,sha256=AdmMMUAAVkTxCNDAANY8SJsTlxBoXVKg2zdxj4-RgOs,35579
|
33
|
+
google_genai-1.19.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
34
|
+
google_genai-1.19.0.dist-info/top_level.txt,sha256=_1QvSJIhFAGfxb79D6DhB7SUw2X6T4rwnz_LLrbcD3c,7
|
35
|
+
google_genai-1.19.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|