def _prepare_function_call(func: Callable, args: tuple, kwargs: dict) -> tuple[str, dict, Optional[Type[BaseModel]]]:
    """Prepares a function call for LLM processing by extracting and validating necessary information.
    
    This internal helper function handles:
    1. Extracting and validating the function's return type (must be Pydantic model if specified)
    2. Processing function arguments and applying defaults
    3. Rendering the function's docstring as a template using the provided arguments
    
    Args:
        func: The function to be processed
        args: Positional arguments passed to the function
        kwargs: Keyword arguments passed to the function
        
    Returns:
        A tuple containing:
        - formatted_docstring: The rendered docstring with arguments applied
        - all_kwargs: Dictionary of all arguments (both positional and keyword)
        - return_type: The expected return type (Pydantic model) or None
        
    Raises:
        AssertionError: If return type is specified but is not a Pydantic BaseModel
    """
    signature = inspect.signature(func)
    docstring = inspect.getdoc(func) or ""
    type_hints = get_type_hints(func)

    # We only support Pydantic now
    if type_hints.get('return', None):
        assert issubclass(type_hints.get('return', None), BaseModel), "Output type must be Pydantic class"

    # Create a dictionary of parameter types
    bound_args = signature.bind(*args, **kwargs)
    bound_args.apply_defaults()  # Apply default values for missing parameters
    all_kwargs = bound_args.arguments

    template = Template(docstring)
    formatted_docstring = template.render(**all_kwargs)

    func_output = func(*args, **kwargs)
    if isinstance(func_output, str):
        formatted_docstring += f" {func_output}"
    return formatted_docstring, all_kwargs, type_hints.get('return', None)
Prepares a function call for LLM processing by extracting and validating necessary information.
    
    This internal helper function handles:
    1. Extracting and validating the function's return type (must be Pydantic model if specified)
    2. Processing function arguments and applying defaults
    3. Rendering the function's docstring as a template using the provided arguments
    
    Args:
        func: The function to be processed
        args: Positional arguments passed to the function
        kwargs: Keyword arguments passed to the function
        
    Returns:
        A tuple containing:
        - formatted_docstring: The rendered docstring with arguments applied
        - all_kwargs: Dictionary of all arguments (both positional and keyword)
        - return_type: The expected return type (Pydantic model) or None
        
    Raises:
        AssertionError: If return type is specified but is not a Pydantic BaseModel
    
smartfunc/__init__.py