mirror of
https://github.com/microsoft/autogen.git
synced 2025-08-03 14:22:34 +00:00

* Move contrib-openai.yml
* Moved groupgroupchat
* From #753
* Removed local test references
* Added ignore=test/agentchat/contrib
* Trying to pass contrib-openai tests
* More specific in unit testing.
* Update .github/workflows/contrib-tests.yml
Co-authored-by: Li Jiang <lijiang1@microsoft.com>
* Remove coverage as it is included in test dependencies
* Improved docstring with overview of GraphGroupChat
* Iterate on feedback
* Precommit pass
* user just use pip install pyautogen[graphs]
* Pass precommit
* Pas precommit
* Graph utils an test completed
* Added inversion tests
* Added inversion util
* allow_repeat_speaker can be a list of Agents
* Remove unnessary imports
* Expect ValueError with 1 and 0 agents
* Check that main passes all tests
* Check main
* Pytest all in main
* All done
* pre-commit changes
* noqa E402
* precommit pass
* Removed bin
* Removed old unit test
* Test test_graph_utils
* minor cleanup
* restore tests
* Correct documentation
* Special case of only one agent remaining.
* Improved pytest
* precommit pass
* Delete OAI_CONFIG_LIST_sample copy
* Returns a filtered list for auto to work
* Rename var speaker_order_dict
* To write test cases
* Added check for a list of Agents to repeat
* precommit pass
* Update documentation
* Extract names in allow_repeat_speaker
* Post review changes
* hange "pull_request_target" into "pull_request" temporarily.
* 3 return values from main
* pre-commit changes
* PC edits
* docstr changes
* PC edits
* Rest of changes from main
* Update autogen/agentchat/groupchat.py
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
* Remove unnecessary script files from tracking
* Non empty scripts files from main
* Revert changes in script files to match main branch
* Removed link from website as notebook is removed.
* test/test_graph_utils.py is tested as part of L52 of build.yml
* GroupChat ValueError check
* docstr update
* More clarification in docstr
* Update autogen/agentchat/groupchat.py
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
* Update autogen/agentchat/groupchat.py
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
* Update autogen/agentchat/groupchat.py
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
* Update autogen/agentchat/groupchat.py
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
* 1.add commit to line138 in groupchat.py;2.fix bug if random choice [];3.return selected_agent if len(graph_eligible_agents) is 1;4.replace all speaker_order to speaker_transitions;5.format
* fix graph_modelling notebook in the last cell
* fix failure in test_groupchat.py
* fix agent out of group to initiate a chat like SocietyOfMind
* add a warning rule in graph_utils to check duplicates in any lists
* refactor allowed_or_disallowed_speaker_transitions to Dict[Agent, List[Agent]] and modify the tests and notebook
* delete Rule 4 in graph_utils and related test case. Add a test to resolve 993fd006e9 (r1460726831)
* fix as the final comments
* modify setup option from graphs to graph and add texts in optional-dependencies.md
* Update autogen/graph_utils.py
---------
Co-authored-by: Li Jiang <lijiang1@microsoft.com>
Co-authored-by: Beibin Li <BeibinLi@users.noreply.github.com>
Co-authored-by: Chi Wang <wang.chi@microsoft.com>
Co-authored-by: Qingyun Wu <qingyun0327@gmail.com>
Co-authored-by: Yishen Sun <freedeaths@FREEDEATHS-XPS>
Co-authored-by: freedeaths <register917@gmail.com>
166 lines
7.2 KiB
Python
166 lines
7.2 KiB
Python
import sys
|
|
import pytest
|
|
import logging
|
|
from autogen.agentchat import Agent
|
|
import autogen.graph_utils as gru
|
|
|
|
|
|
class TestHelpers:
|
|
def test_has_self_loops(self):
|
|
# Setup test data
|
|
agents = [Agent(name=f"Agent{i}") for i in range(3)]
|
|
allowed_speaker_transitions = {
|
|
agents[0]: [agents[1], agents[2]],
|
|
agents[1]: [agents[2]],
|
|
agents[2]: [agents[0]],
|
|
}
|
|
allowed_speaker_transitions_with_self_loops = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[1], agents[2]],
|
|
agents[2]: [agents[0]],
|
|
}
|
|
|
|
# Testing
|
|
assert not gru.has_self_loops(allowed_speaker_transitions)
|
|
assert gru.has_self_loops(allowed_speaker_transitions_with_self_loops)
|
|
|
|
|
|
class TestGraphUtilCheckGraphValidity:
|
|
def test_valid_structure(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
valid_speaker_transitions_dict = {agent: [other_agent for other_agent in agents] for agent in agents}
|
|
gru.check_graph_validity(allowed_speaker_transitions_dict=valid_speaker_transitions_dict, agents=agents)
|
|
|
|
def test_graph_with_invalid_structure(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
unseen_agent = Agent("unseen_agent")
|
|
invalid_speaker_transitions_dict = {unseen_agent: ["stranger"]}
|
|
with pytest.raises(ValueError):
|
|
gru.check_graph_validity(invalid_speaker_transitions_dict, agents)
|
|
|
|
def test_graph_with_invalid_string(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
invalid_speaker_transitions_dict = {
|
|
agent: ["agent1"] for agent in agents
|
|
} # 'agent1' is a string, not an Agent. Therefore raises an error.
|
|
with pytest.raises(ValueError):
|
|
gru.check_graph_validity(invalid_speaker_transitions_dict, agents)
|
|
|
|
def test_graph_with_unauthorized_self_loops(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
# Creating a subset of agents allowed to have self-loops
|
|
allowed_repeat_speakers = agents[: len(agents) // 2]
|
|
|
|
# Constructing a speaker transitions dictionary with self-loops for all agents
|
|
# Ensuring at least one agent outside the allowed_repeat_speakers has a self-loop
|
|
speaker_transitions_dict_with_self_loop = {agent: agent for agent in agents}
|
|
|
|
# Testing the function with the constructed speaker transitions dict
|
|
with pytest.raises(ValueError):
|
|
gru.check_graph_validity(
|
|
speaker_transitions_dict_with_self_loop, agents, allow_repeat_speaker=allowed_repeat_speakers
|
|
)
|
|
|
|
# Test for Warning 1: Isolated agent nodes
|
|
def test_isolated_agent_nodes_warning(self, caplog):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
# Create a speaker_transitions_dict where at least one agent is isolated
|
|
speaker_transitions_dict_with_isolation = {agents[0]: [agents[0], agents[1]], agents[1]: [agents[0]]}
|
|
# Add an isolated agent
|
|
speaker_transitions_dict_with_isolation[agents[2]] = []
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
gru.check_graph_validity(
|
|
allowed_speaker_transitions_dict=speaker_transitions_dict_with_isolation, agents=agents
|
|
)
|
|
assert "isolated" in caplog.text
|
|
|
|
# Test for Warning 2: Warning if the set of agents in allowed_speaker_transitions do not match agents
|
|
def test_warning_for_mismatch_in_agents(self, caplog):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
|
|
# Test with missing agents in allowed_speaker_transitions_dict
|
|
|
|
unknown_agent_dict = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[0], agents[1], agents[2]],
|
|
agents[2]: [agents[0], agents[1], agents[2], Agent("unknown_agent")],
|
|
}
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
gru.check_graph_validity(allowed_speaker_transitions_dict=unknown_agent_dict, agents=agents)
|
|
|
|
assert "allowed_speaker_transitions do not match agents" in caplog.text
|
|
|
|
# Test for Warning 3: Warning if there is duplicated agents in allowed_speaker_transitions_dict
|
|
def test_warning_for_duplicate_agents(self, caplog):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
|
|
# Construct an `allowed_speaker_transitions_dict` with duplicated agents
|
|
duplicate_agents_dict = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[0], agents[1], agents[2], agents[1]],
|
|
agents[2]: [agents[0], agents[1], agents[2], agents[0], agents[2]],
|
|
}
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
gru.check_graph_validity(allowed_speaker_transitions_dict=duplicate_agents_dict, agents=agents)
|
|
|
|
assert "duplicate" in caplog.text
|
|
|
|
|
|
class TestGraphUtilInvertDisallowedToAllowed:
|
|
def test_basic_functionality(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
disallowed_graph = {agents[0]: [agents[1]], agents[1]: [agents[0], agents[2]], agents[2]: []}
|
|
expected_allowed_graph = {
|
|
agents[0]: [agents[0], agents[2]],
|
|
agents[1]: [agents[1]],
|
|
agents[2]: [agents[0], agents[1], agents[2]],
|
|
}
|
|
|
|
# Compare names of agents
|
|
inverted = gru.invert_disallowed_to_allowed(disallowed_graph, agents)
|
|
assert inverted == expected_allowed_graph
|
|
|
|
def test_empty_disallowed_graph(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
disallowed_graph = {}
|
|
expected_allowed_graph = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[0], agents[1], agents[2]],
|
|
agents[2]: [agents[0], agents[1], agents[2]],
|
|
}
|
|
|
|
# Compare names of agents
|
|
inverted = gru.invert_disallowed_to_allowed(disallowed_graph, agents)
|
|
assert inverted == expected_allowed_graph
|
|
|
|
def test_fully_disallowed_graph(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
|
|
disallowed_graph = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[0], agents[1], agents[2]],
|
|
agents[2]: [agents[0], agents[1], agents[2]],
|
|
}
|
|
expected_allowed_graph = {agents[0]: [], agents[1]: [], agents[2]: []}
|
|
|
|
# Compare names of agents
|
|
inverted = gru.invert_disallowed_to_allowed(disallowed_graph, agents)
|
|
assert inverted == expected_allowed_graph
|
|
|
|
def test_disallowed_graph_with_nonexistent_agent(self):
|
|
agents = [Agent("agent1"), Agent("agent2"), Agent("agent3")]
|
|
|
|
disallowed_graph = {agents[0]: [Agent("nonexistent_agent")]}
|
|
# In this case, the function should ignore the nonexistent agent and proceed with the inversion
|
|
expected_allowed_graph = {
|
|
agents[0]: [agents[0], agents[1], agents[2]],
|
|
agents[1]: [agents[0], agents[1], agents[2]],
|
|
agents[2]: [agents[0], agents[1], agents[2]],
|
|
}
|
|
# Compare names of agents
|
|
inverted = gru.invert_disallowed_to_allowed(disallowed_graph, agents)
|
|
assert inverted == expected_allowed_graph
|