Add verbose flag to EventListener for controlled logging

This commit is contained in:
Lorenze Jay
2025-03-11 08:43:56 -07:00
parent f2d53350d8
commit 7c46dce2f7
3 changed files with 365 additions and 338 deletions

View File

@@ -248,7 +248,10 @@ class Crew(BaseModel):
@model_validator(mode="after")
def set_private_attrs(self) -> "Crew":
"""Set private attributes."""
from crewai.utilities.events.event_listener import EventListener
self._cache_handler = CacheHandler()
EventListener().verbose = self.verbose
self._logger = Logger(verbose=self.verbose)
if self.output_log_file:
self._file_handler = FileHandler(self.output_log_file)

View File

@@ -5,6 +5,8 @@ from crewai.utilities.events.crewai_event_bus import CrewAIEventsBus, crewai_eve
class BaseEventListener(ABC):
verbose: bool = False
def __init__(self):
super().__init__()
self.setup_listeners(crewai_event_bus)

View File

@@ -1,6 +1,6 @@
from datetime import datetime
from io import StringIO
from typing import Any, Dict
from typing import Any, Dict, Optional
from pydantic import Field, PrivateAttr
from rich.console import Console
@@ -112,7 +112,7 @@ class EventListener(BaseEventListener):
prefix: str,
name: str,
style: str = "blue",
status: str = None,
status: Optional[str] = None,
) -> None:
"""Update tree label with consistent formatting."""
label = Text()
@@ -130,19 +130,23 @@ class EventListener(BaseEventListener):
# ----------- METHODS -----------
def on_crew_start(self, source: Any, event: Any) -> None:
# Create the crew tree that will hold tasks
if self.verbose:
self.current_crew_tree = Tree(
Text("🚀 Crew: ", style="cyan bold") + Text(event.crew_name, style="cyan")
Text("🚀 Crew: ", style="cyan bold")
+ Text(event.crew_name, style="cyan")
)
content = Text()
content.append(f"NAME: {event.crew_name}", style="white")
content.append(f"\nID: {source.id}", style="blue")
content = self._create_status_content(
"Crew Execution Started",
event.crew_name,
"cyan",
ID=source.id,
)
panel = self._create_panel(content, "Crew Execution Started", "cyan")
self.console.print(panel)
self.console.print() # Add spacing
self.console.print()
self._telemetry.crew_execution_span(source, event.inputs)
# ----------- CREW EVENTS -----------
@@ -157,28 +161,24 @@ class EventListener(BaseEventListener):
# Handle telemetry
final_string_output = event.output.raw
self._telemetry.end_crew(source, final_string_output)
if self.verbose:
if self.current_crew_tree:
# Update crew tree label to show completion
crew_content = Text()
crew_content.append("✅ Crew: ", style="green bold")
crew_content.append(event.crew_name or "Crew", style="green")
self.current_crew_tree.label = crew_content
# Create completion panel
completion_content = Text()
completion_content.append(
"Crew Execution Completed\n", style="green bold"
self._update_tree_label(
self.current_crew_tree,
"✅ Crew:",
event.crew_name or "Crew",
"green",
)
completion_content = self._create_status_content(
"Crew Execution Completed",
event.crew_name or "Crew",
"green",
ID=source.id,
)
completion_content.append("Name: ", style="white")
completion_content.append(f"{event.crew_name}\n", style="green")
completion_content.append("ID: ", style="white")
completion_content.append(str(source.id), style="blue")
# Show final tree and completion panel
self.console.print(self.current_crew_tree)
self.console.print()
panel = self._create_panel(
completion_content, "Crew Completion", "green"
)
@@ -187,6 +187,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(CrewKickoffFailedEvent)
def on_crew_failed(source, event: CrewKickoffFailedEvent):
if self.verbose:
if self.current_crew_tree:
# Update crew tree label to show failure
crew_content = Text()
@@ -212,7 +213,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(CrewTestFailedEvent)
def on_crew_test_failed(source, event: CrewTestFailedEvent):
# Create test failure content
if self.verbose:
failure_content = Text()
failure_content.append("❌ Crew Test Failed\n", style="red bold")
failure_content.append("Crew: ", style="white")
@@ -238,7 +239,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(CrewTrainFailedEvent)
def on_crew_train_failed(source, event: CrewTrainFailedEvent):
# Create training failure content
if self.verbose:
failure_content = Text()
failure_content.append("❌ Crew Training Failed\n", style="red bold")
failure_content.append("Crew: ", style="white")
@@ -255,7 +256,7 @@ class EventListener(BaseEventListener):
span = self._telemetry.task_started(crew=source.agent.crew, task=source)
self.execution_spans[source] = span
# Create task content
if self.verbose:
task_content = Text()
task_content.append("📋 Task: ", style="yellow bold")
task_content.append("\n Assigned to: ", style="white")
@@ -281,7 +282,7 @@ class EventListener(BaseEventListener):
self._telemetry.task_ended(span, source, source.agent.crew)
self.execution_spans[source] = None
# Create completion content
if self.verbose:
completion_content = Text()
completion_content.append("✅ Task Completed\n", style="green bold")
completion_content.append(f"Task: {str(source.id)}", style="white")
@@ -290,18 +291,20 @@ class EventListener(BaseEventListener):
# Update the tree if it exists
if self.current_crew_tree:
# Find the task branch and update it with completion status
for branch in self.current_crew_tree.children:
if source.description in branch.label:
branch.label = Text("", style="green bold") + branch.label
branch.label = (
Text("", style="green bold") + branch.label
)
self.console.print(self.current_crew_tree)
break
# Always show completion panel
panel = self._create_panel(completion_content, "Task Completion", "green")
panel = self._create_panel(
completion_content, "Task Completion", "green"
)
self.console.print(panel)
self.console.print() # Add spacing
self.console.print()
@crewai_event_bus.on(TaskFailedEvent)
def on_task_failed(source, event: TaskFailedEvent):
@@ -311,7 +314,7 @@ class EventListener(BaseEventListener):
self._telemetry.task_ended(span, source, source.agent.crew)
self.execution_spans[source] = None
# Create failure content
if self.verbose:
failure_content = Text()
failure_content.append("❌ Task Failed\n", style="red bold")
failure_content.append("Task: ", style="white")
@@ -338,31 +341,33 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(AgentExecutionStartedEvent)
def on_agent_execution_started(source, event: AgentExecutionStartedEvent):
if self.verbose:
if self.current_task_branch:
# Create agent execution branch
agent_content = Text()
agent_content.append("🤖 Agent: ", style="green bold")
agent_content.append(event.agent.role, style="green")
agent_content.append("\n Status: ", style="white")
agent_content.append("In Progress", style="blue bold")
# Create agent execution branch with empty label
self.current_agent_branch = self.current_task_branch.add("")
self._update_tree_label(
self.current_agent_branch,
"🤖 Agent:",
event.agent.role,
"green",
"In Progress",
)
# Create a branch for the agent's activities
self.current_agent_branch = self.current_task_branch.add(agent_content)
self.console.print(self.current_crew_tree)
self.console.print()
@crewai_event_bus.on(AgentExecutionCompletedEvent)
def on_agent_execution_completed(source, event: AgentExecutionCompletedEvent):
if self.verbose:
if self.current_agent_branch:
# Update agent branch to show completion
agent_content = Text()
agent_content.append("🤖 Agent: ", style="green bold")
agent_content.append(event.agent.role, style="green")
agent_content.append("\n Status: ", style="white")
agent_content.append("✅ Completed", style="green bold")
self._update_tree_label(
self.current_agent_branch,
"🤖 Agent:",
event.agent.role,
"green",
"✅ Completed",
)
# Update the agent branch label
self.current_agent_branch.label = agent_content
self.console.print(self.current_crew_tree)
self.console.print()
@@ -372,11 +377,10 @@ class EventListener(BaseEventListener):
def on_flow_created(source, event: FlowCreatedEvent):
self._telemetry.flow_creation_span(event.flow_name)
# Create flow content for panel
content = Text()
content.append("🌊 Starting Flow Execution\n\n", style="blue bold")
content.append("Name: ", style="white")
content.append(event.flow_name, style="blue")
if self.verbose:
content = self._create_status_content(
"Starting Flow Execution", event.flow_name, "blue"
)
panel = self._create_panel(content, "Flow Execution", "blue")
@@ -406,14 +410,15 @@ class EventListener(BaseEventListener):
event.flow_name, list(source._methods.keys())
)
# Create flow tree with status
flow_label = Text()
flow_label.append("🌊 Flow: ", style="blue bold")
flow_label.append(event.flow_name, style="blue")
flow_label.append("\n Status: ", style="white")
flow_label.append("In Progress", style="yellow")
self.current_flow_tree = Tree(flow_label)
if self.verbose:
self.current_flow_tree = Tree("")
self._update_tree_label(
self.current_flow_tree,
"🌊 Flow:",
event.flow_name,
"blue",
"In Progress",
)
# Add initial thinking state
self.current_flow_tree.add(Text("🧠 Initializing...", style="yellow"))
@@ -424,19 +429,21 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(FlowFinishedEvent)
def on_flow_finished(source, event: FlowFinishedEvent):
if self.verbose:
if self.current_flow_tree:
# Update flow tree label to show completion
self.current_flow_tree.label = Text(
"✅ Flow Finished: ", style="green bold"
) + Text(event.flow_name, style="green")
self._update_tree_label(
self.current_flow_tree,
"✅ Flow Finished:",
event.flow_name,
"green",
)
# Create completion content
content = Text()
content.append("Flow Execution Completed\n", style="green bold")
content.append("Name: ", style="white")
content.append(f"{event.flow_name}\n", style="green")
content.append("ID: ", style="white")
content.append(source.flow_id, style="blue")
content = self._create_status_content(
"Flow Execution Completed",
event.flow_name,
"green",
ID=source.flow_id,
)
panel = self._create_panel(content, "Flow Completion", "green")
self.console.print(panel)
@@ -444,14 +451,15 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(MethodExecutionStartedEvent)
def on_method_execution_started(source, event: MethodExecutionStartedEvent):
if self.verbose:
if self.current_flow_tree:
# Find and update the method branch
for branch in self.current_flow_tree.children:
if event.method_name in branch.label:
self.current_method_branch = branch
branch.label = Text("🔄 Running: ", style="yellow bold") + Text(
event.method_name, style="yellow"
)
branch.label = Text(
"🔄 Running: ", style="yellow bold"
) + Text(event.method_name, style="yellow")
break
self.console.print(self.current_flow_tree)
@@ -459,6 +467,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(MethodExecutionFinishedEvent)
def on_method_execution_finished(source, event: MethodExecutionFinishedEvent):
if self.verbose:
if self.current_method_branch:
# Update method status
self.current_method_branch.label = Text(
@@ -469,8 +478,8 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(MethodExecutionFailedEvent)
def on_method_execution_failed(source, event: MethodExecutionFailedEvent):
if self.verbose:
if self.current_method_branch:
# Update method status to show failure
self.current_method_branch.label = Text(
"❌ Failed: ", style="red bold"
) + Text(event.method_name, style="red")
@@ -481,6 +490,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(ToolUsageStartedEvent)
def on_tool_usage_started(source, event: ToolUsageStartedEvent):
if self.verbose:
# Create tool usage content
tool_content = Text()
tool_content.append("🔧 Using ", style="yellow bold")
@@ -488,13 +498,15 @@ class EventListener(BaseEventListener):
# Add to tree under the agent branch
if self.current_agent_branch:
self.current_tool_branch = self.current_agent_branch.add(tool_content)
self.current_tool_branch = self.current_agent_branch.add(
tool_content
)
self.console.print(self.current_crew_tree)
self.console.print()
@crewai_event_bus.on(ToolUsageFinishedEvent)
def on_tool_usage_finished(source, event: ToolUsageFinishedEvent):
# Create completion content
if self.verbose:
completion_content = Text()
completion_content.append("🔧 Used ", style="green bold")
completion_content.append(event.tool_name, style="green")
@@ -507,7 +519,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(ToolUsageErrorEvent)
def on_tool_usage_error(source, event: ToolUsageErrorEvent):
# Create tool error content
if self.verbose:
error_content = Text()
error_content.append("🔧 Tool Failed: ", style="red bold")
error_content.append(event.tool_name, style="red")
@@ -521,7 +533,8 @@ class EventListener(BaseEventListener):
# Show error panel
panel = self._create_panel(
Text(
f"Tool usage failed: {event.tool_name}: {event.error}", style="red"
f"Tool usage failed: {event.tool_name}: {event.error}",
style="red",
),
"Tool Error",
"red",
@@ -533,19 +546,21 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(LLMCallStartedEvent)
def on_llm_call_started(source, event: LLMCallStartedEvent):
# Create simple LLM call content
if self.verbose:
llm_content = Text()
llm_content.append("🧠 Thinking...", style="blue bold")
# Add to tree under the agent branch
if self.current_agent_branch:
self.current_tool_branch = self.current_agent_branch.add(llm_content)
self.current_tool_branch = self.current_agent_branch.add(
llm_content
)
self.console.print(self.current_crew_tree)
self.console.print()
@crewai_event_bus.on(LLMCallCompletedEvent)
def on_llm_call_completed(source, event: LLMCallCompletedEvent):
# Create simple completion content
if self.verbose:
completion_content = Text()
completion_content.append("✨ Done", style="green bold")
@@ -557,7 +572,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(LLMCallFailedEvent)
def on_llm_call_failed(source, event: LLMCallFailedEvent):
# Create LLM error content
if self.verbose:
error_content = Text()
error_content.append("❌ LLM Call Failed\n", style="red bold")
error_content.append("Error: ", style="white")
@@ -565,7 +580,9 @@ class EventListener(BaseEventListener):
# Update under the agent branch if it exists
if self.current_tool_branch:
self.current_tool_branch.label = Text("❌ LLM Failed", style="red bold")
self.current_tool_branch.label = Text(
"❌ LLM Failed", style="red bold"
)
self.console.print(self.current_crew_tree)
self.console.print()
@@ -595,7 +612,7 @@ class EventListener(BaseEventListener):
event.eval_llm or "",
)
# Create test content for panel
if self.verbose:
content = Text()
content.append("🧪 Starting Crew Test\n\n", style="blue bold")
content.append("Crew: ", style="white")
@@ -626,6 +643,7 @@ class EventListener(BaseEventListener):
@crewai_event_bus.on(CrewTestCompletedEvent)
def on_crew_test_completed(source, event: CrewTestCompletedEvent):
if self.verbose:
if self.current_flow_tree:
# Update test tree label to show completion
test_label = Text()
@@ -647,13 +665,17 @@ class EventListener(BaseEventListener):
# Create completion panel
completion_content = Text()
completion_content.append("Test Execution Completed\n", style="green bold")
completion_content.append(
"Test Execution Completed\n", style="green bold"
)
completion_content.append("Crew: ", style="white")
completion_content.append(f"{event.crew_name}\n", style="green")
completion_content.append("Status: ", style="white")
completion_content.append("All tests passed", style="green")
panel = self._create_panel(completion_content, "Test Completion", "green")
panel = self._create_panel(
completion_content, "Test Completion", "green"
)
self.console.print(panel)
self.console.print()