def get_function_description(fn: Callable) -> tuple[str, dict[str, str], list[str]]:
    """
    Get the description of a function, its parameters, and return values by parsing the docstring.
    The docstring should be formatted as follows: first lines are the description
    of the function, then a line starts with "Args:", "Parameters:", or "Arguments:",
    followed by lines of the form "param_name: description", then optionally a line
    that starts with "Returns:" followed by descriptions of return values.

    Parameters:
        fn: The function to get the docstring for.

    Returns:
        - The docstring of the function
        - A dictionary of parameter names and their descriptions
        - A list of return value descriptions
    """
    fn_docstring = fn.__doc__
    description = ""
    parameters = {}
    returns = []

    if not fn_docstring:
        return description, parameters, returns

    lines = fn_docstring.strip().split("\n")

    description_lines = []
    for line in lines:
        line = line.strip()
        if line.startswith(("Args:", "Parameters:", "Arguments:", "Returns:")):
            break
        if line:
            description_lines.append(line)

    description = " ".join(description_lines)

    try:
        param_start_idx = next(
            (
                i
                for i, line in enumerate(lines)
                if line.strip().startswith(("Args:", "Parameters:", "Arguments:"))
            ),
            len(lines),
        )

        returns_start_idx = next(
            (i for i, line in enumerate(lines) if line.strip().startswith("Returns:")),
            len(lines),
        )

        # Parse parameters section (from param_start_idx to returns_start_idx or end)
        param_end_idx = (
            returns_start_idx if returns_start_idx < len(lines) else len(lines)
        )
        for line in lines[param_start_idx + 1 : param_end_idx]:
            line = line.strip()
            if not line:
                continue
            if line.startswith("Returns:"):
                break

            try:
                if ":" in line:
                    param_name, param_desc = line.split(":", 1)
                    param_name = param_name.split(" ")[0].strip()
                    if param_name:
                        parameters[param_name] = param_desc.strip()
            except Exception:
                continue

        # Parse returns section
        if returns_start_idx < len(lines):
            for line in lines[returns_start_idx + 1 :]:
                line = line.strip()
                if not line:
                    continue

                try:
                    if line.startswith("-"):
                        returns.append(line[1:].strip())
                    elif ":" in line:
                        _, return_desc = line.split(":", 1)
                        returns.append(return_desc.strip())
                    else:
                        returns.append(line)
                except Exception:
                    continue

    except Exception:
        pass

    return description, parameters, returns

    Get the description of a function, its parameters, and return values by parsing the docstring.
    The docstring should be formatted as follows: first lines are the description
    of the function, then a line starts with "Args:", "Parameters:", or "Arguments:",
    followed by lines of the form "param_name: description", then optionally a line
    that starts with "Returns:" followed by descriptions of return values.

    Parameters:
        fn: The function to get the docstring for.

    Returns:
        - The docstring of the function
        - A dictionary of parameter names and their descriptions
        - A list of return value descriptions
    
gradio/utils.py