mirror of
https://github.com/microsoft/autogen.git
synced 2025-11-02 18:59:48 +00:00
Groupchat send introductions (#961)
* Allow the GroupChatManager to send introductions. * Fixed function name. * Added test cases for sending introductions. * Trying to sort out why remote pytest is failing. * Fixed broken plugin behavior. * Update autogen/agentchat/groupchat.py Co-authored-by: Chi Wang <wang.chi@microsoft.com> * Updated as per Chi's suggestions. --------- Co-authored-by: Chi Wang <wang.chi@microsoft.com> Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
This commit is contained in:
parent
fb2b412c4a
commit
477598afff
@ -58,7 +58,8 @@ class GroupChat:
|
|||||||
Must be supplied if `allowed_or_disallowed_speaker_transitions` is not None.
|
Must be supplied if `allowed_or_disallowed_speaker_transitions` is not None.
|
||||||
- enable_clear_history: enable possibility to clear history of messages for agents manually by providing
|
- enable_clear_history: enable possibility to clear history of messages for agents manually by providing
|
||||||
"clear history" phrase in user prompt. This is experimental feature.
|
"clear history" phrase in user prompt. This is experimental feature.
|
||||||
See description of `GroupChatManager.clear_agents_history` function for more info.
|
See description of GroupChatManager.clear_agents_history function for more info.
|
||||||
|
- send_introductions: send a round of introductions at the start of the group chat, so agents know who they can speak to (default: False)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
agents: List[Agent]
|
agents: List[Agent]
|
||||||
@ -71,6 +72,7 @@ class GroupChat:
|
|||||||
allowed_or_disallowed_speaker_transitions: Optional[Dict] = None
|
allowed_or_disallowed_speaker_transitions: Optional[Dict] = None
|
||||||
speaker_transitions_type: Optional[str] = None
|
speaker_transitions_type: Optional[str] = None
|
||||||
enable_clear_history: Optional[bool] = False
|
enable_clear_history: Optional[bool] = False
|
||||||
|
send_introductions: Optional[bool] = False
|
||||||
|
|
||||||
_VALID_SPEAKER_SELECTION_METHODS = ["auto", "manual", "random", "round_robin"]
|
_VALID_SPEAKER_SELECTION_METHODS = ["auto", "manual", "random", "round_robin"]
|
||||||
_VALID_SPEAKER_TRANSITIONS_TYPE = ["allowed", "disallowed", None]
|
_VALID_SPEAKER_TRANSITIONS_TYPE = ["allowed", "disallowed", None]
|
||||||
@ -229,6 +231,16 @@ Then select the next role from {[agent.name for agent in agents]} to play. Only
|
|||||||
agents = self.agents
|
agents = self.agents
|
||||||
return f"Read the above conversation. Then select the next role from {[agent.name for agent in agents]} to play. Only return the role."
|
return f"Read the above conversation. Then select the next role from {[agent.name for agent in agents]} to play. Only return the role."
|
||||||
|
|
||||||
|
def introductions_msg(self, agents: Optional[List[Agent]] = None) -> str:
|
||||||
|
"""Return the system message for selecting the next speaker. This is always the *first* message in the context."""
|
||||||
|
if agents is None:
|
||||||
|
agents = self.agents
|
||||||
|
|
||||||
|
return f"""Hello everyone. We have assembled a great team today to answer questions and solve tasks. In attendance are:
|
||||||
|
|
||||||
|
{self._participant_roles(agents)}
|
||||||
|
"""
|
||||||
|
|
||||||
def manual_select_speaker(self, agents: Optional[List[Agent]] = None) -> Union[Agent, None]:
|
def manual_select_speaker(self, agents: Optional[List[Agent]] = None) -> Union[Agent, None]:
|
||||||
"""Manually select the next speaker."""
|
"""Manually select the next speaker."""
|
||||||
if agents is None:
|
if agents is None:
|
||||||
@ -535,6 +547,16 @@ class GroupChatManager(ConversableAgent):
|
|||||||
message = messages[-1]
|
message = messages[-1]
|
||||||
speaker = sender
|
speaker = sender
|
||||||
groupchat = config
|
groupchat = config
|
||||||
|
send_introductions = getattr(groupchat, "send_introductions", False)
|
||||||
|
|
||||||
|
if send_introductions:
|
||||||
|
# Broadcast the intro
|
||||||
|
intro = groupchat.introductions_msg()
|
||||||
|
for agent in groupchat.agents:
|
||||||
|
self.send(intro, agent, request_reply=False, silent=True)
|
||||||
|
# NOTE: We do not also append to groupchat.messages,
|
||||||
|
# since groupchat handles its own introductions
|
||||||
|
|
||||||
if self.client_cache is not None:
|
if self.client_cache is not None:
|
||||||
for a in groupchat.agents:
|
for a in groupchat.agents:
|
||||||
a.previous_cache = a.client_cache
|
a.previous_cache = a.client_cache
|
||||||
@ -598,6 +620,16 @@ class GroupChatManager(ConversableAgent):
|
|||||||
message = messages[-1]
|
message = messages[-1]
|
||||||
speaker = sender
|
speaker = sender
|
||||||
groupchat = config
|
groupchat = config
|
||||||
|
send_introductions = getattr(groupchat, "send_introductions", False)
|
||||||
|
|
||||||
|
if send_introductions:
|
||||||
|
# Broadcast the intro
|
||||||
|
intro = groupchat.introductions_msg()
|
||||||
|
for agent in groupchat.agents:
|
||||||
|
self.a_send(intro, agent, request_reply=False, silent=True)
|
||||||
|
# NOTE: We do not also append to groupchat.messages,
|
||||||
|
# since groupchat handles its own introductions
|
||||||
|
|
||||||
if self.client_cache is not None:
|
if self.client_cache is not None:
|
||||||
for a in groupchat.agents:
|
for a in groupchat.agents:
|
||||||
a.previous_cache = a.client_cache
|
a.previous_cache = a.client_cache
|
||||||
|
|||||||
@ -448,6 +448,110 @@ def test_next_agent():
|
|||||||
assert groupchat.next_agent(agent4, [agent1, agent2, agent3]) == agent1
|
assert groupchat.next_agent(agent4, [agent1, agent2, agent3]) == agent1
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_intros():
|
||||||
|
agent1 = autogen.ConversableAgent(
|
||||||
|
"alice",
|
||||||
|
description="The first agent.",
|
||||||
|
max_consecutive_auto_reply=10,
|
||||||
|
human_input_mode="NEVER",
|
||||||
|
llm_config=False,
|
||||||
|
default_auto_reply="This is alice speaking. TERMINATE",
|
||||||
|
)
|
||||||
|
agent2 = autogen.ConversableAgent(
|
||||||
|
"bob",
|
||||||
|
description="The second agent.",
|
||||||
|
max_consecutive_auto_reply=10,
|
||||||
|
human_input_mode="NEVER",
|
||||||
|
llm_config=False,
|
||||||
|
default_auto_reply="This is bob speaking. TERMINATE",
|
||||||
|
)
|
||||||
|
agent3 = autogen.ConversableAgent(
|
||||||
|
"sam",
|
||||||
|
description="The third agent.",
|
||||||
|
max_consecutive_auto_reply=10,
|
||||||
|
human_input_mode="NEVER",
|
||||||
|
llm_config=False,
|
||||||
|
default_auto_reply="This is sam speaking. TERMINATE",
|
||||||
|
)
|
||||||
|
agent4 = autogen.ConversableAgent(
|
||||||
|
"sally",
|
||||||
|
description="The fourth agent.",
|
||||||
|
max_consecutive_auto_reply=10,
|
||||||
|
human_input_mode="NEVER",
|
||||||
|
llm_config=False,
|
||||||
|
default_auto_reply="This is sally speaking. TERMINATE",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test empty is_termination_msg function
|
||||||
|
groupchat = autogen.GroupChat(
|
||||||
|
agents=[agent1, agent2, agent3],
|
||||||
|
messages=[],
|
||||||
|
speaker_selection_method="round_robin",
|
||||||
|
max_round=10,
|
||||||
|
send_introductions=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
intro = groupchat.introductions_msg()
|
||||||
|
assert "The first agent." in intro
|
||||||
|
assert "The second agent." in intro
|
||||||
|
assert "The third agent." in intro
|
||||||
|
assert "The fourth agent." not in intro
|
||||||
|
|
||||||
|
intro = groupchat.introductions_msg([agent1, agent2, agent4])
|
||||||
|
assert "The first agent." in intro
|
||||||
|
assert "The second agent." in intro
|
||||||
|
assert "The third agent." not in intro
|
||||||
|
assert "The fourth agent." in intro
|
||||||
|
|
||||||
|
groupchat = autogen.GroupChat(
|
||||||
|
agents=[agent1, agent2, agent3],
|
||||||
|
messages=[],
|
||||||
|
speaker_selection_method="round_robin",
|
||||||
|
max_round=10,
|
||||||
|
send_introductions=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
group_chat_manager = autogen.GroupChatManager(
|
||||||
|
groupchat=groupchat,
|
||||||
|
llm_config=False,
|
||||||
|
is_termination_msg=lambda x: x.get("content", "").rstrip().find("TERMINATE") >= 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
group_chat_manager.initiate_chat(group_chat_manager, message="The initiating message.")
|
||||||
|
for a in [agent1, agent2, agent3]:
|
||||||
|
messages = agent1.chat_messages[group_chat_manager]
|
||||||
|
assert len(messages) == 3
|
||||||
|
assert "The first agent." in messages[0]["content"]
|
||||||
|
assert "The second agent." in messages[0]["content"]
|
||||||
|
assert "The third agent." in messages[0]["content"]
|
||||||
|
assert "The initiating message." == messages[1]["content"]
|
||||||
|
assert messages[2]["content"] == agent1._default_auto_reply
|
||||||
|
|
||||||
|
# Reset and start again
|
||||||
|
agent1.reset()
|
||||||
|
agent2.reset()
|
||||||
|
agent3.reset()
|
||||||
|
agent4.reset()
|
||||||
|
|
||||||
|
# Check the default (no introductions)
|
||||||
|
groupchat2 = autogen.GroupChat(
|
||||||
|
agents=[agent1, agent2, agent3], messages=[], speaker_selection_method="round_robin", max_round=10
|
||||||
|
)
|
||||||
|
|
||||||
|
group_chat_manager2 = autogen.GroupChatManager(
|
||||||
|
groupchat=groupchat2,
|
||||||
|
llm_config=False,
|
||||||
|
is_termination_msg=lambda x: x.get("content", "").rstrip().find("TERMINATE") >= 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
group_chat_manager2.initiate_chat(group_chat_manager2, message="The initiating message.")
|
||||||
|
for a in [agent1, agent2, agent3]:
|
||||||
|
messages = agent1.chat_messages[group_chat_manager2]
|
||||||
|
assert len(messages) == 2
|
||||||
|
assert "The initiating message." == messages[0]["content"]
|
||||||
|
assert messages[1]["content"] == agent1._default_auto_reply
|
||||||
|
|
||||||
|
|
||||||
def test_selection_helpers():
|
def test_selection_helpers():
|
||||||
agent1 = autogen.ConversableAgent(
|
agent1 = autogen.ConversableAgent(
|
||||||
"alice",
|
"alice",
|
||||||
@ -814,6 +918,7 @@ if __name__ == "__main__":
|
|||||||
# test_agent_mentions()
|
# test_agent_mentions()
|
||||||
# test_termination()
|
# test_termination()
|
||||||
# test_next_agent()
|
# test_next_agent()
|
||||||
|
test_send_intros()
|
||||||
# test_invalid_allow_repeat_speaker()
|
# test_invalid_allow_repeat_speaker()
|
||||||
# test_graceful_exit_before_max_round()
|
# test_graceful_exit_before_max_round()
|
||||||
test_clear_agents_history()
|
# test_clear_agents_history()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user