code: from typing import TYPE_CHECKING, Any, Optional
  
  from llama_index.legacy.core.base_query_engine import BaseQueryEngine
  
  if TYPE_CHECKING:
      from llama_index.legacy.langchain_helpers.agents.tools import (
          LlamaIndexTool,
      )
  from llama_index.legacy.tools.types import AsyncBaseTool, ToolMetadata, ToolOutput
  
  DEFAULT_NAME = "query_engine_tool"
  DEFAULT_DESCRIPTION = """Useful for running a natural language query
  against a knowledge base and get back a natural language response.
  """
  
  
  class QueryEngineTool(AsyncBaseTool):
      """Query engine tool.
  
      A tool making use of a query engine.
  
      Args:
          query_engine (BaseQueryEngine): A query engine.
          metadata (ToolMetadata): The associated metadata of the query engine.
      """
  
      def __init__(
          self,
          query_engine: BaseQueryEngine,
          metadata: ToolMetadata,
          resolve_input_errors: bool = True,
      ) -> None:
          self._query_engine = query_engine
          self._metadata = metadata
          self._resolve_input_errors = resolve_input_errors
  
      @classmethod
      def from_defaults(
          cls,
          query_engine: BaseQueryEngine,
          name: Optional[str] = None,
          description: Optional[str] = None,
          resolve_input_errors: bool = True,
      ) -> "QueryEngineTool":
          name = name or DEFAULT_NAME
          description = description or DEFAULT_DESCRIPTION
  
          metadata = ToolMetadata(name=name, description=description)
          return cls(
              query_engine=query_engine,
              metadata=metadata,
              resolve_input_errors=resolve_input_errors,
          )
  
      @property
      def query_engine(self) -> BaseQueryEngine:
          return self._query_engine
  
      @property
      def metadata(self) -> ToolMetadata:
          return self._metadata
  
      def call(self, *args: Any, **kwargs: Any) -> ToolOutput:
          if args is not None and len(args) > 0:
              query_str = str(args[0])
          elif kwargs is not None and "input" in kwargs:
              # NOTE: this assumes our default function schema of `input`
              query_str = kwargs["input"]
          elif kwargs is not None and self._resolve_input_errors:
              query_str = str(kwargs)
          else:
              raise ValueError(
                  "Cannot call query engine without specifying `input` parameter."
              )
  
          response = self._query_engine.query(query_str)
          return ToolOutput(
              content=str(response),
              tool_name=self.metadata.name,
              raw_input={"input": query_str},
              raw_output=response,
          )
  
      async def acall(self, *args: Any, **kwargs: Any) -> ToolOutput:
          if args is not None and len(args) > 0:
              query_str = str(args[0])
          elif kwargs is not None and "input" in kwargs:
              # NOTE: this assumes our default function schema of `input`
              query_str = kwargs["input"]
          elif kwargs is not None and self._resolve_input_errors:
              query_str = str(kwargs)
          else:
              raise ValueError("Cannot call query engine without inputs")
  
          response = await self._query_engine.aquery(query_str)
          return ToolOutput(
              content=str(response),
              tool_name=self.metadata.name,
              raw_input={"input": query_str},
              raw_output=response,
          )
  
      def as_langchain_tool(self) -> "LlamaIndexTool":
          from llama_index.legacy.langchain_helpers.agents.tools import (
              IndexToolConfig,
              LlamaIndexTool,
          )
  
          tool_config = IndexToolConfig(
              query_engine=self.query_engine,
              name=self.metadata.name,
              description=self.metadata.description,
          )
          return LlamaIndexTool.from_tool_config(tool_config=tool_config)
  
apis: llama_index.legacy.langchain_helpers.agents.tools.LlamaIndexTool.from_tool_config llama_index.legacy.tools.types.ToolMetadata llama_index.legacy.langchain_helpers.agents.tools.IndexToolConfig
extract_api: [((1408, 1456), 'llama_index.legacy.tools.types.ToolMetadata', 'ToolMetadata', ([], {'name': 'name', 'description': 'description'}), '(name=name, description=description)\n', (1420, 1456), False, 'from llama_index.legacy.tools.types import AsyncBaseTool, ToolMetadata, ToolOutput\n'), ((3568, 3683), 'llama_index.legacy.langchain_helpers.agents.tools.IndexToolConfig', 'IndexToolConfig', ([], {'query_engine': 'self.query_engine', 'name': 'self.metadata.name', 'description': 'self.metadata.description'}), '(query_engine=self.query_engine, name=self.metadata.name,\n    description=self.metadata.description)\n', (3583, 3683), False, 'from llama_index.legacy.langchain_helpers.agents.tools import IndexToolConfig, LlamaIndexTool\n'), ((3742, 3798), 'llama_index.legacy.langchain_helpers.agents.tools.LlamaIndexTool.from_tool_config', 'LlamaIndexTool.from_tool_config', ([], {'tool_config': 'tool_config'}), '(tool_config=tool_config)\n', (3773, 3798), False, 'from llama_index.legacy.langchain_helpers.agents.tools import IndexToolConfig, LlamaIndexTool\n')]