diff --git a/crewai/agents/__init__.py b/crewai/agents/__init__.py index 3684f2897..c14004aee 100644 --- a/crewai/agents/__init__.py +++ b/crewai/agents/__init__.py @@ -1,4 +1,4 @@ -from .cache_handler import CacheHandler +from .cache.cache_handler import CacheHandler from .executor import CrewAgentExecutor from .output_parser import CrewAgentOutputParser from .tools_handler import ToolsHandler diff --git a/crewai/agents/cache/__init__.py b/crewai/agents/cache/__init__.py new file mode 100644 index 000000000..ab6ba9674 --- /dev/null +++ b/crewai/agents/cache/__init__.py @@ -0,0 +1,2 @@ +from .cache_handler import CacheHandler +from .cache_hit import CacheHit diff --git a/crewai/agents/cache_handler.py b/crewai/agents/cache/cache_handler.py similarity index 100% rename from crewai/agents/cache_handler.py rename to crewai/agents/cache/cache_handler.py diff --git a/crewai/agents/cache_hit.py b/crewai/agents/cache/cache_hit.py similarity index 100% rename from crewai/agents/cache_hit.py rename to crewai/agents/cache/cache_hit.py diff --git a/crewai/agents/exceptions.py b/crewai/agents/exceptions.py new file mode 100644 index 000000000..651bbda25 --- /dev/null +++ b/crewai/agents/exceptions.py @@ -0,0 +1,20 @@ +from langchain_core.exceptions import OutputParserException + + +class TaskRepeatedUsageException(OutputParserException): + """Exception raised when a task is used twice in a roll.""" + + error: str = "TaskRepeatedUsageException" + message: str = "\nI just used the {tool} tool with input {tool_input}. So I already know the result of that.\n" + + def __init__(self, tool: str, tool_input: str): + self.tool = tool + self.tool_input = tool_input + self.message = self.message.format(tool=tool, tool_input=tool_input) + + super().__init__( + error=self.error, observation=self.message, send_to_llm=True, llm_output="" + ) + + def __str__(self): + return self.message diff --git a/crewai/agents/executor.py b/crewai/agents/executor.py index a29a248cf..a28363223 100644 --- a/crewai/agents/executor.py +++ b/crewai/agents/executor.py @@ -9,7 +9,7 @@ from langchain_core.exceptions import OutputParserException from langchain_core.tools import BaseTool from ..tools.cache_tools import CacheTools -from .cache_hit import CacheHit +from .cache.cache_hit import CacheHit class CrewAgentExecutor(AgentExecutor): diff --git a/crewai/agents/output_parser.py b/crewai/agents/output_parser.py index 8d54a5cfc..dc70d54d2 100644 --- a/crewai/agents/output_parser.py +++ b/crewai/agents/output_parser.py @@ -3,10 +3,9 @@ from typing import Union from langchain.agents.output_parsers import ReActSingleInputOutputParser from langchain_core.agents import AgentAction, AgentFinish -from langchain_core.exceptions import OutputParserException -from .cache_handler import CacheHandler -from .cache_hit import CacheHit +from .cache import CacheHandler, CacheHit +from .exceptions import TaskRepeatedUsageException from .tools_handler import ToolsHandler FINAL_ANSWER_ACTION = "Final Answer:" @@ -67,9 +66,7 @@ class CrewAgentOutputParser(ReActSingleInputOutputParser): "input": tool_input, } if usage == last_tool_usage: - raise OutputParserException( - f"""\nI just used the {action} tool with input {tool_input}. So I already know the result of that.""" - ) + raise TaskRepeatedUsageException(tool=action, tool_input=tool_input) result = self.cache.read(action, tool_input) if result: diff --git a/crewai/agents/tools_handler.py b/crewai/agents/tools_handler.py index 3f88ea8ca..d2f2ac568 100644 --- a/crewai/agents/tools_handler.py +++ b/crewai/agents/tools_handler.py @@ -3,7 +3,7 @@ from typing import Any, Dict from langchain.callbacks.base import BaseCallbackHandler from ..tools.cache_tools import CacheTools -from .cache_handler import CacheHandler +from .cache.cache_handler import CacheHandler class ToolsHandler(BaseCallbackHandler): diff --git a/crewai/base/__init__.py b/crewai/base/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/crewai/base/model.py b/crewai/base/model.py deleted file mode 100644 index 211ae5be7..000000000 --- a/crewai/base/model.py +++ /dev/null @@ -1,24 +0,0 @@ -import uuid -from typing import Optional - -from pydantic import UUID4, BaseModel, Field, field_validator -from pydantic_core import PydanticCustomError - - -class CrewAIBaseModel(BaseModel): - """Base model with unique identifier.""" - - __hash__ = object.__hash__ - id: UUID4 = Field( - default_factory=uuid.uuid4, - frozen=True, - description="Unique identifier for the object, not set by user.", - ) - - @field_validator("id", mode="before") - @classmethod - def _deny_user_set_id(cls, v: Optional[UUID4]) -> None: - if v: - raise PydanticCustomError( - "may_not_set_field", "This field is not to be set by the user.", {} - ) diff --git a/crewai/crew.py b/crewai/crew.py index f26ffad20..554ca3fce 100644 --- a/crewai/crew.py +++ b/crewai/crew.py @@ -15,7 +15,7 @@ from pydantic import ( from pydantic_core import PydanticCustomError from crewai.agent import Agent -from crewai.agents import CacheHandler +from crewai.agents.cache import CacheHandler from crewai.process import Process from crewai.task import Task from crewai.tools.agent_tools import AgentTools diff --git a/crewai/tools/agent_tools.py b/crewai/tools/agent_tools.py index 9e8cb2d8d..5c4e12e99 100644 --- a/crewai/tools/agent_tools.py +++ b/crewai/tools/agent_tools.py @@ -53,10 +53,10 @@ class AgentTools(BaseModel): try: agent, task, information = command.split("|") except ValueError: - return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|information`." + return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|information`.\n" if not agent or not task or not information: - return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|question|information`." + return "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|question|information`.\n" agent = [ available_agent @@ -65,7 +65,7 @@ class AgentTools(BaseModel): ] if len(agent) == 0: - return f"\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: {', '.join([agent.role for agent in self.agents])}." + return f"\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: {', '.join([agent.role for agent in self.agents])}.\n" agent = agent[0] result = agent.execute_task(task, information) diff --git a/crewai/tools/cache_tools.py b/crewai/tools/cache_tools.py index 66ba2a8a5..a8e6dbf3c 100644 --- a/crewai/tools/cache_tools.py +++ b/crewai/tools/cache_tools.py @@ -1,7 +1,7 @@ from langchain.tools import Tool from pydantic import BaseModel, ConfigDict, Field -from crewai.agents import CacheHandler +from crewai.agents.cache import CacheHandler class CacheTools(BaseModel): diff --git a/tests/agent_test.py b/tests/agent_test.py index e8a6c58e7..580b8d01f 100644 --- a/tests/agent_test.py +++ b/tests/agent_test.py @@ -4,7 +4,7 @@ import pytest from langchain.chat_models import ChatOpenAI as OpenAI from crewai.agent import Agent -from crewai.agents import CacheHandler +from crewai.agents.cache import CacheHandler def test_agent_creation(): diff --git a/tests/agent_tools/agent_tools_test.py b/tests/agent_tools/agent_tools_test.py index ffac3298b..02437eb88 100644 --- a/tests/agent_tools/agent_tools_test.py +++ b/tests/agent_tools/agent_tools_test.py @@ -48,7 +48,7 @@ def test_delegate_work_with_wrong_input(): assert ( result - == "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|information`." + == "\nError executing tool. Missing exact 3 pipe (|) separated values. For example, `coworker|task|information`.\n" ) @@ -59,7 +59,7 @@ def test_delegate_work_to_wrong_agent(): assert ( result - == "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: researcher." + == "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: researcher.\n" ) @@ -70,5 +70,5 @@ def test_ask_question_to_wrong_agent(): assert ( result - == "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: researcher." + == "\nError executing tool. Co-worker mentioned on the Action Input not found, it must to be one of the following options: researcher.\n" ) diff --git a/tests/crew_test.py b/tests/crew_test.py index 88a7b824f..ddbab470b 100644 --- a/tests/crew_test.py +++ b/tests/crew_test.py @@ -5,7 +5,7 @@ import json import pytest from crewai.agent import Agent -from crewai.agents import CacheHandler +from crewai.agents.cache import CacheHandler from crewai.crew import Crew from crewai.process import Process from crewai.task import Task