google-genai 1.15.0__tar.gz → 1.16.1__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.15.0/google_genai.egg-info → google_genai-1.16.1}/PKG-INFO +8 -4
  2. {google_genai-1.15.0 → google_genai-1.16.1}/README.md +7 -3
  3. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/__init__.py +5 -3
  4. google_genai-1.16.1/google/genai/_adapters.py +55 -0
  5. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_api_client.py +3 -3
  6. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_api_module.py +1 -1
  7. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_automatic_function_calling_util.py +1 -1
  8. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_common.py +1 -1
  9. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_extra_utils.py +114 -9
  10. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_live_converters.py +1295 -20
  11. google_genai-1.16.1/google/genai/_mcp_utils.py +117 -0
  12. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_replay_api_client.py +1 -1
  13. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_test_api_client.py +1 -1
  14. google_genai-1.16.1/google/genai/_tokens_converters.py +1701 -0
  15. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_transformers.py +66 -33
  16. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/caches.py +223 -20
  17. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/chats.py +1 -1
  18. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/client.py +12 -1
  19. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/errors.py +1 -1
  20. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/live.py +218 -35
  21. google_genai-1.16.1/google/genai/live_music.py +201 -0
  22. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/models.py +505 -44
  23. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/pagers.py +1 -1
  24. google_genai-1.16.1/google/genai/tokens.py +357 -0
  25. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/types.py +7887 -6765
  26. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/version.py +2 -2
  27. {google_genai-1.15.0 → google_genai-1.16.1/google_genai.egg-info}/PKG-INFO +8 -4
  28. {google_genai-1.15.0 → google_genai-1.16.1}/google_genai.egg-info/SOURCES.txt +5 -0
  29. {google_genai-1.15.0 → google_genai-1.16.1}/pyproject.toml +1 -1
  30. {google_genai-1.15.0 → google_genai-1.16.1}/LICENSE +0 -0
  31. {google_genai-1.15.0 → google_genai-1.16.1}/MANIFEST.in +0 -0
  32. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/_base_url.py +0 -0
  33. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/batches.py +0 -0
  34. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/files.py +0 -0
  35. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/operations.py +0 -0
  36. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/py.typed +0 -0
  37. {google_genai-1.15.0 → google_genai-1.16.1}/google/genai/tunings.py +0 -0
  38. {google_genai-1.15.0 → google_genai-1.16.1}/google_genai.egg-info/dependency_links.txt +0 -0
  39. {google_genai-1.15.0 → google_genai-1.16.1}/google_genai.egg-info/requires.txt +0 -0
  40. {google_genai-1.15.0 → google_genai-1.16.1}/google_genai.egg-info/top_level.txt +0 -0
  41. {google_genai-1.15.0 → google_genai-1.16.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-genai
3
- Version: 1.15.0
3
+ Version: 1.16.1
4
4
  Summary: GenAI Python SDK
5
5
  Author-email: Google LLC <googleapis-packages@google.com>
6
6
  License: Apache-2.0
@@ -40,7 +40,11 @@ Dynamic: license-file
40
40
 
41
41
  -----
42
42
 
43
- Google Gen AI Python SDK provides an interface for developers to integrate Google's generative models into their Python applications. It supports the [Gemini Developer API](https://ai.google.dev/gemini-api/docs) and [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview) APIs.
43
+ Google Gen AI Python SDK provides an interface for developers to integrate
44
+ Google's generative models into their Python applications. It supports the
45
+ [Gemini Developer API](https://ai.google.dev/gemini-api/docs) and
46
+ [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview)
47
+ APIs.
44
48
 
45
49
  ## Installation
46
50
 
@@ -88,8 +92,8 @@ Developer API or the Gemini API in Vertex AI.
88
92
  export GOOGLE_API_KEY='your-api-key'
89
93
  ```
90
94
 
91
- **Gemini API on Vertex AI:** Set `GOOGLE_GENAI_USE_VERTEXAI`, `GOOGLE_CLOUD_PROJECT`
92
- and `GOOGLE_CLOUD_LOCATION`, as shown below:
95
+ **Gemini API on Vertex AI:** Set `GOOGLE_GENAI_USE_VERTEXAI`,
96
+ `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`, as shown below:
93
97
 
94
98
  ```bash
95
99
  export GOOGLE_GENAI_USE_VERTEXAI=true
@@ -9,7 +9,11 @@
9
9
 
10
10
  -----
11
11
 
12
- Google Gen AI Python SDK provides an interface for developers to integrate Google's generative models into their Python applications. It supports the [Gemini Developer API](https://ai.google.dev/gemini-api/docs) and [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview) APIs.
12
+ Google Gen AI Python SDK provides an interface for developers to integrate
13
+ Google's generative models into their Python applications. It supports the
14
+ [Gemini Developer API](https://ai.google.dev/gemini-api/docs) and
15
+ [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview)
16
+ APIs.
13
17
 
14
18
  ## Installation
15
19
 
@@ -57,8 +61,8 @@ Developer API or the Gemini API in Vertex AI.
57
61
  export GOOGLE_API_KEY='your-api-key'
58
62
  ```
59
63
 
60
- **Gemini API on Vertex AI:** Set `GOOGLE_GENAI_USE_VERTEXAI`, `GOOGLE_CLOUD_PROJECT`
61
- and `GOOGLE_CLOUD_LOCATION`, as shown below:
64
+ **Gemini API on Vertex AI:** Set `GOOGLE_GENAI_USE_VERTEXAI`,
65
+ `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`, as shown below:
62
66
 
63
67
  ```bash
64
68
  export GOOGLE_GENAI_USE_VERTEXAI=true
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,9 +15,11 @@
15
15
 
16
16
  """Google Gen AI SDK"""
17
17
 
18
+ from . import version
18
19
  from .client import Client
19
- from . import version
20
+ from .live import live_ephemeral_connect
21
+
20
22
 
21
23
  __version__ = version.__version__
22
24
 
23
- __all__ = ['Client']
25
+ __all__ = ['Client', 'live_ephemeral_connect']
@@ -0,0 +1,55 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ import typing
17
+
18
+ from ._mcp_utils import mcp_to_gemini_tools
19
+ from .types import FunctionCall, Tool
20
+
21
+ if typing.TYPE_CHECKING:
22
+ from mcp import types as mcp_types
23
+ from mcp import ClientSession
24
+
25
+
26
+ class McpToGenAiToolAdapter:
27
+ """Adapter for working with MCP tools in a GenAI client."""
28
+
29
+ def __init__(
30
+ self,
31
+ session: "mcp.ClientSession", # type: ignore # noqa: F821
32
+ list_tools_result: "mcp_types.ListToolsResult", # type: ignore
33
+ ) -> None:
34
+ self._mcp_session = session
35
+ self._list_tools_result = list_tools_result
36
+
37
+ async def call_tool(
38
+ self, function_call: FunctionCall
39
+ ) -> "mcp_types.CallToolResult": # type: ignore
40
+ """Calls a function on the MCP server."""
41
+ name = function_call.name if function_call.name else ""
42
+ arguments = dict(function_call.args) if function_call.args else {}
43
+
44
+ return typing.cast(
45
+ "mcp_types.CallToolResult",
46
+ await self._mcp_session.call_tool(
47
+ name=name,
48
+ arguments=arguments,
49
+ ),
50
+ )
51
+
52
+ @property
53
+ def tools(self) -> list[Tool]:
54
+ """Returns a list of Google GenAI tools."""
55
+ return mcp_to_gemini_tools(self._list_tools_result.tools)
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -72,14 +72,14 @@ def _append_library_version_headers(headers: dict[str, str]) -> None:
72
72
  'user-agent' in headers
73
73
  and version_header_value not in headers['user-agent']
74
74
  ):
75
- headers['user-agent'] += f' {version_header_value}'
75
+ headers['user-agent'] = f'{version_header_value} ' + headers['user-agent']
76
76
  elif 'user-agent' not in headers:
77
77
  headers['user-agent'] = version_header_value
78
78
  if (
79
79
  'x-goog-api-client' in headers
80
80
  and version_header_value not in headers['x-goog-api-client']
81
81
  ):
82
- headers['x-goog-api-client'] += f' {version_header_value}'
82
+ headers['x-goog-api-client'] = f'{version_header_value} ' + headers['x-goog-api-client']
83
83
  elif 'x-goog-api-client' not in headers:
84
84
  headers['x-goog-api-client'] = version_header_value
85
85
 
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 Google LLC
1
+ # Copyright 2025 Google LLC
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -24,14 +24,30 @@ from typing import Any, Callable, Dict, Optional, Union, get_args, get_origin
24
24
  import pydantic
25
25
 
26
26
  from . import _common
27
+ from . import _mcp_utils
27
28
  from . import errors
28
29
  from . import types
30
+ from ._adapters import McpToGenAiToolAdapter
31
+
29
32
 
30
33
  if sys.version_info >= (3, 10):
31
34
  from types import UnionType
32
35
  else:
33
36
  UnionType = typing._UnionGenericAlias # type: ignore[attr-defined]
34
37
 
38
+ if typing.TYPE_CHECKING:
39
+ from mcp import ClientSession as McpClientSession
40
+ from mcp.types import Tool as McpTool
41
+ else:
42
+ McpClientSession: typing.Type = Any
43
+ McpTool: typing.Type = Any
44
+ try:
45
+ from mcp import ClientSession as McpClientSession
46
+ from mcp.types import Tool as McpTool
47
+ except ImportError:
48
+ McpClientSession = None
49
+ McpTool = None
50
+
35
51
  _DEFAULT_MAX_REMOTE_CALLS_AFC = 10
36
52
 
37
53
  logger = logging.getLogger('google_genai.models')
@@ -78,10 +94,13 @@ def format_destination(
78
94
 
79
95
  def get_function_map(
80
96
  config: Optional[types.GenerateContentConfigOrDict] = None,
97
+ mcp_to_genai_tool_adapters: Optional[
98
+ dict[str, McpToGenAiToolAdapter]
99
+ ] = None,
81
100
  is_caller_method_async: bool = False,
82
- ) -> dict[str, Callable[..., Any]]:
101
+ ) -> dict[str, Union[Callable[..., Any], McpToGenAiToolAdapter]]:
83
102
  """Returns a function map from the config."""
84
- function_map: dict[str, Callable[..., Any]] = {}
103
+ function_map: dict[str, Union[Callable[..., Any], McpToGenAiToolAdapter]] = {}
85
104
  if not config:
86
105
  return function_map
87
106
  config_model = _create_generate_content_config_model(config)
@@ -95,6 +114,17 @@ def get_function_map(
95
114
  f' invoke {tool.__name__} to get the function response.'
96
115
  )
97
116
  function_map[tool.__name__] = tool
117
+ if mcp_to_genai_tool_adapters:
118
+ if not is_caller_method_async:
119
+ raise errors.UnsupportedFunctionError(
120
+ 'MCP tools are not supported in synchronous methods.'
121
+ )
122
+ for tool_name, _ in mcp_to_genai_tool_adapters.items():
123
+ if function_map.get(tool_name):
124
+ raise ValueError(
125
+ f'Tool {tool_name} is already defined for the request.'
126
+ )
127
+ function_map.update(mcp_to_genai_tool_adapters)
98
128
  return function_map
99
129
 
100
130
 
@@ -247,7 +277,7 @@ async def invoke_function_from_dict_args_async(
247
277
 
248
278
  def get_function_response_parts(
249
279
  response: types.GenerateContentResponse,
250
- function_map: dict[str, Callable[..., Any]],
280
+ function_map: dict[str, Union[Callable[..., Any], McpToGenAiToolAdapter]],
251
281
  ) -> list[types.Part]:
252
282
  """Returns the function response parts from the response."""
253
283
  func_response_parts = []
@@ -267,9 +297,10 @@ def get_function_response_parts(
267
297
  )
268
298
  func_response: dict[str, Any]
269
299
  try:
270
- func_response = {
271
- 'result': invoke_function_from_dict_args(args, func)
272
- }
300
+ if not isinstance(func, McpToGenAiToolAdapter):
301
+ func_response = {
302
+ 'result': invoke_function_from_dict_args(args, func)
303
+ }
273
304
  except Exception as e: # pylint: disable=broad-except
274
305
  func_response = {'error': str(e)}
275
306
  func_response_part = types.Part.from_function_response(
@@ -278,9 +309,10 @@ def get_function_response_parts(
278
309
  func_response_parts.append(func_response_part)
279
310
  return func_response_parts
280
311
 
312
+
281
313
  async def get_function_response_parts_async(
282
314
  response: types.GenerateContentResponse,
283
- function_map: dict[str, Callable[..., Any]],
315
+ function_map: dict[str, Union[Callable[..., Any], McpToGenAiToolAdapter]],
284
316
  ) -> list[types.Part]:
285
317
  """Returns the function response parts from the response."""
286
318
  func_response_parts = []
@@ -300,7 +332,15 @@ async def get_function_response_parts_async(
300
332
  )
301
333
  func_response: dict[str, Any]
302
334
  try:
303
- if inspect.iscoroutinefunction(func):
335
+ if isinstance(func, McpToGenAiToolAdapter):
336
+ mcp_tool_response = await func.call_tool(
337
+ types.FunctionCall(name=func_name, args=args)
338
+ )
339
+ if mcp_tool_response.isError:
340
+ func_response = {'error': mcp_tool_response}
341
+ else:
342
+ func_response = {'result': mcp_tool_response}
343
+ elif inspect.iscoroutinefunction(func):
304
344
  func_response = {
305
345
  'result': await invoke_function_from_dict_args_async(args, func)
306
346
  }
@@ -401,3 +441,68 @@ def should_append_afc_history(
401
441
  if not config_model.automatic_function_calling:
402
442
  return True
403
443
  return not config_model.automatic_function_calling.ignore_call_history
444
+
445
+
446
+ def parse_config_for_mcp_usage(
447
+ config: Optional[types.GenerateContentConfigOrDict] = None,
448
+ ) -> Optional[types.GenerateContentConfig]:
449
+ """Returns a parsed config with an appended MCP header if MCP tools or sessions are used."""
450
+ if not config:
451
+ return None
452
+ config_model = _create_generate_content_config_model(config)
453
+ # Create a copy of the config model with the tools field cleared since some
454
+ # tools may not be pickleable.
455
+ config_model_copy = config_model.model_copy(update={'tools': None})
456
+ config_model_copy.tools = config_model.tools
457
+ if config_model.tools and _mcp_utils.has_mcp_tool_usage(config_model.tools):
458
+ if config_model_copy.http_options is None:
459
+ config_model_copy.http_options = types.HttpOptions(headers={})
460
+ if config_model_copy.http_options.headers is None:
461
+ config_model_copy.http_options.headers = {}
462
+ _mcp_utils.set_mcp_usage_header(config_model_copy.http_options.headers)
463
+
464
+ return config_model_copy
465
+
466
+
467
+ async def parse_config_for_mcp_sessions(
468
+ config: Optional[types.GenerateContentConfigOrDict] = None,
469
+ ) -> tuple[
470
+ Optional[types.GenerateContentConfig],
471
+ dict[str, McpToGenAiToolAdapter],
472
+ ]:
473
+ """Returns a parsed config with MCP sessions converted to GenAI tools.
474
+
475
+ Also returns a map of MCP tools to GenAI tool adapters to be used for AFC.
476
+ """
477
+ mcp_to_genai_tool_adapters: dict[str, McpToGenAiToolAdapter] = {}
478
+ parsed_config = parse_config_for_mcp_usage(config)
479
+ if not parsed_config:
480
+ return None, mcp_to_genai_tool_adapters
481
+ # Create a copy of the config model with the tools field cleared as they will
482
+ # be replaced with the MCP tools converted to GenAI tools.
483
+ parsed_config_copy = parsed_config.model_copy(update={'tools': None})
484
+ if parsed_config.tools:
485
+ parsed_config_copy.tools = []
486
+ for tool in parsed_config.tools:
487
+ if McpClientSession is not None and isinstance(tool, McpClientSession):
488
+ mcp_to_genai_tool_adapter = McpToGenAiToolAdapter(
489
+ tool, await tool.list_tools()
490
+ )
491
+ # Extend the config with the MCP session tools converted to GenAI tools.
492
+ parsed_config_copy.tools.extend(mcp_to_genai_tool_adapter.tools)
493
+ for genai_tool in mcp_to_genai_tool_adapter.tools:
494
+ if genai_tool.function_declarations:
495
+ for function_declaration in genai_tool.function_declarations:
496
+ if function_declaration.name:
497
+ if mcp_to_genai_tool_adapters.get(function_declaration.name):
498
+ raise ValueError(
499
+ f'Tool {function_declaration.name} is already defined for'
500
+ ' the request.'
501
+ )
502
+ mcp_to_genai_tool_adapters[function_declaration.name] = (
503
+ mcp_to_genai_tool_adapter
504
+ )
505
+ else:
506
+ parsed_config_copy.tools.append(tool)
507
+
508
+ return parsed_config_copy, mcp_to_genai_tool_adapters