run sync and async in async (#1242)

* run sync and async in async

* test for async multitool call

* uncomment notebook

---------

Co-authored-by: Chi Wang <wang.chi@microsoft.com>
Co-authored-by: Davor Runje <davor@airt.ai>
This commit is contained in:
Brian Finney 2024-01-14 18:34:27 -08:00 committed by GitHub
parent 156579565d
commit 63a35e79f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 190 additions and 24 deletions

View File

@ -950,9 +950,7 @@ class ConversableAgent(Agent):
message = messages[-1] message = messages[-1]
async_tool_calls = [] async_tool_calls = []
for tool_call in message.get("tool_calls", []): for tool_call in message.get("tool_calls", []):
func = self._function_map.get(tool_call.get("function", {}).get("name", None), None) async_tool_calls.append(self._a_execute_tool_call(tool_call))
if func and asyncio.coroutines.iscoroutinefunction(func):
async_tool_calls.append(self._a_execute_tool_call(tool_call))
if async_tool_calls: if async_tool_calls:
tool_returns = await asyncio.gather(*async_tool_calls) tool_returns = await asyncio.gather(*async_tool_calls)
return True, { return True, {

View File

@ -61,7 +61,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 2, "execution_count": 5,
"id": "dca301a4", "id": "dca301a4",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@ -119,7 +119,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 6,
"id": "9fb85afb", "id": "9fb85afb",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -134,14 +134,22 @@
"--------------------------------------------------------------------------------\n", "--------------------------------------------------------------------------------\n",
"\u001b[33mchatbot\u001b[0m (to user_proxy):\n", "\u001b[33mchatbot\u001b[0m (to user_proxy):\n",
"\n", "\n",
"\u001b[32m***** Suggested tool Call (call_thUjscBN349eGd6xh3XrVT18): timer *****\u001b[0m\n", "\u001b[32m***** Suggested tool Call (call_mZqUtVEf6hwarnCqdiKtVhAE): timer *****\u001b[0m\n",
"Arguments: \n", "Arguments: \n",
"{\"num_seconds\":\"5\"}\n", "{\n",
" \"num_seconds\": \"5\"\n",
"}\n",
"\u001b[32m**********************************************************************\u001b[0m\n", "\u001b[32m**********************************************************************\u001b[0m\n",
"\n", "\n",
"--------------------------------------------------------------------------------\n", "--------------------------------------------------------------------------------\n",
"\u001b[35m\n", "\u001b[35m\n",
">>>>>>>> EXECUTING ASYNC FUNCTION timer...\u001b[0m\n", ">>>>>>>> EXECUTING ASYNC FUNCTION timer...\u001b[0m\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[33muser_proxy\u001b[0m (to chatbot):\n", "\u001b[33muser_proxy\u001b[0m (to chatbot):\n",
"\n", "\n",
"\u001b[33muser_proxy\u001b[0m (to chatbot):\n", "\u001b[33muser_proxy\u001b[0m (to chatbot):\n",
@ -153,14 +161,16 @@
"--------------------------------------------------------------------------------\n", "--------------------------------------------------------------------------------\n",
"\u001b[33mchatbot\u001b[0m (to user_proxy):\n", "\u001b[33mchatbot\u001b[0m (to user_proxy):\n",
"\n", "\n",
"\u001b[32m***** Suggested tool Call (call_ubo7cKE3TKumGHkqGjQtZisy): stopwatch *****\u001b[0m\n", "\u001b[32m***** Suggested tool Call (call_xHz73PpH4ipdv7kTxK2AiVCf): stopwatch *****\u001b[0m\n",
"Arguments: \n", "Arguments: \n",
"{\"num_seconds\":\"5\"}\n", "{\n",
" \"num_seconds\": \"5\"\n",
"}\n",
"\u001b[32m**************************************************************************\u001b[0m\n", "\u001b[32m**************************************************************************\u001b[0m\n",
"\n", "\n",
"--------------------------------------------------------------------------------\n", "--------------------------------------------------------------------------------\n",
"\u001b[35m\n", "\u001b[35m\n",
">>>>>>>> EXECUTING FUNCTION stopwatch...\u001b[0m\n", ">>>>>>>> EXECUTING ASYNC FUNCTION stopwatch...\u001b[0m\n",
"\u001b[33muser_proxy\u001b[0m (to chatbot):\n", "\u001b[33muser_proxy\u001b[0m (to chatbot):\n",
"\n", "\n",
"\u001b[33muser_proxy\u001b[0m (to chatbot):\n", "\u001b[33muser_proxy\u001b[0m (to chatbot):\n",
@ -172,8 +182,6 @@
"--------------------------------------------------------------------------------\n", "--------------------------------------------------------------------------------\n",
"\u001b[33mchatbot\u001b[0m (to user_proxy):\n", "\u001b[33mchatbot\u001b[0m (to user_proxy):\n",
"\n", "\n",
"Both the timer and the stopwatch for 5 seconds have been completed. \n",
"\n",
"TERMINATE\n", "TERMINATE\n",
"\n", "\n",
"--------------------------------------------------------------------------------\n" "--------------------------------------------------------------------------------\n"
@ -245,7 +253,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 7,
"id": "2472f95c", "id": "2472f95c",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@ -280,20 +288,77 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 8,
"id": "e2c9267a", "id": "e2c9267a",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\n",
"1) Create a timer for 5 seconds.\n",
"2) a stopwatch for 5 seconds.\n",
"3) Pretty print the result as md.\n",
"4) when 1-3 are done, terminate the group chat\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[33mchatbot\u001b[0m (to chat_manager):\n",
"\n",
"\u001b[32m***** Suggested tool Call (call_rdYofiAgFpRfaZaCT4tzAhOb): timer *****\u001b[0m\n",
"Arguments: \n",
"{\n",
" \"num_seconds\": \"5\"\n",
"}\n",
"\u001b[32m**********************************************************************\u001b[0m\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[35m\n",
">>>>>>>> EXECUTING ASYNC FUNCTION timer...\u001b[0m\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\u001b[32m***** Response from calling tool \"timer\" *****\u001b[0m\n",
"Timer is done!\n",
"\u001b[32m**********************************************\u001b[0m\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\n",
"\n",
"--------------------------------------------------------------------------------\n",
"\u001b[33muser_proxy\u001b[0m (to chat_manager):\n",
"\n",
"\n",
"\n",
"--------------------------------------------------------------------------------\n"
]
}
],
"source": [ "source": [
"# todo: remove comment after fixing https://github.com/microsoft/autogen/issues/1205\n", "# todo: remove comment after fixing https://github.com/microsoft/autogen/issues/1205\n",
"# await user_proxy.a_initiate_chat( # noqa: F704\n", "await user_proxy.a_initiate_chat( # noqa: F704\n",
"# manager,\n", " manager,\n",
"# message=\"\"\"\n", " message=\"\"\"\n",
"# 1) Create a timer for 5 seconds.\n", "1) Create a timer for 5 seconds.\n",
"# 2) a stopwatch for 5 seconds.\n", "2) a stopwatch for 5 seconds.\n",
"# 3) Pretty print the result as md.\n", "3) Pretty print the result as md.\n",
"# 4) when 1-3 are done, terminate the group chat\"\"\",\n", "4) when 1-3 are done, terminate the group chat\"\"\",\n",
"# )" ")"
] ]
}, },
{ {

View File

@ -278,6 +278,109 @@ def test_multi_tool_call():
] ]
@pytest.mark.skipif(not TOOL_ENABLED, reason="openai>=1.1.0 not installed")
@pytest.mark.asyncio
async def test_async_multi_tool_call():
class FakeAgent(autogen.Agent):
def __init__(self, name):
super().__init__(name)
self.received = []
async def a_receive(
self,
message,
sender,
request_reply=None,
silent=False,
):
message = message if isinstance(message, list) else [message]
self.received.extend(message)
return ""
user_proxy = autogen.UserProxyAgent(
name="user_proxy",
human_input_mode="NEVER",
is_termination_msg=lambda x: True if "TERMINATE" in x.get("content") else False,
)
def echo(str):
return str
async def a_echo(str):
return str
user_proxy.register_function({"a_echo": a_echo, "echo": echo})
fake_agent = FakeAgent("fake_agent")
await user_proxy.a_receive(
message={
"content": "test multi tool call",
"tool_calls": [
{
"id": "tool_1",
"type": "function",
"function": {"name": "a_echo", "arguments": json.JSONEncoder().encode({"str": "hello world"})},
},
{
"id": "tool_2",
"type": "function",
"function": {
"name": "echo",
"arguments": json.JSONEncoder().encode({"str": "goodbye and thanks for all the fish"}),
},
},
{
"id": "tool_3",
"type": "function",
"function": {
"name": "multi_tool_call_echo", # normalized "multi_tool_call.echo"
"arguments": json.JSONEncoder().encode({"str": "goodbye and thanks for all the fish"}),
},
},
],
},
sender=fake_agent,
request_reply=True,
)
assert fake_agent.received == [
{
"role": "tool",
"tool_responses": [
{"tool_call_id": "tool_1", "role": "tool", "name": "a_echo", "content": "hello world"},
{
"tool_call_id": "tool_2",
"role": "tool",
"name": "echo",
"content": "goodbye and thanks for all the fish",
},
{
"tool_call_id": "tool_3",
"role": "tool",
"name": "multi_tool_call_echo",
"content": "Error: Function multi_tool_call_echo not found.",
},
],
"content": inspect.cleandoc(
"""
Tool call: a_echo
Id: tool_1
hello world
Tool call: echo
Id: tool_2
goodbye and thanks for all the fish
Tool call: multi_tool_call_echo
Id: tool_3
Error: Function multi_tool_call_echo not found.
"""
),
}
]
if __name__ == "__main__": if __name__ == "__main__":
# test_update_tool() # test_update_tool()
# test_eval_math_responses() # test_eval_math_responses()