import os import tempfile from typing import Dict, Union import uuid import pytest from autogen.agentchat.conversable_agent import ConversableAgent from autogen.coding.base import CodeBlock, CodeExecutor from autogen.coding.factory import CodeExecutorFactory from autogen.oai.openai_utils import config_list_from_json from conftest import skip_openai # noqa: E402 try: from autogen.coding.embedded_ipython_code_executor import EmbeddedIPythonCodeExecutor skip = False skip_reason = "" except ImportError: skip = True skip_reason = "Dependencies for EmbeddedIPythonCodeExecutor not installed." @pytest.mark.skipif(skip, reason=skip_reason) def test_create() -> None: config: Dict[str, Union[str, CodeExecutor]] = {"executor": "ipython-embedded"} executor = CodeExecutorFactory.create(config) assert isinstance(executor, EmbeddedIPythonCodeExecutor) config = {"executor": EmbeddedIPythonCodeExecutor()} executor = CodeExecutorFactory.create(config) assert executor is config["executor"] @pytest.mark.skipif(skip, reason=skip_reason) def test_init() -> None: executor = EmbeddedIPythonCodeExecutor(timeout=10, kernel_name="python3", output_dir=".") assert executor.timeout == 10 and executor.kernel_name == "python3" and executor.output_dir == "." # Try invalid output directory. with pytest.raises(ValueError, match="Output directory .* does not exist."): executor = EmbeddedIPythonCodeExecutor(timeout=111, kernel_name="python3", output_dir="/invalid/directory") # Try invalid kernel name. with pytest.raises(ValueError, match="Kernel .* is not installed."): executor = EmbeddedIPythonCodeExecutor(timeout=111, kernel_name="invalid_kernel_name", output_dir=".") @pytest.mark.skipif(skip, reason=skip_reason) def test_execute_code_single_code_block() -> None: executor = EmbeddedIPythonCodeExecutor() code_blocks = [CodeBlock(code="import sys\nprint('hello world!')", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "hello world!" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_execute_code_multiple_code_blocks() -> None: executor = EmbeddedIPythonCodeExecutor() code_blocks = [ CodeBlock(code="import sys\na = 123 + 123\n", language="python"), CodeBlock(code="print(a)", language="python"), ] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "246" in code_result.output msg = """ def test_function(a, b): return a + b """ code_blocks = [ CodeBlock(code=msg, language="python"), CodeBlock(code="test_function(431, 423)", language="python"), ] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "854" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_execute_code_bash_script() -> None: executor = EmbeddedIPythonCodeExecutor() # Test bash script. code_blocks = [CodeBlock(code='!echo "hello world!"', language="bash")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "hello world!" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_timeout() -> None: executor = EmbeddedIPythonCodeExecutor(timeout=1) code_blocks = [CodeBlock(code="import time; time.sleep(10); print('hello world!')", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code and "Timeout" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_silent_pip_install() -> None: executor = EmbeddedIPythonCodeExecutor() code_blocks = [CodeBlock(code="!pip install matplotlib numpy", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and code_result.output.strip() == "" none_existing_package = uuid.uuid4().hex code_blocks = [CodeBlock(code=f"!pip install matplotlib_{none_existing_package}", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "ERROR: " in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_restart() -> None: executor = EmbeddedIPythonCodeExecutor() code_blocks = [CodeBlock(code="x = 123", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and code_result.output.strip() == "" executor.restart() code_blocks = [CodeBlock(code="print(x)", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code and "NameError" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_save_image() -> None: with tempfile.TemporaryDirectory() as temp_dir: executor = EmbeddedIPythonCodeExecutor(output_dir=temp_dir) # Install matplotlib. code_blocks = [CodeBlock(code="!pip install matplotlib", language="python")] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and code_result.output.strip() == "" # Test saving image. code_blocks = [ CodeBlock(code="import matplotlib.pyplot as plt\nplt.plot([1, 2, 3, 4])\nplt.show()", language="python") ] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 assert os.path.exists(code_result.output_files[0]) assert f"Image data saved to {code_result.output_files[0]}" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) def test_save_html() -> None: with tempfile.TemporaryDirectory() as temp_dir: executor = EmbeddedIPythonCodeExecutor(output_dir=temp_dir) # Test saving html. code_blocks = [ CodeBlock(code="from IPython.display import HTML\nHTML('

Hello, world!

')", language="python") ] code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 assert os.path.exists(code_result.output_files[0]) assert f"HTML data saved to {code_result.output_files[0]}" in code_result.output @pytest.mark.skipif(skip, reason=skip_reason) @pytest.mark.skipif(skip_openai, reason="openai not installed OR requested to skip") def test_conversable_agent_capability() -> None: KEY_LOC = "notebook" OAI_CONFIG_LIST = "OAI_CONFIG_LIST" config_list = config_list_from_json( OAI_CONFIG_LIST, file_location=KEY_LOC, filter_dict={ "model": { "gpt-3.5-turbo", "gpt-35-turbo", }, }, ) llm_config = {"config_list": config_list} agent = ConversableAgent( "coding_agent", llm_config=llm_config, code_execution_config=False, ) executor = EmbeddedIPythonCodeExecutor() executor.user_capability.add_to_agent(agent) # Test updated system prompt. assert executor.DEFAULT_SYSTEM_MESSAGE_UPDATE in agent.system_message # Test code generation. reply = agent.generate_reply( [{"role": "user", "content": "print 'hello world' to the console in a single python code block"}], sender=ConversableAgent("user", llm_config=False, code_execution_config=False), ) # Test code extraction. code_blocks = executor.code_extractor.extract_code_blocks(reply) # type: ignore[arg-type] assert len(code_blocks) == 1 and code_blocks[0].language == "python" # Test code execution. code_result = executor.execute_code_blocks(code_blocks) assert code_result.exit_code == 0 and "hello world" in code_result.output.lower() @pytest.mark.skipif(skip, reason=skip_reason) def test_conversable_agent_code_execution() -> None: agent = ConversableAgent( "user_proxy", llm_config=False, code_execution_config={"executor": "ipython-embedded"}, ) msg = """ Run this code: ```python def test_function(a, b): return a * b ``` And then this: ```python print(test_function(123, 4)) ``` """ with pytest.MonkeyPatch.context() as mp: mp.setenv("OPENAI_API_KEY", "mock") reply = agent.generate_reply( [{"role": "user", "content": msg}], sender=ConversableAgent("user", llm_config=False, code_execution_config=False), ) assert "492" in reply # type: ignore[operator]