Skip to content

Commit cd15c08

Browse files
authored
fix: fix self-loop in workflow (#6677)
1 parent 8c1236d commit cd15c08

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_graph/_digraph_group_chat.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def get_parents(self) -> Dict[str, List[str]]:
112112
parents: Dict[str, List[str]] = {node: [] for node in self.nodes}
113113
for node in self.nodes.values():
114114
for edge in node.edges:
115-
parents[edge.target].append(node.name)
115+
if edge.target != node.name:
116+
parents[edge.target].append(node.name)
116117
return parents
117118

118119
def get_start_nodes(self) -> Set[str]:

python/packages/autogen-agentchat/tests/test_group_chat_graph.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,65 @@ async def test_digraph_group_chat_loop_with_exit_condition(runtime: AgentRuntime
718718
assert result.messages[-1].source == _DIGRAPH_STOP_AGENT_NAME
719719

720720

721+
@pytest.mark.asyncio
722+
async def test_digraph_group_chat_loop_with_exit_condition_2(runtime: AgentRuntime | None) -> None:
723+
# Agents A and C: Echo Agents
724+
agent_a = _EchoAgent("A", description="Echo agent A")
725+
agent_c = _EchoAgent("C", description="Echo agent C")
726+
727+
# Replay model client for agent B
728+
model_client = ReplayChatCompletionClient(
729+
chat_completions=[
730+
"loop", # First time B will ask to loop
731+
"loop", # Second time B will ask to loop
732+
"exit", # Third time B will say exit
733+
]
734+
)
735+
# Agent B: Assistant Agent using Replay Client
736+
agent_b = AssistantAgent("B", description="Decision agent B", model_client=model_client)
737+
738+
# DiGraph: A → B(self loop) → C (conditional back to A or terminate)
739+
graph = DiGraph(
740+
nodes={
741+
"A": DiGraphNode(name="A", edges=[DiGraphEdge(target="B")]),
742+
"B": DiGraphNode(
743+
name="B", edges=[DiGraphEdge(target="C", condition="exit"), DiGraphEdge(target="B", condition="loop")]
744+
),
745+
"C": DiGraphNode(name="C", edges=[]),
746+
},
747+
default_start_node="A",
748+
)
749+
750+
team = GraphFlow(
751+
participants=[agent_a, agent_b, agent_c],
752+
graph=graph,
753+
runtime=runtime,
754+
termination_condition=MaxMessageTermination(20),
755+
)
756+
757+
# Run
758+
result = await team.run(task="Start")
759+
760+
# Assert message order
761+
expected_sources = [
762+
"user",
763+
"A",
764+
"B", # 1st loop
765+
"B", # 2nd loop
766+
"B",
767+
"C",
768+
_DIGRAPH_STOP_AGENT_NAME,
769+
]
770+
771+
actual_sources = [m.source for m in result.messages]
772+
773+
assert actual_sources == expected_sources
774+
assert result.stop_reason is not None
775+
assert result.messages[-2].source == "C"
776+
assert any(m.content == "exit" for m in result.messages[:-1]) # type: ignore[attr-defined,union-attr]
777+
assert result.messages[-1].source == _DIGRAPH_STOP_AGENT_NAME
778+
779+
721780
@pytest.mark.asyncio
722781
async def test_digraph_group_chat_parallel_join_any_1(runtime: AgentRuntime | None) -> None:
723782
agent_a = _EchoAgent("A", description="Echo agent A")

0 commit comments

Comments
 (0)