Skip to content

Tool Description not showing correct return type. #723

@ygicp

Description

@ygicp

[FEEL FREE TO POINT OUT MY MISTAKES IN THE QUESTION ITSELF]

I am running the code provided by documentation here. I have setup logging, so I am setting logs from google.adk.models.lite_llm.

The logs however look like below:

14-May-2025 17:45:57 - INFO - google.adk.models.lite_llm:614 - 
LLM Request:
-----------------------------------------------------------
System Instruction:
You are a helpful agent who can answer user questions about the time and weather in a city.

You are an agent. Your internal name is "weather_time_agent".

 The description about you is "Agent to answer questions about the time and weather in a city."
-----------------------------------------------------------
Contents:
{"parts":[{"text":"What is the weather in SF?"}],"role":"User"}
-----------------------------------------------------------
Functions:
get_weather: {'city': {'type': <Type.STRING: 'STRING'>}} -> None
get_current_time: {'city': {'type': <Type.STRING: 'STRING'>}} -> None
-----------------------------------------------------------

17:45:57 - LiteLLM:INFO: utils.py:3108 - 
LiteLLM completion() model= deepseek-ai/DeepSeek-V3; provider = together_ai


.
.
.

Don't you think the functions should have a return type? instead of None? is the Agent seeing the same?

The code is here:

play.py

import datetime
from zoneinfo import ZoneInfo

import dotenv
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types

from utils import core_utils

core_utils.setup_logging()

logger = core_utils.get_logger(__name__)


# litellm._turn_on_debug()


dotenv.load_dotenv("./agent_google/.env")

# Temporary Configs
APP_NAME = "poc_app_2"
USER_ID = "1234_2"
SESSION_ID = "session1234_2"


def get_weather(city: str) -> dict:
  """Retrieves the current weather report for a specified city.

  Args:
      city (str): The name of the city for which to retrieve the weather report.

  Returns:
      dict: status and result or error msg.
  """
  if city.lower() == "new york":
    return {
      "status": "success",
      "report": (
        "The weather in New York is sunny with a temperature of 25 degrees"
        " Celsius (77 degrees Fahrenheit)."
      ),
    }
  else:
    return {
      "status": "error",
      "error_message": f"Weather information for '{city}' is not available.",
    }


def get_current_time(city: str) -> dict:
  """Returns the current time in a specified city.

  Args:
      city (str): The name of the city for which to retrieve the current time.

  Returns:
      dict: status and result or error msg.
  """

  if city.lower() == "new york":
    tz_identifier = "America/New_York"
  else:
    return {
      "status": "error",
      "error_message": (
        f"Sorry, I don't have timezone information for {city}."
      ),
    }

  tz = ZoneInfo(tz_identifier)
  now = datetime.datetime.now(tz)
  report = (
    f"The current time in {city} is {now.strftime('%Y-%m-%d %H:%M:%S %Z%z')}"
  )
  return {"status": "success", "report": report}


root_agent = Agent(
  name="weather_time_agent",
  model=LiteLlm("together_ai/deepseek-ai/DeepSeek-V3"),
  description=(
    "Agent to answer questions about the time and weather in a city."
  ),
  instruction=(
    "You are a helpful agent who can answer user questions about the time and weather in a city."
  ),
  tools=[get_weather, get_current_time],
)

# Session and Runner
session_service = InMemorySessionService()
session = session_service.create_session(
  app_name=APP_NAME,
  user_id=USER_ID,
  session_id=SESSION_ID,
)
runner = Runner(
  agent=root_agent,
  app_name=APP_NAME,
  session_service=session_service,
)

content = types.Content(
  role="User", parts=[types.Part(text="What is the weather in SF?")]
)
events = runner.run(
  user_id=USER_ID,
  session_id=SESSION_ID,
  new_message=content,
)

utils/core_utils.py

"""Core utils for all different modules."""

import logging
import os
import pathlib

_LOGGER_SETUP = False

DASH_LINE = "\n" + "-" * 80 + "\n"


def create_dirs(path: str) -> str:
  """Generate the directory tree based on filepath or directory path.

  Args:
    path (str): File path or directory path.

  Returns:
    str: The path of the directory that is created.

  """
  # First check if a given path is file or dir
  is_file = False
  _, ext = os.path.split(path)
  if ext:
    is_file = True
  elif path.endswith(os.path.sep):
    is_file = False

  if is_file:
    dirname = os.path.dirname(path)
  else:
    dirname = path

  path_obj = pathlib.Path(dirname)
  try:
    path_obj.mkdir(parents=True, exist_ok=False)
  except FileExistsError:
    print(f"Directory : {dirname} already exists")

  return dirname


def setup_logging(logger_file_path: str = "./logger.log") -> None:
  """Setup logging, with a given filepath.

  Args:
      logger_file_path (str): filepath to save logs to. Defaults to logger.log
  """
  global _LOGGER_SETUP
  if _LOGGER_SETUP:
    return

  if not os.path.exists(logger_file_path):
    create_dirs(logger_file_path)

  formatter = logging.Formatter(
    fmt="%(asctime)s - %(levelname)s - %(name)s:%(lineno)d - %(message)s",
    datefmt="%d-%b-%Y %H:%M:%S",
  )

  file_handler = logging.FileHandler(
    filename=logger_file_path, mode="w", encoding="utf-8"
  )
  file_handler.setFormatter(formatter)
  file_handler.setLevel(logging.INFO)

  stream_handler = logging.StreamHandler()
  stream_handler.setFormatter(formatter)
  stream_handler.setLevel(logging.INFO)

  root_logger = logging.getLogger()
  root_logger.setLevel(logging.INFO)
  root_logger.addHandler(file_handler)
  root_logger.addHandler(stream_handler)

  _LOGGER_SETUP = True


def get_logger(name) -> logging.Logger:
  """Get logger for a particular module name.

  Args:
      name (str): Name of the file.

  Returns:
      Logger: Logger object.
  """
  return logging.getLogger(name)

Metadata

Metadata

Assignees

Labels

models[Component] Issues related to model support

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions