from datetime import datetime class DebugLogger: """In-memory logger for code execution events. Collects timestamped INFO and ERROR entries during a single run. Call clear() before each new execution to start fresh. """ def __init__(self): self.logs: list[dict] = [] def log(self, message: str) -> None: """Append a general info message.""" self.logs.append({ "level": "INFO", "message": message, "timestamp": datetime.now().strftime("%H:%M:%S"), }) def log_error(self, error_message: str) -> None: """Append an error message.""" self.logs.append({ "level": "ERROR", "message": error_message, "timestamp": datetime.now().strftime("%H:%M:%S"), }) def get_logs(self) -> list[dict]: """Return a copy of all collected log entries.""" return list(self.logs) def clear(self) -> None: """Reset the log — call before each new execution.""" self.logs = [] def format_debug_output(self, output: dict) -> str: """Format an ExecutionEngine result dict into a human-readable string. Args: output: dict with keys 'stdout', 'stderr', and 'rc'. Returns: A formatted string ready for display in the UI. """ lines = [] status = "SUCCESS" if output.get("rc") == 0 else "FAILED" lines.append(f"[{status}] Exit code: {output.get('rc')}") if output.get("stdout"): lines.append("\n--- stdout ---") lines.append(output["stdout"].rstrip()) if output.get("stderr"): lines.append("\n--- stderr ---") lines.append(output["stderr"].rstrip()) if not output.get("stdout") and not output.get("stderr"): lines.append("No output produced.") for entry in self.logs: lines.append(f"[{entry['timestamp']}] [{entry['level']}] {entry['message']}") return "\n".join(lines) if __name__ == "__main__": logger = DebugLogger() print(logger.get_logs())