diff --git a/lib/crewai-tools/src/crewai_tools/aws/s3/__init__.py b/lib/crewai-tools/src/crewai_tools/aws/s3/__init__.py index 4dfe44415..6fda9fe1d 100644 --- a/lib/crewai-tools/src/crewai_tools/aws/s3/__init__.py +++ b/lib/crewai-tools/src/crewai_tools/aws/s3/__init__.py @@ -1,2 +1,2 @@ -from .reader_tool import S3ReaderTool -from .writer_tool import S3WriterTool +from .reader_tool import S3ReaderTool as S3ReaderTool +from .writer_tool import S3WriterTool as S3WriterTool diff --git a/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/__init__.py b/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/__init__.py index 351cced92..3442b6b16 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/__init__.py +++ b/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/__init__.py @@ -1,3 +1,7 @@ -from .patronus_eval_tool import PatronusEvalTool -from .patronus_local_evaluator_tool import PatronusLocalEvaluatorTool -from .patronus_predefined_criteria_eval_tool import PatronusPredefinedCriteriaEvalTool +from .patronus_eval_tool import PatronusEvalTool as PatronusEvalTool +from .patronus_local_evaluator_tool import ( + PatronusLocalEvaluatorTool as PatronusLocalEvaluatorTool, +) +from .patronus_predefined_criteria_eval_tool import ( + PatronusPredefinedCriteriaEvalTool as PatronusPredefinedCriteriaEvalTool, +) diff --git a/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/example.py b/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/example.py index d7702e946..d9b788b2c 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/example.py +++ b/lib/crewai-tools/src/crewai_tools/tools/patronus_eval_tool/example.py @@ -1,8 +1,11 @@ import random +from patronus import Client, EvaluationResult # type: ignore[import-not-found] +from patronus_local_evaluator_tool import ( # type: ignore[import-not-found] + PatronusLocalEvaluatorTool, +) + from crewai import Agent, Crew, Task -from patronus import Client, EvaluationResult -from patronus_local_evaluator_tool import PatronusLocalEvaluatorTool # Test the PatronusLocalEvaluatorTool where agent uses the local evaluator @@ -12,7 +15,7 @@ client = Client() # Example of an evaluator that returns a random pass/fail result @client.register_local_evaluator("random_evaluator") def random_evaluator(**kwargs): - score = random.random() + score = random.random() # noqa: S311 return EvaluationResult( score_raw=score, pass_=score >= 0.5, diff --git a/lib/crewai-tools/src/crewai_tools/tools/stagehand_tool/example.py b/lib/crewai-tools/src/crewai_tools/tools/stagehand_tool/example.py index 37220d61f..a14df60df 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/stagehand_tool/example.py +++ b/lib/crewai-tools/src/crewai_tools/tools/stagehand_tool/example.py @@ -17,13 +17,17 @@ Usage: import os -from crewai import Agent, Crew, Process, Task +from crewai.utilities.printer import Printer from dotenv import load_dotenv -from stagehand.schemas import AvailableModel +from stagehand.schemas import AvailableModel # type: ignore[import-untyped] +from crewai import Agent, Crew, Process, Task from crewai_tools import StagehandTool +_printer = Printer() + + # Load environment variables from .env file load_dotenv() @@ -111,7 +115,7 @@ with StagehandTool( # Run the crew and get the result result = crew.kickoff() - print("\n==== RESULTS ====\n") - print(result) + _printer.print("\n==== RESULTS ====\n", color="cyan") + _printer.print(str(result)) # Resources are automatically cleaned up when exiting the context manager diff --git a/lib/crewai/src/crewai/cli/add_crew_to_flow.py b/lib/crewai/src/crewai/cli/add_crew_to_flow.py index ef693a22b..bab9e81b1 100644 --- a/lib/crewai/src/crewai/cli/add_crew_to_flow.py +++ b/lib/crewai/src/crewai/cli/add_crew_to_flow.py @@ -3,13 +3,16 @@ from pathlib import Path import click from crewai.cli.utils import copy_template +from crewai.utilities.printer import Printer + +_printer = Printer() def add_crew_to_flow(crew_name: str) -> None: """Add a new crew to the current flow.""" # Check if pyproject.toml exists in the current directory if not Path("pyproject.toml").exists(): - print("This command must be run from the root of a flow project.") + _printer.print("This command must be run from the root of a flow project.", color="red") raise click.ClickException( "This command must be run from the root of a flow project." ) @@ -19,7 +22,7 @@ def add_crew_to_flow(crew_name: str) -> None: crews_folder = flow_folder / "src" / flow_folder.name / "crews" if not crews_folder.exists(): - print("Crews folder does not exist in the current flow.") + _printer.print("Crews folder does not exist in the current flow.", color="red") raise click.ClickException("Crews folder does not exist in the current flow.") # Create the crew within the flow's crews directory diff --git a/lib/crewai/src/crewai/cli/command.py b/lib/crewai/src/crewai/cli/command.py index 7ddddeafd..003d6927e 100644 --- a/lib/crewai/src/crewai/cli/command.py +++ b/lib/crewai/src/crewai/cli/command.py @@ -27,7 +27,7 @@ class PlusAPIMixin: style="bold red", ) console.print("Run 'crewai login' to sign up/login.", style="bold green") - raise SystemExit + raise SystemExit from None def _validate_response(self, response: requests.Response) -> None: """ @@ -45,7 +45,7 @@ class PlusAPIMixin: ) console.print(f"Status Code: {response.status_code}") console.print(f"Response:\n{response.content}") - raise SystemExit + raise SystemExit from None if response.status_code == 422: console.print( diff --git a/lib/crewai/src/crewai/cli/crew_chat.py b/lib/crewai/src/crewai/cli/crew_chat.py index 6fe9d87c8..0da126e5e 100644 --- a/lib/crewai/src/crewai/cli/crew_chat.py +++ b/lib/crewai/src/crewai/cli/crew_chat.py @@ -17,6 +17,9 @@ from crewai.crew import Crew from crewai.llm import LLM, BaseLLM from crewai.types.crew_chat import ChatInputField, ChatInputs from crewai.utilities.llm_utils import create_llm +from crewai.utilities.printer import Printer + +_printer = Printer() MIN_REQUIRED_VERSION = "0.98.0" @@ -111,9 +114,9 @@ def run_chat(): def show_loading(event: threading.Event): """Display animated loading dots while processing.""" while not event.is_set(): - print(".", end="", flush=True) + _printer.print(".", end="", flush=True) time.sleep(1) - print() + _printer.print() def initialize_chat_llm(crew: Crew) -> LLM | BaseLLM | None: diff --git a/lib/crewai/src/crewai/cli/enterprise/main.py b/lib/crewai/src/crewai/cli/enterprise/main.py index 4c25fb1c7..0ca2fc957 100644 --- a/lib/crewai/src/crewai/cli/enterprise/main.py +++ b/lib/crewai/src/crewai/cli/enterprise/main.py @@ -33,7 +33,7 @@ class EnterpriseConfigureCommand(BaseCommand): console.print( f"❌ Failed to configure Enterprise settings: {e!s}", style="bold red" ) - raise SystemExit(1) + raise SystemExit(1) from e def _fetch_oauth_config(self, enterprise_url: str) -> Dict[str, Any]: oauth_endpoint = f"{enterprise_url}/auth/parameters" @@ -50,8 +50,8 @@ class EnterpriseConfigureCommand(BaseCommand): try: oauth_config = response.json() - except JSONDecodeError: - raise ValueError(f"Invalid JSON response from {oauth_endpoint}") + except JSONDecodeError as e: + raise ValueError(f"Invalid JSON response from {oauth_endpoint}") from e required_fields = [ "audience", diff --git a/lib/crewai/src/crewai/events/event_listener.py b/lib/crewai/src/crewai/events/event_listener.py index a0b113f35..8adbc21bb 100644 --- a/lib/crewai/src/crewai/events/event_listener.py +++ b/lib/crewai/src/crewai/events/event_listener.py @@ -53,6 +53,7 @@ from crewai.task import Task from crewai.telemetry.telemetry import Telemetry from crewai.utilities import Logger from crewai.utilities.constants import EMITTER_COLOR +from crewai.utilities.printer import Printer from .listeners.memory_listener import MemoryListener from .types.flow_events import ( @@ -75,6 +76,8 @@ from .types.tool_usage_events import ( ToolUsageStartedEvent, ) +_printer = Printer() + class EventListener(BaseEventListener): _instance = None @@ -383,7 +386,7 @@ class EventListener(BaseEventListener): # Read from the in-memory stream content = self.text_stream.read() - print(content, end="", flush=True) + _printer.print(content, end="", flush=True) self.next_chunk = self.text_stream.tell() # ----------- LLM GUARDRAIL EVENTS ----------- diff --git a/lib/crewai/src/crewai/flow/flow.py b/lib/crewai/src/crewai/flow/flow.py index 85bb077ee..edac7827f 100644 --- a/lib/crewai/src/crewai/flow/flow.py +++ b/lib/crewai/src/crewai/flow/flow.py @@ -1086,7 +1086,7 @@ class Flow(Generic[T], metaclass=FlowMeta): for method_name in self._start_methods: # Check if this start method is triggered by the current trigger if method_name in self._listeners: - condition_type, trigger_methods = self._listeners[ + _condition_type, trigger_methods = self._listeners[ method_name ] if current_trigger in trigger_methods: diff --git a/lib/crewai/src/crewai/flow/flow_visualizer.py b/lib/crewai/src/crewai/flow/flow_visualizer.py index 5b50c3844..2ac11a3bb 100644 --- a/lib/crewai/src/crewai/flow/flow_visualizer.py +++ b/lib/crewai/src/crewai/flow/flow_visualizer.py @@ -14,6 +14,9 @@ from crewai.flow.visualization_utils import ( add_nodes_to_network, compute_positions, ) +from crewai.utilities.printer import Printer + +_printer = Printer() class FlowPlot: @@ -128,7 +131,7 @@ class FlowPlot: try: with open(f"{filename}.html", "w", encoding="utf-8") as f: f.write(final_html_content) - print(f"Plot saved as {filename}.html") + _printer.print(f"Plot saved as {filename}.html", color="green") except IOError as e: raise IOError( f"Failed to save flow visualization to {filename}.html: {e!s}" @@ -204,9 +207,9 @@ class FlowPlot: shutil.rmtree(lib_folder) except ValueError as e: - print(f"Error validating lib folder path: {e}") + _printer.print(f"Error validating lib folder path: {e}", color="red") except Exception as e: - print(f"Error cleaning up lib folder: {e}") + _printer.print(f"Error cleaning up lib folder: {e}", color="red") def plot_flow(flow, filename="flow_plot"): diff --git a/lib/crewai/src/crewai/flow/utils.py b/lib/crewai/src/crewai/flow/utils.py index 74e617bee..2a4f4fbf1 100644 --- a/lib/crewai/src/crewai/flow/utils.py +++ b/lib/crewai/src/crewai/flow/utils.py @@ -19,6 +19,10 @@ import textwrap from collections import defaultdict, deque from typing import Any +from crewai.utilities.printer import Printer + +_printer = Printer() + def get_possible_return_constants(function: Any) -> list[str] | None: try: @@ -27,7 +31,7 @@ def get_possible_return_constants(function: Any) -> list[str] | None: # Can't get source code return None except Exception as e: - print(f"Error retrieving source code for function {function.__name__}: {e}") + _printer.print(f"Error retrieving source code for function {function.__name__}: {e}", color="red") return None try: @@ -36,16 +40,16 @@ def get_possible_return_constants(function: Any) -> list[str] | None: # Parse the source code into an AST code_ast = ast.parse(source) except IndentationError as e: - print(f"IndentationError while parsing source code of {function.__name__}: {e}") - print(f"Source code:\n{source}") + _printer.print(f"IndentationError while parsing source code of {function.__name__}: {e}", color="red") + _printer.print(f"Source code:\n{source}", color="yellow") return None except SyntaxError as e: - print(f"SyntaxError while parsing source code of {function.__name__}: {e}") - print(f"Source code:\n{source}") + _printer.print(f"SyntaxError while parsing source code of {function.__name__}: {e}", color="red") + _printer.print(f"Source code:\n{source}", color="yellow") return None except Exception as e: - print(f"Unexpected error while parsing source code of {function.__name__}: {e}") - print(f"Source code:\n{source}") + _printer.print(f"Unexpected error while parsing source code of {function.__name__}: {e}", color="red") + _printer.print(f"Source code:\n{source}", color="yellow") return None return_values = set() diff --git a/lib/crewai/src/crewai/flow/visualization_utils.py b/lib/crewai/src/crewai/flow/visualization_utils.py index 721aef23b..abf31df88 100644 --- a/lib/crewai/src/crewai/flow/visualization_utils.py +++ b/lib/crewai/src/crewai/flow/visualization_utils.py @@ -19,6 +19,8 @@ import ast import inspect from typing import Any +from crewai.utilities.printer import Printer + from .utils import ( build_ancestor_dict, build_parent_children_dict, @@ -26,6 +28,8 @@ from .utils import ( is_ancestor, ) +_printer = Printer() + def method_calls_crew(method: Any) -> bool: """ @@ -51,7 +55,7 @@ def method_calls_crew(method: Any) -> bool: source = inspect.cleandoc(source) tree = ast.parse(source) except Exception as e: - print(f"Could not parse method {method.__name__}: {e}") + _printer.print(f"Could not parse method {method.__name__}: {e}", color="red") return False class CrewCallVisitor(ast.NodeVisitor): @@ -263,8 +267,9 @@ def add_edges( # If it's a known router edge and the method is known, don't warn. # This means the path is legitimate, just not reflected as nodes here. if not (is_router_edge and method_known): - print( - f"Warning: No node found for '{trigger}' or '{method_name}'. Skipping edge." + _printer.print( + f"Warning: No node found for '{trigger}' or '{method_name}'. Skipping edge.", + color="yellow", ) # Edges for router return paths @@ -318,6 +323,7 @@ def add_edges( # Same check here: known router edge and known method? method_known = listener_name in flow._methods if not method_known: - print( - f"Warning: No node found for '{router_method_name}' or '{listener_name}'. Skipping edge." + _printer.print( + f"Warning: No node found for '{router_method_name}' or '{listener_name}'. Skipping edge.", + color="yellow", ) diff --git a/lib/crewai/src/crewai/project/annotations.py b/lib/crewai/src/crewai/project/annotations.py index d7c636ccf..b5f560ad1 100644 --- a/lib/crewai/src/crewai/project/annotations.py +++ b/lib/crewai/src/crewai/project/annotations.py @@ -36,15 +36,13 @@ def task(func): def agent(func): """Marks a method as a crew agent.""" func.is_agent = True - func = memoize(func) - return func + return memoize(func) def llm(func): """Marks a method as an LLM provider.""" func.is_llm = True - func = memoize(func) - return func + return memoize(func) def output_json(cls): @@ -91,7 +89,7 @@ def crew(func) -> Callable[..., Crew]: agents = self._original_agents.items() # Instantiate tasks in order - for task_name, task_method in tasks: + for _task_name, task_method in tasks: task_instance = task_method(self) instantiated_tasks.append(task_instance) agent_instance = getattr(task_instance, "agent", None) @@ -100,7 +98,7 @@ def crew(func) -> Callable[..., Crew]: agent_roles.add(agent_instance.role) # Instantiate agents not included by tasks - for agent_name, agent_method in agents: + for _agent_name, agent_method in agents: agent_instance = agent_method(self) if agent_instance.role not in agent_roles: instantiated_agents.append(agent_instance) @@ -117,9 +115,9 @@ def crew(func) -> Callable[..., Crew]: return wrapper - for _, callback in self._before_kickoff.items(): + for callback in self._before_kickoff.values(): crew.before_kickoff_callbacks.append(callback_wrapper(callback, self)) - for _, callback in self._after_kickoff.items(): + for callback in self._after_kickoff.values(): crew.after_kickoff_callbacks.append(callback_wrapper(callback, self)) return crew diff --git a/lib/crewai/src/crewai/project/crew_base.py b/lib/crewai/src/crewai/project/crew_base.py index ea49d3e77..1065012c9 100644 --- a/lib/crewai/src/crewai/project/crew_base.py +++ b/lib/crewai/src/crewai/project/crew_base.py @@ -8,9 +8,11 @@ import yaml from dotenv import load_dotenv from crewai.tools import BaseTool +from crewai.utilities.printer import Printer load_dotenv() +_printer = Printer() T = TypeVar("T", bound=type) """Base decorator for creating crew classes with configuration and function management.""" @@ -148,7 +150,7 @@ def CrewBase(cls: T) -> T: # noqa: N802 with open(config_path, "r", encoding="utf-8") as file: return yaml.safe_load(file) except FileNotFoundError: - print(f"File not found: {config_path}") + _printer.print(f"File not found: {config_path}", color="red") raise def _get_all_functions(self): diff --git a/lib/crewai/src/crewai/rag/embeddings/providers/ibm/embedding_callable.py b/lib/crewai/src/crewai/rag/embeddings/providers/ibm/embedding_callable.py index 56198987d..e8b39932b 100644 --- a/lib/crewai/src/crewai/rag/embeddings/providers/ibm/embedding_callable.py +++ b/lib/crewai/src/crewai/rag/embeddings/providers/ibm/embedding_callable.py @@ -6,6 +6,9 @@ from chromadb.api.types import Documents, EmbeddingFunction, Embeddings from typing_extensions import Unpack from crewai.rag.embeddings.providers.ibm.types import WatsonXProviderConfig +from crewai.utilities.printer import Printer + +_printer = Printer() class WatsonXEmbeddingFunction(EmbeddingFunction[Documents]): @@ -155,5 +158,5 @@ class WatsonXEmbeddingFunction(EmbeddingFunction[Documents]): embeddings = embedding.embed_documents(input) return cast(Embeddings, embeddings) except Exception as e: - print(f"Error during WatsonX embedding: {e}") + _printer.print(f"Error during WatsonX embedding: {e}", color="red") raise diff --git a/lib/crewai/src/crewai/task.py b/lib/crewai/src/crewai/task.py index ebf284317..2d2b946ae 100644 --- a/lib/crewai/src/crewai/task.py +++ b/lib/crewai/src/crewai/task.py @@ -47,6 +47,8 @@ from crewai.utilities.i18n import I18N from crewai.utilities.printer import Printer from crewai.utilities.string_utils import interpolate_only +_printer = Printer() + class Task(BaseModel): """Class that represents a task to be executed. @@ -626,7 +628,7 @@ Follow these guidelines: try: crew_chat_messages = json.loads(crew_chat_messages_json) except json.JSONDecodeError as e: - print("An error occurred while parsing crew chat messages:", e) + _printer.print(f"An error occurred while parsing crew chat messages: {e}", color="red") raise conversation_history = "\n".join( diff --git a/lib/crewai/src/crewai/tools/base_tool.py b/lib/crewai/src/crewai/tools/base_tool.py index 0905db320..e8f9f796c 100644 --- a/lib/crewai/src/crewai/tools/base_tool.py +++ b/lib/crewai/src/crewai/tools/base_tool.py @@ -14,6 +14,9 @@ from pydantic import ( from pydantic import BaseModel as PydanticBaseModel from crewai.tools.structured_tool import CrewStructuredTool +from crewai.utilities.printer import Printer + +_printer = Printer() class EnvVar(BaseModel): @@ -85,7 +88,7 @@ class BaseTool(BaseModel, ABC): *args: Any, **kwargs: Any, ) -> Any: - print(f"Using Tool: {self.name}") + _printer.print(f"Using Tool: {self.name}", color="cyan") result = self._run(*args, **kwargs) # If _run is async, we safely run it