Skip to content

[FEATURE] [UX] before_tool_call decorator's tools parameter should auto-normalize tool names to match ToolCallHookContext.tool_name #5335

@wuwenrufeng

Description

@wuwenrufeng

Feature Area

Core functionality

Is your feature request related to a an existing bug? Please link it here.

no

Describe the solution you'd like

Modify the before_tool_call decorator (and after_tool_call) to sanitize the tools list parameter using crewai.utilities.string_utils.sanitize_tool_name() before comparison:

# In crewai/hooks/decorators.py (pseudocode)
from crewai.utilities.string_utils import sanitize_tool_name

def _create_hook_decorator(
    hook_type: str,
    register_function: Callable[..., Any],
    marker_attribute: str,
) -> Callable[..., Any]:
    """Create a hook decorator with filtering support.

    This factory function eliminates code duplication across the four hook decorators.

    Args:
        hook_type: Type of hook ("llm" or "tool")
        register_function: Function to call for registration (e.g., register_before_llm_call_hook)
        marker_attribute: Attribute name to mark functions (e.g., "is_before_llm_call_hook")

    Returns:
        A decorator function that supports filters and auto-registration
    """
    def decorator_factory(
        func: Callable[..., Any] | None = None,
        *,
        tools: list[str] | None = None,
        agents: list[str] | None = None,
    ) -> Callable[..., Any]:
        tools = [sanitize_tool_name(tool) for tool in tools]
        def decorator(f: Callable[..., Any]) -> Callable[..., Any]:
            setattr(f, marker_attribute, True)

            ...

Describe alternatives you've considered

No response

Additional context

This inconsistency was discovered while debugging why file operation hooks weren't triggering. The developer expectation is that the string defined in BaseTool.name should be the same string used for filtering in hooks, without needing to understand internal sanitization logic.

Willingness to Contribute

Yes, I'd be happy to submit a pull request

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions