Skip to content

Commit e229ef4

Browse files
refactor: improve flow handling, typing, and logging; update UI and tests
fix: refine nested flow conditionals and ensure router methods and routes are fully parsed fix: improve docstrings, typing, and logging coverage across all events feat: update flow.plot feature with new UI enhancements chore: apply Ruff linting, reorganize imports, and remove deprecated utilities/files chore: split constants and utils, clean JS comments, and add typing for linters tests: strengthen test coverage for flow execution paths and router logic
1 parent 2e9eb8c commit e229ef4

27 files changed

+4995
-1648
lines changed

lib/crewai/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ dependencies = [
2323
"chromadb~=1.1.0",
2424
"tokenizers>=0.20.3",
2525
"openpyxl>=3.1.5",
26-
"pyvis>=0.3.2",
2726
# Authentication and Security
2827
"python-dotenv>=1.1.1",
2928
"pyjwt>=2.9.0",

lib/crewai/src/crewai/events/event_listener.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class EventListener(BaseEventListener):
8888
text_stream = StringIO()
8989
knowledge_retrieval_in_progress = False
9090
knowledge_query_in_progress = False
91+
method_branches: dict[str, Any] = Field(default_factory=dict)
9192

9293
def __new__(cls):
9394
if cls._instance is None:
@@ -101,6 +102,7 @@ def __init__(self):
101102
self._telemetry = Telemetry()
102103
self._telemetry.set_tracer()
103104
self.execution_spans = {}
105+
self.method_branches = {}
104106
self._initialized = True
105107
self.formatter = ConsoleFormatter(verbose=True)
106108

@@ -263,7 +265,8 @@ def on_lite_agent_execution_error(source, event: LiteAgentExecutionErrorEvent):
263265
@crewai_event_bus.on(FlowCreatedEvent)
264266
def on_flow_created(source, event: FlowCreatedEvent):
265267
self._telemetry.flow_creation_span(event.flow_name)
266-
self.formatter.create_flow_tree(event.flow_name, str(source.flow_id))
268+
tree = self.formatter.create_flow_tree(event.flow_name, str(source.flow_id))
269+
self.formatter.current_flow_tree = tree
267270

268271
@crewai_event_bus.on(FlowStartedEvent)
269272
def on_flow_started(source, event: FlowStartedEvent):
@@ -280,30 +283,36 @@ def on_flow_finished(source, event: FlowFinishedEvent):
280283

281284
@crewai_event_bus.on(MethodExecutionStartedEvent)
282285
def on_method_execution_started(source, event: MethodExecutionStartedEvent):
283-
self.formatter.update_method_status(
284-
self.formatter.current_method_branch,
286+
method_branch = self.method_branches.get(event.method_name)
287+
updated_branch = self.formatter.update_method_status(
288+
method_branch,
285289
self.formatter.current_flow_tree,
286290
event.method_name,
287291
"running",
288292
)
293+
self.method_branches[event.method_name] = updated_branch
289294

290295
@crewai_event_bus.on(MethodExecutionFinishedEvent)
291296
def on_method_execution_finished(source, event: MethodExecutionFinishedEvent):
292-
self.formatter.update_method_status(
293-
self.formatter.current_method_branch,
297+
method_branch = self.method_branches.get(event.method_name)
298+
updated_branch = self.formatter.update_method_status(
299+
method_branch,
294300
self.formatter.current_flow_tree,
295301
event.method_name,
296302
"completed",
297303
)
304+
self.method_branches[event.method_name] = updated_branch
298305

299306
@crewai_event_bus.on(MethodExecutionFailedEvent)
300307
def on_method_execution_failed(source, event: MethodExecutionFailedEvent):
301-
self.formatter.update_method_status(
302-
self.formatter.current_method_branch,
308+
method_branch = self.method_branches.get(event.method_name)
309+
updated_branch = self.formatter.update_method_status(
310+
method_branch,
303311
self.formatter.current_flow_tree,
304312
event.method_name,
305313
"failed",
306314
)
315+
self.method_branches[event.method_name] = updated_branch
307316

308317
# ----------- TOOL USAGE EVENTS -----------
309318

lib/crewai/src/crewai/events/utils/console_formatter.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,14 @@ def create_flow_tree(self, flow_name: str, flow_id: str) -> Tree | None:
357357
return flow_tree
358358

359359
def start_flow(self, flow_name: str, flow_id: str) -> Tree | None:
360-
"""Initialize a flow execution tree."""
360+
"""Initialize or update a flow execution tree."""
361+
if self.current_flow_tree is not None:
362+
for child in self.current_flow_tree.children:
363+
if "Starting Flow" in str(child.label):
364+
child.label = Text("🚀 Flow Started", style="green")
365+
break
366+
return self.current_flow_tree
367+
361368
flow_tree = Tree("")
362369
flow_label = Text()
363370
flow_label.append("🌊 Flow: ", style="blue bold")
@@ -436,34 +443,46 @@ def update_method_status(
436443
prefix, style = "🔄 Running:", "yellow"
437444
elif status == "completed":
438445
prefix, style = "✅ Completed:", "green"
439-
# Update initialization node when a method completes successfully
440446
for child in flow_tree.children:
441447
if "Starting Flow" in str(child.label):
442448
child.label = Text("Flow Method Step", style="white")
443449
break
444450
else:
445451
prefix, style = "❌ Failed:", "red"
446-
# Update initialization node on failure
447452
for child in flow_tree.children:
448453
if "Starting Flow" in str(child.label):
449454
child.label = Text("❌ Flow Step Failed", style="red")
450455
break
451456

452-
if not method_branch:
453-
# Find or create method branch
454-
for branch in flow_tree.children:
455-
if method_name in str(branch.label):
456-
method_branch = branch
457-
break
458-
if not method_branch:
459-
method_branch = flow_tree.add("")
457+
if method_branch is not None:
458+
if method_branch in flow_tree.children:
459+
method_branch.label = Text(prefix, style=f"{style} bold") + Text(
460+
f" {method_name}", style=style
461+
)
462+
self.print(flow_tree)
463+
self.print()
464+
return method_branch
465+
466+
for branch in flow_tree.children:
467+
label_str = str(branch.label)
468+
if f" {method_name}" in label_str and (
469+
"Running:" in label_str
470+
or "Completed:" in label_str
471+
or "Failed:" in label_str
472+
):
473+
method_branch = branch
474+
break
475+
476+
if method_branch is None:
477+
method_branch = flow_tree.add("")
460478

461479
method_branch.label = Text(prefix, style=f"{style} bold") + Text(
462480
f" {method_name}", style=style
463481
)
464482

465483
self.print(flow_tree)
466484
self.print()
485+
467486
return method_branch
468487

469488
def get_llm_tree(self, tool_name: str):
Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
1+
from crewai.flow.visualization import (
2+
FlowStructure,
3+
build_flow_structure,
4+
print_structure_summary,
5+
structure_to_dict,
6+
visualize_flow_structure,
7+
)
18
from crewai.flow.flow import Flow, and_, listen, or_, router, start
29
from crewai.flow.persistence import persist
310

411

5-
__all__ = ["Flow", "and_", "listen", "or_", "persist", "router", "start"]
12+
__all__ = [
13+
"Flow",
14+
"FlowStructure",
15+
"and_",
16+
"build_flow_structure",
17+
"listen",
18+
"or_",
19+
"persist",
20+
"print_structure_summary",
21+
"router",
22+
"start",
23+
"structure_to_dict",
24+
"visualize_flow_structure",
25+
]

lib/crewai/src/crewai/flow/assets/crewai_flow_visual_template.html

Lines changed: 0 additions & 93 deletions
This file was deleted.

0 commit comments

Comments
 (0)