From 109e41f0ef78639eb64694fe19b2d10b8b034443 Mon Sep 17 00:00:00 2001 From: Eduardo Chiarotti Date: Thu, 4 Jul 2024 23:21:36 -0300 Subject: [PATCH] fix: fix and add comments for all type checking errors --- src/crewai/agent.py | 17 ++++--- src/crewai/agents/agent_builder/base_agent.py | 2 +- .../utilities/base_agent_tool.py | 8 ++-- .../utilities/base_output_converter_base.py | 5 +-- src/crewai/agents/executor.py | 7 ++- src/crewai/crew.py | 26 +++++------ src/crewai/task.py | 45 +++++++------------ src/crewai/tools/tool_usage.py | 5 +-- 8 files changed, 49 insertions(+), 66 deletions(-) diff --git a/src/crewai/agent.py b/src/crewai/agent.py index d0773d9a6..9f953d61d 100644 --- a/src/crewai/agent.py +++ b/src/crewai/agent.py @@ -20,7 +20,7 @@ from crewai.utilities.training_handler import CrewTrainingHandler agentops = None try: - import agentops + import agentops # type: ignore # Name "agentops" already defined on line 21 from agentops import track_agent except ImportError: @@ -60,8 +60,8 @@ class Agent(BaseAgent): default=None, description="Maximum execution time for an agent to execute a task", ) - agent_ops_agent_name: str = None - agent_ops_agent_id: str = None + agent_ops_agent_name: str = None # type: ignore # Incompatible types in assignment (expression has type "None", variable has type "str") + agent_ops_agent_id: str = None # type: ignore # Incompatible types in assignment (expression has type "None", variable has type "str") cache_handler: InstanceOf[CacheHandler] = Field( default=None, description="An instance of the CacheHandler class." ) @@ -148,8 +148,7 @@ class Agent(BaseAgent): Output of the agent """ if self.tools_handler: - # type: ignore # Incompatible types in assignment (expression has type "dict[Never, Never]", variable has type "ToolCalling") - self.tools_handler.last_used_tool = {} + self.tools_handler.last_used_tool = {} # type: ignore # Incompatible types in assignment (expression has type "dict[Never, Never]", variable has type "ToolCalling") task_prompt = task.prompt() @@ -169,8 +168,8 @@ class Agent(BaseAgent): task_prompt += self.i18n.slice("memory").format(memory=memory) tools = tools or self.tools - # type: ignore # Argument 1 to "_parse_tools" of "Agent" has incompatible type "list[Any] | None"; expected "list[Any]" - parsed_tools = self._parse_tools(tools or []) + + parsed_tools = self._parse_tools(tools or []) # type: ignore # Argument 1 to "_parse_tools" of "Agent" has incompatible type "list[Any] | None"; expected "list[Any]" self.create_agent_executor(tools=tools) self.agent_executor.tools = parsed_tools self.agent_executor.task = task @@ -196,7 +195,7 @@ class Agent(BaseAgent): # If there was any tool in self.tools_results that had result_as_answer # set to True, return the results of the last tool that had # result_as_answer set to True - for tool_result in self.tools_results: + for tool_result in self.tools_results: # type: ignore # Item "None" of "list[Any] | None" has no attribute "__iter__" (not iterable) if tool_result.get("result_as_answer", False): result = tool_result["result"] @@ -300,7 +299,7 @@ class Agent(BaseAgent): def get_output_converter(self, llm, text, model, instructions): return Converter(llm=llm, text=text, model=model, instructions=instructions) - def _parse_tools(self, tools: List[Any]) -> List[LangChainTool]: + def _parse_tools(self, tools: List[Any]) -> List[LangChainTool]: # type: ignore # Function "langchain_core.tools.tool" is not valid as a type """Parse tools to be used for the task.""" tools_list = [] try: diff --git a/src/crewai/agents/agent_builder/base_agent.py b/src/crewai/agents/agent_builder/base_agent.py index 90e27dec6..5619a0f6d 100644 --- a/src/crewai/agents/agent_builder/base_agent.py +++ b/src/crewai/agents/agent_builder/base_agent.py @@ -191,7 +191,7 @@ class BaseAgent(ABC, BaseModel): """Get the converter class for the agent to create json/pydantic outputs.""" pass - def copy(self: T) -> T: + def copy(self: T) -> T: # type: ignore # Signature of "copy" incompatible with supertype "BaseModel" """Create a deep copy of the Agent.""" exclude = { "id", diff --git a/src/crewai/agents/agent_builder/utilities/base_agent_tool.py b/src/crewai/agents/agent_builder/utilities/base_agent_tool.py index ef9c65d6b..c307aeb08 100644 --- a/src/crewai/agents/agent_builder/utilities/base_agent_tool.py +++ b/src/crewai/agents/agent_builder/utilities/base_agent_tool.py @@ -1,6 +1,8 @@ from abc import ABC, abstractmethod from typing import List, Optional, Union + from pydantic import BaseModel, Field + from crewai.agents.agent_builder.base_agent import BaseAgent from crewai.task import Task from crewai.utilities import I18N @@ -53,7 +55,7 @@ class BaseAgentTools(BaseModel, ABC): # {"task": "....", "coworker": "...."} agent_name = agent.casefold().replace('"', "").replace("\n", "") - agent = [ + agent = [ # type: ignore # Incompatible types in assignment (expression has type "list[BaseAgent]", variable has type "str | None") available_agent for available_agent in self.agents if available_agent.role.casefold().replace("\n", "") == agent_name @@ -73,9 +75,9 @@ class BaseAgentTools(BaseModel, ABC): ) agent = agent[0] - task = Task( + task = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str") description=task, agent=agent, expected_output="Your best answer to your coworker asking you this, accounting for the context shared.", ) - return agent.execute_task(task, context) + return agent.execute_task(task, context) # type: ignore # "str" has no attribute "execute_task" diff --git a/src/crewai/agents/agent_builder/utilities/base_output_converter_base.py b/src/crewai/agents/agent_builder/utilities/base_output_converter_base.py index f2d2321ed..f33c51da6 100644 --- a/src/crewai/agents/agent_builder/utilities/base_output_converter_base.py +++ b/src/crewai/agents/agent_builder/utilities/base_output_converter_base.py @@ -1,7 +1,6 @@ from abc import ABC, abstractmethod from typing import Any, Optional - from pydantic import BaseModel, Field, PrivateAttr @@ -42,7 +41,7 @@ class OutputConverter(BaseModel, ABC): """Convert text to json.""" pass - @abstractmethod - def _is_gpt(self, llm): + @abstractmethod # type: ignore # Name "_is_gpt" already defined on line 25 + def _is_gpt(self, llm): # type: ignore # Name "_is_gpt" already defined on line 25 """Return if llm provided is of gpt from openai.""" pass diff --git a/src/crewai/agents/executor.py b/src/crewai/agents/executor.py index 2aa8d2fe2..58ab81e6f 100644 --- a/src/crewai/agents/executor.py +++ b/src/crewai/agents/executor.py @@ -15,19 +15,18 @@ from langchain.agents.agent import ExceptionTool from langchain.callbacks.manager import CallbackManagerForChainRun from langchain_core.agents import AgentAction, AgentFinish, AgentStep from langchain_core.exceptions import OutputParserException - from langchain_core.tools import BaseTool from langchain_core.utils.input import get_color_mapping from pydantic import InstanceOf + from crewai.agents.agent_builder.base_agent_executor_mixin import ( CrewAgentExecutorMixin, ) - from crewai.agents.tools_handler import ToolsHandler from crewai.tools.tool_usage import ToolUsage, ToolUsageErrorException +from crewai.utilities import I18N from crewai.utilities.constants import TRAINING_DATA_FILE from crewai.utilities.training_handler import CrewTrainingHandler -from crewai.utilities import I18N class CrewAgentExecutor(AgentExecutor, CrewAgentExecutorMixin): @@ -46,7 +45,7 @@ class CrewAgentExecutor(AgentExecutor, CrewAgentExecutorMixin): tools_handler: Optional[InstanceOf[ToolsHandler]] = None max_iterations: Optional[int] = 15 have_forced_answer: bool = False - force_answer_max_iterations: Optional[int] = None + force_answer_max_iterations: Optional[int] = None # type: ignore # Incompatible types in assignment (expression has type "int | None", base class "CrewAgentExecutorMixin" defined the type as "int") step_callback: Optional[Any] = None system_template: Optional[str] = None prompt_template: Optional[str] = None diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 25e1fe096..e15199c01 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -232,7 +232,7 @@ class Crew(BaseModel): if task.agent is None: raise PydanticCustomError( "missing_agent_in_task", - f"Sequential process error: Agent is missing in the task with the following description: {task.description}", # type: ignore Argument of type "str" cannot be assigned to parameter "message_template" of type "LiteralString" + f"Sequential process error: Agent is missing in the task with the following description: {task.description}", # type: ignore # Argument of type "str" cannot be assigned to parameter "message_template" of type "LiteralString" {}, ) @@ -318,26 +318,25 @@ class Crew(BaseModel): ) -> Union[str, Dict[str, Any]]: """Starts the crew to work on its assigned tasks.""" self._execution_span = self._telemetry.crew_execution_span(self, inputs) - # type: ignore # Argument 1 to "_interpolate_inputs" of "Crew" has incompatible type "dict[str, Any] | None"; expected "dict[str, Any]" - self._interpolate_inputs(inputs) + + self._interpolate_inputs(inputs) # type: ignore # Argument 1 to "_interpolate_inputs" of "Crew" has incompatible type "dict[str, Any] | None"; expected "dict[str, Any]" self._set_tasks_callbacks() i18n = I18N(prompt_file=self.prompt_file) for agent in self.agents: - # type: ignore # Argument 1 to "_interpolate_inputs" of "Crew" has incompatible type "dict[str, Any] | None"; expected "dict[str, Any]" agent.i18n = i18n # type: ignore[attr-defined] # Argument 1 to "_interpolate_inputs" of "Crew" has incompatible type "dict[str, Any] | None"; expected "dict[str, Any]" agent.crew = self # type: ignore[attr-defined] # TODO: Create an AgentFunctionCalling protocol for future refactoring - if not agent.function_calling_llm: - agent.function_calling_llm = self.function_calling_llm + if not agent.function_calling_llm: # type: ignore # "BaseAgent" has no attribute "function_calling_llm" + agent.function_calling_llm = self.function_calling_llm # type: ignore # "BaseAgent" has no attribute "function_calling_llm" - if agent.allow_code_execution: - agent.tools += agent.get_code_execution_tools() + if agent.allow_code_execution: # type: ignore # BaseAgent" has no attribute "allow_code_execution" + agent.tools += agent.get_code_execution_tools() # type: ignore # "BaseAgent" has no attribute "get_code_execution_tools"; maybe "get_delegation_tools"? - if not agent.step_callback: - agent.step_callback = self.step_callback + if not agent.step_callback: # type: ignore # "BaseAgent" has no attribute "step_callback" + agent.step_callback = self.step_callback # type: ignore # "BaseAgent" has no attribute "step_callback" agent.create_agent_executor() @@ -346,7 +345,7 @@ class Crew(BaseModel): if self.process == Process.sequential: result = self._run_sequential_process() elif self.process == Process.hierarchical: - result, manager_metrics = self._run_hierarchical_process() + result, manager_metrics = self._run_hierarchical_process() # type: ignore # Incompatible types in assignment (expression has type "str | dict[str, Any]", variable has type "str") metrics.append(manager_metrics) else: raise NotImplementedError( @@ -432,7 +431,7 @@ class Crew(BaseModel): agent for agent in self.agents if agent != task.agent ] if len(self.agents) > 1 and len(agents_for_delegation) > 0: - task.tools += task.agent.get_delegation_tools(agents_for_delegation) + task.tools += task.agent.get_delegation_tools(agents_for_delegation) # type: ignore # Item "None" of "BaseAgent | None" has no attribute "get_delegation_tools" role = task.agent.role if task.agent is not None else "None" self._logger.log("debug", f"== Working Agent: {role}", color="bold_purple") @@ -459,8 +458,7 @@ class Crew(BaseModel): token_usage = self.calculate_usage_metrics() - # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str") - return self._format_output(task_output, token_usage) + return self._format_output(task_output, token_usage) # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str") def _run_hierarchical_process( self, diff --git a/src/crewai/task.py b/src/crewai/task.py index aba197f04..168d5db87 100644 --- a/src/crewai/task.py +++ b/src/crewai/task.py @@ -190,16 +190,13 @@ class Task(BaseModel): ) if self.context: - # type: ignore # Incompatible types in assignment (expression has type "list[Never]", variable has type "str | None") - context = [] + context = [] # type: ignore # Incompatible types in assignment (expression has type "list[Never]", variable has type "str | None") for task in self.context: if task.async_execution: task.wait_for_completion() if task.output: - # type: ignore # Item "str" of "str | None" has no attribute "append" - context.append(task.output.raw_output) - # type: ignore # Argument 1 to "join" of "str" has incompatible type "str | None"; expected "Iterable[str]" - context = "\n".join(context) + context.append(task.output.raw_output) # type: ignore # Item "str" of "str | None" has no attribute "append" + context = "\n".join(context) # type: ignore # Argument 1 to "join" of "str" has incompatible type "str | None"; expected "Iterable[str]" self.prompt_context = context tools = tools or self.tools @@ -226,8 +223,7 @@ class Task(BaseModel): ) exported_output = self._export_output(result) - # type: ignore # the responses are usually str but need to figure out a more elegant solution here - self.output = TaskOutput( + self.output = TaskOutput( # type: ignore # the responses are usually str but need to figure out a more elegant solution here description=self.description, exported_output=exported_output, raw_output=result, @@ -276,7 +272,7 @@ class Task(BaseModel): """Increment the delegations counter.""" self.delegations += 1 - def copy(self, agents: Optional[List["BaseAgent"]] = None) -> "Task": + def copy(self, agents: Optional[List["BaseAgent"]] = None) -> "Task": # type: ignore # Signature of "copy" incompatible with supertype "BaseModel" """Create a deep copy of the Task.""" exclude = { "id", @@ -293,7 +289,7 @@ class Task(BaseModel): ) def get_agent_by_role(role: str) -> Union["BaseAgent", None]: - return next((agent for agent in agents if agent.role == role), None) + return next((agent for agent in agents if agent.role == role), None) # type: ignore # Item "None" of "list[BaseAgent] | None" has no attribute "__iter__" (not iterable) cloned_agent = get_agent_by_role(self.agent.role) if self.agent else None cloned_tools = copy(self.tools) if self.tools else [] @@ -316,34 +312,28 @@ class Task(BaseModel): # try to convert task_output directly to pydantic/json try: - # type: ignore # Item "None" of "type[BaseModel] | None" has no attribute "model_validate_json" - exported_result = model.model_validate_json(result) + exported_result = model.model_validate_json(result) # type: ignore # Item "None" of "type[BaseModel] | None" has no attribute "model_validate_json" if self.output_json: - # type: ignore # "str" has no attribute "model_dump" - return exported_result.model_dump() + return exported_result.model_dump() # type: ignore # "str" has no attribute "model_dump" return exported_result except Exception: # sometimes the response contains valid JSON in the middle of text match = re.search(r"({.*})", result, re.DOTALL) if match: try: - # type: ignore # Item "None" of "type[BaseModel] | None" has no attribute "model_validate_json" - exported_result = model.model_validate_json(match.group(0)) + exported_result = model.model_validate_json(match.group(0)) # type: ignore # Item "None" of "type[BaseModel] | None" has no attribute "model_validate_json" if self.output_json: - # type: ignore # "str" has no attribute "model_dump" - return exported_result.model_dump() + return exported_result.model_dump() # type: ignore # "str" has no attribute "model_dump" return exported_result except Exception: pass - # type: ignore # Item "None" of "BaseAgent | None" has no attribute "function_calling_llm" - llm = getattr(self.agent, "function_calling_llm", None) or self.agent.llm + llm = getattr(self.agent, "function_calling_llm", None) or self.agent.llm # type: ignore # Item "None" of "BaseAgent | None" has no attribute "function_calling_llm" if not self._is_gpt(llm): - # type: ignore # Argument "model" to "PydanticSchemaParser" has incompatible type "type[BaseModel] | None"; expected "type[BaseModel]" - model_schema = PydanticSchemaParser(model=model).get_schema() + model_schema = PydanticSchemaParser(model=model).get_schema() # type: ignore # Argument "model" to "PydanticSchemaParser" has incompatible type "type[BaseModel] | None"; expected "type[BaseModel]" instructions = f"{instructions}\n\nThe json should have the following structure, with the following keys:\n{model_schema}" - converter = self.agent.get_output_converter( + converter = self.agent.get_output_converter( # type: ignore # Item "None" of "BaseAgent | None" has no attribute "get_output_converter" llm=llm, text=result, model=model, instructions=instructions ) @@ -361,10 +351,9 @@ class Task(BaseModel): if self.output_file: content = ( - # type: ignore # "str" has no attribute "json" exported_result if not self.output_pydantic - else exported_result.model_dump_json() + else exported_result.model_dump_json() # type: ignore # "str" has no attribute "json" ) self._save_file(content) @@ -374,14 +363,12 @@ class Task(BaseModel): return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None def _save_file(self, result: Any) -> None: - # type: ignore # Value of type variable "AnyOrLiteralStr" of "dirname" cannot be "str | None" - directory = os.path.dirname(self.output_file) + directory = os.path.dirname(self.output_file) # type: ignore # Value of type variable "AnyOrLiteralStr" of "dirname" cannot be "str | None" if directory and not os.path.exists(directory): os.makedirs(directory) - # type: ignore # Argument 1 to "open" has incompatible type "str | None"; expected "int | str | bytes | PathLike[str] | PathLike[bytes]" - with open(self.output_file, "w", encoding="utf-8") as file: + with open(self.output_file, "w", encoding="utf-8") as file: # type: ignore # Argument 1 to "open" has incompatible type "str | None"; expected "int | str | bytes | PathLike[str] | PathLike[bytes]" file.write(result) return None diff --git a/src/crewai/tools/tool_usage.py b/src/crewai/tools/tool_usage.py index 62fa43c3f..d2fe8d886 100644 --- a/src/crewai/tools/tool_usage.py +++ b/src/crewai/tools/tool_usage.py @@ -11,11 +11,10 @@ from crewai.telemetry import Telemetry from crewai.tools.tool_calling import InstructorToolCalling, ToolCalling from crewai.utilities import I18N, Converter, ConverterError, Printer -agentops = None try: import agentops except ImportError: - pass + agentops = None OPENAI_BIGGER_MODELS = ["gpt-4"] @@ -216,7 +215,7 @@ class ToolUsage: hasattr(original_tool, "result_as_answer") and original_tool.result_as_answer # type: ignore # Item "None" of "Any | None" has no attribute "cache_function" ): - result_as_answer = original_tool.result_as_answer + result_as_answer = original_tool.result_as_answer # type: ignore # Item "None" of "Any | None" has no attribute "result_as_answer" data["result_as_answer"] = result_as_answer self.agent.tools_results.append(data)