Executes Python code and captures stdout and stderr outputs. Returns the output or formatted error message.
(self, code_str: str)
| 24 | self.max_rounds = max_rounds |
| 25 | |
| 26 | def execute_code(self, code_str: str) -> str: |
| 27 | """ |
| 28 | Executes Python code and captures stdout and stderr outputs. |
| 29 | Returns the output or formatted error message. |
| 30 | """ |
| 31 | stdout_capture = io.StringIO() |
| 32 | stderr_capture = io.StringIO() |
| 33 | |
| 34 | try: |
| 35 | with contextlib.redirect_stdout(stdout_capture), contextlib.redirect_stderr( |
| 36 | stderr_capture |
| 37 | ): |
| 38 | exec(code_str, {}) |
| 39 | output = stdout_capture.getvalue() |
| 40 | if stderr_capture.getvalue(): |
| 41 | output += stderr_capture.getvalue() |
| 42 | return output |
| 43 | except Exception as exec_error: |
| 44 | code_lines = code_str.splitlines() |
| 45 | tb_lines = traceback.format_exc().splitlines() |
| 46 | error_line = None |
| 47 | |
| 48 | # Attempt to extract line number from traceback |
| 49 | for line in tb_lines: |
| 50 | if 'File "<string>", line' in line: |
| 51 | try: |
| 52 | line_num = int(line.split(", line ")[1].split(",")[0]) |
| 53 | error_line = line_num |
| 54 | break |
| 55 | except (IndexError, ValueError): |
| 56 | continue |
| 57 | |
| 58 | # Build formatted error message |
| 59 | error_message = "Traceback (most recent call last):\n" |
| 60 | if error_line and 1 <= error_line <= len(code_lines): |
| 61 | error_message += f' File "<string>", line {error_line}, in <module>\n' |
| 62 | error_message += f" {code_lines[error_line - 1].strip()}\n" |
| 63 | error_message += f"{type(exec_error).__name__}: {str(exec_error)}" |
| 64 | if stderr_capture.getvalue(): |
| 65 | error_message += f"\n{stderr_capture.getvalue()}" |
| 66 | return f"[Error]:\n{error_message.strip()}" |
| 67 | |
| 68 | def generate( |
| 69 | self, |