Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minor fix #31

Merged
merged 15 commits into from
Oct 2, 2023
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