async def acall_function(
    tools: List[BaseTool], fn_obj: Any, verbose: bool = False
) -> Tuple[ChatMessage, ToolOutput]:
    """Call an async function and return the output as a string."""
    from openai.types.beta.threads.required_action_function_tool_call import Function

    fn_obj = cast(Function, fn_obj)
    # TMP: consolidate with other abstractions
    name = fn_obj.name
    arguments_str = fn_obj.arguments

    if verbose:
        print("=== Calling Function ===")
        print(f"Calling function: {name} with args: {arguments_str}")

    tool = get_function_by_name(tools, name)
    if tool is not None:
        argument_dict = json.loads(arguments_str)
        tool = adapt_to_async_tool(tool)
        output = await tool.acall(**argument_dict)

        if verbose:
            print(f"Got output: {output!s}")
            print("========================")
    else:
        err_msg = build_missing_tool_message(name)
        output = build_error_tool_output(name, arguments_str, err_msg)

        if verbose:
            print(err_msg)
            print("========================")

    return (
        ChatMessage(
            content=str(output),
            role=MessageRole.FUNCTION,
            additional_kwargs={
                "name": fn_obj.name,
            },
        ),
        output,
    )
Call an async function and return the output as a string.
llama-index-integrations/agent/llama-index-agent-openai/llama_index/agent/openai/openai_assistant_agent.py