You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_commandline_code_executor.py 6.7 kB

Code executors (#1405) * code executor * test * revert to main conversable agent * prepare for pr * kernel * run open ai tests only when it's out of draft status * update workflow file * revert workflow changes * ipython executor * check kernel installed; fix tests * fix tests * fix tests * update system prompt * Update notebook, more tests * notebook * raise instead of return None * allow user provided code executor. * fixing types * wip * refactoring * polishing * fixed failing tests * resolved merge conflict * fixing failing test * wip * local command line executor and embedded ipython executor * revert notebook * fix format * fix merged error * fix lmm test * fix lmm test * move warning * name and description should be part of the agent protocol, reset is not as it is only used for ConversableAgent; removing accidentally commited file * version for dependency * Update autogen/agentchat/conversable_agent.py Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com> * ordering of protocol * description * fix tests * make ipython executor dependency optional * update document optional dependencies * Remove exclude from Agent protocol * Make ConversableAgent consistent with Agent * fix tests * add doc string * add doc string * fix notebook * fix interface * merge and update agents * disable config usage in reply function * description field setter * customize system message update * update doc --------- Co-authored-by: Davor Runje <davor@airt.ai> Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com> Co-authored-by: Aaron <aaronlaptop12@hotmail.com> Co-authored-by: Chi Wang <wang.chi@microsoft.com>
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. import sys
  2. import tempfile
  3. import pytest
  4. from autogen.agentchat.conversable_agent import ConversableAgent
  5. from autogen.coding.base import CodeBlock, CodeExecutor
  6. from autogen.coding.factory import CodeExecutorFactory
  7. from autogen.coding.local_commandline_code_executor import LocalCommandlineCodeExecutor
  8. from autogen.oai.openai_utils import config_list_from_json
  9. from conftest import skip_openai
  10. def test_create() -> None:
  11. config = {"executor": "commandline-local"}
  12. executor = CodeExecutorFactory.create(config)
  13. assert isinstance(executor, LocalCommandlineCodeExecutor)
  14. config = {"executor": LocalCommandlineCodeExecutor()}
  15. executor = CodeExecutorFactory.create(config)
  16. assert executor is config["executor"]
  17. def test_local_commandline_executor_init() -> None:
  18. executor = LocalCommandlineCodeExecutor(timeout=10, work_dir=".")
  19. assert executor.timeout == 10 and executor.work_dir == "."
  20. # Try invalid working directory.
  21. with pytest.raises(ValueError, match="Working directory .* does not exist."):
  22. executor = LocalCommandlineCodeExecutor(timeout=111, work_dir="/invalid/directory")
  23. def test_local_commandline_executor_execute_code() -> None:
  24. with tempfile.TemporaryDirectory() as temp_dir:
  25. executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
  26. _test_execute_code(executor=executor)
  27. def _test_execute_code(executor: CodeExecutor) -> None:
  28. # Test single code block.
  29. code_blocks = [CodeBlock(code="import sys; print('hello world!')", language="python")]
  30. code_result = executor.execute_code_blocks(code_blocks)
  31. assert code_result.exit_code == 0 and "hello world!" in code_result.output and code_result.code_file is not None
  32. # Test multiple code blocks.
  33. code_blocks = [
  34. CodeBlock(code="import sys; print('hello world!')", language="python"),
  35. CodeBlock(code="a = 100 + 100; print(a)", language="python"),
  36. ]
  37. code_result = executor.execute_code_blocks(code_blocks)
  38. assert (
  39. code_result.exit_code == 0
  40. and "hello world!" in code_result.output
  41. and "200" in code_result.output
  42. and code_result.code_file is not None
  43. )
  44. # Test bash script.
  45. if sys.platform not in ["win32"]:
  46. code_blocks = [CodeBlock(code="echo 'hello world!'", language="bash")]
  47. code_result = executor.execute_code_blocks(code_blocks)
  48. assert code_result.exit_code == 0 and "hello world!" in code_result.output and code_result.code_file is not None
  49. # Test running code.
  50. file_lines = ["import sys", "print('hello world!')", "a = 100 + 100", "print(a)"]
  51. code_blocks = [CodeBlock(code="\n".join(file_lines), language="python")]
  52. code_result = executor.execute_code_blocks(code_blocks)
  53. assert (
  54. code_result.exit_code == 0
  55. and "hello world!" in code_result.output
  56. and "200" in code_result.output
  57. and code_result.code_file is not None
  58. )
  59. # Check saved code file.
  60. with open(code_result.code_file) as f:
  61. code_lines = f.readlines()
  62. for file_line, code_line in zip(file_lines, code_lines):
  63. assert file_line.strip() == code_line.strip()
  64. @pytest.mark.skipif(sys.platform in ["win32"], reason="do not run on windows")
  65. def test_local_commandline_code_executor_timeout() -> None:
  66. with tempfile.TemporaryDirectory() as temp_dir:
  67. executor = LocalCommandlineCodeExecutor(timeout=1, work_dir=temp_dir)
  68. _test_timeout(executor)
  69. def _test_timeout(executor: CodeExecutor) -> None:
  70. code_blocks = [CodeBlock(code="import time; time.sleep(10); print('hello world!')", language="python")]
  71. code_result = executor.execute_code_blocks(code_blocks)
  72. assert code_result.exit_code and "Timeout" in code_result.output
  73. def test_local_commandline_code_executor_restart() -> None:
  74. executor = LocalCommandlineCodeExecutor()
  75. _test_restart(executor)
  76. def _test_restart(executor: CodeExecutor) -> None:
  77. # Check warning.
  78. with pytest.warns(UserWarning, match=r".*No action is taken."):
  79. executor.restart()
  80. @pytest.mark.skipif(skip_openai, reason="requested to skip openai tests")
  81. def test_local_commandline_executor_conversable_agent_capability() -> None:
  82. with tempfile.TemporaryDirectory() as temp_dir:
  83. executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
  84. _test_conversable_agent_capability(executor=executor)
  85. def _test_conversable_agent_capability(executor: CodeExecutor) -> None:
  86. KEY_LOC = "notebook"
  87. OAI_CONFIG_LIST = "OAI_CONFIG_LIST"
  88. config_list = config_list_from_json(
  89. OAI_CONFIG_LIST,
  90. file_location=KEY_LOC,
  91. filter_dict={
  92. "model": {
  93. "gpt-3.5-turbo",
  94. "gpt-35-turbo",
  95. },
  96. },
  97. )
  98. llm_config = {"config_list": config_list}
  99. agent = ConversableAgent(
  100. "coding_agent",
  101. llm_config=llm_config,
  102. code_execution_config=False,
  103. )
  104. executor.user_capability.add_to_agent(agent)
  105. # Test updated system prompt.
  106. assert executor.DEFAULT_SYSTEM_MESSAGE_UPDATE in agent.system_message
  107. # Test code generation.
  108. reply = agent.generate_reply(
  109. [{"role": "user", "content": "write a python script to print 'hello world' to the console"}],
  110. sender=ConversableAgent(name="user", llm_config=False, code_execution_config=False),
  111. )
  112. # Test code extraction.
  113. code_blocks = executor.code_extractor.extract_code_blocks(reply) # type: ignore[arg-type]
  114. assert len(code_blocks) == 1 and code_blocks[0].language == "python"
  115. # Test code execution.
  116. code_result = executor.execute_code_blocks(code_blocks)
  117. assert code_result.exit_code == 0 and "hello world" in code_result.output.lower().replace(",", "")
  118. def test_local_commandline_executor_conversable_agent_code_execution() -> None:
  119. with tempfile.TemporaryDirectory() as temp_dir:
  120. executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
  121. with pytest.MonkeyPatch.context() as mp:
  122. mp.setenv("OPENAI_API_KEY", "mock")
  123. _test_conversable_agent_code_execution(executor)
  124. def _test_conversable_agent_code_execution(executor: CodeExecutor) -> None:
  125. agent = ConversableAgent(
  126. "user_proxy",
  127. code_execution_config={"executor": executor},
  128. llm_config=False,
  129. )
  130. assert agent.code_executor is executor
  131. message = """
  132. Example:
  133. ```python
  134. print("hello extract code")
  135. ```
  136. """
  137. reply = agent.generate_reply(
  138. [{"role": "user", "content": message}],
  139. sender=ConversableAgent("user", llm_config=False, code_execution_config=False),
  140. )
  141. assert "hello extract code" in reply # type: ignore[operator]