mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-03 16:22:49 +00:00
refactor: Implement code review suggestions for emoji disable feature
- Move EMOJI_MAP to module level as DEFAULT_EMOJI_MAP for memory efficiency - Add _parse_bool_env() helper function for cleaner boolean conversion - Implement performance optimization with icon caching - Improve error handling for unknown emojis with better fallback format - Update tests to work with new module structure - All functionality preserved and tests passing Addresses feedback from PR review #3063 Co-Authored-By: João <joao@crewai.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
from typing import Any, Dict, Optional
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
@@ -8,32 +8,7 @@ from rich.tree import Tree
|
||||
from rich.live import Live
|
||||
from rich.syntax import Syntax
|
||||
|
||||
|
||||
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
|
||||
current_lite_agent_branch: Optional[Tree] = None
|
||||
tool_usage_counts: Dict[str, int] = {}
|
||||
current_reasoning_branch: Optional[Tree] = None # Track reasoning status
|
||||
_live_paused: bool = False
|
||||
current_llm_tool_tree: Optional[Tree] = None
|
||||
|
||||
def __init__(self, verbose: bool = False):
|
||||
self.console = Console(width=None)
|
||||
self.verbose = verbose
|
||||
self.disable_emojis = os.getenv("CREWAI_DISABLE_EMOJIS", "").lower() in ("true", "1", "yes")
|
||||
# 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.
|
||||
# Once any non-Tree renderable is printed we stop the Live session so the
|
||||
# final Tree persists on the terminal.
|
||||
self._live: Optional[Live] = None
|
||||
|
||||
EMOJI_MAP = {
|
||||
DEFAULT_EMOJI_MAP = {
|
||||
"✅": "[DONE]",
|
||||
"❌": "[FAILED]",
|
||||
"🚀": "[CREW]",
|
||||
@@ -59,11 +34,53 @@ class ConsoleFormatter:
|
||||
"💾": "[SAVE]",
|
||||
"🔒": "[SECURE]",
|
||||
"🌟": "[STAR]",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def _parse_bool_env(val: str) -> bool:
|
||||
"""Parse environment variable value to boolean."""
|
||||
return val.lower() in ("true", "1", "yes") if val else False
|
||||
|
||||
|
||||
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
|
||||
current_lite_agent_branch: Optional[Tree] = None
|
||||
tool_usage_counts: Dict[str, int] = {}
|
||||
current_reasoning_branch: Optional[Tree] = None # Track reasoning status
|
||||
_live_paused: bool = False
|
||||
current_llm_tool_tree: Optional[Tree] = None
|
||||
|
||||
def __init__(self, verbose: bool = False):
|
||||
self.console = Console(width=None)
|
||||
self.verbose = verbose
|
||||
self.disable_emojis = _parse_bool_env(os.getenv("CREWAI_DISABLE_EMOJIS", ""))
|
||||
|
||||
self.emoji_map = DEFAULT_EMOJI_MAP.copy()
|
||||
self.icon_cache: Dict[str, str] = {}
|
||||
if self.disable_emojis:
|
||||
self.icon_cache = {emoji: text for emoji, text in self.emoji_map.items()}
|
||||
|
||||
# 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.
|
||||
# Once any non-Tree renderable is printed we stop the Live session so the
|
||||
# final Tree persists on the terminal.
|
||||
self._live: Optional[Live] = None
|
||||
|
||||
def _get_icon(self, emoji: str) -> str:
|
||||
"""Get emoji or text alternative based on disable_emojis setting."""
|
||||
if self.disable_emojis:
|
||||
return self.EMOJI_MAP.get(emoji, emoji.encode('ascii', 'ignore').decode('ascii'))
|
||||
if emoji in self.icon_cache:
|
||||
return self.icon_cache[emoji]
|
||||
ascii_fallback = emoji.encode('ascii', 'ignore').decode('ascii')
|
||||
fallback = f"[ICON:{ascii_fallback or 'UNKNOWN'}]"
|
||||
self.icon_cache[emoji] = fallback
|
||||
return fallback
|
||||
return emoji
|
||||
|
||||
def create_panel(self, content: Text, title: str, style: str = "blue") -> Panel:
|
||||
|
||||
@@ -96,11 +96,11 @@ class TestConsoleFormatterEmojiDisable:
|
||||
assert formatter._get_icon(emoji) == expected_text
|
||||
|
||||
def test_unknown_emoji_fallback(self):
|
||||
"""Test that unknown emojis fall back to ASCII-only representation."""
|
||||
"""Test that unknown emojis fall back to proper representation."""
|
||||
with patch.dict(os.environ, {"CREWAI_DISABLE_EMOJIS": "true"}):
|
||||
formatter = ConsoleFormatter(verbose=True)
|
||||
result = formatter._get_icon("🦄")
|
||||
assert result == ""
|
||||
assert result == "[ICON:UNKNOWN]"
|
||||
|
||||
@patch.dict(os.environ, {"CREWAI_DISABLE_EMOJIS": "true"})
|
||||
def test_crew_tree_creation_without_emojis(self):
|
||||
|
||||
Reference in New Issue
Block a user