@@ -296,20 +296,59 @@ def from_function_with_options(
296296) -> 'types.FunctionDeclaration' :
297297
298298 parameters_properties = {}
299- for name , param in inspect .signature (func ).parameters .items ():
300- if param .kind in (
301- inspect .Parameter .POSITIONAL_OR_KEYWORD ,
302- inspect .Parameter .KEYWORD_ONLY ,
303- inspect .Parameter .POSITIONAL_ONLY ,
304- ):
305- # This snippet catches the case when type hints are stored as strings
306- if isinstance (param .annotation , str ):
307- param = param .replace (annotation = typing .get_type_hints (func )[name ])
308-
309- schema = _function_parameter_parse_util ._parse_schema_from_parameter (
310- variant , param , func .__name__
311- )
312- parameters_properties [name ] = schema
299+ parameters_json_schema = {}
300+ try :
301+ annotation_under_future = typing .get_type_hints (func )
302+ except TypeError :
303+ # This can happen if func is a mock object
304+ annotation_under_future = {}
305+ try :
306+ for name , param in inspect .signature (func ).parameters .items ():
307+ if param .kind in (
308+ inspect .Parameter .POSITIONAL_OR_KEYWORD ,
309+ inspect .Parameter .KEYWORD_ONLY ,
310+ inspect .Parameter .POSITIONAL_ONLY ,
311+ ):
312+ param = _function_parameter_parse_util ._handle_params_as_deferred_annotations (
313+ param , annotation_under_future , name
314+ )
315+
316+ schema = _function_parameter_parse_util ._parse_schema_from_parameter (
317+ variant , param , func .__name__
318+ )
319+ parameters_properties [name ] = schema
320+ except ValueError :
321+ # If the function has complex parameter types that fail in _parse_schema_from_parameter,
322+ # we try to generate a json schema for the parameter using pydantic.TypeAdapter.
323+ parameters_properties = {}
324+ for name , param in inspect .signature (func ).parameters .items ():
325+ if param .kind in (
326+ inspect .Parameter .POSITIONAL_OR_KEYWORD ,
327+ inspect .Parameter .KEYWORD_ONLY ,
328+ inspect .Parameter .POSITIONAL_ONLY ,
329+ ):
330+ try :
331+ if param .annotation == inspect .Parameter .empty :
332+ param = param .replace (annotation = Any )
333+
334+ param = _function_parameter_parse_util ._handle_params_as_deferred_annotations (
335+ param , annotation_under_future , name
336+ )
337+
338+ _function_parameter_parse_util ._raise_for_invalid_enum_value (param )
339+
340+ json_schema_dict = _function_parameter_parse_util ._generate_json_schema_for_parameter (
341+ param
342+ )
343+
344+ parameters_json_schema [name ] = types .Schema .model_validate (
345+ json_schema_dict
346+ )
347+ except Exception as e :
348+ _function_parameter_parse_util ._raise_for_unsupported_param (
349+ param , func .__name__ , e
350+ )
351+
313352 declaration = types .FunctionDeclaration (
314353 name = func .__name__ ,
315354 description = func .__doc__ ,
@@ -324,6 +363,12 @@ def from_function_with_options(
324363 declaration .parameters
325364 )
326365 )
366+ elif parameters_json_schema :
367+ declaration .parameters = types .Schema (
368+ type = 'OBJECT' ,
369+ properties = parameters_json_schema ,
370+ )
371+
327372 if variant == GoogleLLMVariant .GEMINI_API :
328373 return declaration
329374
@@ -372,17 +417,35 @@ def from_function_with_options(
372417 inspect .Parameter .POSITIONAL_OR_KEYWORD ,
373418 annotation = return_annotation ,
374419 )
375- # This snippet catches the case when type hints are stored as strings
376420 if isinstance (return_value .annotation , str ):
377421 return_value = return_value .replace (
378422 annotation = typing .get_type_hints (func )['return' ]
379423 )
380424
381- declaration .response = (
382- _function_parameter_parse_util ._parse_schema_from_parameter (
383- variant ,
384- return_value ,
385- func .__name__ ,
425+ response_schema : Optional [types .Schema ] = None
426+ response_json_schema : Optional [Union [Dict [str , Any ], types .Schema ]] = None
427+ try :
428+ response_schema = (
429+ _function_parameter_parse_util ._parse_schema_from_parameter (
430+ variant ,
431+ return_value ,
432+ func .__name__ ,
433+ )
434+ )
435+ except ValueError :
436+ try :
437+ response_json_schema = (
438+ _function_parameter_parse_util ._generate_json_schema_for_parameter (
439+ return_value
440+ )
386441 )
387- )
442+ response_json_schema = types .Schema .model_validate (response_json_schema )
443+ except Exception as e :
444+ _function_parameter_parse_util ._raise_for_unsupported_param (
445+ return_value , func .__name__ , e
446+ )
447+ if response_schema :
448+ declaration .response = response_schema
449+ elif response_json_schema :
450+ declaration .response = response_json_schema
388451 return declaration
0 commit comments