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

Re-commit of #2222: Expanded speaker name matching during speaker selection #2267

Merged
merged 1 commit into from
Apr 3, 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: 14 additions & 2 deletions autogen/agentchat/groupchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,10 @@ def _participant_roles(self, agents: List[Agent] = None) -> str:

def _mentioned_agents(self, message_content: Union[str, List], agents: Optional[List[Agent]]) -> Dict:
"""Counts the number of times each agent is mentioned in the provided message content.
Agent names will match under any of the following conditions (all case-sensitive):
- Exact name match
- If the agent name has underscores it will match with spaces instead (e.g. 'Story_writer' == 'Story writer')
- If the agent name has underscores it will match with '\\_' instead of '_' (e.g. 'Story_writer' == 'Story\\_writer')

Args:
message_content (Union[str, List]): The content of the message, either as a single string or a list of strings.
Expand All @@ -530,9 +534,17 @@ def _mentioned_agents(self, message_content: Union[str, List], agents: Optional[

mentions = dict()
for agent in agents:
# Finds agent mentions, taking word boundaries into account,
# accommodates escaping underscores and underscores as spaces
regex = (
r"(?<=\W)" + re.escape(agent.name) + r"(?=\W)"
) # Finds agent mentions, taking word boundaries into account
r"(?<=\W)("
+ re.escape(agent.name)
+ r"|"
+ re.escape(agent.name.replace("_", " "))
+ r"|"
+ re.escape(agent.name.replace("_", r"\_"))
+ r")(?=\W)"
)
count = len(re.findall(regex, f" {message_content} ")) # Pad the message to help with matching
if count > 0:
mentions[agent.name] = count
Expand Down
97 changes: 96 additions & 1 deletion test/agentchat/test_groupchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,100 @@ def test_select_speaker_message_and_prompt_templates():
)


def test_speaker_selection_agent_name_match():
"""
In this test a group chat, with auto speaker selection, the speaker name match
function is tested against the extended name match regex.
"""

user_proxy = autogen.UserProxyAgent(
name="User_proxy",
system_message="A human admin.",
code_execution_config=False,
human_input_mode="NEVER",
)
storywriter = autogen.AssistantAgent(
name="Story_writer",
system_message="An ideas person.",
llm_config=None,
)
pm = autogen.AssistantAgent(
name="Product_manager",
system_message="Great in evaluating story ideas.",
llm_config=None,
)

all_agents = [user_proxy, storywriter, pm]
groupchat = autogen.GroupChat(agents=all_agents, messages=[], max_round=8, speaker_selection_method="auto")

# Test exact match (unchanged outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="Story_writer")
assert result == {"Story_writer": 1}

# Test match with extra text (unchanged outcome)
result = groupchat._mentioned_agents(
agents=all_agents,
message_content="' Story_writer.\n\nHere are three story ideas for Grade 3 kids:\n\n1. **The Adventure of the Magic Garden:** A you...",
)
assert result == {"Story_writer": 1}

# Test match with escaped underscore (new outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="Story\\_writer")
assert result == {"Story_writer": 1}

# Test match with space (new outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="Story writer")
assert result == {"Story_writer": 1}

# Test match with different casing (unchanged outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="Story_Writer")
assert result == {}

# Test match with invalid name (unchanged outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="NoName_Person")
assert result == {}

# Test match with no name (unchanged outcome)
result = groupchat._mentioned_agents(agents=all_agents, message_content="")
assert result == {}

# Test match with multiple agents and exact matches (unchanged outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story_writer will follow the Product_manager."
)
assert result == {"Story_writer": 1, "Product_manager": 1}

# Test match with multiple agents and escaped underscores (new outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story\\_writer will follow the Product\\_manager."
)
assert result == {"Story_writer": 1, "Product_manager": 1}

# Test match with multiple agents and escaped underscores (new outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story\\_writer will follow the Product\\_manager."
)
assert result == {"Story_writer": 1, "Product_manager": 1}

# Test match with multiple agents and spaces (new outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story writer will follow the Product manager."
)
assert result == {"Story_writer": 1, "Product_manager": 1}

# Test match with multiple agents and escaped underscores and spaces mixed (new outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story writer will follow the Product\\_manager."
)
assert result == {"Story_writer": 1, "Product_manager": 1}

# Test match with multiple agents and incorrect casing (unchanged outcome)
result = groupchat._mentioned_agents(
agents=all_agents, message_content="Story Writer will follow the product\\_manager."
)
assert result == {}


if __name__ == "__main__":
# test_func_call_groupchat()
# test_broadcast()
Expand All @@ -1348,5 +1442,6 @@ def test_select_speaker_message_and_prompt_templates():
# test_clear_agents_history()
# test_custom_speaker_selection_overrides_transition_graph()
# test_role_for_select_speaker_messages()
test_select_speaker_message_and_prompt_templates()
# test_select_speaker_message_and_prompt_templates()
test_speaker_selection_agent_name_match()
# pass
Loading