Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions src/crewai/events/utils/console_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class ConsoleFormatter:
def __init__(self, verbose: bool = False):
self.console = Console(width=None)
self.verbose = verbose
self.tool_usage_counts: dict[str, int] = {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Instance Variable Shadows Class Variable

The tool_usage_counts instance variable, initialized in __init__, shadows the class variable of the same name. This prevents tool usage from being tracked globally across all instances, leading to each instance having its own isolated count instead of a shared one.

Fix in Cursor Fix in Web

# Live instance to dynamically update a Tree renderable (e.g. the Crew tree)
# When multiple Tree objects are printed sequentially we reuse this Live
# instance so the previous render is replaced instead of writing a new one.
Expand Down Expand Up @@ -693,7 +694,8 @@ def handle_llm_call_completed(
if tool_branch is not None and "Thinking" in str(tool_branch.label):
thinking_branch_to_remove = tool_branch

# Method 2: Fallback - search for any thinking node if tool_branch is None or not thinking
# Method 2: Fallback - search for any thinking node if tool_branch is None
# or not thinking
if thinking_branch_to_remove is None:
parents = [
self.current_lite_agent_branch,
Expand Down Expand Up @@ -752,7 +754,8 @@ def handle_llm_call_failed(
if tool_branch is not None and "Thinking" in str(tool_branch.label):
thinking_branch_to_update = tool_branch

# Method 2: Fallback - search for any thinking node if tool_branch is None or not thinking
# Method 2: Fallback - search for any thinking node if tool_branch is None or
# not thinking
if thinking_branch_to_update is None:
parents = [
self.current_lite_agent_branch,
Expand Down Expand Up @@ -1377,7 +1380,7 @@ def handle_agent_logs_execution(
if isinstance(formatted_answer, AgentAction):
thought = re.sub(r"\n+", "\n", formatted_answer.thought)
formatted_json = json.dumps(
formatted_answer.tool_input,
json.loads(formatted_answer.tool_input),
indent=2,
ensure_ascii=False,
)
Expand Down Expand Up @@ -1592,10 +1595,14 @@ def handle_memory_query_completed(
if "Sources Used" in str(inner_child.label):
sources_branch.add(f"✅ {memory_type} ({query_time_ms:.2f}ms)")
break
else:
sources_branch = child.add("Sources Used")
sources_branch.add(f"✅ {memory_type} ({query_time_ms:.2f}ms)")
break

# If not found, create it under this child
if sources_branch is None:
sources_branch = child.add("🧠 Sources Used")

sources_branch.add(f"✅ {memory_type} ({query_time_ms:.2f}ms)")
break

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Memory Query Handling Fails

The refactored logic in handle_memory_query_completed and handle_memory_query_failed incorrectly replaces the for...else construct. The sources_branch variable is reassigned to each inner_child during iteration, making the subsequent if sources_branch is None: check ineffective. This leads to new memory entries being added to the wrong child when no "Sources Used" branch is found, or duplicated if one is found and updated.

Additional Locations (1)

Fix in Cursor Fix in Web


def handle_memory_query_failed(
self,
Expand Down Expand Up @@ -1625,10 +1632,14 @@ def handle_memory_query_failed(
if "Sources Used" in str(inner_child.label):
sources_branch.add(f"❌ {memory_type} - Error: {error}")
break
else:

# If not found, create it under this child
if sources_branch is None:
sources_branch = child.add("🧠 Sources Used")
sources_branch.add(f"❌ {memory_type} - Error: {error}")
break

sources_branch.add(f"❌ {memory_type} - Error: {error}")
break


def handle_memory_save_started(
self, agent_branch: Tree | None, crew_tree: Tree | None
Expand Down
2 changes: 1 addition & 1 deletion src/crewai/tools/structured_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def invoke(

if inspect.iscoroutinefunction(self.func):
return asyncio.run(self.func(**parsed_args, **kwargs))

result = self.func(**parsed_args, **kwargs)

if asyncio.iscoroutine(result):
Expand Down
Loading