diff --git a/lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py b/lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py index 0846e8a27..977cc0fb4 100644 --- a/lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py +++ b/lib/crewai-tools/src/crewai_tools/tools/code_interpreter_tool/code_interpreter_tool.py @@ -8,6 +8,7 @@ potentially unsafe operations and importing restricted modules. import importlib.util import os import subprocess +import sys from types import ModuleType from typing import Any, ClassVar, TypedDict @@ -321,7 +322,7 @@ class CodeInterpreterTool(BaseTool): """ if self._check_docker_available(): return self.run_code_in_docker(code, libraries_used) - + error_msg = ( "Docker is required for safe code execution but is not available. " "The restricted sandbox fallback has been removed due to security vulnerabilities " @@ -411,7 +412,7 @@ class CodeInterpreterTool(BaseTool): Printer.print("WARNING: Running code in unsafe mode", color="bold_magenta") # Install libraries on the host machine for library in libraries_used: - subprocess.run(["pip", "install", library], check=False) # noqa: S603 + subprocess.run([sys.executable, "-m", "pip", "install", library], check=False) # noqa: S603 # Execute the code try: diff --git a/lib/crewai-tools/tests/tools/test_code_interpreter_tool.py b/lib/crewai-tools/tests/tools/test_code_interpreter_tool.py index 70ba02c7e..5b0144790 100644 --- a/lib/crewai-tools/tests/tools/test_code_interpreter_tool.py +++ b/lib/crewai-tools/tests/tools/test_code_interpreter_tool.py @@ -1,3 +1,4 @@ +import sys from unittest.mock import patch from crewai_tools.tools.code_interpreter_tool.code_interpreter_tool import ( @@ -167,7 +168,7 @@ def test_unsafe_mode_installs_libraries_without_shell( for call, library in zip(subprocess_run_mock.call_args_list, libraries_used): args, kwargs = call # Must be list form (no shell expansion possible) - assert args[0] == ["pip", "install", library] + assert args[0] == [sys.executable, "-m", "pip", "install", library] # shell= must not be True (defaults to False) assert kwargs.get("shell", False) is False @@ -186,7 +187,7 @@ def test_unsafe_mode_library_name_with_shell_metacharacters_does_not_invoke_shel subprocess_run_mock.assert_called_once() args, kwargs = subprocess_run_mock.call_args # The entire malicious string is passed as a single argument — no shell parsing - assert args[0] == ["pip", "install", malicious_library] + assert args[0] == [sys.executable, "-m", "pip", "install", malicious_library] assert kwargs.get("shell", False) is False