google-adk 1.6.1__py3-none-any.whl → 1.8.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/adk/a2a/converters/event_converter.py +5 -85
- google/adk/a2a/converters/request_converter.py +1 -2
- google/adk/a2a/executor/a2a_agent_executor.py +45 -16
- google/adk/a2a/logs/log_utils.py +1 -2
- google/adk/a2a/utils/__init__.py +0 -0
- google/adk/a2a/utils/agent_card_builder.py +544 -0
- google/adk/a2a/utils/agent_to_a2a.py +118 -0
- google/adk/agents/__init__.py +5 -0
- google/adk/agents/agent_config.py +46 -0
- google/adk/agents/base_agent.py +239 -41
- google/adk/agents/callback_context.py +41 -0
- google/adk/agents/common_configs.py +79 -0
- google/adk/agents/config_agent_utils.py +184 -0
- google/adk/agents/config_schemas/AgentConfig.json +566 -0
- google/adk/agents/invocation_context.py +5 -1
- google/adk/agents/live_request_queue.py +15 -0
- google/adk/agents/llm_agent.py +201 -9
- google/adk/agents/loop_agent.py +35 -1
- google/adk/agents/parallel_agent.py +24 -3
- google/adk/agents/remote_a2a_agent.py +17 -5
- google/adk/agents/sequential_agent.py +22 -1
- google/adk/artifacts/gcs_artifact_service.py +110 -20
- google/adk/auth/auth_handler.py +3 -3
- google/adk/auth/credential_manager.py +23 -23
- google/adk/auth/credential_service/base_credential_service.py +6 -6
- google/adk/auth/credential_service/in_memory_credential_service.py +10 -8
- google/adk/auth/credential_service/session_state_credential_service.py +8 -8
- google/adk/auth/exchanger/oauth2_credential_exchanger.py +3 -3
- google/adk/auth/oauth2_credential_util.py +2 -2
- google/adk/auth/refresher/oauth2_credential_refresher.py +4 -4
- google/adk/cli/agent_graph.py +3 -1
- google/adk/cli/browser/index.html +2 -2
- google/adk/cli/browser/main-W7QZBYAR.js +3914 -0
- google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
- google/adk/cli/cli_eval.py +87 -12
- google/adk/cli/cli_tools_click.py +143 -82
- google/adk/cli/fast_api.py +150 -69
- google/adk/cli/utils/agent_loader.py +35 -1
- google/adk/code_executors/base_code_executor.py +14 -19
- google/adk/code_executors/built_in_code_executor.py +4 -1
- google/adk/evaluation/base_eval_service.py +46 -2
- google/adk/evaluation/eval_metrics.py +4 -0
- google/adk/evaluation/eval_sets_manager.py +5 -1
- google/adk/evaluation/evaluation_generator.py +1 -1
- google/adk/evaluation/final_response_match_v2.py +2 -2
- google/adk/evaluation/gcs_eval_sets_manager.py +2 -1
- google/adk/evaluation/in_memory_eval_sets_manager.py +151 -0
- google/adk/evaluation/local_eval_service.py +389 -0
- google/adk/evaluation/local_eval_set_results_manager.py +2 -2
- google/adk/evaluation/local_eval_sets_manager.py +24 -9
- google/adk/evaluation/metric_evaluator_registry.py +16 -6
- google/adk/evaluation/vertex_ai_eval_facade.py +7 -1
- google/adk/events/event.py +7 -2
- google/adk/flows/llm_flows/auto_flow.py +6 -11
- google/adk/flows/llm_flows/base_llm_flow.py +66 -29
- google/adk/flows/llm_flows/contents.py +16 -10
- google/adk/flows/llm_flows/functions.py +89 -52
- google/adk/memory/in_memory_memory_service.py +21 -15
- google/adk/memory/vertex_ai_memory_bank_service.py +12 -10
- google/adk/models/anthropic_llm.py +46 -6
- google/adk/models/base_llm_connection.py +2 -0
- google/adk/models/gemini_llm_connection.py +17 -6
- google/adk/models/google_llm.py +46 -11
- google/adk/models/lite_llm.py +52 -22
- google/adk/plugins/__init__.py +17 -0
- google/adk/plugins/base_plugin.py +317 -0
- google/adk/plugins/plugin_manager.py +265 -0
- google/adk/runners.py +122 -18
- google/adk/sessions/database_session_service.py +51 -52
- google/adk/sessions/vertex_ai_session_service.py +27 -12
- google/adk/tools/__init__.py +2 -0
- google/adk/tools/_automatic_function_calling_util.py +20 -2
- google/adk/tools/agent_tool.py +15 -3
- google/adk/tools/apihub_tool/apihub_toolset.py +38 -39
- google/adk/tools/application_integration_tool/application_integration_toolset.py +35 -37
- google/adk/tools/application_integration_tool/integration_connector_tool.py +2 -3
- google/adk/tools/base_tool.py +9 -9
- google/adk/tools/base_toolset.py +29 -5
- google/adk/tools/bigquery/__init__.py +3 -3
- google/adk/tools/bigquery/metadata_tool.py +2 -0
- google/adk/tools/bigquery/query_tool.py +15 -1
- google/adk/tools/computer_use/__init__.py +13 -0
- google/adk/tools/computer_use/base_computer.py +265 -0
- google/adk/tools/computer_use/computer_use_tool.py +166 -0
- google/adk/tools/computer_use/computer_use_toolset.py +220 -0
- google/adk/tools/enterprise_search_tool.py +4 -2
- google/adk/tools/exit_loop_tool.py +1 -0
- google/adk/tools/google_api_tool/google_api_tool.py +16 -1
- google/adk/tools/google_api_tool/google_api_toolset.py +9 -7
- google/adk/tools/google_api_tool/google_api_toolsets.py +41 -20
- google/adk/tools/google_search_tool.py +4 -2
- google/adk/tools/langchain_tool.py +16 -6
- google/adk/tools/long_running_tool.py +21 -0
- google/adk/tools/mcp_tool/mcp_toolset.py +27 -28
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +5 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +8 -8
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +4 -6
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +3 -2
- google/adk/tools/tool_context.py +0 -10
- google/adk/tools/url_context_tool.py +4 -2
- google/adk/tools/vertex_ai_search_tool.py +4 -2
- google/adk/utils/model_name_utils.py +90 -0
- google/adk/version.py +1 -1
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/METADATA +3 -2
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/RECORD +108 -91
- google/adk/cli/browser/main-RXDVX3K6.js +0 -3914
- google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -17
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/WHEEL +0 -0
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/entry_points.txt +0 -0
- {google_adk-1.6.1.dist-info → google_adk-1.8.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
|
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
|
-
|
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(
|
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__(
|
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__(
|
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__(
|
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__(
|
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__(
|
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__(
|
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
|
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
|
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
|
-
|
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]
|
@@ -60,15 +59,26 @@ class LangchainTool(FunctionTool):
|
|
60
59
|
name: Optional[str] = None,
|
61
60
|
description: Optional[str] = None,
|
62
61
|
):
|
63
|
-
# Check if the tool has a 'run' method
|
64
62
|
if not hasattr(tool, 'run') and not hasattr(tool, '_run'):
|
65
|
-
raise ValueError(
|
63
|
+
raise ValueError(
|
64
|
+
"Tool must be a Langchain tool, have a 'run' or '_run' method."
|
65
|
+
)
|
66
66
|
|
67
67
|
# Determine which function to use
|
68
68
|
if isinstance(tool, StructuredTool):
|
69
69
|
func = tool.func
|
70
|
-
|
70
|
+
# For async tools, func might be None but coroutine exists
|
71
|
+
if func is None and hasattr(tool, 'coroutine') and tool.coroutine:
|
72
|
+
func = tool.coroutine
|
73
|
+
elif hasattr(tool, '_run') or hasattr(tool, 'run'):
|
71
74
|
func = tool._run if hasattr(tool, '_run') else tool.run
|
75
|
+
else:
|
76
|
+
raise ValueError(
|
77
|
+
"This is not supported. Tool must be a Langchain tool, have a 'run'"
|
78
|
+
" or '_run' method. The tool is: ",
|
79
|
+
type(tool),
|
80
|
+
)
|
81
|
+
|
72
82
|
super().__init__(func)
|
73
83
|
# run_manager is a special parameter for langchain tool
|
74
84
|
self._ignore_params.append('run_manager')
|
@@ -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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
107
|
-
|
108
|
-
|
109
|
-
server. Note,
|
110
|
-
mcp server (e.g. using
|
111
|
-
timeout, and we recommend to use
|
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
|
@@ -111,6 +111,11 @@ class OpenApiSpecParser:
|
|
111
111
|
if operation_dict is None:
|
112
112
|
continue
|
113
113
|
|
114
|
+
# Append path-level parameters
|
115
|
+
operation_dict["parameters"] = operation_dict.get(
|
116
|
+
"parameters", []
|
117
|
+
) + path_item.get("parameters", [])
|
118
|
+
|
114
119
|
# If operation ID is missing, assign an operation id based on path
|
115
120
|
# and method
|
116
121
|
if "operationId" not in operation_dict:
|
@@ -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
|
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
|
-
|
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
|
"""
|
@@ -70,13 +70,12 @@ class RestApiTool(BaseTool):
|
|
70
70
|
* Generates request params and body
|
71
71
|
* Attaches auth credentials to API call.
|
72
72
|
|
73
|
-
Example
|
74
|
-
|
73
|
+
Example::
|
74
|
+
|
75
75
|
# Each API operation in the spec will be turned into its own tool
|
76
76
|
# Name of the tool is the operationId of that operation, in snake case
|
77
77
|
operations = OperationGenerator().parse(openapi_spec_dict)
|
78
78
|
tool = [RestApiTool.from_parsed_operation(o) for o in operations]
|
79
|
-
```
|
80
79
|
"""
|
81
80
|
|
82
81
|
def __init__(
|
@@ -92,13 +91,12 @@ class RestApiTool(BaseTool):
|
|
92
91
|
"""Initializes the RestApiTool with the given parameters.
|
93
92
|
|
94
93
|
To generate RestApiTool from OpenAPI Specs, use OperationGenerator.
|
95
|
-
Example
|
96
|
-
|
94
|
+
Example::
|
95
|
+
|
97
96
|
# Each API operation in the spec will be turned into its own tool
|
98
97
|
# Name of the tool is the operationId of that operation, in snake case
|
99
98
|
operations = OperationGenerator().parse(openapi_spec_dict)
|
100
99
|
tool = [RestApiTool.from_parsed_operation(o) for o in operations]
|
101
|
-
```
|
102
100
|
|
103
101
|
Hint: Use google.adk.tools.openapi_tool.auth.auth_helpers to construct
|
104
102
|
auth_scheme and auth_credential.
|
@@ -24,11 +24,12 @@ from google.genai import types
|
|
24
24
|
from typing_extensions import override
|
25
25
|
from vertexai.preview import rag
|
26
26
|
|
27
|
+
from ...utils.model_name_utils import is_gemini_2_model
|
27
28
|
from ..tool_context import ToolContext
|
28
29
|
from .base_retrieval_tool import BaseRetrievalTool
|
29
30
|
|
30
31
|
if TYPE_CHECKING:
|
31
|
-
from ...models
|
32
|
+
from ...models import LlmRequest
|
32
33
|
|
33
34
|
logger = logging.getLogger('google_adk.' + __name__)
|
34
35
|
|
@@ -62,7 +63,7 @@ class VertexAiRagRetrieval(BaseRetrievalTool):
|
|
62
63
|
llm_request: LlmRequest,
|
63
64
|
) -> None:
|
64
65
|
# Use Gemini built-in Vertex AI RAG tool for Gemini 2 models.
|
65
|
-
if llm_request.model
|
66
|
+
if is_gemini_2_model(llm_request.model):
|
66
67
|
llm_request.config = (
|
67
68
|
types.GenerateContentConfig()
|
68
69
|
if not llm_request.config
|
google/adk/tools/tool_context.py
CHANGED
@@ -69,16 +69,6 @@ class ToolContext(CallbackContext):
|
|
69
69
|
def get_auth_response(self, auth_config: AuthConfig) -> AuthCredential:
|
70
70
|
return AuthHandler(auth_config).get_auth_response(self.state)
|
71
71
|
|
72
|
-
async def list_artifacts(self) -> list[str]:
|
73
|
-
"""Lists the filenames of the artifacts attached to the current session."""
|
74
|
-
if self._invocation_context.artifact_service is None:
|
75
|
-
raise ValueError('Artifact service is not initialized.')
|
76
|
-
return await self._invocation_context.artifact_service.list_artifact_keys(
|
77
|
-
app_name=self._invocation_context.app_name,
|
78
|
-
user_id=self._invocation_context.user_id,
|
79
|
-
session_id=self._invocation_context.session.id,
|
80
|
-
)
|
81
|
-
|
82
72
|
async def search_memory(self, query: str) -> SearchMemoryResponse:
|
83
73
|
"""Searches the memory of the current user."""
|
84
74
|
if self._invocation_context.memory_service is None:
|
@@ -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_2_model
|
22
24
|
from .base_tool import BaseTool
|
23
25
|
from .tool_context import ToolContext
|
24
26
|
|
@@ -46,9 +48,9 @@ class UrlContextTool(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
|
51
|
+
if is_gemini_1_model(llm_request.model):
|
50
52
|
raise ValueError('Url context tool can not be used in Gemini 1.x.')
|
51
|
-
elif llm_request.model
|
53
|
+
elif is_gemini_2_model(llm_request.model):
|
52
54
|
llm_request.config.tools.append(
|
53
55
|
types.Tool(url_context=types.UrlContext())
|
54
56
|
)
|
@@ -20,6 +20,8 @@ from typing import TYPE_CHECKING
|
|
20
20
|
from google.genai import types
|
21
21
|
from typing_extensions import override
|
22
22
|
|
23
|
+
from ..utils.model_name_utils import is_gemini_1_model
|
24
|
+
from ..utils.model_name_utils import is_gemini_model
|
23
25
|
from .base_tool import BaseTool
|
24
26
|
from .tool_context import ToolContext
|
25
27
|
|
@@ -86,8 +88,8 @@ class VertexAiSearchTool(BaseTool):
|
|
86
88
|
tool_context: ToolContext,
|
87
89
|
llm_request: LlmRequest,
|
88
90
|
) -> None:
|
89
|
-
if llm_request.model
|
90
|
-
if
|
91
|
+
if is_gemini_model(llm_request.model):
|
92
|
+
if is_gemini_1_model(llm_request.model) and llm_request.config.tools:
|
91
93
|
raise ValueError(
|
92
94
|
'Vertex AI search tool can not be used with other tools in Gemini'
|
93
95
|
' 1.x.'
|