(the_func: ToolFunction[...])
| 1965 | """ |
| 1966 | |
| 1967 | def _create_function_tool(the_func: ToolFunction[...]) -> FunctionTool: |
| 1968 | is_sync_function_tool = not inspect.iscoroutinefunction(the_func) |
| 1969 | schema = function_schema( |
| 1970 | func=the_func, |
| 1971 | name_override=name_override, |
| 1972 | description_override=description_override, |
| 1973 | docstring_style=docstring_style, |
| 1974 | use_docstring_info=use_docstring_info, |
| 1975 | strict_json_schema=strict_mode, |
| 1976 | ) |
| 1977 | |
| 1978 | async def _on_invoke_tool_impl(ctx: ToolContext[Any], input: str) -> Any: |
| 1979 | tool_name = ctx.tool_name |
| 1980 | json_data = _parse_function_tool_json_input(tool_name=tool_name, input_json=input) |
| 1981 | _log_function_tool_invocation(tool_name=tool_name, input_json=input) |
| 1982 | |
| 1983 | try: |
| 1984 | parsed = ( |
| 1985 | schema.params_pydantic_model(**json_data) |
| 1986 | if json_data |
| 1987 | else schema.params_pydantic_model() |
| 1988 | ) |
| 1989 | except ValidationError as e: |
| 1990 | raise ModelBehaviorError(f"Invalid JSON input for tool {tool_name}: {e}") from e |
| 1991 | |
| 1992 | args, kwargs_dict = schema.to_call_args(parsed) |
| 1993 | |
| 1994 | if not _debug.DONT_LOG_TOOL_DATA: |
| 1995 | logger.debug(f"Tool call args: {args}, kwargs: {kwargs_dict}") |
| 1996 | |
| 1997 | if not is_sync_function_tool: |
| 1998 | if schema.takes_context: |
| 1999 | result = await the_func(ctx, *args, **kwargs_dict) |
| 2000 | else: |
| 2001 | result = await the_func(*args, **kwargs_dict) |
| 2002 | else: |
| 2003 | if schema.takes_context: |
| 2004 | result = await asyncio.to_thread(the_func, ctx, *args, **kwargs_dict) |
| 2005 | else: |
| 2006 | result = await asyncio.to_thread(the_func, *args, **kwargs_dict) |
| 2007 | |
| 2008 | if _debug.DONT_LOG_TOOL_DATA: |
| 2009 | logger.debug(f"Tool {tool_name} completed.") |
| 2010 | else: |
| 2011 | logger.debug(f"Tool {tool_name} returned {result}") |
| 2012 | |
| 2013 | return result |
| 2014 | |
| 2015 | function_tool = _build_wrapped_function_tool( |
| 2016 | name=schema.name, |
| 2017 | description=schema.description or "", |
| 2018 | params_json_schema=schema.params_json_schema, |
| 2019 | invoke_tool_impl=_on_invoke_tool_impl, |
| 2020 | on_handled_error=_build_handled_function_tool_error_handler( |
| 2021 | span_message="Error running tool (non-fatal)", |
| 2022 | span_message_for_json_decode_error="Error running tool", |
| 2023 | log_label="Tool", |
| 2024 | ), |
no test coverage detected