I found that the library is unable to parse a function tool parameter if it's a union type and contains a parametrized generic. The example type in my case was Optional[list[str]]. The error occurs when using the automatic function calling functionality.
The function tool worked correctly after making this modification.
from typing import Optional
from google import genai
from google.genai import types as genai_types
def find_products(
max_results: int = 3,
brands: Optional[list[str]] = None,
):
"""Search for top popular products. Optionally filter for certain brands.
Args:
max_results (int): The max number of results to be returned.
brands (Optional[list[str]]): List of brands to filter products.
"""
return "Not Implemented."
genai_client = genai.Client(vertexai=True, project=PROJECT_ID, location=REGION)
generate_content_response = genai_client.models.generate_content(
model="gemini-1.5-flash-002",
contents="What gucci products do you sell?",
config=genai_types.GenerateContentConfig(
system_instruction="You are a Cymbal Retail chat assistant. Help answer any user questions.",
temperature=0.2,
candidate_count=1,
seed=42,
tools=[find_products],
),
)
print(generate_content_response)
candidates=[Candidate(content=Content(parts=[Part(video_metadata=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=None, inline_data=None, text='I am sorry, I cannot fulfill this request. There was an error when I tried to search for Gucci products.')], role='model'), citation_metadata=None, finish_message=None, token_count=None, avg_logprobs=-0.07933367853579314, finish_reason='STOP', grounding_metadata=None, index=None, logprobs_result=None, safety_ratings=None)] model_version='gemini-1.5-flash-002' prompt_feedback=None usage_metadata=GenerateContentResponseUsageMetadata(cached_content_token_count=None, candidates_token_count=23, prompt_token_count=105, total_token_count=128) automatic_function_calling_history=[Content(parts=[Part(video_metadata=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=None, inline_data=None, text='What gucci products do you sell?')], role='user'), Content(parts=[Part(video_metadata=None, code_execution_result=None, executable_code=None, file_data=None, function_call=FunctionCall(id=None, args={'max_results': 10, 'brands': ['gucci']}, name='find_products'), function_response=None, inline_data=None, text=None)], role='model'), Content(parts=[Part(video_metadata=None, code_execution_result=None, executable_code=None, file_data=None, function_call=None, function_response=FunctionResponse(id=None, name='find_products', response={'error': 'isinstance() argument 2 cannot be a parameterized generic'}), inline_data=None, text=None)], role='user')] parsed=None
I found that the library is unable to parse a function tool parameter if it's a union type and contains a parametrized generic. The example type in my case was
Optional[list[str]]. The error occurs when using the automatic function calling functionality.When iterating over the union types,
isinstance(value, arg)is called, I believe the fix is to modify this toisinstance(value, get_origin(arg))on this line:python-genai/google/genai/_extra_utils.py
Line 141 in cf3c476
The function tool worked correctly after making this modification.
Environment details
Steps to reproduce
When I run this snippet, the library catches the error
'isinstance() argument 2 cannot be a parameterized generic'and the full output is: