Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/google/adk/agents/llm_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,28 @@ async def _convert_tool_union_to_tools(
# other tools.
# TODO: Remove once the workaround is no longer needed.
if multiple_tools and isinstance(tool_union, VertexAiSearchTool):
from ..tools.discovery_engine_search_tool import DiscoveryEngineSearchTool

vais_tool = tool_union
if vais_tool.bypass_multi_tools_limit:
# Imported lazily and only on the bypass path: the Discovery Engine
# client is an optional dependency, and agents that leave the flag off
# must not be forced to install it.
try:
from ..tools.discovery_engine_search_tool import DiscoveryEngineSearchTool
except ImportError as e:
raise ImportError(
'bypass_multi_tools_limit=True requires the Discovery Engine'
' client. Install it with `pip install google-adk[gcp]`.'
) from e

return [
DiscoveryEngineSearchTool(
data_store_id=vais_tool.data_store_id,
data_store_specs=vais_tool.data_store_specs,
search_engine_id=vais_tool.search_engine_id,
filter=vais_tool.filter,
max_results=vais_tool.max_results,
name=vais_tool._name_override,
description=vais_tool._description_override,
)
]
from ..workflow._base_node import BaseNode
Expand Down
27 changes: 27 additions & 0 deletions src/google/adk/tools/discovery_engine_search_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import google.auth
from google.cloud import discoveryengine_v1beta as discoveryengine
from google.genai import types
from typing_extensions import override

from ..utils._mtls_utils import get_api_endpoint
from .function_tool import FunctionTool
Expand Down Expand Up @@ -144,6 +145,8 @@ def __init__(
*,
search_result_mode: Optional[SearchResultMode] = None,
location: Optional[str] = None,
name: Optional[str] = None,
description: Optional[str] = None,
):
"""Initializes the DiscoveryEngineSearchTool.

Expand All @@ -164,8 +167,16 @@ def __init__(
location: Optional endpoint location override.
Examples: "global", "us", "eu". If not specified, location is inferred
from `data_store_id` or `search_engine_id` and defaults to "global".
name: Optional override for the tool name advertised to the model.
Defaults to the function name, "discovery_engine_search".
description: Optional override for the tool description advertised to
the model. Defaults to the function docstring.
"""
super().__init__(self.discovery_engine_search)
if name:
self.name = name
if description:
self.description = description
if (data_store_id is None and search_engine_id is None) or (
data_store_id is not None and search_engine_id is not None
):
Expand Down Expand Up @@ -200,6 +211,22 @@ def __init__(
credentials=credentials, client_options=options
)

@override
def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
# FunctionTool builds the declaration from `self.func`, ignoring
# `self.name`. LlmRequest.append_tools advertises `declaration.name` to the
# model but keys dispatch on `tool.name`; if the two diverge the model emits
# a call that cannot be resolved. Keep them in sync here.
#
# Safe to mutate: FunctionTool._get_declaration() already returns
# `declaration.model_copy(deep=True)`, so the shared
# `_build_declaration_cached` lru_cache entry is not touched.
declaration = super()._get_declaration()
if declaration is not None:
declaration.name = self.name
declaration.description = self.description
return declaration

def discovery_engine_search(
self,
query: str,
Expand Down
8 changes: 8 additions & 0 deletions src/google/adk/tools/vertex_ai_search_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def __init__(
filter: Optional[str] = None,
max_results: Optional[int] = None,
bypass_multi_tools_limit: bool = False,
name: Optional[str] = None,
description: Optional[str] = None,
):
"""Initializes the Vertex AI Search tool.

Expand All @@ -86,6 +88,10 @@ def __init__(
max_results: The maximum number of results to return.
bypass_multi_tools_limit: Whether to bypass the multi tools limitation,
so that the tool can be used with other tools in the same agent.
name: Optional tool name. Only takes effect when
bypass_multi_tools_limit=True, where it renames the substituted
DiscoveryEngineSearchTool. Ignored on the built-in grounding path.
description: Optional tool description.

Raises:
ValueError: If both data_store_id and search_engine_id are not specified
Expand All @@ -109,6 +115,8 @@ def __init__(
self.filter = filter
self.max_results = max_results
self.bypass_multi_tools_limit = bypass_multi_tools_limit
self._name_override = name
self._description_override = description

def _build_vertex_ai_search_config(
self, readonly_context: ReadonlyContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12200,7 +12200,6 @@ async def test_multiple_plugins_share_background_loop_state_with_equivalent_cred
creds1
)


plugin1 = bigquery_agent_analytics_plugin.BigQueryAgentAnalyticsPlugin(
project_id=PROJECT_ID,
dataset_id=DATASET_ID,
Expand Down
Loading