google-adk 0.5.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.
- google/adk/agents/base_agent.py +76 -30
- google/adk/agents/callback_context.py +2 -6
- google/adk/agents/llm_agent.py +122 -30
- google/adk/agents/loop_agent.py +1 -1
- google/adk/agents/parallel_agent.py +7 -0
- google/adk/agents/readonly_context.py +8 -0
- google/adk/agents/run_config.py +1 -1
- google/adk/agents/sequential_agent.py +31 -0
- google/adk/agents/transcription_entry.py +4 -2
- google/adk/artifacts/gcs_artifact_service.py +1 -1
- google/adk/artifacts/in_memory_artifact_service.py +1 -1
- google/adk/auth/auth_credential.py +10 -2
- google/adk/auth/auth_preprocessor.py +7 -1
- google/adk/auth/auth_tool.py +3 -4
- google/adk/cli/agent_graph.py +5 -5
- google/adk/cli/browser/index.html +4 -4
- google/adk/cli/browser/{main-ULN5R5I5.js → main-PKDNKWJE.js} +59 -60
- google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
- google/adk/cli/cli.py +10 -9
- google/adk/cli/cli_deploy.py +7 -2
- google/adk/cli/cli_eval.py +109 -115
- google/adk/cli/cli_tools_click.py +179 -67
- google/adk/cli/fast_api.py +248 -197
- google/adk/cli/utils/agent_loader.py +137 -0
- google/adk/cli/utils/cleanup.py +40 -0
- google/adk/cli/utils/common.py +23 -0
- google/adk/cli/utils/evals.py +83 -0
- google/adk/cli/utils/logs.py +8 -5
- google/adk/code_executors/__init__.py +3 -1
- google/adk/code_executors/built_in_code_executor.py +52 -0
- google/adk/code_executors/code_execution_utils.py +2 -1
- google/adk/code_executors/container_code_executor.py +0 -1
- google/adk/code_executors/vertex_ai_code_executor.py +6 -8
- google/adk/evaluation/__init__.py +1 -1
- google/adk/evaluation/agent_evaluator.py +168 -128
- google/adk/evaluation/eval_case.py +104 -0
- google/adk/evaluation/eval_metrics.py +74 -0
- google/adk/evaluation/eval_result.py +86 -0
- google/adk/evaluation/eval_set.py +39 -0
- google/adk/evaluation/eval_set_results_manager.py +47 -0
- google/adk/evaluation/eval_sets_manager.py +43 -0
- google/adk/evaluation/evaluation_generator.py +88 -113
- google/adk/evaluation/evaluator.py +58 -0
- google/adk/evaluation/local_eval_set_results_manager.py +113 -0
- google/adk/evaluation/local_eval_sets_manager.py +264 -0
- google/adk/evaluation/response_evaluator.py +106 -1
- google/adk/evaluation/trajectory_evaluator.py +84 -2
- google/adk/events/event.py +6 -1
- google/adk/events/event_actions.py +6 -1
- google/adk/examples/base_example_provider.py +1 -0
- google/adk/examples/example_util.py +3 -2
- google/adk/flows/llm_flows/_code_execution.py +9 -1
- google/adk/flows/llm_flows/audio_transcriber.py +4 -3
- google/adk/flows/llm_flows/base_llm_flow.py +58 -21
- google/adk/flows/llm_flows/contents.py +3 -1
- google/adk/flows/llm_flows/functions.py +9 -8
- google/adk/flows/llm_flows/instructions.py +18 -80
- google/adk/flows/llm_flows/single_flow.py +2 -2
- google/adk/memory/__init__.py +1 -1
- google/adk/memory/_utils.py +23 -0
- google/adk/memory/base_memory_service.py +23 -21
- google/adk/memory/in_memory_memory_service.py +57 -25
- google/adk/memory/memory_entry.py +37 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +38 -15
- google/adk/models/anthropic_llm.py +16 -9
- google/adk/models/base_llm.py +2 -1
- google/adk/models/base_llm_connection.py +2 -0
- google/adk/models/gemini_llm_connection.py +11 -11
- google/adk/models/google_llm.py +12 -2
- google/adk/models/lite_llm.py +80 -23
- google/adk/models/llm_response.py +16 -3
- google/adk/models/registry.py +1 -1
- google/adk/runners.py +98 -42
- google/adk/sessions/__init__.py +1 -1
- google/adk/sessions/_session_util.py +2 -1
- google/adk/sessions/base_session_service.py +6 -33
- google/adk/sessions/database_session_service.py +57 -67
- google/adk/sessions/in_memory_session_service.py +106 -24
- google/adk/sessions/session.py +3 -0
- google/adk/sessions/vertex_ai_session_service.py +44 -51
- google/adk/telemetry.py +7 -2
- google/adk/tools/__init__.py +4 -7
- google/adk/tools/_memory_entry_utils.py +30 -0
- google/adk/tools/agent_tool.py +10 -10
- google/adk/tools/apihub_tool/apihub_toolset.py +55 -74
- google/adk/tools/apihub_tool/clients/apihub_client.py +10 -3
- google/adk/tools/apihub_tool/clients/secret_client.py +1 -0
- google/adk/tools/application_integration_tool/application_integration_toolset.py +111 -85
- google/adk/tools/application_integration_tool/clients/connections_client.py +28 -1
- google/adk/tools/application_integration_tool/clients/integration_client.py +7 -5
- google/adk/tools/application_integration_tool/integration_connector_tool.py +69 -26
- google/adk/tools/base_toolset.py +96 -0
- google/adk/tools/bigquery/__init__.py +28 -0
- google/adk/tools/bigquery/bigquery_credentials.py +216 -0
- google/adk/tools/bigquery/bigquery_tool.py +116 -0
- google/adk/tools/{built_in_code_execution_tool.py → enterprise_search_tool.py} +17 -11
- google/adk/tools/function_parameter_parse_util.py +9 -2
- google/adk/tools/function_tool.py +33 -3
- google/adk/tools/get_user_choice_tool.py +1 -0
- google/adk/tools/google_api_tool/__init__.py +24 -70
- google/adk/tools/google_api_tool/google_api_tool.py +12 -6
- google/adk/tools/google_api_tool/{google_api_tool_set.py → google_api_toolset.py} +57 -55
- google/adk/tools/google_api_tool/google_api_toolsets.py +108 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +40 -42
- google/adk/tools/google_search_tool.py +2 -2
- google/adk/tools/langchain_tool.py +96 -49
- google/adk/tools/load_memory_tool.py +14 -5
- google/adk/tools/mcp_tool/__init__.py +3 -2
- google/adk/tools/mcp_tool/conversion_utils.py +6 -2
- google/adk/tools/mcp_tool/mcp_session_manager.py +80 -69
- google/adk/tools/mcp_tool/mcp_tool.py +35 -32
- google/adk/tools/mcp_tool/mcp_toolset.py +99 -194
- google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +1 -3
- google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +6 -7
- google/adk/tools/openapi_tool/common/common.py +5 -1
- google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +7 -2
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +27 -7
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +36 -32
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +11 -1
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +1 -1
- google/adk/tools/preload_memory_tool.py +27 -18
- google/adk/tools/retrieval/__init__.py +1 -1
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +1 -1
- google/adk/tools/toolbox_toolset.py +107 -0
- google/adk/tools/transfer_to_agent_tool.py +0 -1
- google/adk/utils/__init__.py +13 -0
- google/adk/utils/instructions_utils.py +131 -0
- google/adk/version.py +1 -1
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/METADATA +18 -19
- google_adk-1.1.0.dist-info/RECORD +200 -0
- google/adk/agents/remote_agent.py +0 -50
- google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -18
- google/adk/cli/fast_api.py.orig +0 -728
- google/adk/tools/google_api_tool/google_api_tool_sets.py +0 -112
- google/adk/tools/toolbox_tool.py +0 -46
- google_adk-0.5.0.dist-info/RECORD +0 -180
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/WHEEL +0 -0
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/entry_points.txt +0 -0
- {google_adk-0.5.0.dist-info → google_adk-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -18,19 +18,13 @@ import logging
|
|
18
18
|
from typing import Any
|
19
19
|
from typing import Dict
|
20
20
|
from typing import List
|
21
|
-
from typing import Optional
|
22
|
-
from typing import Union
|
23
21
|
|
24
22
|
# Google API client
|
25
23
|
from googleapiclient.discovery import build
|
26
|
-
from googleapiclient.discovery import Resource
|
27
24
|
from googleapiclient.errors import HttpError
|
28
25
|
|
29
26
|
# Configure logging
|
30
|
-
logging.
|
31
|
-
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
32
|
-
)
|
33
|
-
logger = logging.getLogger(__name__)
|
27
|
+
logger = logging.getLogger("google_adk." + __name__)
|
34
28
|
|
35
29
|
|
36
30
|
class GoogleApiToOpenApiConverter:
|
@@ -43,11 +37,11 @@ class GoogleApiToOpenApiConverter:
|
|
43
37
|
api_name: The name of the Google API (e.g., "calendar")
|
44
38
|
api_version: The version of the API (e.g., "v3")
|
45
39
|
"""
|
46
|
-
self.
|
47
|
-
self.
|
48
|
-
self.
|
49
|
-
self.
|
50
|
-
self.
|
40
|
+
self._api_name = api_name
|
41
|
+
self._api_version = api_version
|
42
|
+
self._google_api_resource = None
|
43
|
+
self._google_api_spec = None
|
44
|
+
self._openapi_spec = {
|
51
45
|
"openapi": "3.0.0",
|
52
46
|
"info": {},
|
53
47
|
"servers": [],
|
@@ -59,18 +53,20 @@ class GoogleApiToOpenApiConverter:
|
|
59
53
|
"""Fetches the Google API specification using discovery service."""
|
60
54
|
try:
|
61
55
|
logger.info(
|
62
|
-
"Fetching Google API spec for %s %s",
|
56
|
+
"Fetching Google API spec for %s %s",
|
57
|
+
self._api_name,
|
58
|
+
self._api_version,
|
63
59
|
)
|
64
60
|
# Build a resource object for the specified API
|
65
|
-
self.
|
61
|
+
self._google_api_resource = build(self._api_name, self._api_version)
|
66
62
|
|
67
63
|
# Access the underlying API discovery document
|
68
|
-
self.
|
64
|
+
self._google_api_spec = self._google_api_resource._rootDesc
|
69
65
|
|
70
|
-
if not self.
|
66
|
+
if not self._google_api_spec:
|
71
67
|
raise ValueError("Failed to retrieve API specification")
|
72
68
|
|
73
|
-
logger.info("Successfully fetched %s API specification", self.
|
69
|
+
logger.info("Successfully fetched %s API specification", self._api_name)
|
74
70
|
except HttpError as e:
|
75
71
|
logger.error("HTTP Error: %s", e)
|
76
72
|
raise
|
@@ -84,7 +80,7 @@ class GoogleApiToOpenApiConverter:
|
|
84
80
|
Returns:
|
85
81
|
Dict containing the converted OpenAPI v3 specification
|
86
82
|
"""
|
87
|
-
if not self.
|
83
|
+
if not self._google_api_spec:
|
88
84
|
self.fetch_google_api_spec()
|
89
85
|
|
90
86
|
# Convert basic API information
|
@@ -100,49 +96,49 @@ class GoogleApiToOpenApiConverter:
|
|
100
96
|
self._convert_schemas()
|
101
97
|
|
102
98
|
# Convert endpoints/paths
|
103
|
-
self._convert_resources(self.
|
99
|
+
self._convert_resources(self._google_api_spec.get("resources", {}))
|
104
100
|
|
105
101
|
# Convert top-level methods, if any
|
106
|
-
self._convert_methods(self.
|
102
|
+
self._convert_methods(self._google_api_spec.get("methods", {}), "/")
|
107
103
|
|
108
|
-
return self.
|
104
|
+
return self._openapi_spec
|
109
105
|
|
110
106
|
def _convert_info(self) -> None:
|
111
107
|
"""Convert basic API information."""
|
112
|
-
self.
|
113
|
-
"title": self.
|
114
|
-
"description": self.
|
115
|
-
"version": self.
|
108
|
+
self._openapi_spec["info"] = {
|
109
|
+
"title": self._google_api_spec.get("title", f"{self._api_name} API"),
|
110
|
+
"description": self._google_api_spec.get("description", ""),
|
111
|
+
"version": self._google_api_spec.get("version", self._api_version),
|
116
112
|
"contact": {},
|
117
|
-
"termsOfService": self.
|
113
|
+
"termsOfService": self._google_api_spec.get("documentationLink", ""),
|
118
114
|
}
|
119
115
|
|
120
116
|
# Add documentation links if available
|
121
|
-
docs_link = self.
|
117
|
+
docs_link = self._google_api_spec.get("documentationLink")
|
122
118
|
if docs_link:
|
123
|
-
self.
|
119
|
+
self._openapi_spec["externalDocs"] = {
|
124
120
|
"description": "API Documentation",
|
125
121
|
"url": docs_link,
|
126
122
|
}
|
127
123
|
|
128
124
|
def _convert_servers(self) -> None:
|
129
125
|
"""Convert server information."""
|
130
|
-
base_url = self.
|
126
|
+
base_url = self._google_api_spec.get(
|
131
127
|
"rootUrl", ""
|
132
|
-
) + self.
|
128
|
+
) + self._google_api_spec.get("servicePath", "")
|
133
129
|
|
134
130
|
# Remove trailing slash if present
|
135
131
|
if base_url.endswith("/"):
|
136
132
|
base_url = base_url[:-1]
|
137
133
|
|
138
|
-
self.
|
134
|
+
self._openapi_spec["servers"] = [{
|
139
135
|
"url": base_url,
|
140
|
-
"description": f"{self.
|
136
|
+
"description": f"{self._api_name} {self._api_version} API",
|
141
137
|
}]
|
142
138
|
|
143
139
|
def _convert_security_schemes(self) -> None:
|
144
140
|
"""Convert authentication and authorization schemes."""
|
145
|
-
auth = self.
|
141
|
+
auth = self._google_api_spec.get("auth", {})
|
146
142
|
oauth2 = auth.get("oauth2", {})
|
147
143
|
|
148
144
|
if oauth2:
|
@@ -153,7 +149,7 @@ class GoogleApiToOpenApiConverter:
|
|
153
149
|
for scope, scope_info in scopes.items():
|
154
150
|
formatted_scopes[scope] = scope_info.get("description", "")
|
155
151
|
|
156
|
-
self.
|
152
|
+
self._openapi_spec["components"]["securitySchemes"]["oauth2"] = {
|
157
153
|
"type": "oauth2",
|
158
154
|
"description": "OAuth 2.0 authentication",
|
159
155
|
"flows": {
|
@@ -168,7 +164,7 @@ class GoogleApiToOpenApiConverter:
|
|
168
164
|
}
|
169
165
|
|
170
166
|
# Add API key authentication (most Google APIs support this)
|
171
|
-
self.
|
167
|
+
self._openapi_spec["components"]["securitySchemes"]["apiKey"] = {
|
172
168
|
"type": "apiKey",
|
173
169
|
"in": "query",
|
174
170
|
"name": "key",
|
@@ -176,18 +172,20 @@ class GoogleApiToOpenApiConverter:
|
|
176
172
|
}
|
177
173
|
|
178
174
|
# Create global security requirement
|
179
|
-
self.
|
175
|
+
self._openapi_spec["security"] = [
|
180
176
|
{"oauth2": list(formatted_scopes.keys())} if oauth2 else {},
|
181
177
|
{"apiKey": []},
|
182
178
|
]
|
183
179
|
|
184
180
|
def _convert_schemas(self) -> None:
|
185
181
|
"""Convert schema definitions (models)."""
|
186
|
-
schemas = self.
|
182
|
+
schemas = self._google_api_spec.get("schemas", {})
|
187
183
|
|
188
184
|
for schema_name, schema_def in schemas.items():
|
189
185
|
converted_schema = self._convert_schema_object(schema_def)
|
190
|
-
self.
|
186
|
+
self._openapi_spec["components"]["schemas"][
|
187
|
+
schema_name
|
188
|
+
] = converted_schema
|
191
189
|
|
192
190
|
def _convert_schema_object(
|
193
191
|
self, schema_def: Dict[str, Any]
|
@@ -320,11 +318,11 @@ class GoogleApiToOpenApiConverter:
|
|
320
318
|
path_params = self._extract_path_parameters(rest_path)
|
321
319
|
|
322
320
|
# Create path entry if it doesn't exist
|
323
|
-
if rest_path not in self.
|
324
|
-
self.
|
321
|
+
if rest_path not in self._openapi_spec["paths"]:
|
322
|
+
self._openapi_spec["paths"][rest_path] = {}
|
325
323
|
|
326
324
|
# Add the operation for this method
|
327
|
-
self.
|
325
|
+
self._openapi_spec["paths"][rest_path][http_method] = (
|
328
326
|
self._convert_operation(method_data, path_params)
|
329
327
|
)
|
330
328
|
|
@@ -478,7 +476,7 @@ class GoogleApiToOpenApiConverter:
|
|
478
476
|
output_path: Path where the OpenAPI spec should be saved
|
479
477
|
"""
|
480
478
|
with open(output_path, "w", encoding="utf-8") as f:
|
481
|
-
json.dump(self.
|
479
|
+
json.dump(self._openapi_spec, f, indent=2)
|
482
480
|
logger.info("OpenAPI specification saved to %s", output_path)
|
483
481
|
|
484
482
|
|
@@ -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
|
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
|
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
|
)
|
@@ -13,10 +13,12 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
from typing import Any
|
16
|
-
from typing import
|
16
|
+
from typing import Optional
|
17
|
+
from typing import Union
|
17
18
|
|
18
19
|
from google.genai import types
|
19
|
-
from
|
20
|
+
from langchain.agents import Tool
|
21
|
+
from langchain_core.tools import BaseTool
|
20
22
|
from typing_extensions import override
|
21
23
|
|
22
24
|
from . import _automatic_function_calling_util
|
@@ -24,63 +26,108 @@ from .function_tool import FunctionTool
|
|
24
26
|
|
25
27
|
|
26
28
|
class LangchainTool(FunctionTool):
|
27
|
-
"""
|
29
|
+
"""Adapter class that wraps a Langchain tool for use with ADK.
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
+
This adapter converts Langchain tools into a format compatible with Google's
|
32
|
+
generative AI function calling interface. It preserves the tool's name,
|
33
|
+
description, and functionality while adapting its schema.
|
34
|
+
|
35
|
+
The original tool's name and description can be overridden if needed.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
tool: A Langchain tool to wrap (BaseTool or a tool with a .run method)
|
39
|
+
name: Optional override for the tool's name
|
40
|
+
description: Optional override for the tool's description
|
41
|
+
|
42
|
+
Examples:
|
43
|
+
```python
|
44
|
+
from langchain.tools import DuckDuckGoSearchTool
|
45
|
+
from google.genai.tools import LangchainTool
|
46
|
+
|
47
|
+
search_tool = DuckDuckGoSearchTool()
|
48
|
+
wrapped_tool = LangchainTool(search_tool)
|
49
|
+
```
|
31
50
|
"""
|
32
51
|
|
33
|
-
|
52
|
+
_langchain_tool: Union[BaseTool, object]
|
34
53
|
"""The wrapped langchain tool."""
|
35
54
|
|
36
|
-
def __init__(
|
37
|
-
|
38
|
-
|
39
|
-
|
55
|
+
def __init__(
|
56
|
+
self,
|
57
|
+
tool: Union[BaseTool, object],
|
58
|
+
name: Optional[str] = None,
|
59
|
+
description: Optional[str] = None,
|
60
|
+
):
|
61
|
+
# Check if the tool has a 'run' method
|
62
|
+
if not hasattr(tool, 'run') and not hasattr(tool, '_run'):
|
63
|
+
raise ValueError("Langchain tool must have a 'run' or '_run' method")
|
64
|
+
|
65
|
+
# Determine which function to use
|
66
|
+
func = tool._run if hasattr(tool, '_run') else tool.run
|
67
|
+
super().__init__(func)
|
68
|
+
|
69
|
+
self._langchain_tool = tool
|
70
|
+
|
71
|
+
# Set name: priority is 1) explicitly provided name, 2) tool's name, 3) default
|
72
|
+
if name is not None:
|
73
|
+
self.name = name
|
74
|
+
elif hasattr(tool, 'name') and tool.name:
|
40
75
|
self.name = tool.name
|
41
|
-
|
42
|
-
self.description = tool.description
|
76
|
+
# else: keep default from FunctionTool
|
43
77
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
78
|
+
# Set description: similar priority
|
79
|
+
if description is not None:
|
80
|
+
self.description = description
|
81
|
+
elif hasattr(tool, 'description') and tool.description:
|
82
|
+
self.description = tool.description
|
83
|
+
# else: keep default from FunctionTool
|
50
84
|
|
51
85
|
@override
|
52
86
|
def _get_declaration(self) -> types.FunctionDeclaration:
|
53
|
-
"""Build the function declaration for the tool.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
)
|
67
|
-
if self.
|
68
|
-
tool_wrapper
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
"""Build the function declaration for the tool.
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
A FunctionDeclaration object that describes the tool's interface.
|
91
|
+
|
92
|
+
Raises:
|
93
|
+
ValueError: If the tool schema cannot be correctly parsed.
|
94
|
+
"""
|
95
|
+
try:
|
96
|
+
# There are two types of tools:
|
97
|
+
# 1. BaseTool: the tool is defined in langchain_core.tools.
|
98
|
+
# 2. Other tools: the tool doesn't inherit any class but follow some
|
99
|
+
# conventions, like having a "run" method.
|
100
|
+
# Handle BaseTool type (preferred Langchain approach)
|
101
|
+
if isinstance(self._langchain_tool, BaseTool):
|
102
|
+
tool_wrapper = Tool(
|
103
|
+
name=self.name,
|
104
|
+
func=self.func,
|
105
|
+
description=self.description,
|
106
|
+
)
|
107
|
+
|
108
|
+
# Add schema if available
|
109
|
+
if (
|
110
|
+
hasattr(self._langchain_tool, 'args_schema')
|
111
|
+
and self._langchain_tool.args_schema
|
112
|
+
):
|
113
|
+
tool_wrapper.args_schema = self._langchain_tool.args_schema
|
114
|
+
|
115
|
+
return _automatic_function_calling_util.build_function_declaration_for_langchain(
|
116
|
+
False,
|
117
|
+
self.name,
|
118
|
+
self.description,
|
119
|
+
tool_wrapper.func,
|
120
|
+
getattr(tool_wrapper, 'args', None),
|
121
|
+
)
|
122
|
+
|
78
123
|
# Need to provide a way to override the function names and descriptions
|
79
124
|
# as the original function names are mostly ".run" and the descriptions
|
80
|
-
# may not meet users' needs
|
81
|
-
|
82
|
-
|
83
|
-
func=self.tool.run,
|
84
|
-
)
|
125
|
+
# may not meet users' needs
|
126
|
+
return _automatic_function_calling_util.build_function_declaration(
|
127
|
+
func=self._langchain_tool.run,
|
85
128
|
)
|
86
|
-
|
129
|
+
|
130
|
+
except Exception as e:
|
131
|
+
raise ValueError(
|
132
|
+
f'Failed to build function declaration for Langchain tool: {e}'
|
133
|
+
) from e
|
@@ -17,19 +17,25 @@ from __future__ import annotations
|
|
17
17
|
from typing import TYPE_CHECKING
|
18
18
|
|
19
19
|
from google.genai import types
|
20
|
+
from pydantic import BaseModel
|
21
|
+
from pydantic import Field
|
20
22
|
from typing_extensions import override
|
21
23
|
|
24
|
+
from ..memory.memory_entry import MemoryEntry
|
22
25
|
from .function_tool import FunctionTool
|
23
26
|
from .tool_context import ToolContext
|
24
27
|
|
25
28
|
if TYPE_CHECKING:
|
26
|
-
from ..memory.base_memory_service import MemoryResult
|
27
29
|
from ..models import LlmRequest
|
28
30
|
|
29
31
|
|
32
|
+
class LoadMemoryResponse(BaseModel):
|
33
|
+
memories: list[MemoryEntry] = Field(default_factory=list)
|
34
|
+
|
35
|
+
|
30
36
|
async def load_memory(
|
31
37
|
query: str, tool_context: ToolContext
|
32
|
-
) ->
|
38
|
+
) -> LoadMemoryResponse:
|
33
39
|
"""Loads the memory for the current user.
|
34
40
|
|
35
41
|
Args:
|
@@ -38,12 +44,15 @@ async def load_memory(
|
|
38
44
|
Returns:
|
39
45
|
A list of memory results.
|
40
46
|
"""
|
41
|
-
|
42
|
-
return
|
47
|
+
search_memory_response = await tool_context.search_memory(query)
|
48
|
+
return LoadMemoryResponse(memories=search_memory_response.memories)
|
43
49
|
|
44
50
|
|
45
51
|
class LoadMemoryTool(FunctionTool):
|
46
|
-
"""A tool that loads the memory for the current user.
|
52
|
+
"""A tool that loads the memory for the current user.
|
53
|
+
|
54
|
+
NOTE: Currently this tool only uses text part from the memory.
|
55
|
+
"""
|
47
56
|
|
48
57
|
def __init__(self):
|
49
58
|
super().__init__(load_memory)
|
@@ -15,7 +15,8 @@
|
|
15
15
|
__all__ = []
|
16
16
|
|
17
17
|
try:
|
18
|
-
from .conversion_utils import adk_to_mcp_tool_type
|
18
|
+
from .conversion_utils import adk_to_mcp_tool_type
|
19
|
+
from .conversion_utils import gemini_to_json_schema
|
19
20
|
from .mcp_tool import MCPTool
|
20
21
|
from .mcp_toolset import MCPToolset
|
21
22
|
|
@@ -30,7 +31,7 @@ except ImportError as e:
|
|
30
31
|
import logging
|
31
32
|
import sys
|
32
33
|
|
33
|
-
logger = logging.getLogger(__name__)
|
34
|
+
logger = logging.getLogger('google_adk.' + __name__)
|
34
35
|
|
35
36
|
if sys.version_info < (3, 10):
|
36
37
|
logger.warning(
|
@@ -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
|
16
|
-
from
|
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
|
|