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

Allow Function Execution return a non-string object #25

Merged
merged 10 commits into from
Nov 20, 2024
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
16 changes: 10 additions & 6 deletions autogen/agentchat/conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@ def _append_oai_message(self, message: Union[Dict, str], role, conversation_id:

if message.get("role") in ["function", "tool"]:
oai_message["role"] = message.get("role")
if "tool_responses" in oai_message:
for tool_response in oai_message["tool_responses"]:
tool_response["content"] = str(tool_response["content"])
elif "override_role" in message:
# If we have a direction to override the role then set the
# role accordingly. Used to customise the role for the
Expand Down Expand Up @@ -791,15 +794,16 @@ async def a_send(
"Message can't be converted into a valid ChatCompletion message. Either content or function_call must be provided."
)

def _print_received_message(self, message: Union[Dict, str], sender: Agent):
def _print_received_message(self, message: Union[Dict, str], sender: Agent, skip_head: bool = False):
iostream = IOStream.get_default()
# print the message received
iostream.print(colored(sender.name, "yellow"), "(to", f"{self.name}):\n", flush=True)
if not skip_head:
iostream.print(colored(sender.name, "yellow"), "(to", f"{self.name}):\n", flush=True)
message = self._message_to_dict(message)

if message.get("tool_responses"): # Handle tool multi-call responses
for tool_response in message["tool_responses"]:
self._print_received_message(tool_response, sender)
self._print_received_message(tool_response, sender, skip_head=True)
if message.get("role") == "tool":
return # If role is tool, then content is just a concatenation of all tool_responses

Expand Down Expand Up @@ -2288,7 +2292,7 @@ def _format_json_str(jstr):
result.append(char)
return "".join(result)

def execute_function(self, func_call, verbose: bool = False) -> Tuple[bool, Dict[str, str]]:
def execute_function(self, func_call, verbose: bool = False) -> Tuple[bool, Dict[str, Any]]:
"""Execute a function call and return the result.

Override this function to modify the way to execute function and tool calls.
Expand Down Expand Up @@ -2342,7 +2346,7 @@ def execute_function(self, func_call, verbose: bool = False) -> Tuple[bool, Dict
return is_exec_success, {
"name": func_name,
"role": "function",
"content": str(content),
"content": content,
}

async def a_execute_function(self, func_call):
Expand Down Expand Up @@ -2397,7 +2401,7 @@ async def a_execute_function(self, func_call):
return is_exec_success, {
"name": func_name,
"role": "function",
"content": str(content),
"content": content,
}

def generate_init_message(self, message: Union[Dict, str, None], **kwargs) -> Union[str, Dict]:
Expand Down
2 changes: 2 additions & 0 deletions autogen/agentchat/groupchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ def append(self, message: Dict, speaker: Agent):
# if the role is tool, it is OK to modify the name
if message["role"] != "function":
message["name"] = speaker.name
if not isinstance(message["content"], str) and not isinstance(message["content"], list):
message["content"] = str(message["content"])
message["content"] = content_str(message["content"])
self.messages.append(message)

Expand Down
8 changes: 4 additions & 4 deletions test/agentchat/test_conversable_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,14 +464,14 @@ def add_num(num_to_be_added):

# when sender is None, messages is provided
assert (
dummy_agent_2.generate_reply(messages=messages, sender=None)["content"] == "15"
dummy_agent_2.generate_reply(messages=messages, sender=None)["content"] == 15
), "generate_reply not working when sender is None"

# when sender is provided, messages is None
dummy_agent_1 = ConversableAgent(name="dummy_agent_1", llm_config=False, human_input_mode="ALWAYS")
dummy_agent_2._oai_messages[dummy_agent_1] = messages
assert (
dummy_agent_2.generate_reply(messages=None, sender=dummy_agent_1)["content"] == "15"
dummy_agent_2.generate_reply(messages=None, sender=dummy_agent_1)["content"] == 15
), "generate_reply not working when messages is None"

dummy_agent_2.register_reply(["str", None], ConversableAgent.generate_oai_reply)
Expand Down Expand Up @@ -1115,7 +1115,7 @@ class Function:

def get_random_number(self):
self.call_count += 1
return random.randint(0, 100)
return str(random.randint(0, 100))

config_list = autogen.config_list_from_json(
OAI_CONFIG_LIST,
Expand Down Expand Up @@ -1171,7 +1171,7 @@ class Function:

def get_random_number(self):
self.call_count += 1
return random.randint(0, 100)
return str(random.randint(0, 100))

config_list = autogen.config_list_from_json(
OAI_CONFIG_LIST, file_location=KEY_LOC, filter_dict={"tags": ["gpt-3.5-turbo"]}
Expand Down
12 changes: 6 additions & 6 deletions test/agentchat/test_function_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def test_execute_function():
# 1. test calling a simple function
def add_num(num_to_be_added):
given_num = 10
return num_to_be_added + given_num
return str(num_to_be_added + given_num)

user = UserProxyAgent(name="test", function_map={"add_num": add_num})

Expand Down Expand Up @@ -140,7 +140,7 @@ def __init__(self, given_num):

def add(self, num_to_be_added):
self.given_num = num_to_be_added + self.given_num
return self.given_num
return str(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 }'}
Expand All @@ -149,7 +149,7 @@ def add(self, num_to_be_added):

# 3. test calling a function with no arguments
def get_number():
return 42
return str(42)

user = UserProxyAgent("user", function_map={"get_number": get_number})
func_call = {"name": "get_number", "arguments": "{}"}
Expand Down Expand Up @@ -179,7 +179,7 @@ async def test_a_execute_function():
async def add_num(num_to_be_added):
given_num = 10
time.sleep(1)
return num_to_be_added + given_num
return str(num_to_be_added + given_num)

user = UserProxyAgent(name="test", function_map={"add_num": add_num})
correct_args = {"name": "add_num", "arguments": '{ "num_to_be_added": 5 }'}
Expand Down Expand Up @@ -214,7 +214,7 @@ def __init__(self, given_num):

def add(self, num_to_be_added):
self.given_num = num_to_be_added + self.given_num
return self.given_num
return str(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 }'}
Expand All @@ -223,7 +223,7 @@ def add(self, num_to_be_added):

# 3. test calling a function with no arguments
def get_number():
return 42
return str(42)

user = UserProxyAgent("user", function_map={"get_number": get_number})
func_call = {"name": "get_number", "arguments": "{}"}
Expand Down
Loading