Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 12 additions & 11 deletions autogen/agentchat/conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,25 +611,26 @@ def generate_code_execution_reply(
if messages is None:
messages = self._oai_messages[sender]
last_n_messages = code_execution_config.pop("last_n_messages", 1)

# iterate through the last n messages reversly
# if code blocks are found, execute the code blocks and return the output
# if no code blocks are found, continue
for i in range(min(len(messages), last_n_messages)):
message = messages[-(i + 1)]
code_blocks = extract_code(message["content"])
if len(code_blocks) == 1 and code_blocks[0][0] == UNKNOWN:
# no code block is found, lang should be `UNKNOWN`

if i == last_n_messages - 1:
code_execution_config["last_n_messages"] = last_n_messages
return False, None
continue
# code_blocks, _ = find_code(messages, sys_msg=self._oai_system_message, **self.llm_config)
# if len(code_blocks) == 1 and code_blocks[0][0] == UNKNOWN:
# return code_blocks[0][1]
# try to execute the code

# found code blocks, execute code and push "last_n_messages" back
exitcode, logs = self.execute_code_blocks(code_blocks)
code_execution_config["last_n_messages"] = last_n_messages
exitcode2str = "execution succeeded" if exitcode == 0 else "execution failed"
break
return True, f"exitcode: {exitcode} ({exitcode2str})\nCode output: {logs}"

# no code blocks are found, push last_n_messages back and return.
code_execution_config["last_n_messages"] = last_n_messages
return True, f"exitcode: {exitcode} ({exitcode2str})\nCode output: {logs}"

return False, None

def generate_function_call_reply(
self,
Expand Down
11 changes: 9 additions & 2 deletions autogen/code_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ def infer_lang(code):
"""
if code.startswith("python ") or code.startswith("pip") or code.startswith("python3 "):
return "sh"
return "python"

# check if code is a valid python code
try:
compile(code, "test", "exec")
return "python"
except SyntaxError:
# not a valid python code
return UNKNOWN


def extract_code(
Expand Down Expand Up @@ -258,7 +265,7 @@ def execute_code(
file_dir = os.path.dirname(filepath)
os.makedirs(file_dir, exist_ok=True)
if code is not None:
with open(filepath, "w") as fout:
with open(filepath, "w", encoding="utf-8") as fout:
fout.write(code)
# check if already running in a docker container
in_docker_container = os.path.exists("/.dockerenv")
Expand Down
42 changes: 42 additions & 0 deletions test/agentchat/test_conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,48 @@ def test_context():
# expect hello there to be printed


def test_generate_code_execution_reply():
agent = ConversableAgent(
"a0", max_consecutive_auto_reply=10, code_execution_config=False, llm_config=False, human_input_mode="NEVER"
)

dummy_messages = [
{
"content": "no code block",
"role": "user",
},
{
"content": "no code block",
"role": "user",
},
]

code_message = {
"content": '```python\nprint("hello world")\n```',
"role": "user",
}

# scenario 1: if code_execution_config is not provided, the code execution should return false, none
assert agent.generate_code_execution_reply(dummy_messages, config=False) == (False, None)

# scenario 2: if code_execution_config is provided, but no code block is found, the code execution should return false, none
assert agent.generate_code_execution_reply(dummy_messages, config={}) == (False, None)

# scenario 3: if code_execution_config is provided, and code block is found, but it's not within the range of last_n_messages, the code execution should return false, none
assert agent.generate_code_execution_reply([code_message] + dummy_messages, config={"last_n_messages": 1}) == (
False,
None,
)

# scenario 4: if code_execution_config is provided, and code block is found, and it's within the range of last_n_messages, the code execution should return true, code block
agent._code_execution_config = {"last_n_messages": 3, "use_docker": False}
assert agent.generate_code_execution_reply([code_message] + dummy_messages) == (
True,
"exitcode: 0 (execution succeeded)\nCode output: \nhello world\n",
)
assert agent._code_execution_config["last_n_messages"] == 3


def test_max_consecutive_auto_reply():
agent = ConversableAgent("a0", max_consecutive_auto_reply=2, llm_config=False, human_input_mode="NEVER")
agent1 = ConversableAgent("a1", max_consecutive_auto_reply=0, human_input_mode="NEVER")
Expand Down
4 changes: 4 additions & 0 deletions test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ def test_infer_lang():
assert infer_lang("print('hello world')") == "python"
assert infer_lang("pip install autogen") == "sh"

# test infer lang for unknown code/invalid code
assert infer_lang("dummy text") == UNKNOWN
assert infer_lang("print('hello world'))") == UNKNOWN


def test_extract_code():
print(extract_code("```bash\npython temp.py\n```"))
Expand Down