| 114 | |
| 115 | |
| 116 | def debug_code( |
| 117 | debugger: LMM, |
| 118 | tool_docs: str, |
| 119 | plan: str, |
| 120 | code: str, |
| 121 | test: str, |
| 122 | result: Execution, |
| 123 | debug_info: str, |
| 124 | verbose: bool, |
| 125 | ) -> tuple[str, str, str]: |
| 126 | fixed_code = None |
| 127 | fixed_test = None |
| 128 | thoughts = "" |
| 129 | success = False |
| 130 | count = 0 |
| 131 | while not success and count < 3: |
| 132 | try: |
| 133 | # LLMs write worse code when it's in JSON, so we have it write JSON |
| 134 | # followed by code each wrapped in markdown blocks. |
| 135 | fixed_code_and_test_str = debugger( |
| 136 | FIX_BUG.format( |
| 137 | docstring=tool_docs, |
| 138 | plan=plan, |
| 139 | code=code, |
| 140 | tests=test, |
| 141 | # Because of the way we trace function calls the trace information |
| 142 | # ends up in the results. We don't want to show this info to the |
| 143 | # LLM so we don't include it in the tool_output_str. |
| 144 | result="\n".join( |
| 145 | result.text(include_results=False).splitlines()[-50:] |
| 146 | ), |
| 147 | debug=debug_info, |
| 148 | ), |
| 149 | stream=False, |
| 150 | ) |
| 151 | fixed_code_and_test_str = cast(str, fixed_code_and_test_str) |
| 152 | thoughts_tag = extract_tag(fixed_code_and_test_str, "thoughts") |
| 153 | thoughts = thoughts_tag if thoughts_tag is not None else "" |
| 154 | fixed_code = extract_tag( |
| 155 | fixed_code_and_test_str, "code", extract_markdown="python" |
| 156 | ) |
| 157 | fixed_test = extract_tag( |
| 158 | fixed_code_and_test_str, "test", extract_markdown="python" |
| 159 | ) |
| 160 | |
| 161 | success = not (fixed_code is None and fixed_test is None) |
| 162 | |
| 163 | except Exception as e: |
| 164 | _CONSOLE.print(f"[bold red]Error while extracting JSON:[/bold red] {e}") |
| 165 | |
| 166 | count += 1 |
| 167 | |
| 168 | old_code = code |
| 169 | old_test = test |
| 170 | |
| 171 | if fixed_code is not None and fixed_code.strip() != "": |
| 172 | code = fixed_code |
| 173 | if fixed_test is not None and fixed_test.strip() != "": |