Skip to content

Commit 1c3055b

Browse files
fix sandbox backend hardening and stabilize remote backend tests
Agent-Logs-Url: https://github.com/MervinPraison/PraisonAI/sessions/4bc8984f-6a71-42f9-b345-acfff0df8234 Co-authored-by: MervinPraison <454862+MervinPraison@users.noreply.github.com>
1 parent 92ce12a commit 1c3055b

2 files changed

Lines changed: 20 additions & 5 deletions

File tree

src/praisonai/praisonai/sandbox/modal.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
)
1919

2020
logger = logging.getLogger(__name__)
21+
TIMEOUT_EXIT_CODE = 124
2122

2223

2324
class ModalSandbox:
@@ -85,6 +86,7 @@ async def start(self) -> None:
8586

8687
try:
8788
import modal
89+
execution_timeout = self.timeout
8890

8991
# Create Modal app
9092
self._app = modal.App(self.app_name)
@@ -117,10 +119,12 @@ async def start(self) -> None:
117119
)
118120
def execute_code(code: str, language: str = "python", env_vars: Dict[str, str] = None):
119121
"""Execute code in Modal environment."""
122+
import logging
120123
import subprocess
121124
import tempfile
122125
import os
123126
import sys
127+
execute_logger = logging.getLogger(__name__)
124128

125129
extension_map = {
126130
"python": "py",
@@ -161,7 +165,7 @@ def execute_code(code: str, language: str = "python", env_vars: Dict[str, str] =
161165
cmd,
162166
capture_output=True,
163167
text=True,
164-
timeout=self.timeout,
168+
timeout=execution_timeout,
165169
env=execution_env,
166170
)
167171

@@ -172,7 +176,7 @@ def execute_code(code: str, language: str = "python", env_vars: Dict[str, str] =
172176
}
173177
except subprocess.TimeoutExpired:
174178
return {
175-
"exit_code": 124, # Timeout exit code
179+
"exit_code": TIMEOUT_EXIT_CODE,
176180
"stdout": "",
177181
"stderr": "Execution timed out",
178182
}
@@ -186,8 +190,10 @@ def execute_code(code: str, language: str = "python", env_vars: Dict[str, str] =
186190
# Clean up temp file
187191
try:
188192
os.unlink(temp_file)
189-
except OSError:
190-
pass
193+
except OSError as e:
194+
execute_logger.debug(
195+
f"Failed to remove temporary file {temp_file}: {e}"
196+
)
191197

192198
self._function = execute_code
193199
self._is_running = True

src/praisonai/praisonai/sandbox/ssh.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,23 @@ def _build_command(
447447
env: Optional[Dict[str, str]]
448448
) -> str:
449449
"""Build execution command for language."""
450+
java_command = None
451+
if language.lower() == "java":
452+
java_class_name = os.path.splitext(os.path.basename(file_path))[0]
453+
if not re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", java_class_name):
454+
raise ValueError(f"Invalid Java class name derived from file path: {java_class_name}")
455+
java_command = f"javac {shlex.quote(file_path)} && java {shlex.quote(java_class_name)}"
456+
450457
interpreters = {
451458
"python": f"python3 {shlex.quote(file_path)}",
452459
"bash": f"bash {shlex.quote(file_path)}",
453460
"shell": f"bash {shlex.quote(file_path)}",
454461
"javascript": f"node {shlex.quote(file_path)}",
455462
"typescript": f"npx ts-node {shlex.quote(file_path)}",
456-
"java": f"javac {shlex.quote(file_path)} && java {shlex.quote(os.path.splitext(os.path.basename(file_path))[0])}",
457463
}
464+
465+
if java_command:
466+
interpreters["java"] = java_command
458467

459468
base_command = interpreters.get(language.lower(), f"cat {shlex.quote(file_path)}")
460469

0 commit comments

Comments
 (0)