google-adk 1.6.1__py3-none-any.whl → 1.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. google/adk/a2a/converters/event_converter.py +5 -85
  2. google/adk/a2a/executor/a2a_agent_executor.py +45 -16
  3. google/adk/agents/__init__.py +5 -0
  4. google/adk/agents/agent_config.py +46 -0
  5. google/adk/agents/base_agent.py +234 -41
  6. google/adk/agents/callback_context.py +41 -0
  7. google/adk/agents/common_configs.py +79 -0
  8. google/adk/agents/config_agent_utils.py +184 -0
  9. google/adk/agents/config_schemas/AgentConfig.json +544 -0
  10. google/adk/agents/invocation_context.py +5 -1
  11. google/adk/agents/llm_agent.py +190 -9
  12. google/adk/agents/loop_agent.py +29 -0
  13. google/adk/agents/parallel_agent.py +24 -3
  14. google/adk/agents/remote_a2a_agent.py +15 -3
  15. google/adk/agents/sequential_agent.py +22 -1
  16. google/adk/artifacts/gcs_artifact_service.py +24 -2
  17. google/adk/auth/auth_handler.py +3 -3
  18. google/adk/auth/credential_manager.py +23 -23
  19. google/adk/auth/credential_service/base_credential_service.py +6 -6
  20. google/adk/auth/credential_service/in_memory_credential_service.py +10 -8
  21. google/adk/auth/credential_service/session_state_credential_service.py +8 -8
  22. google/adk/auth/exchanger/oauth2_credential_exchanger.py +3 -3
  23. google/adk/auth/oauth2_credential_util.py +2 -2
  24. google/adk/auth/refresher/oauth2_credential_refresher.py +4 -4
  25. google/adk/cli/agent_graph.py +3 -1
  26. google/adk/cli/browser/index.html +1 -1
  27. google/adk/cli/browser/main-SRBSE46V.js +3914 -0
  28. google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
  29. google/adk/cli/fast_api.py +42 -2
  30. google/adk/cli/utils/agent_loader.py +35 -1
  31. google/adk/code_executors/base_code_executor.py +14 -19
  32. google/adk/code_executors/built_in_code_executor.py +4 -1
  33. google/adk/evaluation/base_eval_service.py +46 -2
  34. google/adk/evaluation/evaluation_generator.py +1 -1
  35. google/adk/evaluation/in_memory_eval_sets_manager.py +151 -0
  36. google/adk/evaluation/local_eval_service.py +389 -0
  37. google/adk/evaluation/local_eval_sets_manager.py +23 -8
  38. google/adk/flows/llm_flows/auto_flow.py +6 -11
  39. google/adk/flows/llm_flows/base_llm_flow.py +41 -23
  40. google/adk/flows/llm_flows/contents.py +16 -10
  41. google/adk/flows/llm_flows/functions.py +76 -33
  42. google/adk/memory/in_memory_memory_service.py +20 -14
  43. google/adk/models/anthropic_llm.py +44 -5
  44. google/adk/models/google_llm.py +11 -6
  45. google/adk/models/lite_llm.py +21 -4
  46. google/adk/plugins/__init__.py +17 -0
  47. google/adk/plugins/base_plugin.py +317 -0
  48. google/adk/plugins/plugin_manager.py +265 -0
  49. google/adk/runners.py +122 -18
  50. google/adk/sessions/database_session_service.py +26 -28
  51. google/adk/sessions/vertex_ai_session_service.py +14 -7
  52. google/adk/tools/agent_tool.py +1 -0
  53. google/adk/tools/apihub_tool/apihub_toolset.py +38 -39
  54. google/adk/tools/application_integration_tool/application_integration_toolset.py +35 -37
  55. google/adk/tools/application_integration_tool/integration_connector_tool.py +2 -3
  56. google/adk/tools/base_tool.py +9 -9
  57. google/adk/tools/base_toolset.py +7 -5
  58. google/adk/tools/bigquery/__init__.py +3 -3
  59. google/adk/tools/enterprise_search_tool.py +4 -2
  60. google/adk/tools/google_api_tool/google_api_tool.py +16 -1
  61. google/adk/tools/google_api_tool/google_api_toolset.py +9 -7
  62. google/adk/tools/google_api_tool/google_api_toolsets.py +41 -20
  63. google/adk/tools/google_search_tool.py +4 -2
  64. google/adk/tools/langchain_tool.py +2 -3
  65. google/adk/tools/long_running_tool.py +21 -0
  66. google/adk/tools/mcp_tool/mcp_toolset.py +27 -28
  67. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +8 -8
  68. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +4 -6
  69. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +3 -2
  70. google/adk/tools/tool_context.py +0 -10
  71. google/adk/tools/url_context_tool.py +4 -2
  72. google/adk/tools/vertex_ai_search_tool.py +4 -2
  73. google/adk/utils/model_name_utils.py +90 -0
  74. google/adk/version.py +1 -1
  75. {google_adk-1.6.1.dist-info → google_adk-1.7.0.dist-info}/METADATA +2 -2
  76. {google_adk-1.6.1.dist-info → google_adk-1.7.0.dist-info}/RECORD +79 -69
  77. google/adk/cli/browser/main-RXDVX3K6.js +0 -3914
  78. google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -17
  79. {google_adk-1.6.1.dist-info → google_adk-1.7.0.dist-info}/WHEEL +0 -0
  80. {google_adk-1.6.1.dist-info → google_adk-1.7.0.dist-info}/entry_points.txt +0 -0
  81. {google_adk-1.6.1.dist-info → google_adk-1.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import logging
16
18
  from typing import List
17
19
  from typing import Optional
@@ -42,43 +44,39 @@ logger = logging.getLogger("google_adk." + __name__)
42
44
  # TODO(cheliu): Apply a common toolset interface
43
45
  class ApplicationIntegrationToolset(BaseToolset):
44
46
  """ApplicationIntegrationToolset generates tools from a given Application
45
-
46
47
  Integration or Integration Connector resource.
47
- Example Usage:
48
- ```
49
- # Get all available tools for an integration with api trigger
50
- application_integration_toolset = ApplicationIntegrationToolset(
51
48
 
52
- project="test-project",
53
- location="us-central1"
54
- integration="test-integration",
55
- triggers=["api_trigger/test_trigger"],
56
- service_account_credentials={...},
57
- )
49
+ Example Usage::
58
50
 
59
- # Get all available tools for a connection using entity operations and
60
- # actions
61
- # Note: Find the list of supported entity operations and actions for a
62
- connection
63
- # using integration connector apis:
64
- #
65
- https://cloud.google.com/integration-connectors/docs/reference/rest/v1/projects.locations.connections.connectionSchemaMetadata
66
- application_integration_toolset = ApplicationIntegrationToolset(
67
- project="test-project",
68
- location="us-central1"
69
- connection="test-connection",
70
- entity_operations=["EntityId1": ["LIST","CREATE"], "EntityId2": []],
71
- #empty list for actions means all operations on the entity are supported
72
- actions=["action1"],
73
- service_account_credentials={...},
74
- )
51
+ # Get all available tools for an integration with api trigger
52
+ application_integration_toolset = ApplicationIntegrationToolset(
53
+ project="test-project",
54
+ location="us-central1"
55
+ integration="test-integration",
56
+ triggers=["api_trigger/test_trigger"],
57
+ service_account_credentials={...},
58
+ )
59
+
60
+ # Get all available tools for a connection using entity operations and
61
+ # actions
62
+ # Note: Find the list of supported entity operations and actions for a
63
+ # connection using integration connector apis:
64
+ # https://cloud.google.com/integration-connectors/docs/reference/rest/v1/projects.locations.connections.connectionSchemaMetadata
65
+ application_integration_toolset = ApplicationIntegrationToolset(
66
+ project="test-project",
67
+ location="us-central1"
68
+ connection="test-connection",
69
+ entity_operations=["EntityId1": ["LIST","CREATE"], "EntityId2": []],
70
+ #empty list for actions means all operations on the entity are supported
71
+ actions=["action1"],
72
+ service_account_credentials={...},
73
+ )
75
74
 
76
- # Feed the toolset to agent
77
- agent = LlmAgent(tools=[
78
- ...,
79
- application_integration_toolset,
80
- ])
81
- ```
75
+ # Feed the toolset to agent
76
+ agent = LlmAgent(tools=[
77
+ ...,
78
+ application_integration_toolset,
79
+ ])
82
80
  """
83
81
 
84
82
  def __init__(
@@ -122,11 +120,11 @@ class ApplicationIntegrationToolset(BaseToolset):
122
120
 
123
121
  Raises:
124
122
  ValueError: If none of the following conditions are met:
125
- - `integration` is provided.
126
- - `connection` is provided and at least one of `entity_operations`
127
- or `actions` is provided.
123
+ - ``integration`` is provided.
124
+ - ``connection`` is provided and at least one of ``entity_operations``
125
+ or ``actions`` is provided.
128
126
  Exception: If there is an error during the initialization of the
129
- integration or connection client.
127
+ integration or connection client.
130
128
  """
131
129
  super().__init__(tool_filter=tool_filter)
132
130
  self.project = project
@@ -45,13 +45,12 @@ class IntegrationConnectorTool(BaseTool):
45
45
  * Generates request params and body
46
46
  * Attaches auth credentials to API call.
47
47
 
48
- Example:
49
- ```
48
+ Example::
49
+
50
50
  # Each API operation in the spec will be turned into its own tool
51
51
  # Name of the tool is the operationId of that operation, in snake case
52
52
  operations = OperationGenerator().parse(openapi_spec_dict)
53
53
  tool = [RestApiTool.from_parsed_operation(o) for o in operations]
54
- ```
55
54
  """
56
55
 
57
56
  EXCLUDE_FIELDS = [
@@ -49,11 +49,11 @@ class BaseTool(ABC):
49
49
  def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
50
50
  """Gets the OpenAPI specification of this tool in the form of a FunctionDeclaration.
51
51
 
52
- NOTE
53
- - Required if subclass uses the default implementation of
54
- `process_llm_request` to add function declaration to LLM request.
55
- - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
56
- Gemini.
52
+ NOTE:
53
+ - Required if subclass uses the default implementation of
54
+ `process_llm_request` to add function declaration to LLM request.
55
+ - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
56
+ Gemini.
57
57
 
58
58
  Returns:
59
59
  The FunctionDeclaration of this tool, or None if it doesn't need to be
@@ -66,10 +66,10 @@ class BaseTool(ABC):
66
66
  ) -> Any:
67
67
  """Runs the tool with the given arguments and context.
68
68
 
69
- NOTE
70
- - Required if this tool needs to run at the client side.
71
- - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
72
- Gemini.
69
+ NOTE:
70
+ - Required if this tool needs to run at the client side.
71
+ - Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
72
+ Gemini.
73
73
 
74
74
  Args:
75
75
  args: The LLM-filled arguments.
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
15
16
 
16
17
  from abc import ABC
17
18
  from abc import abstractmethod
@@ -64,7 +65,7 @@ class BaseToolset(ABC):
64
65
  """Return all tools in the toolset based on the provided context.
65
66
 
66
67
  Args:
67
- readony_context (ReadonlyContext, optional): Context used to filter tools
68
+ readonly_context (ReadonlyContext, optional): Context used to filter tools
68
69
  available to the agent. If None, all tools in the toolset are returned.
69
70
 
70
71
  Returns:
@@ -75,10 +76,11 @@ class BaseToolset(ABC):
75
76
  async def close(self) -> None:
76
77
  """Performs cleanup and releases resources held by the toolset.
77
78
 
78
- NOTE: This method is invoked, for example, at the end of an agent server's
79
- lifecycle or when the toolset is no longer needed. Implementations
80
- should ensure that any open connections, files, or other managed
81
- resources are properly released to prevent leaks.
79
+ NOTE:
80
+ This method is invoked, for example, at the end of an agent server's
81
+ lifecycle or when the toolset is no longer needed. Implementations
82
+ should ensure that any open connections, files, or other managed
83
+ resources are properly released to prevent leaks.
82
84
  """
83
85
 
84
86
  def _is_tool_selected(
@@ -20,11 +20,11 @@ definition. The rationales to have customized tool are:
20
20
 
21
21
  1. BigQuery APIs have functions overlaps and LLM can't tell what tool to use
22
22
  2. BigQuery APIs have a lot of parameters with some rarely used, which are not
23
- LLM-friendly
23
+ LLM-friendly
24
24
  3. We want to provide more high-level tools like forecasting, RAG, segmentation,
25
- etc.
25
+ etc.
26
26
  4. We want to provide extra access guardrails in those tools. For example,
27
- execute_sql can't arbitrarily mutate existing data.
27
+ execute_sql can't arbitrarily mutate existing data.
28
28
  """
29
29
 
30
30
  from .bigquery_credentials import BigQueryCredentialsConfig
@@ -19,6 +19,8 @@ from typing import TYPE_CHECKING
19
19
  from google.genai import types
20
20
  from typing_extensions import override
21
21
 
22
+ from ..utils.model_name_utils import is_gemini_1_model
23
+ from ..utils.model_name_utils import is_gemini_model
22
24
  from .base_tool import BaseTool
23
25
  from .tool_context import ToolContext
24
26
 
@@ -47,8 +49,8 @@ class EnterpriseWebSearchTool(BaseTool):
47
49
  tool_context: ToolContext,
48
50
  llm_request: LlmRequest,
49
51
  ) -> None:
50
- if llm_request.model and 'gemini-' in llm_request.model:
51
- if 'gemini-1' in llm_request.model and llm_request.config.tools:
52
+ if is_gemini_model(llm_request.model):
53
+ if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
52
54
  raise ValueError(
53
55
  'Enterprise web search tool can not be used with other tools in'
54
56
  ' Gemini 1.x.'
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import Any
16
18
  from typing import Dict
17
19
  from typing import Optional
@@ -23,7 +25,9 @@ from .. import BaseTool
23
25
  from ...auth import AuthCredential
24
26
  from ...auth import AuthCredentialTypes
25
27
  from ...auth import OAuth2Auth
28
+ from ...auth.auth_credential import ServiceAccount
26
29
  from ..openapi_tool import RestApiTool
30
+ from ..openapi_tool.auth.auth_helpers import service_account_scheme_credential
27
31
  from ..tool_context import ToolContext
28
32
 
29
33
 
@@ -34,6 +38,7 @@ class GoogleApiTool(BaseTool):
34
38
  rest_api_tool: RestApiTool,
35
39
  client_id: Optional[str] = None,
36
40
  client_secret: Optional[str] = None,
41
+ service_account: Optional[ServiceAccount] = None,
37
42
  ):
38
43
  super().__init__(
39
44
  name=rest_api_tool.name,
@@ -41,7 +46,10 @@ class GoogleApiTool(BaseTool):
41
46
  is_long_running=rest_api_tool.is_long_running,
42
47
  )
43
48
  self._rest_api_tool = rest_api_tool
44
- self.configure_auth(client_id, client_secret)
49
+ if service_account is not None:
50
+ self.configure_sa_auth(service_account)
51
+ else:
52
+ self.configure_auth(client_id, client_secret)
45
53
 
46
54
  @override
47
55
  def _get_declaration(self) -> FunctionDeclaration:
@@ -63,3 +71,10 @@ class GoogleApiTool(BaseTool):
63
71
  client_secret=client_secret,
64
72
  ),
65
73
  )
74
+
75
+ def configure_sa_auth(self, service_account: ServiceAccount):
76
+ auth_scheme, auth_credential = service_account_scheme_credential(
77
+ service_account
78
+ )
79
+ self._rest_api_tool.auth_scheme = auth_scheme
80
+ self._rest_api_tool.auth_credential = auth_credential
@@ -14,18 +14,15 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- import inspect
18
- import os
19
- from typing import Any
20
17
  from typing import List
21
18
  from typing import Optional
22
- from typing import Type
23
19
  from typing import Union
24
20
 
25
21
  from typing_extensions import override
26
22
 
27
23
  from ...agents.readonly_context import ReadonlyContext
28
24
  from ...auth import OpenIdConnectWithConfig
25
+ from ...auth.auth_credential import ServiceAccount
29
26
  from ...tools.base_toolset import BaseToolset
30
27
  from ...tools.base_toolset import ToolPredicate
31
28
  from ..openapi_tool import OpenAPIToolset
@@ -48,11 +45,13 @@ class GoogleApiToolset(BaseToolset):
48
45
  client_id: Optional[str] = None,
49
46
  client_secret: Optional[str] = None,
50
47
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
48
+ service_account: Optional[ServiceAccount] = None,
51
49
  ):
52
50
  self.api_name = api_name
53
51
  self.api_version = api_version
54
52
  self._client_id = client_id
55
53
  self._client_secret = client_secret
54
+ self._service_account = service_account
56
55
  self._openapi_toolset = self._load_toolset_with_oidc_auth()
57
56
  self.tool_filter = tool_filter
58
57
 
@@ -61,10 +60,10 @@ class GoogleApiToolset(BaseToolset):
61
60
  self, readonly_context: Optional[ReadonlyContext] = None
62
61
  ) -> List[GoogleApiTool]:
63
62
  """Get all tools in the toolset."""
64
- tools = []
65
-
66
63
  return [
67
- GoogleApiTool(tool, self._client_id, self._client_secret)
64
+ GoogleApiTool(
65
+ tool, self._client_id, self._client_secret, self._service_account
66
+ )
68
67
  for tool in await self._openapi_toolset.get_tools(readonly_context)
69
68
  if self._is_tool_selected(tool, readonly_context)
70
69
  ]
@@ -106,6 +105,9 @@ class GoogleApiToolset(BaseToolset):
106
105
  self._client_id = client_id
107
106
  self._client_secret = client_secret
108
107
 
108
+ def configure_sa_auth(self, service_account: ServiceAccount):
109
+ self._service_account = service_account
110
+
109
111
  @override
110
112
  async def close(self):
111
113
  if self._openapi_toolset:
@@ -12,12 +12,14 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
15
16
 
16
17
  import logging
17
18
  from typing import List
18
19
  from typing import Optional
19
20
  from typing import Union
20
21
 
22
+ from ...auth.auth_credential import ServiceAccount
21
23
  from ..base_toolset import ToolPredicate
22
24
  from .google_api_toolset import GoogleApiToolset
23
25
 
@@ -29,11 +31,14 @@ class BigQueryToolset(GoogleApiToolset):
29
31
 
30
32
  def __init__(
31
33
  self,
32
- client_id: str = None,
33
- client_secret: str = None,
34
+ client_id: Optional[str] = None,
35
+ client_secret: Optional[str] = None,
34
36
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
37
+ service_account: Optional[ServiceAccount] = None,
35
38
  ):
36
- super().__init__("bigquery", "v2", client_id, client_secret, tool_filter)
39
+ super().__init__(
40
+ "bigquery", "v2", client_id, client_secret, tool_filter, service_account
41
+ )
37
42
 
38
43
 
39
44
  class CalendarToolset(GoogleApiToolset):
@@ -41,11 +46,14 @@ class CalendarToolset(GoogleApiToolset):
41
46
 
42
47
  def __init__(
43
48
  self,
44
- client_id: str = None,
45
- client_secret: str = None,
49
+ client_id: Optional[str] = None,
50
+ client_secret: Optional[str] = None,
46
51
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
52
+ service_account: Optional[ServiceAccount] = None,
47
53
  ):
48
- super().__init__("calendar", "v3", client_id, client_secret, tool_filter)
54
+ super().__init__(
55
+ "calendar", "v3", client_id, client_secret, tool_filter, service_account
56
+ )
49
57
 
50
58
 
51
59
  class GmailToolset(GoogleApiToolset):
@@ -53,11 +61,14 @@ class GmailToolset(GoogleApiToolset):
53
61
 
54
62
  def __init__(
55
63
  self,
56
- client_id: str = None,
57
- client_secret: str = None,
64
+ client_id: Optional[str] = None,
65
+ client_secret: Optional[str] = None,
58
66
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
67
+ service_account: Optional[ServiceAccount] = None,
59
68
  ):
60
- super().__init__("gmail", "v1", client_id, client_secret, tool_filter)
69
+ super().__init__(
70
+ "gmail", "v1", client_id, client_secret, tool_filter, service_account
71
+ )
61
72
 
62
73
 
63
74
  class YoutubeToolset(GoogleApiToolset):
@@ -65,11 +76,14 @@ class YoutubeToolset(GoogleApiToolset):
65
76
 
66
77
  def __init__(
67
78
  self,
68
- client_id: str = None,
69
- client_secret: str = None,
79
+ client_id: Optional[str] = None,
80
+ client_secret: Optional[str] = None,
70
81
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
82
+ service_account: Optional[ServiceAccount] = None,
71
83
  ):
72
- super().__init__("youtube", "v3", client_id, client_secret, tool_filter)
84
+ super().__init__(
85
+ "youtube", "v3", client_id, client_secret, tool_filter, service_account
86
+ )
73
87
 
74
88
 
75
89
  class SlidesToolset(GoogleApiToolset):
@@ -77,11 +91,14 @@ class SlidesToolset(GoogleApiToolset):
77
91
 
78
92
  def __init__(
79
93
  self,
80
- client_id: str = None,
81
- client_secret: str = None,
94
+ client_id: Optional[str] = None,
95
+ client_secret: Optional[str] = None,
82
96
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
97
+ service_account: Optional[ServiceAccount] = None,
83
98
  ):
84
- super().__init__("slides", "v1", client_id, client_secret, tool_filter)
99
+ super().__init__(
100
+ "slides", "v1", client_id, client_secret, tool_filter, service_account
101
+ )
85
102
 
86
103
 
87
104
  class SheetsToolset(GoogleApiToolset):
@@ -89,9 +106,10 @@ class SheetsToolset(GoogleApiToolset):
89
106
 
90
107
  def __init__(
91
108
  self,
92
- client_id: str = None,
93
- client_secret: str = None,
109
+ client_id: Optional[str] = None,
110
+ client_secret: Optional[str] = None,
94
111
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
112
+ service_account: Optional[ServiceAccount] = None,
95
113
  ):
96
114
  super().__init__("sheets", "v4", client_id, client_secret, tool_filter)
97
115
 
@@ -101,8 +119,11 @@ class DocsToolset(GoogleApiToolset):
101
119
 
102
120
  def __init__(
103
121
  self,
104
- client_id: str = None,
105
- client_secret: str = None,
122
+ client_id: Optional[str] = None,
123
+ client_secret: Optional[str] = None,
106
124
  tool_filter: Optional[Union[ToolPredicate, List[str]]] = None,
125
+ service_account: Optional[ServiceAccount] = None,
107
126
  ):
108
- super().__init__("docs", "v1", client_id, client_secret, tool_filter)
127
+ super().__init__(
128
+ "docs", "v1", client_id, client_secret, tool_filter, service_account
129
+ )
@@ -19,6 +19,8 @@ from typing import TYPE_CHECKING
19
19
  from google.genai import types
20
20
  from typing_extensions import override
21
21
 
22
+ from ..utils.model_name_utils import is_gemini_1_model
23
+ from ..utils.model_name_utils import is_gemini_model
22
24
  from .base_tool import BaseTool
23
25
  from .tool_context import ToolContext
24
26
 
@@ -46,7 +48,7 @@ class GoogleSearchTool(BaseTool):
46
48
  ) -> None:
47
49
  llm_request.config = llm_request.config or types.GenerateContentConfig()
48
50
  llm_request.config.tools = llm_request.config.tools or []
49
- if llm_request.model and 'gemini-1' in llm_request.model:
51
+ if is_gemini_1_model(llm_request.model):
50
52
  if llm_request.config.tools:
51
53
  raise ValueError(
52
54
  'Google search tool can not be used with other tools in Gemini 1.x.'
@@ -54,7 +56,7 @@ class GoogleSearchTool(BaseTool):
54
56
  llm_request.config.tools.append(
55
57
  types.Tool(google_search_retrieval=types.GoogleSearchRetrieval())
56
58
  )
57
- elif llm_request.model and 'gemini-' in llm_request.model:
59
+ elif is_gemini_model(llm_request.model):
58
60
  llm_request.config.tools.append(
59
61
  types.Tool(google_search=types.GoogleSearch())
60
62
  )
@@ -41,14 +41,13 @@ class LangchainTool(FunctionTool):
41
41
  name: Optional override for the tool's name
42
42
  description: Optional override for the tool's description
43
43
 
44
- Examples:
45
- ```python
44
+ Examples::
45
+
46
46
  from langchain.tools import DuckDuckGoSearchTool
47
47
  from google.genai.tools import LangchainTool
48
48
 
49
49
  search_tool = DuckDuckGoSearchTool()
50
50
  wrapped_tool = LangchainTool(search_tool)
51
- ```
52
51
  """
53
52
 
54
53
  _langchain_tool: Union[BaseTool, object]
@@ -12,7 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  from typing import Callable
18
+ from typing import Optional
19
+
20
+ from google.genai import types
21
+ from typing_extensions import override
16
22
 
17
23
  from .function_tool import FunctionTool
18
24
 
@@ -37,3 +43,18 @@ class LongRunningFunctionTool(FunctionTool):
37
43
  def __init__(self, func: Callable):
38
44
  super().__init__(func)
39
45
  self.is_long_running = True
46
+
47
+ @override
48
+ def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
49
+ declaration = super()._get_declaration()
50
+ if declaration:
51
+ instruction = (
52
+ "\n\nNOTE: This is a long-running operation. Do not call this tool"
53
+ " again if it has already returned some intermediate or pending"
54
+ " status."
55
+ )
56
+ if declaration.description:
57
+ declaration.description += instruction
58
+ else:
59
+ declaration.description = instruction.lstrip()
60
+ return declaration
@@ -61,28 +61,27 @@ class MCPToolset(BaseToolset):
61
61
  that can be used by an agent. It properly implements the BaseToolset
62
62
  interface for easy integration with the agent framework.
63
63
 
64
- Usage:
65
- ```python
66
- toolset = MCPToolset(
67
- connection_params=StdioServerParameters(
68
- command='npx',
69
- args=["-y", "@modelcontextprotocol/server-filesystem"],
70
- ),
71
- tool_filter=['read_file', 'list_directory'] # Optional: filter specific tools
72
- )
73
-
74
- # Use in an agent
75
- agent = LlmAgent(
76
- model='gemini-2.0-flash',
77
- name='enterprise_assistant',
78
- instruction='Help user accessing their file systems',
79
- tools=[toolset],
80
- )
81
-
82
- # Cleanup is handled automatically by the agent framework
83
- # But you can also manually close if needed:
84
- # await toolset.close()
85
- ```
64
+ Usage::
65
+
66
+ toolset = MCPToolset(
67
+ connection_params=StdioServerParameters(
68
+ command='npx',
69
+ args=["-y", "@modelcontextprotocol/server-filesystem"],
70
+ ),
71
+ tool_filter=['read_file', 'list_directory'] # Optional: filter specific tools
72
+ )
73
+
74
+ # Use in an agent
75
+ agent = LlmAgent(
76
+ model='gemini-2.0-flash',
77
+ name='enterprise_assistant',
78
+ instruction='Help user accessing their file systems',
79
+ tools=[toolset],
80
+ )
81
+
82
+ # Cleanup is handled automatically by the agent framework
83
+ # But you can also manually close if needed:
84
+ # await toolset.close()
86
85
  """
87
86
 
88
87
  def __init__(
@@ -103,12 +102,12 @@ class MCPToolset(BaseToolset):
103
102
 
104
103
  Args:
105
104
  connection_params: The connection parameters to the MCP server. Can be:
106
- `StdioConnectionParams` for using local mcp server (e.g. using `npx` or
107
- `python3`); or `SseConnectionParams` for a local/remote SSE server; or
108
- `StreamableHTTPConnectionParams` for local/remote Streamable http
109
- server. Note, `StdioServerParameters` is also supported for using local
110
- mcp server (e.g. using `npx` or `python3` ), but it does not support
111
- timeout, and we recommend to use `StdioConnectionParams` instead when
105
+ ``StdioConnectionParams`` for using local mcp server (e.g. using ``npx`` or
106
+ ``python3``); or ``SseConnectionParams`` for a local/remote SSE server; or
107
+ ``StreamableHTTPConnectionParams`` for local/remote Streamable http
108
+ server. Note, ``StdioServerParameters`` is also supported for using local
109
+ mcp server (e.g. using ``npx`` or ``python3`` ), but it does not support
110
+ timeout, and we recommend to use ``StdioConnectionParams`` instead when
112
111
  timeout is needed.
113
112
  tool_filter: Optional filter to select specific tools. Can be either: - A
114
113
  list of tool names to include - A ToolPredicate function for custom
@@ -12,6 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ from __future__ import annotations
16
+
15
17
  import json
16
18
  import logging
17
19
  from typing import Any
@@ -39,8 +41,8 @@ logger = logging.getLogger("google_adk." + __name__)
39
41
  class OpenAPIToolset(BaseToolset):
40
42
  """Class for parsing OpenAPI spec into a list of RestApiTool.
41
43
 
42
- Usage:
43
- ```
44
+ Usage::
45
+
44
46
  # Initialize OpenAPI toolset from a spec string.
45
47
  openapi_toolset = OpenAPIToolset(spec_str=openapi_spec_str,
46
48
  spec_str_type="json")
@@ -55,7 +57,6 @@ class OpenAPIToolset(BaseToolset):
55
57
  agent = Agent(
56
58
  tools=[openapi_toolset.get_tool('tool_name')]
57
59
  )
58
- ```
59
60
  """
60
61
 
61
62
  def __init__(
@@ -70,8 +71,8 @@ class OpenAPIToolset(BaseToolset):
70
71
  ):
71
72
  """Initializes the OpenAPIToolset.
72
73
 
73
- Usage:
74
- ```
74
+ Usage::
75
+
75
76
  # Initialize OpenAPI toolset from a spec string.
76
77
  openapi_toolset = OpenAPIToolset(spec_str=openapi_spec_str,
77
78
  spec_str_type="json")
@@ -86,7 +87,6 @@ class OpenAPIToolset(BaseToolset):
86
87
  agent = Agent(
87
88
  tools=[openapi_toolset.get_tool('tool_name')]
88
89
  )
89
- ```
90
90
 
91
91
  Args:
92
92
  spec_dict: The OpenAPI spec dictionary. If provided, it will be used
@@ -96,10 +96,10 @@ class OpenAPIToolset(BaseToolset):
96
96
  spec_str_type: The type of the OpenAPI spec string. Can be "json" or
97
97
  "yaml".
98
98
  auth_scheme: The auth scheme to use for all tools. Use AuthScheme or use
99
- helpers in `google.adk.tools.openapi_tool.auth.auth_helpers`
99
+ helpers in ``google.adk.tools.openapi_tool.auth.auth_helpers``
100
100
  auth_credential: The auth credential to use for all tools. Use
101
101
  AuthCredential or use helpers in
102
- `google.adk.tools.openapi_tool.auth.auth_helpers`
102
+ ``google.adk.tools.openapi_tool.auth.auth_helpers``
103
103
  tool_filter: The filter used to filter the tools in the toolset. It can be
104
104
  either a tool predicate or a list of tool names of the tools to expose.
105
105
  """