from typing import Dict, Optional from rich.console import Console from rich.panel import Panel from rich.text import Text from rich.tree import Tree class ConsoleFormatter: current_crew_tree: Optional[Tree] = None current_task_branch: Optional[Tree] = None current_agent_branch: Optional[Tree] = None current_tool_branch: Optional[Tree] = None current_flow_tree: Optional[Tree] = None current_method_branch: Optional[Tree] = None tool_usage_counts: Dict[str, int] = {} def __init__(self, verbose: bool = False): self.console = Console(width=None) self.verbose = verbose def create_panel(self, content: Text, title: str, style: str = "blue") -> Panel: """Create a standardized panel with consistent styling.""" return Panel( content, title=title, border_style=style, padding=(1, 2), ) def create_status_content( self, title: str, name: str, status_style: str = "blue", **fields ) -> Text: """Create standardized status content with consistent formatting.""" content = Text() content.append(f"{title}\n", style=f"{status_style} bold") content.append("Name: ", style="white") content.append(f"{name}\n", style=status_style) for label, value in fields.items(): content.append(f"{label}: ", style="white") content.append( f"{value}\n", style=fields.get(f"{label}_style", status_style) ) return content def update_tree_label( self, tree: Tree, prefix: str, name: str, style: str = "blue", status: Optional[str] = None, ) -> None: """Update tree label with consistent formatting.""" label = Text() label.append(f"{prefix} ", style=f"{style} bold") label.append(name, style=style) if status: label.append("\n Status: ", style="white") label.append(status, style=f"{style} bold") tree.label = label def add_tree_node(self, parent: Tree, text: str, style: str = "yellow") -> Tree: """Add a node to the tree with consistent styling.""" return parent.add(Text(text, style=style)) def print(self, *args, **kwargs) -> None: """Print to console with consistent formatting if verbose is enabled.""" self.console.print(*args, **kwargs) def print_panel( self, content: Text, title: str, style: str = "blue", is_flow: bool = False ) -> None: """Print a panel with consistent formatting if verbose is enabled.""" panel = self.create_panel(content, title, style) if is_flow: self.print(panel) self.print() else: if self.verbose: self.print(panel) self.print() def update_crew_tree( self, tree: Optional[Tree], crew_name: str, source_id: str, status: str = "completed", ) -> None: """Handle crew tree updates with consistent formatting.""" if not self.verbose or tree is None: return if status == "completed": prefix, style = "โœ… Crew:", "green" title = "Crew Completion" content_title = "Crew Execution Completed" elif status == "failed": prefix, style = "โŒ Crew:", "red" title = "Crew Failure" content_title = "Crew Execution Failed" else: prefix, style = "๐Ÿš€ Crew:", "cyan" title = "Crew Execution" content_title = "Crew Execution Started" self.update_tree_label( tree, prefix, crew_name or "Crew", style, ) content = self.create_status_content( content_title, crew_name or "Crew", style, ID=source_id, ) self.print_panel(content, title, style) def create_crew_tree(self, crew_name: str, source_id: str) -> Optional[Tree]: """Create and initialize a new crew tree with initial status.""" if not self.verbose: return None tree = Tree( Text("๐Ÿš€ Crew: ", style="cyan bold") + Text(crew_name, style="cyan") ) content = self.create_status_content( "Crew Execution Started", crew_name, "cyan", ID=source_id, ) self.print_panel(content, "Crew Execution Started", "cyan") # Set the current_crew_tree attribute directly self.current_crew_tree = tree return tree def create_task_branch( self, crew_tree: Optional[Tree], task_id: str ) -> Optional[Tree]: """Create and initialize a task branch.""" if not self.verbose: return None task_content = Text() task_content.append(f"๐Ÿ“‹ Task: {task_id}", style="yellow bold") task_content.append("\n Status: ", style="white") task_content.append("Executing Task...", style="yellow dim") task_branch = None if crew_tree: task_branch = crew_tree.add(task_content) self.print(crew_tree) else: self.print_panel(task_content, "Task Started", "yellow") self.print() # Set the current_task_branch attribute directly self.current_task_branch = task_branch return task_branch def update_task_status( self, crew_tree: Optional[Tree], task_id: str, agent_role: str, status: str = "completed", ) -> None: """Update task status in the tree.""" if not self.verbose or crew_tree is None: return if status == "completed": style = "green" status_text = "โœ… Completed" panel_title = "Task Completion" else: style = "red" status_text = "โŒ Failed" panel_title = "Task Failure" # Update tree label for branch in crew_tree.children: if str(task_id) in str(branch.label): task_content = Text() task_content.append(f"๐Ÿ“‹ Task: {task_id}", style=f"{style} bold") task_content.append("\n Assigned to: ", style="white") task_content.append(agent_role, style=style) task_content.append("\n Status: ", style="white") task_content.append(status_text, style=f"{style} bold") branch.label = task_content self.print(crew_tree) break # Show status panel content = self.create_status_content( f"Task {status.title()}", str(task_id), style, Agent=agent_role ) self.print_panel(content, panel_title, style) def create_agent_branch( self, task_branch: Optional[Tree], agent_role: str, crew_tree: Optional[Tree] ) -> Optional[Tree]: """Create and initialize an agent branch.""" if not self.verbose or not task_branch or not crew_tree: return None agent_branch = task_branch.add("") self.update_tree_label( agent_branch, "๐Ÿค– Agent:", agent_role, "green", "In Progress" ) self.print(crew_tree) self.print() # Set the current_agent_branch attribute directly self.current_agent_branch = agent_branch return agent_branch def update_agent_status( self, agent_branch: Optional[Tree], agent_role: str, crew_tree: Optional[Tree], status: str = "completed", ) -> None: """Update agent status in the tree.""" if not self.verbose or agent_branch is None or crew_tree is None: return self.update_tree_label( agent_branch, "๐Ÿค– Agent:", agent_role, "green", "โœ… Completed" if status == "completed" else "โŒ Failed", ) self.print(crew_tree) self.print() def create_flow_tree(self, flow_name: str, flow_id: str) -> Optional[Tree]: """Create and initialize a flow tree.""" content = self.create_status_content( "Starting Flow Execution", flow_name, "blue", ID=flow_id ) self.print_panel(content, "Flow Execution", "blue", is_flow=True) # Create initial tree with flow ID flow_label = Text() flow_label.append("๐ŸŒŠ Flow: ", style="blue bold") flow_label.append(flow_name, style="blue") flow_label.append("\n ID: ", style="white") flow_label.append(flow_id, style="blue") flow_tree = Tree(flow_label) self.add_tree_node(flow_tree, "โœจ Created", "blue") self.add_tree_node(flow_tree, "โœ… Initialization Complete", "green") return flow_tree def start_flow(self, flow_name: str, flow_id: str) -> Optional[Tree]: """Initialize a flow execution tree.""" flow_tree = Tree("") flow_label = Text() flow_label.append("๐ŸŒŠ Flow: ", style="blue bold") flow_label.append(flow_name, style="blue") flow_label.append("\n ID: ", style="white") flow_label.append(flow_id, style="blue") flow_tree.label = flow_label self.add_tree_node(flow_tree, "๐Ÿง  Starting Flow...", "yellow") self.print(flow_tree) self.print() self.current_flow_tree = flow_tree return flow_tree def update_flow_status( self, flow_tree: Optional[Tree], flow_name: str, flow_id: str, status: str = "completed", ) -> None: """Update flow status in the tree.""" if flow_tree is None: return # Update main flow label self.update_tree_label( flow_tree, "โœ… Flow Finished:" if status == "completed" else "โŒ Flow Failed:", flow_name, "green" if status == "completed" else "red", ) # Update initialization node status for child in flow_tree.children: if "Starting Flow" in str(child.label): child.label = Text( ( "โœ… Flow Completed" if status == "completed" else "โŒ Flow Failed" ), style="green" if status == "completed" else "red", ) break content = self.create_status_content( ( "Flow Execution Completed" if status == "completed" else "Flow Execution Failed" ), flow_name, "green" if status == "completed" else "red", ID=flow_id, ) self.print(flow_tree) self.print_panel( content, "Flow Completion", "green" if status == "completed" else "red" ) def update_method_status( self, method_branch: Optional[Tree], flow_tree: Optional[Tree], method_name: str, status: str = "running", ) -> Optional[Tree]: """Update method status in the flow tree.""" if not flow_tree: return None if status == "running": prefix, style = "๐Ÿ”„ Running:", "yellow" elif status == "completed": prefix, style = "โœ… Completed:", "green" # Update initialization node when a method completes successfully for child in flow_tree.children: if "Starting Flow" in str(child.label): child.label = Text("Flow Method Step", style="white") break else: prefix, style = "โŒ Failed:", "red" # Update initialization node on failure for child in flow_tree.children: if "Starting Flow" in str(child.label): child.label = Text("โŒ Flow Step Failed", style="red") break if not method_branch: # Find or create method branch for branch in flow_tree.children: if method_name in str(branch.label): method_branch = branch break if not method_branch: method_branch = flow_tree.add("") method_branch.label = Text(prefix, style=f"{style} bold") + Text( f" {method_name}", style=style ) self.print(flow_tree) self.print() return method_branch def handle_tool_usage_started( self, agent_branch: Optional[Tree], tool_name: str, crew_tree: Optional[Tree], ) -> Optional[Tree]: """Handle tool usage started event.""" if not self.verbose or agent_branch is None or crew_tree is None: return None # Update tool usage count self.tool_usage_counts[tool_name] = self.tool_usage_counts.get(tool_name, 0) + 1 # Find existing tool node or create new one tool_branch = None for child in agent_branch.children: if tool_name in str(child.label): tool_branch = child break if not tool_branch: tool_branch = agent_branch.add("") # Update label with current count self.update_tree_label( tool_branch, "๐Ÿ”ง", f"Using {tool_name} ({self.tool_usage_counts[tool_name]})", "yellow", ) self.print(crew_tree) self.print() # Set the current_tool_branch attribute directly self.current_tool_branch = tool_branch return tool_branch def handle_tool_usage_finished( self, tool_branch: Optional[Tree], tool_name: str, crew_tree: Optional[Tree], ) -> None: """Handle tool usage finished event.""" if not self.verbose or tool_branch is None or crew_tree is None: return self.update_tree_label( tool_branch, "๐Ÿ”ง", f"Used {tool_name} ({self.tool_usage_counts[tool_name]})", "green", ) self.print(crew_tree) self.print() def handle_tool_usage_error( self, tool_branch: Optional[Tree], tool_name: str, error: str, crew_tree: Optional[Tree], ) -> None: """Handle tool usage error event.""" if not self.verbose: return if tool_branch: self.update_tree_label( tool_branch, "๐Ÿ”ง Failed", f"{tool_name} ({self.tool_usage_counts[tool_name]})", "red", ) self.print(crew_tree) self.print() # Show error panel error_content = self.create_status_content( "Tool Usage Failed", tool_name, "red", Error=error ) self.print_panel(error_content, "Tool Error", "red") def handle_llm_call_started( self, agent_branch: Optional[Tree], crew_tree: Optional[Tree], ) -> Optional[Tree]: """Handle LLM call started event.""" if not self.verbose or agent_branch is None or crew_tree is None: return None # Only add thinking status if it doesn't exist if not any("Thinking" in str(child.label) for child in agent_branch.children): tool_branch = agent_branch.add("") self.update_tree_label(tool_branch, "๐Ÿง ", "Thinking...", "blue") self.print(crew_tree) self.print() # Set the current_tool_branch attribute directly self.current_tool_branch = tool_branch return tool_branch return None def handle_llm_call_completed( self, tool_branch: Optional[Tree], agent_branch: Optional[Tree], crew_tree: Optional[Tree], ) -> None: """Handle LLM call completed event.""" if ( not self.verbose or tool_branch is None or agent_branch is None or crew_tree is None ): return # Remove the thinking status node when complete if "Thinking" in str(tool_branch.label): if tool_branch in agent_branch.children: agent_branch.children.remove(tool_branch) self.print(crew_tree) self.print() def handle_llm_call_failed( self, tool_branch: Optional[Tree], error: str, crew_tree: Optional[Tree] ) -> None: """Handle LLM call failed event.""" if not self.verbose: return # Update tool branch if it exists if tool_branch: tool_branch.label = Text("โŒ LLM Failed", style="red bold") self.print(crew_tree) self.print() # Show error panel error_content = Text() error_content.append("โŒ LLM Call Failed\n", style="red bold") error_content.append("Error: ", style="white") error_content.append(str(error), style="red") self.print_panel(error_content, "LLM Error", "red") def handle_crew_test_started( self, crew_name: str, source_id: str, n_iterations: int ) -> Optional[Tree]: """Handle crew test started event.""" if not self.verbose: return None # Create initial panel content = Text() content.append("๐Ÿงช Starting Crew Test\n\n", style="blue bold") content.append("Crew: ", style="white") content.append(f"{crew_name}\n", style="blue") content.append("ID: ", style="white") content.append(str(source_id), style="blue") content.append("\nIterations: ", style="white") content.append(str(n_iterations), style="yellow") self.print() self.print_panel(content, "Test Execution", "blue") self.print() # Create and display the test tree test_label = Text() test_label.append("๐Ÿงช Test: ", style="blue bold") test_label.append(crew_name or "Crew", style="blue") test_label.append("\n Status: ", style="white") test_label.append("In Progress", style="yellow") test_tree = Tree(test_label) self.add_tree_node(test_tree, "๐Ÿ”„ Running tests...", "yellow") self.print(test_tree) self.print() return test_tree def handle_crew_test_completed( self, flow_tree: Optional[Tree], crew_name: str ) -> None: """Handle crew test completed event.""" if not self.verbose: return if flow_tree: # Update test tree label to show completion test_label = Text() test_label.append("โœ… Test: ", style="green bold") test_label.append(crew_name or "Crew", style="green") test_label.append("\n Status: ", style="white") test_label.append("Completed", style="green bold") flow_tree.label = test_label # Update the running tests node for child in flow_tree.children: if "Running tests" in str(child.label): child.label = Text("โœ… Tests completed successfully", style="green") break self.print(flow_tree) self.print() # Create completion panel completion_content = Text() completion_content.append("Test Execution Completed\n", style="green bold") completion_content.append("Crew: ", style="white") completion_content.append(f"{crew_name}\n", style="green") completion_content.append("Status: ", style="white") completion_content.append("Completed", style="green") self.print_panel(completion_content, "Test Completion", "green") def handle_crew_train_started(self, crew_name: str, timestamp: str) -> None: """Handle crew train started event.""" if not self.verbose: return content = Text() content.append("๐Ÿ“‹ Crew Training Started\n", style="blue bold") content.append("Crew: ", style="white") content.append(f"{crew_name}\n", style="blue") content.append("Time: ", style="white") content.append(timestamp, style="blue") self.print_panel(content, "Training Started", "blue") self.print() def handle_crew_train_completed(self, crew_name: str, timestamp: str) -> None: """Handle crew train completed event.""" if not self.verbose: return content = Text() content.append("โœ… Crew Training Completed\n", style="green bold") content.append("Crew: ", style="white") content.append(f"{crew_name}\n", style="green") content.append("Time: ", style="white") content.append(timestamp, style="green") self.print_panel(content, "Training Completed", "green") self.print() def handle_crew_train_failed(self, crew_name: str) -> None: """Handle crew train failed event.""" if not self.verbose: return failure_content = Text() failure_content.append("โŒ Crew Training Failed\n", style="red bold") failure_content.append("Crew: ", style="white") failure_content.append(crew_name or "Crew", style="red") self.print_panel(failure_content, "Training Failure", "red") self.print() def handle_crew_test_failed(self, crew_name: str) -> None: """Handle crew test failed event.""" if not self.verbose: return failure_content = Text() failure_content.append("โŒ Crew Test Failed\n", style="red bold") failure_content.append("Crew: ", style="white") failure_content.append(crew_name or "Crew", style="red") self.print_panel(failure_content, "Test Failure", "red") self.print()