Repository navigation
Closed
Description
from google.adk.agents import Agent
import random
from typing import Union
def dice(count: Union[int, str] = 6) -> int:
"Rolls an n-sided dice. n is the parameter as string or int"
return int(random.random() * int(count))
root_agent = Agent(
name="chat_agent",
model="gemini-2.0-flash-exp",
instruction="""
You are a friendly chat companion, answer the user's questions stay social.
When asked about facts only answer for well known topics,
otherwise state that you don't know. Don't make up stuff!
""",
tools=[dice]
)2025-04-11 00:41:15,206 - INFO - _client.py:1740 - HTTP Request: POST https://us-central1-aiplatform.googleapis.com/v1beta1/projects/vertex-ai-neo4j-extension/locations/us-central1/publishers/google/models/gemini-2.0-flash-exp:generateContent "HTTP/1.1 400 Bad Request"
2025-04-11 00:41:15,232 - ERROR - fast_api.py:616 - Error in event_generator: 400 INVALID_ARGUMENT. {'error': {'code': 400, 'message': 'Unable to submit request because `dice` functionDeclaration `parameters.count` schema specified other fields alongside any_of. When using any_of, it must be the only field set. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling', 'status': 'INVALID_ARGUMENT'}}
Traceback (most recent call last):
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/cli/fast_api.py", line 605, in event_generator
async for event in runner.run_async(
...<8 lines>...
yield f"data: {sse_event}\n\n"
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/runners.py", line 197, in run_async
async for event in invocation_context.agent.run_async(invocation_context):
...<2 lines>...
yield event
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/agents/base_agent.py", line 141, in run_async
async for event in self._run_async_impl(ctx):
yield event
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/agents/llm_agent.py", line 232, in _run_async_impl
async for event in self._llm_flow.run_async(ctx):
self.__maybe_save_output_to_state(event)
yield event
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/flows/llm_flows/base_llm_flow.py", line 231, in run_async
async for event in self._run_one_step_async(invocation_context):
last_event = event
yield event
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/flows/llm_flows/base_llm_flow.py", line 257, in _run_one_step_async
async for llm_response in self._call_llm_async(
...<6 lines>...
yield event
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/flows/llm_flows/base_llm_flow.py", line 470, in _call_llm_async
async for llm_response in llm.generate_content_async(
...<16 lines>...
yield llm_response
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/adk/models/google_llm.py", line 140, in generate_content_async
response = await self.api_client.aio.models.generate_content(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<3 lines>...
)
^
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/genai/models.py", line 6429, in generate_content
response = await self._generate_content(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
model=model, contents=contents, config=config
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/genai/models.py", line 5431, in _generate_content
response_dict = await self._api_client.async_request(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
'post', path, request_dict, http_options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/genai/_api_client.py", line 708, in async_request
result = await self._async_request(http_request=http_request, stream=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/genai/_api_client.py", line 652, in _async_request
await errors.APIError.raise_for_async_response(response)
File "/Users/mh/d/llm/adk-test/.venv/lib/python3.13/site-packages/google/genai/errors.py", line 129, in raise_for_async_response
raise ClientError(status_code, response_json, response)
google.genai.errors.ClientError: 400 INVALID_ARGUMENT. {'error': {'code': 400, 'message': 'Unable to submit request because `dice` functionDeclaration `parameters.count` schema specified other fields alongside any_of. When using any_of, it must be the only field set. Learn more: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling', 'status': 'INVALID_ARGUMENT'}}
INFO: 127.0.0.1:57384 - "GET /apps/hello-agent/users/user/sessions/ee4e2bce-9416-43a9-a533-99fdb87da4e5 HTTP/1.1" 200 OK
Reacted by Jonathan Gastón Löwenstern and 이병우
Metadata
Metadata
Assignees
Labels
No labels
Activity
mattbeard0 commentedon Apr 10, 2025
Inputs to functions should be more deterministic. This should work as follows:
jexp commentedon Apr 11, 2025
This was just a minimal example. There are other cases where you have not so easily resolved combinations
hangfei commentedon Apr 12, 2025
Current model function calling generally do better with simpler types.
@jexp could you share examples where union is necessary?
bennnym commentedon Apr 12, 2025
Is there any planned support for pydantic types @hangfei ?
hangfei commentedon Apr 14, 2025
@bennnym could you share a code piece of the expected behaviour?
built-by-as commentedon Apr 15, 2025
@hangfei parity with this would be greatly appreciated: https://openai.github.io/openai-agents-python/tools/#automatic-argument-and-docstring-parsing
Pydantic models allow for calling functions with complex structs seamlessly
boyangsvl commentedon Apr 19, 2025
Automatic parsing of argument and docstring is supported by ADK. You can use Pydantic models as arguments in function tools. We just don't support union types as it's a limitation of the model. I'm closing this issue for now.
sandangel commentedon May 4, 2025
Hi, I'm using simple type:
str | None = Noneto mention this argument is optional, if user is not mentioning it then it should be null. Right now it's returning error. Is it possible to support that case? @boyangsvlmattbeard0 commentedon May 4, 2025
Have tried:
def random_function(input: Optional[str] = None)withfrom typing import Optional.Or a less optimal solution of within your tool prompting either a) forcing the LLM to input something there, or b) prompting the LLM to be "if you want the parameter to be blank, input "None" as the string", and writing
if input == "None" then skipsandangel commentedon May 4, 2025
Hi, in the company, we are using
str | Noneas the new way in python to express Optional args and even have aruffrule to convertOptional[str]tostr | None. I think other framework like autogen already supported it. They also support Annotated type for add description to arguments.https://github.com/microsoft/autogen/blob/main/python/packages/autogen-core/src/autogen_core/tools/_function_tool.py#L65-L67
Is there a reason why we can't support Union syntax for optional type? I believe in the schema for arguments there is a field called
requiredand if it's optional type then we can just turn thestr | Nonetorequired: false?sandangel commentedon May 5, 2025
I also just tried
Optional[str], then it generates an error:This is my code:
jonigl commentedon May 14, 2025
I’m running into the same problem when I hook ADK up to a few community MCP servers. Their tool schemas mark some parameters as Optional[...], and ADK forwards that straight to Vertex AI/Gemini as an anyOf union that includes "type": "null". Gemini then throws
Sadly until ADK flattens those Optional fields to the Vertex-AI–style nullable: true form, we can’t integrate those MCP servers without manually rewriting the schema.
jexp commentedon May 26, 2025
It's still happening, seems to be a shortcoming of the Gemini API itself, that ADK would have to wrap/adapt to?
Trying to use an MCP server (that works well everywhere else)
jexp commentedon May 26, 2025
The source MCP server is using Optional for parameters.