From ef837015f3eda8f5ab41ecdc21a5565365ceebdf Mon Sep 17 00:00:00 2001 From: Liang Wu Date: Wed, 6 Aug 2025 14:17:34 -0700 Subject: [PATCH] refactor(config): move BaseToolConfig to a separate file PiperOrigin-RevId: 791841562 --- src/google/adk/agents/llm_agent.py | 2 +- src/google/adk/agents/llm_agent_config.py | 2 +- src/google/adk/tools/agent_tool.py | 4 +- src/google/adk/tools/base_tool.py | 103 ----------------- src/google/adk/tools/crewai_tool.py | 4 +- src/google/adk/tools/example_tool.py | 4 +- src/google/adk/tools/langchain_tool.py | 4 +- src/google/adk/tools/tool_configs.py | 128 ++++++++++++++++++++++ tests/unittests/tools/test_tool_config.py | 2 +- 9 files changed, 139 insertions(+), 114 deletions(-) create mode 100644 src/google/adk/tools/tool_configs.py diff --git a/src/google/adk/agents/llm_agent.py b/src/google/adk/agents/llm_agent.py index db957f93..23450df1 100644 --- a/src/google/adk/agents/llm_agent.py +++ b/src/google/adk/agents/llm_agent.py @@ -47,9 +47,9 @@ from ..models.llm_response import LlmResponse from ..models.registry import LLMRegistry from ..planners.base_planner import BasePlanner from ..tools.base_tool import BaseTool -from ..tools.base_tool import ToolConfig from ..tools.base_toolset import BaseToolset from ..tools.function_tool import FunctionTool +from ..tools.tool_configs import ToolConfig from ..tools.tool_context import ToolContext from ..utils.feature_decorator import working_in_progress from .base_agent import BaseAgent diff --git a/src/google/adk/agents/llm_agent_config.py b/src/google/adk/agents/llm_agent_config.py index d65ec34e..c7500d09 100644 --- a/src/google/adk/agents/llm_agent_config.py +++ b/src/google/adk/agents/llm_agent_config.py @@ -22,7 +22,7 @@ from typing import Optional from google.genai import types from pydantic import ConfigDict -from ..tools.base_tool import ToolConfig +from ..tools.tool_configs import ToolConfig from .base_agent_config import BaseAgentConfig from .common_configs import CodeConfig diff --git a/src/google/adk/tools/agent_tool.py b/src/google/adk/tools/agent_tool.py index de46b9a7..c0d07238 100644 --- a/src/google/adk/tools/agent_tool.py +++ b/src/google/adk/tools/agent_tool.py @@ -28,8 +28,8 @@ from ..agents.common_configs import AgentRefConfig from ..memory.in_memory_memory_service import InMemoryMemoryService from ._forwarding_artifact_service import ForwardingArtifactService from .base_tool import BaseTool -from .base_tool import BaseToolConfig -from .base_tool import ToolArgsConfig +from .tool_configs import BaseToolConfig +from .tool_configs import ToolArgsConfig from .tool_context import ToolContext if TYPE_CHECKING: diff --git a/src/google/adk/tools/base_tool.py b/src/google/adk/tools/base_tool.py index d38acd08..21f721fb 100644 --- a/src/google/adk/tools/base_tool.py +++ b/src/google/adk/tools/base_tool.py @@ -249,106 +249,3 @@ def _find_tool_with_function_declarations( ), None, ) - - -class ToolArgsConfig(BaseModel): - """The configuration for tool arguments. - - This config allows arbitrary key-value pairs as tool arguments. - """ - - model_config = ConfigDict(extra="allow") - - -class ToolConfig(BaseModel): - """The configuration for a tool. - - The config supports these types of tools: - 1. ADK built-in tools - 2. User-defined tool instances - 3. User-defined tool classes - 4. User-defined functions that generate tool instances - 5. User-defined function tools - - For examples: - - 1. For ADK built-in tool instances or classes in `google.adk.tools` package, - they can be referenced directly with the `name` and optionally with - `config`. - - ``` - tools: - - name: google_search - - name: AgentTool - config: - agent: ./another_agent.yaml - skip_summarization: true - ``` - - 2. For user-defined tool instances, the `name` is the fully qualified path - to the tool instance. - - ``` - tools: - - name: my_package.my_module.my_tool - ``` - - 3. For user-defined tool classes (custom tools), the `name` is the fully - qualified path to the tool class and `config` is the arguments for the tool. - - ``` - tools: - - name: my_package.my_module.my_tool_class - config: - my_tool_arg1: value1 - my_tool_arg2: value2 - ``` - - 4. For user-defined functions that generate tool instances, the `name` is - the fully qualified path to the function and `config` is passed to the - function as arguments. - - ``` - tools: - - name: my_package.my_module.my_tool_function - config: - my_function_arg1: value1 - my_function_arg2: value2 - ``` - - The function must have the following signature: - ``` - def my_function(config: ToolArgsConfig) -> BaseTool: - ... - ``` - - 5. For user-defined function tools, the `name` is the fully qualified path - to the function. - - ``` - tools: - - name: my_package.my_module.my_function_tool - ``` - """ - - model_config = ConfigDict(extra="forbid") - - name: str - """The name of the tool. - - For ADK built-in tools, the name is the name of the tool, e.g. `google_search` - or `AgentTool`. - - For user-defined tools, the name is the fully qualified path to the tool, e.g. - `my_package.my_module.my_tool`. - """ - - args: Optional[ToolArgsConfig] = None - """The args for the tool.""" - - -class BaseToolConfig(BaseModel): - """The base configurations for all the tools.""" - - model_config = ConfigDict(extra="forbid") - """Forbid extra fields.""" diff --git a/src/google/adk/tools/crewai_tool.py b/src/google/adk/tools/crewai_tool.py index 50be61c5..9dfe7cc7 100644 --- a/src/google/adk/tools/crewai_tool.py +++ b/src/google/adk/tools/crewai_tool.py @@ -18,9 +18,9 @@ from google.genai import types from typing_extensions import override from . import _automatic_function_calling_util -from .base_tool import BaseToolConfig -from .base_tool import ToolArgsConfig from .function_tool import FunctionTool +from .tool_configs import BaseToolConfig +from .tool_configs import ToolArgsConfig try: from crewai.tools import BaseTool as CrewaiBaseTool diff --git a/src/google/adk/tools/example_tool.py b/src/google/adk/tools/example_tool.py index 4eab01c6..67197dc3 100644 --- a/src/google/adk/tools/example_tool.py +++ b/src/google/adk/tools/example_tool.py @@ -24,8 +24,8 @@ from ..examples import example_util from ..examples.base_example_provider import BaseExampleProvider from ..examples.example import Example from .base_tool import BaseTool -from .base_tool import BaseToolConfig -from .base_tool import ToolArgsConfig +from .tool_configs import BaseToolConfig +from .tool_configs import ToolArgsConfig from .tool_context import ToolContext if TYPE_CHECKING: diff --git a/src/google/adk/tools/langchain_tool.py b/src/google/adk/tools/langchain_tool.py index f4d2206e..44f884ff 100644 --- a/src/google/adk/tools/langchain_tool.py +++ b/src/google/adk/tools/langchain_tool.py @@ -24,9 +24,9 @@ from langchain_core.tools.structured import StructuredTool from typing_extensions import override from . import _automatic_function_calling_util -from .base_tool import BaseToolConfig -from .base_tool import ToolArgsConfig from .function_tool import FunctionTool +from .tool_configs import BaseToolConfig +from .tool_configs import ToolArgsConfig class LangchainTool(FunctionTool): diff --git a/src/google/adk/tools/tool_configs.py b/src/google/adk/tools/tool_configs.py new file mode 100644 index 00000000..a1b82077 --- /dev/null +++ b/src/google/adk/tools/tool_configs.py @@ -0,0 +1,128 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +from typing import Optional + +from pydantic import BaseModel +from pydantic import ConfigDict + +from ..utils.feature_decorator import working_in_progress + + +@working_in_progress("BaseToolConfig is not ready for use.") +class BaseToolConfig(BaseModel): + """The base class for all tool configs.""" + + model_config = ConfigDict(extra="forbid") + """Forbid extra fields.""" + + +@working_in_progress("ToolArgsConfig is not ready for use.") +class ToolArgsConfig(BaseModel): + """Config to host free key-value pairs for the args in ToolConfig.""" + + model_config = ConfigDict(extra="allow") + + +@working_in_progress("ToolConfig is not ready for use.") +class ToolConfig(BaseModel): + """The configuration for a tool. + + The config supports these types of tools: + 1. ADK built-in tools + 2. User-defined tool instances + 3. User-defined tool classes + 4. User-defined functions that generate tool instances + 5. User-defined function tools + + For examples: + + 1. For ADK built-in tool instances or classes in `google.adk.tools` package, + they can be referenced directly with the `name` and optionally with + `args`. + + ``` + tools: + - name: google_search + - name: AgentTool + args: + agent: ./another_agent.yaml + skip_summarization: true + ``` + + 2. For user-defined tool instances, the `name` is the fully qualified path + to the tool instance. + + ``` + tools: + - name: my_package.my_module.my_tool + ``` + + 3. For user-defined tool classes (custom tools), the `name` is the fully + qualified path to the tool class and `args` is the arguments for the tool. + + ``` + tools: + - name: my_package.my_module.my_tool_class + args: + my_tool_arg1: value1 + my_tool_arg2: value2 + ``` + + 4. For user-defined functions that generate tool instances, the `name` is + the fully qualified path to the function and `args` is passed to the + function as arguments. + + ``` + tools: + - name: my_package.my_module.my_tool_function + args: + my_function_arg1: value1 + my_function_arg2: value2 + ``` + + The function must have the following signature: + ``` + def my_function(args: ToolArgsConfig) -> BaseTool: + ... + ``` + + 5. For user-defined function tools, the `name` is the fully qualified path + to the function. + + ``` + tools: + - name: my_package.my_module.my_function_tool + ``` + + If the above use cases don't suffice, users can define a custom tool config + by extending BaseToolConfig and override from_config() in the custom tool. + """ + + model_config = ConfigDict(extra="forbid") + + name: str + """The name of the tool. + + For ADK built-in tools, `name` is the name of the tool, e.g. `google_search` + or `AgentTool`. + + For user-defined tools, the name is the fully qualified path to the tool, e.g. + `my_package.my_module.my_tool`. + """ + + args: Optional[ToolArgsConfig] = None + """The args for the tool.""" diff --git a/tests/unittests/tools/test_tool_config.py b/tests/unittests/tools/test_tool_config.py index b12bbe5f..fefa5060 100644 --- a/tests/unittests/tools/test_tool_config.py +++ b/tests/unittests/tools/test_tool_config.py @@ -13,7 +13,7 @@ # limitations under the License. from google.adk.tools import VertexAiSearchTool -from google.adk.tools.base_tool import ToolConfig +from google.adk.tools.tool_configs import ToolConfig from google.genai import types import yaml