| """ |
| Terminal display utilities with colors and formatting |
| """ |
|
|
|
|
| |
| class Colors: |
| RED = "\033[91m" |
| GREEN = "\033[92m" |
| YELLOW = "\033[93m" |
| BLUE = "\033[94m" |
| MAGENTA = "\033[95m" |
| CYAN = "\033[96m" |
| BOLD = "\033[1m" |
| UNDERLINE = "\033[4m" |
| RESET = "\033[0m" |
|
|
|
|
| def truncate_to_lines(text: str, max_lines: int = 6) -> str: |
| """Truncate text to max_lines, adding '...' if truncated""" |
| lines = text.split("\n") |
| if len(lines) <= max_lines: |
| return text |
| return ( |
| "\n".join(lines[:max_lines]) |
| + f"\n{Colors.CYAN}... ({len(lines) - max_lines} more lines){Colors.RESET}" |
| ) |
|
|
|
|
| def format_header(text: str, emoji: str = "") -> str: |
| """Format a header with bold""" |
| full_text = f"{emoji} {text}" if emoji else text |
| return f"{Colors.BOLD}{full_text}{Colors.RESET}" |
|
|
|
|
| def format_plan_display() -> str: |
| """Format the current plan for display (no colors, full visibility)""" |
| from agent.tools.plan_tool import get_current_plan |
|
|
| plan = get_current_plan() |
| if not plan: |
| return "" |
|
|
| lines = ["\n" + "=" * 60] |
| lines.append("CURRENT PLAN") |
| lines.append("=" * 60 + "\n") |
|
|
| |
| completed = [t for t in plan if t["status"] == "completed"] |
| in_progress = [t for t in plan if t["status"] == "in_progress"] |
| pending = [t for t in plan if t["status"] == "pending"] |
|
|
| if completed: |
| lines.append("Completed:") |
| for todo in completed: |
| lines.append(f" [x] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| if in_progress: |
| lines.append("In Progress:") |
| for todo in in_progress: |
| lines.append(f" [~] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| if pending: |
| lines.append("Pending:") |
| for todo in pending: |
| lines.append(f" [ ] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| lines.append( |
| f"Total: {len(plan)} todos ({len(completed)} completed, {len(in_progress)} in progress, {len(pending)} pending)" |
| ) |
| lines.append("=" * 60 + "\n") |
|
|
| return "\n".join(lines) |
|
|
|
|
| def format_error(message: str) -> str: |
| """Format an error message in red""" |
| return f"{Colors.RED}ERROR: {message}{Colors.RESET}" |
|
|
|
|
| def format_success(message: str, emoji: str = "") -> str: |
| """Format a success message in green""" |
| prefix = f"{emoji} " if emoji else "" |
| return f"{Colors.GREEN}{prefix}{message}{Colors.RESET}" |
|
|
|
|
| def format_tool_call(tool_name: str, arguments: str) -> str: |
| """Format a tool call message""" |
| return f"{Colors.YELLOW}Calling tool: {Colors.BOLD}{tool_name}{Colors.RESET}{Colors.YELLOW} with arguments: {arguments}{Colors.RESET}" |
|
|
|
|
| def format_tool_output(output: str, success: bool, truncate: bool = True) -> str: |
| """Format tool output with color and optional truncation""" |
| if truncate: |
| output = truncate_to_lines(output, max_lines=6) |
|
|
| if success: |
| return f"{Colors.YELLOW}Tool output:{Colors.RESET}\n{output}" |
| else: |
| return f"{Colors.RED}Tool output:{Colors.RESET}\n{output}" |
|
|
|
|
| def format_turn_complete() -> str: |
| """Format turn complete message in green with hugging face emoji""" |
| return f"{Colors.GREEN}{Colors.BOLD}\U0001f917 Turn complete{Colors.RESET}\n" |
|
|
|
|
| def format_separator(char: str = "=", length: int = 60) -> str: |
| """Format a separator line""" |
| return char * length |
|
|
|
|
| def format_plan_tool_output(todos: list) -> str: |
| """Format the plan tool output (no colors, full visibility)""" |
| if not todos: |
| return "Plan is empty." |
|
|
| lines = ["Plan updated successfully", ""] |
|
|
| |
| completed = [t for t in todos if t["status"] == "completed"] |
| in_progress = [t for t in todos if t["status"] == "in_progress"] |
| pending = [t for t in todos if t["status"] == "pending"] |
|
|
| if completed: |
| lines.append("Completed:") |
| for todo in completed: |
| lines.append(f" [x] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| if in_progress: |
| lines.append("In Progress:") |
| for todo in in_progress: |
| lines.append(f" [~] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| if pending: |
| lines.append("Pending:") |
| for todo in pending: |
| lines.append(f" [ ] {todo['id']}. {todo['content']}") |
| lines.append("") |
|
|
| lines.append( |
| f"Total: {len(todos)} todos ({len(completed)} completed, {len(in_progress)} in progress, {len(pending)} pending)" |
| ) |
|
|
| return "\n".join(lines) |
|
|