Skip to content

Builtin tools that have tool_context as a parameter don't get a description from the doc-string #551

Closed
@efunneko

Description

@efunneko

Describe the bug
If you add a built-in tool (python function) to your agent and that tool contains one of the 'ignored parameters', such as tool_context, in its parameters, the ADK will rebuild that function without that parameter. When it does this, it neglects to copy the doc attribute to the new function. Then when the tool declaration is built for the LLM API call, its description is empty. This is particularly bad if you are calling an Anthropic model on Bedrock because it demands a description.

To Reproduce
Steps to reproduce the behavior:

  1. Create a very basic agent with a single 'python' tool type
  2. Create a python function that has a 'tool_context' parameter
  3. Run an inference and look at the tool list that is sent to the LLM (your tool will have 'description: ""'

Expected behavior
The tool list will contain a description for each tool

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Python version(python -V): 3.11.10
  • ADK version(pip show google-adk): 0.4.0

Possible Fix

def build_function_declaration(
    func: Union[Callable, BaseModel],
    ignore_params: Optional[list[str]] = None,
    variant: Literal['GOOGLE_AI', 'VERTEX_AI', 'DEFAULT'] = 'GOOGLE_AI',
) -> types.FunctionDeclaration:
  signature = inspect.signature(func)
  new_func = None
  if not ignore_params:
    ignore_params = []
  for name, _ in signature.parameters.items():
    if name in ignore_params:
      should_update_signature = True
      break
  if should_update_signature:
    new_params = [
        param
        for name, param in signature.parameters.items()
        if name not in ignore_params
    ]
    if isinstance(func, type):
      fields = {
          name: (param.annotation, param.default)
          for name, param in signature.parameters.items()
          if name not in ignore_params
      }
      new_func = create_model(func.__name__, **fields)
    else:
      new_sig = signature.replace(parameters=new_params)
      new_func = FunctionType(
          func.__code__,
          func.__globals__,
          func.__name__,
          func.__defaults__,
          func.__closure__,
      )
      new_func.__signature__ = new_sig

      # FIX
      new_func.__doc__ = func.__doc__

  return (
      from_function_with_options(func, variant)
      if not should_update_signature
      else from_function_with_options(new_func, variant)
  )

Metadata

Metadata

Assignees

Labels

toolsIssues related to tools

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions