Support function_call in autogen/agent (#1091)

* update funccall

* code format

* update to comments

* update notebook

* remove test for py3.7

* allow funccall to class functions

* add test and clean up notebook

* revise notebook and test

* update

* update mathagent

* Update flaml/autogen/agent/agent.py

Co-authored-by: Chi Wang <wang.chi@microsoft.com>

* Update flaml/autogen/agent/user_proxy_agent.py

Co-authored-by: Chi Wang <wang.chi@microsoft.com>

* revise to comments

* revise function call design, notebook and test. add doc

* code format

* ad message_to_dict function

* update mathproxyagent

* revise docstr

* update

* Update flaml/autogen/agent/math_user_proxy_agent.py

Co-authored-by: Chi Wang <wang.chi@microsoft.com>

* Update flaml/autogen/agent/math_user_proxy_agent.py

Co-authored-by: Qingyun Wu <qingyun.wu@psu.edu>

* Update flaml/autogen/agent/user_proxy_agent.py

Co-authored-by: Qingyun Wu <qingyun.wu@psu.edu>

* simply funccall in userproxyagent, rewind auto-gen.md, revise to comments

* code format

* update

* remove notebook for another pr

* revise oai_conversation part  in agent, revise function exec in user_proxy_agent

* update test_funccall

* update

* update

* fix pydantic version

* Update test/autogen/test_agent.py

Co-authored-by: Chi Wang <wang.chi@microsoft.com>

* fix bug

* fix bug

* update

* update is_termination_msg to accept dict

---------

Co-authored-by: Chi Wang <wang.chi@microsoft.com>
Co-authored-by: Qingyun Wu <qingyun.wu@psu.edu>
Co-authored-by: Li Jiang <bnujli@gmail.com>
This commit is contained in:
Yiran Wu
2023-07-06 06:08:44 +08:00
committed by GitHub
parent dd9202bb01
commit ca10b286cc
12 changed files with 306 additions and 39 deletions

View File

@@ -0,0 +1,40 @@
def test_agent():
from flaml.autogen.agent import Agent
dummy_agent_1 = Agent(name="dummy_agent_1")
dummy_agent_2 = Agent(name="dummy_agent_2")
dummy_agent_1.receive("hello", dummy_agent_2) # receive a str
dummy_agent_1.receive(
{
"content": "hello",
},
dummy_agent_2,
) # receive a dict
# receive dict without openai fields to be printed, such as "content", 'function_call'. There should be no error raised.
pre_len = len(dummy_agent_1._oai_conversations["dummy_agent_2"])
dummy_agent_1.receive({"message": "hello"}, dummy_agent_2)
assert pre_len == len(
dummy_agent_1._oai_conversations["dummy_agent_2"]
), "When the message is not an valid openai message, it should not be appended to the oai conversation."
dummy_agent_1._send("hello", dummy_agent_2) # send a str
dummy_agent_1._send(
{
"content": "hello",
},
dummy_agent_2,
) # send a dict
# receive dict with no openai fields
pre_len = len(dummy_agent_1._oai_conversations["dummy_agent_2"])
dummy_agent_1._send({"message": "hello"}, dummy_agent_2) # send dict with wrong field
assert pre_len == len(
dummy_agent_1._oai_conversations["dummy_agent_2"]
), "When the message is not a valid openai message, it should not be appended to the oai conversation."
if __name__ == "__main__":
test_agent()

View File

@@ -23,7 +23,7 @@ def test_gpt35(human_input_mode="NEVER", max_consecutive_auto_reply=5):
"user",
work_dir=f"{here}/test_agent_scripts",
human_input_mode=human_input_mode,
is_termination_msg=lambda x: x.rstrip().endswith("TERMINATE"),
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
max_consecutive_auto_reply=max_consecutive_auto_reply,
use_docker="python:3",
)
@@ -51,7 +51,7 @@ def test_create_execute_script(human_input_mode="NEVER", max_consecutive_auto_re
"user",
human_input_mode=human_input_mode,
max_consecutive_auto_reply=max_consecutive_auto_reply,
is_termination_msg=lambda x: x.rstrip().endswith("TERMINATE"),
is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
)
assistant.receive(
"""Create and execute a script to plot a rocket without using matplotlib""",

View File

@@ -60,5 +60,68 @@ def test_eval_math_responses():
print(eval_math_responses(**arguments))
def test_json_extraction():
from flaml.autogen.agent import UserProxyAgent
user = UserProxyAgent(name="test", use_docker=False)
jstr = '{\n"location": "Boston, MA"\n}'
assert user._format_json_str(jstr) == '{"location": "Boston, MA"}'
jstr = '{\n"code": "python",\n"query": "x=3\nprint(x)"}'
assert user._format_json_str(jstr) == '{"code": "python","query": "x=3\\nprint(x)"}'
jstr = '{"code": "a=\\"hello\\""}'
assert user._format_json_str(jstr) == '{"code": "a=\\"hello\\""}'
def test_execute_function():
from flaml.autogen.agent import UserProxyAgent
# 1. test calling a simple function
def add_num(num_to_be_added):
given_num = 10
return num_to_be_added + given_num
user = UserProxyAgent(name="test", function_map={"add_num": add_num})
# correct execution
correct_args = {"name": "add_num", "arguments": '{ "num_to_be_added": 5 }'}
assert user._execute_function(func_call=correct_args)[1]["content"] == "15"
# function name called is wrong or doesn't exist
wrong_func_name = {"name": "subtract_num", "arguments": '{ "num_to_be_added": 5 }'}
assert "Error: Function" in user._execute_function(func_call=wrong_func_name)[1]["content"]
# arguments passed is not in correct json format
wrong_json_format = {
"name": "add_num",
"arguments": '{ "num_to_be_added": 5, given_num: 10 }',
} # should be "given_num" with quotes
assert (
"You argument should follow json format." in user._execute_function(func_call=wrong_json_format)[1]["content"]
)
# function execution error with wrong arguments passed
wrong_args = {"name": "add_num", "arguments": '{ "num_to_be_added": 5, "given_num": 10 }'}
assert "Error: " in user._execute_function(func_call=wrong_args)[1]["content"]
# 2. test calling a class method
class AddNum:
def __init__(self, given_num):
self.given_num = given_num
def add(self, num_to_be_added):
self.given_num = num_to_be_added + self.given_num
return self.given_num
user = UserProxyAgent(name="test", function_map={"add_num": AddNum(given_num=10).add})
func_call = {"name": "add_num", "arguments": '{ "num_to_be_added": 5 }'}
assert user._execute_function(func_call=func_call)[1]["content"] == "15"
assert user._execute_function(func_call=func_call)[1]["content"] == "20"
if __name__ == "__main__":
test_json_extraction()
test_execute_function()
test_eval_math_responses()