|
2 | 2 | import logging
|
3 | 3 | import os
|
4 | 4 | import uuid
|
5 |
| -from typing import Dict, List, Optional |
| 5 | +from typing import List, Optional |
6 | 6 |
|
7 |
| -from app.engine.utils.file_helper import save_file |
| 7 | +from app.engine.utils.file_helper import FileMetadata, save_file |
8 | 8 | from e2b_code_interpreter import CodeInterpreter
|
9 | 9 | from e2b_code_interpreter.models import Logs
|
10 | 10 | from llama_index.core.tools import FunctionTool
|
@@ -78,10 +78,11 @@ def _init_interpreter(self, sandbox_files: List[str] = []):
|
78 | 78 |
|
79 | 79 | with open(local_file_path, "rb") as f:
|
80 | 80 | content = f.read()
|
81 |
| - self.interpreter.files.write(sandbox_file_path, content) |
| 81 | + if self.interpreter and self.interpreter.files: |
| 82 | + self.interpreter.files.write(sandbox_file_path, content) |
82 | 83 | logger.info(f"Uploaded {len(sandbox_files)} files to sandbox")
|
83 | 84 |
|
84 |
| - def _save_to_disk(self, base64_data: str, ext: str) -> Dict: |
| 85 | + def _save_to_disk(self, base64_data: str, ext: str) -> FileMetadata: |
85 | 86 | buffer = base64.b64decode(base64_data)
|
86 | 87 |
|
87 | 88 | filename = f"{uuid.uuid4()}.{ext}" # generate a unique filename
|
@@ -166,40 +167,41 @@ def interpret(
|
166 | 167 | if self.interpreter is None:
|
167 | 168 | self._init_interpreter(sandbox_files)
|
168 | 169 |
|
169 |
| - logger.info( |
170 |
| - f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}" |
171 |
| - ) |
172 |
| - exec = self.interpreter.notebook.exec_cell(code) |
173 |
| - |
174 |
| - if exec.error: |
175 |
| - error_message = f"The code failed to execute successfully. Error: {exec.error}. Try to fix the code and run again." |
176 |
| - logger.error(error_message) |
177 |
| - # There would be an error from previous execution, kill the interpreter and return with error message |
178 |
| - try: |
179 |
| - self.interpreter.kill() |
180 |
| - except Exception: |
181 |
| - pass |
182 |
| - finally: |
183 |
| - self.interpreter = None |
184 |
| - output = E2BToolOutput( |
185 |
| - is_error=True, |
186 |
| - logs=exec.logs, |
187 |
| - results=[], |
188 |
| - error_message=error_message, |
189 |
| - retry_count=retry_count + 1, |
| 170 | + if self.interpreter and self.interpreter.notebook: |
| 171 | + logger.info( |
| 172 | + f"\n{'='*50}\n> Running following AI-generated code:\n{code}\n{'='*50}" |
190 | 173 | )
|
191 |
| - else: |
192 |
| - if len(exec.results) == 0: |
193 |
| - output = E2BToolOutput(is_error=False, logs=exec.logs, results=[]) |
194 |
| - else: |
195 |
| - results = self._parse_result(exec.results[0]) |
| 174 | + exec = self.interpreter.notebook.exec_cell(code) |
| 175 | + |
| 176 | + if exec.error: |
| 177 | + error_message = f"The code failed to execute successfully. Error: {exec.error}. Try to fix the code and run again." |
| 178 | + logger.error(error_message) |
| 179 | + # There would be an error from previous execution, kill the interpreter and return with error message |
| 180 | + try: |
| 181 | + self.interpreter.kill() # type: ignore |
| 182 | + except Exception: |
| 183 | + pass |
| 184 | + finally: |
| 185 | + self.interpreter = None |
196 | 186 | output = E2BToolOutput(
|
197 |
| - is_error=False, |
| 187 | + is_error=True, |
198 | 188 | logs=exec.logs,
|
199 |
| - results=results, |
| 189 | + results=[], |
| 190 | + error_message=error_message, |
200 | 191 | retry_count=retry_count + 1,
|
201 | 192 | )
|
202 |
| - return output |
| 193 | + else: |
| 194 | + if len(exec.results) == 0: |
| 195 | + output = E2BToolOutput(is_error=False, logs=exec.logs, results=[]) |
| 196 | + else: |
| 197 | + results = self._parse_result(exec.results[0]) |
| 198 | + output = E2BToolOutput( |
| 199 | + is_error=False, |
| 200 | + logs=exec.logs, |
| 201 | + results=results, |
| 202 | + retry_count=retry_count + 1, |
| 203 | + ) |
| 204 | + return output |
203 | 205 |
|
204 | 206 |
|
205 | 207 | def get_tools(**kwargs):
|
|
0 commit comments