Custom tool usage fails

I have been trying to learn how to create and use custom tools but kept getting errors. So I tried to replicate the training on deeplearning.ai on my local, but still get the same error. Therefore I believe it is not the way I am defining tools, because I have copied and pasted it from the training. There is the detail of the error I am getting:
":rocket: Crew: crew
β”œβ”€β”€ :clipboard: Task: f29b0972-dfbd-453d-b109-0f3942e4880a
β”‚ Assigned to: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ └── :robot: Agent: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ β”œβ”€β”€ :wrench: Used List files in directory (4)
β”‚ └── :wrench: Used Read a file’s content (6)
└── :clipboard: Task: 5b85f8cf-6215-40c3-8b2f-2390961e5542
Status: Executing Task…
└── :robot: Agent: Lead Sales Representative
Status: In Progress
└── :wrench: Using Sentiment Analysis (1)

:rocket: Crew: crew
β”œβ”€β”€ :clipboard: Task: f29b0972-dfbd-453d-b109-0f3942e4880a
β”‚ Assigned to: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ └── :robot: Agent: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ β”œβ”€β”€ :wrench: Used List files in directory (4)
β”‚ └── :wrench: Used Read a file’s content (6)
└── :clipboard: Task: 5b85f8cf-6215-40c3-8b2f-2390961e5542
Status: Executing Task…
└── :robot: Agent: Lead Sales Representative
Status: In Progress
└── :wrench: Failed Sentiment Analysis (1)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ Tool Error ─────────────────────────────────┐
β”‚ β”‚
β”‚ Tool Usage Failed β”‚
β”‚ Name: Sentiment Analysis β”‚
β”‚ Error: β€˜Sentiment Analysis Tool’ β”‚
β”‚ β”‚
β”‚ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

An unknown error occurred. Please check the details below.
Error details: β€˜Sentiment Analysis Tool’
An unknown error occurred. Please check the details below.
Error details: β€˜Sentiment Analysis Tool’
:rocket: Crew: crew
β”œβ”€β”€ :clipboard: Task: f29b0972-dfbd-453d-b109-0f3942e4880a
β”‚ Assigned to: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ └── :robot: Agent: Sales Representative
β”‚ Status: :white_check_mark: Completed
β”‚ β”œβ”€β”€ :wrench: Used List files in directory (4)
β”‚ └── :wrench: Used Read a file’s content (6)
└── :clipboard: Task: 5b85f8cf-6215-40c3-8b2f-2390961e5542
Status: Executing Task…
β”œβ”€β”€ :robot: Agent: Lead Sales Representative
β”‚ Status: In Progress
β”‚ └── :wrench: Failed Sentiment Analysis (1)
└── :robot: Agent: Lead Sales Representative
Status: In Progress"
My import:

from crewai.tools import BaseTool

Defining the tool:

class SentimentAnalysisTool(BaseTool):
name: str =β€œSentiment Analysis Tool”
description: str = ("Analyzes the sentiment of text "
β€œto ensure positive and engaging communication.”)

def _run(self, text: str) -> str:
    # Your custom code tool goes here
    return "positive"

sentiment_analysis_tool = SentimentAnalysisTool()

Task that uses it:
personalized_outreach_task = Task(
description=(
"Using the insights gathered from "
"the lead profiling report on {lead_name}, "
"craft a personalized outreach campaign "
"aimed at {key_decision_maker}, "
"the {position} of {lead_name}. "
"The campaign should address their recent {milestone} "
"and how our solutions can support their goals. "
"Your communication must resonate "
"with {lead_name}'s company culture and values, "
"demonstrating a deep understanding of "
β€œtheir business and needs.\n”
"Don’t make assumptions and only "
β€œuse information you absolutely sure about.”
),
expected_output=(
"A series of personalized email drafts "
"tailored to {lead_name}, "
β€œspecifically targeting {key_decision_maker}.”
"Each draft should include "
"a compelling narrative that connects our solutions "
"with their recent achievements and future goals. "
"Ensure the tone is engaging, professional, "
β€œand aligned with {lead_name}'s corporate identity.”
),
tools=[sentiment_analysis_tool],
agent=lead_sales_rep_agent,)

agent that uses it:
lead_sales_rep_agent = Agent(
role=β€œLead Sales Representative”,
goal=β€œNurture leads with personalized, compelling communications”,
backstory=(
"Within the vibrant ecosystem of CrewAI’s sales department, "
"you stand out as the bridge between potential clients "
β€œand the solutions they need.”
"By creating engaging, personalized messages, "
"you not only inform leads about our offerings "
β€œbut also make them feel seen and heard.”
"Your role is pivotal in converting interest "
"into action, guiding leads through the journey "
β€œfrom curiosity to commitment.”
),
allow_delegation=False,
llm = llm,
verbose=True
)

crew:

crew = Crew(
agents=[sales_rep_agent, lead_sales_rep_agent],
tasks=[lead_profiling_task, personalized_outreach_task],
verbose=True
)

This is my first ever message, sorry if I missed some things and thank you for your support

It is even more weird because later on it managed to use it. Why does tool usage fail or succeed? └── :clipboard: Task: 5b85f8cf-6215-40c3-8b2f-2390961e5542
Status: Executing Task…
β”œβ”€β”€ :robot: Agent: Lead Sales Representative
β”‚ Status: In Progress
β”‚ └── :wrench: Failed Sentiment Analysis (1)
└── :robot: Agent: Lead Sales Representative
Status: In Progress
└── :wrench: Used Sentiment Analysis Tool (1)

Not sure why it’s failing but I can suggest 2 things:

  1. Add a tool input class
  2. Explicitly tell the agent to use the tool in the agent/task description
from crewai.tools import BaseTool
from pydantic import BaseModel, Field

class SentimentAnalysisToolInput(BaseModel):
    """Input schema for SentimentAnalysisTool."""
    text: str = Field(..., description="Text for sentiment analysis")

class SentimentAnalysisTool(BaseTool):
name: str =β€œSentiment Analysis Tool”
description: str = ("Analyzes the sentiment of text "
β€œto ensure positive and engaging communication.”)
args_schema: Type[BaseModel] = SentimentAnalysisToolInput

def _run(self, text: str) -> str:
    # Your custom code tool goes here
    return "positive"

This might help as the agent would know the inputs of the tool and that it has to use it. Let me know how it goes.

args_schema: Type[BaseModel] = SentimentAnalysisToolInput does not work. Can’t find β€˜Type’ and I could not find which package it belongs to
Traceback (most recent call last):

File ~\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)

File c:\users\handealp\untitled19.py:64
class SentimentAnalysisTool(BaseTool):

File c:\users\handealp\untitled19.py:68 in SentimentAnalysisTool
args_schema: Type[BaseModel] = SentimentAnalysisToolInput

NameError: name β€˜Type’ is not defined

Just import Type:

from crewai.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Type

class SentimentAnalysisToolInput(BaseModel):
    """Input schema for SentimentAnalysisTool."""
    text: str = Field(..., description="Text for sentiment analysis")

class SentimentAnalysisTool(BaseTool):
    name: str ="Sentiment Analysis Tool"
    description: str = (
        "Analyzes the sentiment of text to ensure "
        "positive and engaging communication."
    )
    args_schema: Type[BaseModel] = SentimentAnalysisToolInput

    def _run(self, text: str) -> str:
        # Your custom code tool goes here
        return "positive"

if __name__ == "__main__":
    sentiment_analysis_test = SentimentAnalysisTool().run
    result = sentiment_analysis_test("Your support team is useless")
    print(f"\nAnalysis Result = {result}\n")