# 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 typing import Any from typing import Callable from google.genai import types from pydantic import model_validator from typing_extensions import override from . import _automatic_function_calling_util from .function_tool import FunctionTool class LangchainTool(FunctionTool): """Use this class to wrap a langchain tool. If the original tool name and description are not suitable, you can override them in the constructor. """ tool: Any """The wrapped langchain tool.""" def __init__(self, tool: Any): super().__init__(tool._run) self.tool = tool if tool.name: self.name = tool.name if tool.description: self.description = tool.description @model_validator(mode='before') @classmethod def populate_name(cls, data: Any) -> Any: # Override this to not use function's signature name as it's # mostly "run" or "invoke" for thir-party tools. return data @override def _get_declaration(self) -> types.FunctionDeclaration: """Build the function declaration for the tool.""" from langchain.agents import Tool from langchain_core.tools import BaseTool # There are two types of tools: # 1. BaseTool: the tool is defined in langchain.tools. # 2. Other tools: the tool doesn't inherit any class but follow some # conventions, like having a "run" method. if isinstance(self.tool, BaseTool): tool_wrapper = Tool( name=self.name, func=self.func, description=self.description, ) if self.tool.args_schema: tool_wrapper.args_schema = self.tool.args_schema function_declaration = _automatic_function_calling_util.build_function_declaration_for_langchain( False, self.name, self.description, tool_wrapper.func, tool_wrapper.args, ) return function_declaration else: # Need to provide a way to override the function names and descriptions # as the original function names are mostly ".run" and the descriptions # may not meet users' needs. function_declaration = ( _automatic_function_calling_util.build_function_declaration( func=self.tool.run, ) ) return function_declaration