google-adk 1.0.0__py3-none-any.whl → 1.1.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 (90) hide show
  1. google/adk/agents/callback_context.py +2 -1
  2. google/adk/agents/readonly_context.py +3 -1
  3. google/adk/auth/auth_credential.py +4 -1
  4. google/adk/cli/browser/index.html +4 -4
  5. google/adk/cli/browser/{main-QOEMUXM4.js → main-PKDNKWJE.js} +59 -59
  6. google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
  7. google/adk/cli/cli.py +3 -2
  8. google/adk/cli/cli_eval.py +6 -85
  9. google/adk/cli/cli_tools_click.py +39 -10
  10. google/adk/cli/fast_api.py +53 -184
  11. google/adk/cli/utils/agent_loader.py +137 -0
  12. google/adk/cli/utils/cleanup.py +40 -0
  13. google/adk/cli/utils/evals.py +2 -1
  14. google/adk/cli/utils/logs.py +2 -7
  15. google/adk/code_executors/code_execution_utils.py +2 -1
  16. google/adk/code_executors/container_code_executor.py +0 -1
  17. google/adk/code_executors/vertex_ai_code_executor.py +6 -8
  18. google/adk/evaluation/eval_case.py +3 -1
  19. google/adk/evaluation/eval_metrics.py +74 -0
  20. google/adk/evaluation/eval_result.py +86 -0
  21. google/adk/evaluation/eval_set.py +2 -0
  22. google/adk/evaluation/eval_set_results_manager.py +47 -0
  23. google/adk/evaluation/eval_sets_manager.py +2 -1
  24. google/adk/evaluation/evaluator.py +2 -0
  25. google/adk/evaluation/local_eval_set_results_manager.py +113 -0
  26. google/adk/evaluation/local_eval_sets_manager.py +4 -4
  27. google/adk/evaluation/response_evaluator.py +2 -1
  28. google/adk/evaluation/trajectory_evaluator.py +3 -2
  29. google/adk/examples/base_example_provider.py +1 -0
  30. google/adk/flows/llm_flows/base_llm_flow.py +4 -6
  31. google/adk/flows/llm_flows/contents.py +3 -1
  32. google/adk/flows/llm_flows/instructions.py +7 -77
  33. google/adk/flows/llm_flows/single_flow.py +1 -1
  34. google/adk/models/base_llm.py +2 -1
  35. google/adk/models/base_llm_connection.py +2 -0
  36. google/adk/models/google_llm.py +4 -1
  37. google/adk/models/lite_llm.py +3 -2
  38. google/adk/models/llm_response.py +2 -1
  39. google/adk/runners.py +36 -4
  40. google/adk/sessions/_session_util.py +2 -1
  41. google/adk/sessions/database_session_service.py +5 -8
  42. google/adk/sessions/vertex_ai_session_service.py +28 -13
  43. google/adk/telemetry.py +4 -2
  44. google/adk/tools/agent_tool.py +1 -1
  45. google/adk/tools/apihub_tool/apihub_toolset.py +1 -1
  46. google/adk/tools/apihub_tool/clients/apihub_client.py +10 -3
  47. google/adk/tools/apihub_tool/clients/secret_client.py +1 -0
  48. google/adk/tools/application_integration_tool/application_integration_toolset.py +6 -2
  49. google/adk/tools/application_integration_tool/clients/connections_client.py +8 -1
  50. google/adk/tools/application_integration_tool/clients/integration_client.py +3 -1
  51. google/adk/tools/application_integration_tool/integration_connector_tool.py +1 -1
  52. google/adk/tools/base_toolset.py +40 -2
  53. google/adk/tools/bigquery/__init__.py +28 -0
  54. google/adk/tools/bigquery/bigquery_credentials.py +216 -0
  55. google/adk/tools/bigquery/bigquery_tool.py +116 -0
  56. google/adk/tools/function_parameter_parse_util.py +7 -0
  57. google/adk/tools/function_tool.py +33 -3
  58. google/adk/tools/get_user_choice_tool.py +1 -0
  59. google/adk/tools/google_api_tool/__init__.py +17 -11
  60. google/adk/tools/google_api_tool/google_api_tool.py +1 -1
  61. google/adk/tools/google_api_tool/google_api_toolset.py +0 -14
  62. google/adk/tools/google_api_tool/google_api_toolsets.py +8 -2
  63. google/adk/tools/google_search_tool.py +2 -2
  64. google/adk/tools/mcp_tool/conversion_utils.py +6 -2
  65. google/adk/tools/mcp_tool/mcp_session_manager.py +62 -188
  66. google/adk/tools/mcp_tool/mcp_tool.py +27 -24
  67. google/adk/tools/mcp_tool/mcp_toolset.py +76 -131
  68. google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +1 -3
  69. google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +6 -7
  70. google/adk/tools/openapi_tool/common/common.py +5 -1
  71. google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +7 -2
  72. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +2 -7
  73. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +5 -1
  74. google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +11 -1
  75. google/adk/tools/toolbox_toolset.py +31 -3
  76. google/adk/utils/__init__.py +13 -0
  77. google/adk/utils/instructions_utils.py +131 -0
  78. google/adk/version.py +1 -1
  79. {google_adk-1.0.0.dist-info → google_adk-1.1.0.dist-info}/METADATA +12 -15
  80. {google_adk-1.0.0.dist-info → google_adk-1.1.0.dist-info}/RECORD +83 -78
  81. google/adk/agents/base_agent.py.orig +0 -330
  82. google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -18
  83. google/adk/cli/fast_api.py.orig +0 -822
  84. google/adk/memory/base_memory_service.py.orig +0 -76
  85. google/adk/models/google_llm.py.orig +0 -305
  86. google/adk/tools/_built_in_code_execution_tool.py +0 -70
  87. google/adk/tools/mcp_tool/mcp_session_manager.py.orig +0 -322
  88. {google_adk-1.0.0.dist-info → google_adk-1.1.0.dist-info}/WHEEL +0 -0
  89. {google_adk-1.0.0.dist-info → google_adk-1.1.0.dist-info}/entry_points.txt +0 -0
  90. {google_adk-1.0.0.dist-info → google_adk-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,216 @@
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
+ from __future__ import annotations
16
+
17
+ from typing import List
18
+ from typing import Optional
19
+
20
+ from fastapi.openapi.models import OAuth2
21
+ from fastapi.openapi.models import OAuthFlowAuthorizationCode
22
+ from fastapi.openapi.models import OAuthFlows
23
+ from google.auth.exceptions import RefreshError
24
+ from google.auth.transport.requests import Request
25
+ from google.oauth2.credentials import Credentials
26
+ from pydantic import BaseModel
27
+ from pydantic import model_validator
28
+
29
+ from ...auth import AuthConfig
30
+ from ...auth import AuthCredential
31
+ from ...auth import AuthCredentialTypes
32
+ from ...auth import OAuth2Auth
33
+ from ..tool_context import ToolContext
34
+
35
+ BIGQUERY_TOKEN_CACHE_KEY = "bigquery_token_cache"
36
+
37
+
38
+ class BigQueryCredentialsConfig(BaseModel):
39
+ """Configuration for Google API tools. (Experimental)"""
40
+
41
+ # Configure the model to allow arbitrary types like Credentials
42
+ model_config = {"arbitrary_types_allowed": True}
43
+
44
+ credentials: Optional[Credentials] = None
45
+ """the existing oauth credentials to use. If set,this credential will be used
46
+ for every end user, end users don't need to be involved in the oauthflow. This
47
+ field is mutually exclusive with client_id, client_secret and scopes.
48
+ Don't set this field unless you are sure this credential has the permission to
49
+ access every end user's data.
50
+
51
+ Example usage: when the agent is deployed in Google Cloud environment and
52
+ the service account (used as application default credentials) has access to
53
+ all the required BigQuery resource. Setting this credential to allow user to
54
+ access the BigQuery resource without end users going through oauth flow.
55
+
56
+ To get application default credential: `google.auth.default(...)`. See more
57
+ details in https://cloud.google.com/docs/authentication/application-default-credentials.
58
+
59
+ When the deployed environment cannot provide a pre-existing credential,
60
+ consider setting below client_id, client_secret and scope for end users to go
61
+ through oauth flow, so that agent can access the user data.
62
+ """
63
+ client_id: Optional[str] = None
64
+ """the oauth client ID to use."""
65
+ client_secret: Optional[str] = None
66
+ """the oauth client secret to use."""
67
+ scopes: Optional[List[str]] = None
68
+ """the scopes to use.
69
+ """
70
+
71
+ @model_validator(mode="after")
72
+ def __post_init__(self) -> BigQueryCredentialsConfig:
73
+ """Validate that either credentials or client ID/secret are provided."""
74
+ if not self.credentials and (not self.client_id or not self.client_secret):
75
+ raise ValueError(
76
+ "Must provide either credentials or client_id abd client_secret pair."
77
+ )
78
+ if self.credentials and (
79
+ self.client_id or self.client_secret or self.scopes
80
+ ):
81
+ raise ValueError(
82
+ "Cannot provide both existing credentials and"
83
+ " client_id/client_secret/scopes."
84
+ )
85
+
86
+ if self.credentials:
87
+ self.client_id = self.credentials.client_id
88
+ self.client_secret = self.credentials.client_secret
89
+ self.scopes = self.credentials.scopes
90
+ return self
91
+
92
+
93
+ class BigQueryCredentialsManager:
94
+ """Manages Google API credentials with automatic refresh and OAuth flow handling.
95
+
96
+ This class centralizes credential management so multiple tools can share
97
+ the same authenticated session without duplicating OAuth logic.
98
+ """
99
+
100
+ def __init__(self, credentials_config: BigQueryCredentialsConfig):
101
+ """Initialize the credential manager.
102
+
103
+ Args:
104
+ credentials_config: Credentials containing client id and client secrete
105
+ or default credentials
106
+ """
107
+ self.credentials_config = credentials_config
108
+
109
+ async def get_valid_credentials(
110
+ self, tool_context: ToolContext
111
+ ) -> Optional[Credentials]:
112
+ """Get valid credentials, handling refresh and OAuth flow as needed.
113
+
114
+ Args:
115
+ tool_context: The tool context for OAuth flow and state management
116
+
117
+ Returns:
118
+ Valid Credentials object, or None if OAuth flow is needed
119
+ """
120
+ # First, try to get credentials from the tool context
121
+ creds_json = tool_context.state.get(BIGQUERY_TOKEN_CACHE_KEY, None)
122
+ creds = (
123
+ Credentials.from_authorized_user_info(
124
+ creds_json, self.credentials_config.scopes
125
+ )
126
+ if creds_json
127
+ else None
128
+ )
129
+
130
+ # If credentails are empty use the default credential
131
+ if not creds:
132
+ creds = self.credentials_config.credentials
133
+
134
+ # Check if we have valid credentials
135
+ if creds and creds.valid:
136
+ return creds
137
+
138
+ # Try to refresh expired credentials
139
+ if creds and creds.expired and creds.refresh_token:
140
+ try:
141
+ creds.refresh(Request())
142
+ if creds.valid:
143
+ # Cache the refreshed credentials
144
+ tool_context.state[BIGQUERY_TOKEN_CACHE_KEY] = creds.to_json()
145
+ return creds
146
+ except RefreshError:
147
+ # Refresh failed, need to re-authenticate
148
+ pass
149
+
150
+ # Need to perform OAuth flow
151
+ return await self._perform_oauth_flow(tool_context)
152
+
153
+ async def _perform_oauth_flow(
154
+ self, tool_context: ToolContext
155
+ ) -> Optional[Credentials]:
156
+ """Perform OAuth flow to get new credentials.
157
+
158
+ Args:
159
+ tool_context: The tool context for OAuth flow
160
+ required_scopes: Set of required OAuth scopes
161
+
162
+ Returns:
163
+ New Credentials object, or None if flow is in progress
164
+ """
165
+
166
+ # Create OAuth configuration
167
+ auth_scheme = OAuth2(
168
+ flows=OAuthFlows(
169
+ authorizationCode=OAuthFlowAuthorizationCode(
170
+ authorizationUrl="https://accounts.google.com/o/oauth2/auth",
171
+ tokenUrl="https://oauth2.googleapis.com/token",
172
+ scopes={
173
+ scope: f"Access to {scope}"
174
+ for scope in self.credentials_config.scopes
175
+ },
176
+ )
177
+ )
178
+ )
179
+
180
+ auth_credential = AuthCredential(
181
+ auth_type=AuthCredentialTypes.OAUTH2,
182
+ oauth2=OAuth2Auth(
183
+ client_id=self.credentials_config.client_id,
184
+ client_secret=self.credentials_config.client_secret,
185
+ ),
186
+ )
187
+
188
+ # Check if OAuth response is available
189
+ auth_response = tool_context.get_auth_response(
190
+ AuthConfig(auth_scheme=auth_scheme, raw_auth_credential=auth_credential)
191
+ )
192
+
193
+ if auth_response:
194
+ # OAuth flow completed, create credentials
195
+ creds = Credentials(
196
+ token=auth_response.oauth2.access_token,
197
+ refresh_token=auth_response.oauth2.refresh_token,
198
+ token_uri=auth_scheme.flows.authorizationCode.tokenUrl,
199
+ client_id=self.credentials_config.client_id,
200
+ client_secret=self.credentials_config.client_secret,
201
+ scopes=list(self.credentials_config.scopes),
202
+ )
203
+
204
+ # Cache the new credentials
205
+ tool_context.state[BIGQUERY_TOKEN_CACHE_KEY] = creds.to_json()
206
+
207
+ return creds
208
+ else:
209
+ # Request OAuth flow
210
+ tool_context.request_credential(
211
+ AuthConfig(
212
+ auth_scheme=auth_scheme,
213
+ raw_auth_credential=auth_credential,
214
+ )
215
+ )
216
+ return None
@@ -0,0 +1,116 @@
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 inspect
17
+ from typing import Any
18
+ from typing import Callable
19
+ from typing import Optional
20
+
21
+ from google.oauth2.credentials import Credentials
22
+ from typing_extensions import override
23
+
24
+ from ..function_tool import FunctionTool
25
+ from ..tool_context import ToolContext
26
+ from .bigquery_credentials import BigQueryCredentialsConfig
27
+ from .bigquery_credentials import BigQueryCredentialsManager
28
+
29
+
30
+ class BigQueryTool(FunctionTool):
31
+ """GoogleApiTool class for tools that call Google APIs.
32
+
33
+ This class is for developers to handcraft customized Google API tools rather
34
+ than auto generate Google API tools based on API specs.
35
+
36
+ This class handles all the OAuth complexity, credential management,
37
+ and common Google API patterns so subclasses can focus on their
38
+ specific functionality.
39
+ """
40
+
41
+ def __init__(
42
+ self,
43
+ func: Callable[..., Any],
44
+ credentials: Optional[BigQueryCredentialsConfig] = None,
45
+ ):
46
+ """Initialize the Google API tool.
47
+
48
+ Args:
49
+ func: callable that impelments the tool's logic, can accept one
50
+ 'credential" parameter
51
+ credentials: credentials used to call Google API. If None, then we don't
52
+ hanlde the auth logic
53
+ """
54
+ super().__init__(func=func)
55
+ self._ignore_params.append("credentials")
56
+ self.credentials_manager = (
57
+ BigQueryCredentialsManager(credentials) if credentials else None
58
+ )
59
+
60
+ @override
61
+ async def run_async(
62
+ self, *, args: dict[str, Any], tool_context: ToolContext
63
+ ) -> Any:
64
+ """Main entry point for tool execution with credential handling.
65
+
66
+ This method handles all the OAuth complexity and then delegates
67
+ to the subclass's run_async_with_credential method.
68
+ """
69
+ try:
70
+ # Get valid credentials
71
+ credentials = (
72
+ await self.credentials_manager.get_valid_credentials(tool_context)
73
+ if self.credentials_manager
74
+ else None
75
+ )
76
+
77
+ if credentials is None and self.credentials_manager:
78
+ # OAuth flow in progress
79
+ return (
80
+ "User authorization is required to access Google services for"
81
+ f" {self.name}. Please complete the authorization flow."
82
+ )
83
+
84
+ # Execute the tool's specific logic with valid credentials
85
+
86
+ return await self._run_async_with_credential(
87
+ credentials, args, tool_context
88
+ )
89
+
90
+ except Exception as ex:
91
+ return {
92
+ "status": "ERROR",
93
+ "error_details": str(ex),
94
+ }
95
+
96
+ async def _run_async_with_credential(
97
+ self,
98
+ credentials: Credentials,
99
+ args: dict[str, Any],
100
+ tool_context: ToolContext,
101
+ ) -> Any:
102
+ """Execute the tool's specific logic with valid credentials.
103
+
104
+ Args:
105
+ credentials: Valid Google OAuth credentials
106
+ args: Arguments passed to the tool
107
+ tool_context: Tool execution context
108
+
109
+ Returns:
110
+ The result of the tool execution
111
+ """
112
+ args_to_call = args.copy()
113
+ signature = inspect.signature(self.func)
114
+ if "credentials" in signature.parameters:
115
+ args_to_call["credentials"] = credentials
116
+ return await super().run_async(args=args_to_call, tool_context=tool_context)
@@ -289,6 +289,13 @@ def _parse_schema_from_parameter(
289
289
  )
290
290
  _raise_if_schema_unsupported(variant, schema)
291
291
  return schema
292
+ if param.annotation is None:
293
+ # https://swagger.io/docs/specification/v3_0/data-models/data-types/#null
294
+ # null is not a valid type in schema, use object instead.
295
+ schema.type = types.Type.OBJECT
296
+ schema.nullable = True
297
+ _raise_if_schema_unsupported(variant, schema)
298
+ return schema
292
299
  raise ValueError(
293
300
  f'Failed to parse the parameter {param} of function {func_name} for'
294
301
  ' automatic function calling. Automatic function calling works best with'
@@ -33,8 +33,31 @@ class FunctionTool(BaseTool):
33
33
  """
34
34
 
35
35
  def __init__(self, func: Callable[..., Any]):
36
- super().__init__(name=func.__name__, description=func.__doc__)
36
+ """Extract metadata from a callable object."""
37
+ name = ''
38
+ doc = ''
39
+ # Handle different types of callables
40
+ if hasattr(func, '__name__'):
41
+ # Regular functions, unbound methods, etc.
42
+ name = func.__name__
43
+ elif hasattr(func, '__class__'):
44
+ # Callable objects, bound methods, etc.
45
+ name = func.__class__.__name__
46
+
47
+ # Get documentation (prioritize direct __doc__ if available)
48
+ if hasattr(func, '__doc__') and func.__doc__:
49
+ doc = func.__doc__
50
+ elif (
51
+ hasattr(func, '__call__')
52
+ and hasattr(func.__call__, '__doc__')
53
+ and func.__call__.__doc__
54
+ ):
55
+ # For callable objects, try to get docstring from __call__ method
56
+ doc = func.__call__.__doc__
57
+
58
+ super().__init__(name=name, description=doc)
37
59
  self.func = func
60
+ self._ignore_params = ['tool_context', 'input_stream']
38
61
 
39
62
  @override
40
63
  def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
@@ -43,7 +66,7 @@ class FunctionTool(BaseTool):
43
66
  func=self.func,
44
67
  # The model doesn't understand the function context.
45
68
  # input_stream is for streaming tool
46
- ignore_params=['tool_context', 'input_stream'],
69
+ ignore_params=self._ignore_params,
47
70
  variant=self._api_variant,
48
71
  )
49
72
  )
@@ -76,7 +99,14 @@ class FunctionTool(BaseTool):
76
99
  You could retry calling this tool, but it is IMPORTANT for you to provide all the mandatory parameters."""
77
100
  return {'error': error_str}
78
101
 
79
- if inspect.iscoroutinefunction(self.func):
102
+ # Functions are callable objects, but not all callable objects are functions
103
+ # checking coroutine function is not enough. We also need to check whether
104
+ # Callable's __call__ function is a coroutine funciton
105
+ if (
106
+ inspect.iscoroutinefunction(self.func)
107
+ or hasattr(self.func, '__call__')
108
+ and inspect.iscoroutinefunction(self.func.__call__)
109
+ ):
80
110
  return await self.func(**args_to_call) or {}
81
111
  else:
82
112
  return self.func(**args_to_call) or {}
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  from typing import Optional
16
+
16
17
  from .long_running_tool import LongRunningFunctionTool
17
18
  from .tool_context import ToolContext
18
19
 
@@ -11,18 +11,12 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- __all__ = [
15
- 'BigQueryToolset',
16
- 'CalendarToolset',
17
- 'GmailToolset',
18
- 'YoutubeToolset',
19
- 'SlidesToolset',
20
- 'SheetsToolset',
21
- 'DocsToolset',
22
- 'GoogleApiToolset',
23
- 'GoogleApiTool',
24
- ]
25
14
 
15
+ """Auto-generated tools and toolsets for Google APIs.
16
+
17
+ These tools and toolsets are auto-generated based on the API specifications
18
+ provided by the Google API Discovery API.
19
+ """
26
20
 
27
21
  from .google_api_tool import GoogleApiTool
28
22
  from .google_api_toolset import GoogleApiToolset
@@ -33,3 +27,15 @@ from .google_api_toolsets import GmailToolset
33
27
  from .google_api_toolsets import SheetsToolset
34
28
  from .google_api_toolsets import SlidesToolset
35
29
  from .google_api_toolsets import YoutubeToolset
30
+
31
+ __all__ = [
32
+ 'BigQueryToolset',
33
+ 'CalendarToolset',
34
+ 'GmailToolset',
35
+ 'YoutubeToolset',
36
+ 'SlidesToolset',
37
+ 'SheetsToolset',
38
+ 'DocsToolset',
39
+ 'GoogleApiToolset',
40
+ 'GoogleApiTool',
41
+ ]
@@ -19,10 +19,10 @@ from typing import Optional
19
19
  from google.genai.types import FunctionDeclaration
20
20
  from typing_extensions import override
21
21
 
22
+ from .. import BaseTool
22
23
  from ...auth import AuthCredential
23
24
  from ...auth import AuthCredentialTypes
24
25
  from ...auth import OAuth2Auth
25
- from .. import BaseTool
26
26
  from ..openapi_tool import RestApiTool
27
27
  from ..tool_context import ToolContext
28
28
 
@@ -56,20 +56,6 @@ class GoogleApiToolset(BaseToolset):
56
56
  self._openapi_toolset = self._load_toolset_with_oidc_auth()
57
57
  self.tool_filter = tool_filter
58
58
 
59
- def _is_tool_selected(
60
- self, tool: GoogleApiTool, readonly_context: ReadonlyContext
61
- ) -> bool:
62
- if not self.tool_filter:
63
- return True
64
-
65
- if isinstance(self.tool_filter, ToolPredicate):
66
- return self.tool_filter(tool, readonly_context)
67
-
68
- if isinstance(self.tool_filter, list):
69
- return tool.name in self.tool_filter
70
-
71
- return False
72
-
73
59
  @override
74
60
  async def get_tools(
75
61
  self, readonly_context: Optional[ReadonlyContext] = None
@@ -18,14 +18,14 @@ from typing import List
18
18
  from typing import Optional
19
19
  from typing import Union
20
20
 
21
- from google.adk.tools.base_toolset import ToolPredicate
22
-
21
+ from ..base_toolset import ToolPredicate
23
22
  from .google_api_toolset import GoogleApiToolset
24
23
 
25
24
  logger = logging.getLogger("google_adk." + __name__)
26
25
 
27
26
 
28
27
  class BigQueryToolset(GoogleApiToolset):
28
+ """Auto-generated Bigquery toolset based on Google BigQuery API v2 spec exposed by Google API discovery API"""
29
29
 
30
30
  def __init__(
31
31
  self,
@@ -37,6 +37,7 @@ class BigQueryToolset(GoogleApiToolset):
37
37
 
38
38
 
39
39
  class CalendarToolset(GoogleApiToolset):
40
+ """Auto-generated Calendar toolset based on Google Calendar API v3 spec exposed by Google API discovery API"""
40
41
 
41
42
  def __init__(
42
43
  self,
@@ -48,6 +49,7 @@ class CalendarToolset(GoogleApiToolset):
48
49
 
49
50
 
50
51
  class GmailToolset(GoogleApiToolset):
52
+ """Auto-generated Gmail toolset based on Google Gmail API v1 spec exposed by Google API discovery API"""
51
53
 
52
54
  def __init__(
53
55
  self,
@@ -59,6 +61,7 @@ class GmailToolset(GoogleApiToolset):
59
61
 
60
62
 
61
63
  class YoutubeToolset(GoogleApiToolset):
64
+ """Auto-generated Youtube toolset based on Youtube API v3 spec exposed by Google API discovery API"""
62
65
 
63
66
  def __init__(
64
67
  self,
@@ -70,6 +73,7 @@ class YoutubeToolset(GoogleApiToolset):
70
73
 
71
74
 
72
75
  class SlidesToolset(GoogleApiToolset):
76
+ """Auto-generated Slides toolset based on Google Slides API v1 spec exposed by Google API discovery API"""
73
77
 
74
78
  def __init__(
75
79
  self,
@@ -81,6 +85,7 @@ class SlidesToolset(GoogleApiToolset):
81
85
 
82
86
 
83
87
  class SheetsToolset(GoogleApiToolset):
88
+ """Auto-generated Sheets toolset based on Google Sheets API v4 spec exposed by Google API discovery API"""
84
89
 
85
90
  def __init__(
86
91
  self,
@@ -92,6 +97,7 @@ class SheetsToolset(GoogleApiToolset):
92
97
 
93
98
 
94
99
  class DocsToolset(GoogleApiToolset):
100
+ """Auto-generated Docs toolset based on Google Docs API v1 spec exposed by Google API discovery API"""
95
101
 
96
102
  def __init__(
97
103
  self,
@@ -46,7 +46,7 @@ class GoogleSearchTool(BaseTool):
46
46
  ) -> None:
47
47
  llm_request.config = llm_request.config or types.GenerateContentConfig()
48
48
  llm_request.config.tools = llm_request.config.tools or []
49
- if llm_request.model and llm_request.model.startswith('gemini-1'):
49
+ if llm_request.model and 'gemini-1' in llm_request.model:
50
50
  if llm_request.config.tools:
51
51
  print(llm_request.config.tools)
52
52
  raise ValueError(
@@ -55,7 +55,7 @@ class GoogleSearchTool(BaseTool):
55
55
  llm_request.config.tools.append(
56
56
  types.Tool(google_search_retrieval=types.GoogleSearchRetrieval())
57
57
  )
58
- elif llm_request.model and llm_request.model.startswith('gemini-2'):
58
+ elif llm_request.model and 'gemini-2' in llm_request.model:
59
59
  llm_request.config.tools.append(
60
60
  types.Tool(google_search=types.GoogleSearch())
61
61
  )
@@ -12,9 +12,13 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- from typing import Any, Dict
16
- from google.genai.types import Schema, Type
15
+ from typing import Any
16
+ from typing import Dict
17
+
18
+ from google.genai.types import Schema
19
+ from google.genai.types import Type
17
20
  import mcp.types as mcp_types
21
+
18
22
  from ..base_tool import BaseTool
19
23
 
20
24