From 7dc6adf4e563330a09e4cf28d2b1994c24b007d1 Mon Sep 17 00:00:00 2001 From: Google Team Member Date: Fri, 16 Jan 2026 08:26:57 -0800 Subject: [PATCH] feat: migrate `ToolboxToolset` to use `toolbox-adk` and align validation ### Description of Change **Problem:** The `ToolboxToolset` was relying on the legacy `toolbox-core` package. Users wanting to use the Toolbox features were forced to install the heavy `[extensions]` group, lacking a granular installation option. Additionally, `ToolboxToolset` had a validation check enforcing either `toolset_name` or `tool_names` to be present, preventing the default behavior of loading all tools (which `toolbox-adk` supports). **Solution:** * Refactored `ToolboxToolset` to delegate to `toolbox-adk`. * Added a new `toolbox` optional dependency group in `pyproject.toml`. * Users can now run `pip install google-adk[toolbox]` to install only the necessary dependencies. * Updated the `extensions` dependency group to replace `toolbox-core` with `toolbox-adk`. * This ensures existing users of `[extensions]` are not broken upon upgrade. * Removed the restrictive validation check to allow default loading of all tools. * Updated the `ImportError` message to guide users toward the new granular installation command. ### Testing Plan **Unit Tests:** - [x] I have added or updated unit tests for my change. - [x] All unit tests pass locally. **Manual End-to-End (E2E) Tests:** - Verified that the sample agent runs correctly with `toolbox-adk` locally. - Verified that `ToolboxToolset` can now be instantiated without arguments to load all tools. ### Checklist - [x] I have read the [CONTRIBUTING.md](https://github.com/google/adk-python/blob/main/CONTRIBUTING.md) document. - [x] I have performed a self-review of my own code. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have added tests that prove my fix is effective or that my feature works. - [x] New and existing unit tests pass locally with my changes. - [x] I have manually tested my changes end-to-end. - [x] Any dependent changes have been merged and published in downstream modules. PiperOrigin-RevId: 857171811 --- contributing/samples/toolbox_agent/README.md | 4 +- pyproject.toml | 3 +- src/google/adk/tools/toolbox_toolset.py | 56 ++++++++++---------- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/contributing/samples/toolbox_agent/README.md b/contributing/samples/toolbox_agent/README.md index 1c94731a..56a4fe08 100644 --- a/contributing/samples/toolbox_agent/README.md +++ b/contributing/samples/toolbox_agent/README.md @@ -26,10 +26,10 @@ Install SQLite from [https://sqlite.org/](https://sqlite.org/) ### 3. Install Required Python Dependencies -**Important**: The ADK's `ToolboxToolset` class requires the `toolbox-core` package, which is not automatically installed with the ADK. Install it using: +**Important**: The ADK's `ToolboxToolset` class requires the `toolbox-adk` package, which is not automatically installed with the ADK. Install it using: ```bash -pip install toolbox-core +pip install google-adk[toolbox] ``` ### 4. Create Database (Optional) diff --git a/pyproject.toml b/pyproject.toml index f612ef4d..1af96704 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -157,11 +157,12 @@ extensions = [ "llama-index-readers-file>=0.4.0", # For retrieval using LlamaIndex. "llama-index-embeddings-google-genai>=0.3.0", # For files retrieval using LlamaIndex. "lxml>=5.3.0", # For load_web_page tool. - "toolbox-adk>=0.1.0", # For tools.toolbox_toolset.ToolboxToolset + "toolbox-adk>=0.5.7, <0.6.0", # For tools.toolbox_toolset.ToolboxToolset ] otel-gcp = ["opentelemetry-instrumentation-google-genai>=0.3b0, <1.0.0"] +toolbox = ["toolbox-adk>=0.5.7, <0.6.0"] [tool.pyink] # Format py files following Google style-guide diff --git a/src/google/adk/tools/toolbox_toolset.py b/src/google/adk/tools/toolbox_toolset.py index 73f27f3f..e1e7e576 100644 --- a/src/google/adk/tools/toolbox_toolset.py +++ b/src/google/adk/tools/toolbox_toolset.py @@ -35,19 +35,9 @@ if TYPE_CHECKING: class ToolboxToolset(BaseToolset): """A class that provides access to toolbox toolsets. - This class acts as a bridge to the `toolbox-adk` package. - You must install `toolbox-adk` to use this class. - Example: ```python - from toolbox_adk import CredentialStrategy - - toolbox_toolset = ToolboxToolset( - server_url="http://127.0.0.1:5000", - # toolset_name and tool_names are optional. If omitted, all tools are - loaded. - credentials=CredentialStrategy.toolbox_identity() - ) + toolbox_toolset = ToolboxToolset("http://127.0.0.1:5000") ``` """ @@ -64,29 +54,37 @@ class ToolboxToolset(BaseToolset): additional_headers: Optional[Mapping[str, str]] = None, **kwargs, ): - """Args: + """Initializes the ToolboxToolset. - server_url: The URL of the toolbox server. - toolset_name: The name of the toolbox toolset to load. - tool_names: The names of the tools to load. - auth_token_getters: (Deprecated) Map of auth token getters. - bound_params: Parameters to bind to the tools. - credentials: (Optional) toolbox_adk.CredentialConfig object. - additional_headers: (Optional) Static headers dictionary. - **kwargs: Additional arguments passed to the underlying - toolbox_adk.ToolboxToolset. + Args: + server_url: The URL of the toolbox server. + toolset_name: (Optional) The name of the toolbox toolset to load. + tool_names: (Optional) The names of the tools to load. + auth_token_getters: (Optional) A mapping of authentication service names + to callables that return the corresponding authentication token. see: + https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main/packages/toolbox-core#authenticating-tools + for details. + bound_params: (Optional) A mapping of parameter names to bind to specific + values or callables that are called to produce values as needed. see: + https://github.com/googleapis/mcp-toolbox-sdk-python/tree/main/packages/toolbox-core#binding-parameter-values + for details. + credentials: (Optional) toolbox_adk.CredentialConfig object. + additional_headers: (Optional) Static headers mapping. + **kwargs: Additional arguments passed to the underlying + toolbox_adk.ToolboxToolset. + + The resulting ToolboxToolset will contain both tools loaded by tool_names + and toolset_name. + + Note: toolset_name and tool_names are optional. + If both are omitted, all tools are loaded. """ - if not toolset_name and not tool_names: - raise ValueError( - "Either 'toolset_name' or 'tool_names' must be provided." - ) - try: from toolbox_adk import ToolboxToolset as RealToolboxToolset # pylint: disable=import-outside-toplevel except ImportError as exc: raise ImportError( "ToolboxToolset requires the 'toolbox-adk' package. " - "Please install it using `pip install toolbox-adk`." + "Please install it using `pip install google-adk[toolbox]`." ) from exc super().__init__() @@ -95,10 +93,10 @@ class ToolboxToolset(BaseToolset): server_url=server_url, toolset_name=toolset_name, tool_names=tool_names, + auth_token_getters=auth_token_getters, + bound_params=bound_params, credentials=credentials, additional_headers=additional_headers, - bound_params=bound_params, - auth_token_getters=auth_token_getters, **kwargs, )