From a4f7631e57acee70e106acc65f63f07779be762b Mon Sep 17 00:00:00 2001 From: Eduardo Chiarotti Date: Thu, 27 Jun 2024 10:28:52 -0700 Subject: [PATCH] fix: type checking --- src/crewai/agent.py | 10 ++++----- src/crewai/crew.py | 31 +++++++++++++-------------- src/crewai/task.py | 38 +++++++++++---------------------- src/crewai/tools/agent_tools.py | 6 +++--- 4 files changed, 35 insertions(+), 50 deletions(-) diff --git a/src/crewai/agent.py b/src/crewai/agent.py index 8fa5162a2..f7e56a5ed 100644 --- a/src/crewai/agent.py +++ b/src/crewai/agent.py @@ -210,8 +210,7 @@ class Agent(BaseModel): 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() @@ -231,8 +230,8 @@ class Agent(BaseModel): 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) + + parsed_tools = self._parse_tools(tools) # 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 @@ -399,8 +398,7 @@ class Agent(BaseModel): return copied_agent - # type: ignore # Function "langchain_core.tools.tool" is not valid as a type - 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.""" # tentatively try to import from crewai_tools import BaseTool as CrewAITool tools_list = [] diff --git a/src/crewai/crew.py b/src/crewai/crew.py index 4a301a81d..323702943 100644 --- a/src/crewai/crew.py +++ b/src/crewai/crew.py @@ -281,8 +281,8 @@ 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) - # 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) @@ -303,10 +303,8 @@ class Crew(BaseModel): if self.process == Process.sequential: result = self._run_sequential_process() elif self.process == Process.hierarchical: - # type: ignore # Unpacking a string is disallowed - result, manager_metrics = self._run_hierarchical_process() - # type: ignore # Cannot determine type of "manager_metrics" - metrics.append(manager_metrics) + result, manager_metrics = self._run_hierarchical_process() # type: ignore # Unpacking a string is disallowed + metrics.append(manager_metrics) # type: ignore # Cannot determine type of "manager_metrics" else: raise NotImplementedError( f"The process '{self.process}' is not implemented yet." @@ -316,7 +314,8 @@ class Crew(BaseModel): agent._token_process.get_summary() for agent in self.agents ] self.usage_metrics = { - key: sum([m[key] for m in metrics if m is not None]) for key in metrics[0] + key: sum([m[key] for m in metrics if m is not None]) # type: ignore # List comprehension has incompatible type List[Any | str]; expected List[bool] + for key in metrics[0] } return result @@ -395,10 +394,10 @@ class Crew(BaseModel): self._file_handler.log(agent=role, task=task_output, status="completed") self._finish_execution(task_output) - # type: ignore # Item "None" of "Agent | None" has no attribute "_token_process" - token_usage = task.agent._token_process.get_summary() - # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str") - return self._format_output(task_output, token_usage) + + token_usage = task.agent._token_process.get_summary() # type: ignore # Item "None" of "Agent | None" has no attribute "_token_process" + + 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) -> Union[str, Dict[str, Any]]: """Creates and assigns a manager agent to make sure the crew completes the tasks.""" @@ -434,7 +433,7 @@ class Crew(BaseModel): agent=manager, context=task_output, tools=manager.tools ) - self._logger.log("debug", f"[{manager.role}] Task output: {task_output}") + self._logger.log("debug", f"[{manager.role}] Task ouptput: {task_output}") if self.output_log_file: self._file_handler.log( @@ -442,9 +441,9 @@ class Crew(BaseModel): ) self._finish_execution(task_output) - # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str") + manager_token_usage = manager._token_process.get_summary() - return self._format_output( + return self._format_output( # type: ignore # Incompatible return value type (got "tuple[str, Any]", expected "str") task_output, manager_token_usage ), manager_token_usage @@ -493,8 +492,8 @@ class Crew(BaseModel): ) for task in self.tasks ] - # type: ignore # "interpolate_inputs" of "Agent" does not return a value (it only ever returns None) - [agent.interpolate_inputs(inputs) for agent in self.agents] + + [agent.interpolate_inputs(inputs) for agent in self.agents] # type: ignore # "interpolate_inputs" of "Agent" does not return a value (it only ever returns None) def _format_output( self, output: str, token_usage: Optional[Dict[str, Any]] diff --git a/src/crewai/task.py b/src/crewai/task.py index 359f5871f..db92f3ea2 100644 --- a/src/crewai/task.py +++ b/src/crewai/task.py @@ -1,8 +1,8 @@ -from copy import deepcopy import os import re import threading import uuid +from copy import deepcopy from typing import Any, Dict, List, Optional, Type from langchain_openai import ChatOpenAI @@ -164,16 +164,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.thread.join() # type: ignore # Item "None" of "Thread | None" has no attribute "join" if task and 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 @@ -281,32 +278,26 @@ 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 "Agent | None" has no attribute "function_calling_llm" - llm = self.agent.function_calling_llm or self.agent.llm + llm = self.agent.function_calling_llm or self.agent.llm # type: ignore # Item "None" of "Agent | 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 = Converter( @@ -327,8 +318,7 @@ 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.json() + exported_result if not self.output_pydantic else exported_result.json() # type: ignore # "str" has no attribute "json" ) self._save_file(content) @@ -338,14 +328,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/agent_tools.py b/src/crewai/tools/agent_tools.py index 6fe78941d..9bec282b5 100644 --- a/src/crewai/tools/agent_tools.py +++ b/src/crewai/tools/agent_tools.py @@ -78,7 +78,7 @@ class AgentTools(BaseModel): # {"task": "....", "coworker": "...."} agent_name = agent.casefold().replace('"', "").replace("\n", "") - agent = [ + agent = [ # type: ignore # Incompatible types in assignment (expression has type "list[Agent]", variable has type "str | None") available_agent for available_agent in self.agents if available_agent.role.casefold().replace("\n", "") == agent_name @@ -98,9 +98,9 @@ class AgentTools(BaseModel): ) 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"