KEMBAR78
Add callable condition for GraphFlow edges by ekzhu · Pull Request #6623 · microsoft/autogen · GitHub
Skip to content

Conversation

@ekzhu
Copy link
Collaborator

@ekzhu ekzhu commented Jun 3, 2025

This PR adds callable as an option to specify conditional edges in GraphFlow.

import asyncio

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination
from autogen_agentchat.teams import DiGraphBuilder, GraphFlow
from autogen_ext.models.openai import OpenAIChatCompletionClient


async def main():
    # Initialize agents with OpenAI model clients.
    model_client = OpenAIChatCompletionClient(model="gpt-4.1-nano")
    agent_a = AssistantAgent(
        "A",
        model_client=model_client,
        system_message="Detect if the input is in Chinese. If it is, say 'yes', else say 'no', and nothing else.",
    )
    agent_b = AssistantAgent("B", model_client=model_client, system_message="Translate input to English.")
    agent_c = AssistantAgent("C", model_client=model_client, system_message="Translate input to Chinese.")

    # Create a directed graph with conditional branching flow A -> B ("yes"), A -> C (otherwise).
    builder = DiGraphBuilder()
    builder.add_node(agent_a).add_node(agent_b).add_node(agent_c)
    # Create conditions as callables that check the message content.
    builder.add_edge(agent_a, agent_b, condition=lambda msg: "yes" in msg.to_model_text())
    builder.add_edge(agent_a, agent_c, condition=lambda msg: "yes" not in msg.to_model_text())
    graph = builder.build()

    # Create a GraphFlow team with the directed graph.
    team = GraphFlow(
        participants=[agent_a, agent_b, agent_c],
        graph=graph,
        termination_condition=MaxMessageTermination(5),
    )

    # Run the team and print the events.
    async for event in team.run_stream(task="AutoGen is a framework for building AI agents."):
        print(event)


asyncio.run(main())

Copilot AI and others added 18 commits May 19, 2025 23:43
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
…tions

Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
…graph_visibility

Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
@ekzhu ekzhu marked this pull request as ready for review June 3, 2025 20:43
@codecov
Copy link

codecov bot commented Jun 3, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 79.75%. Comparing base (9065c6f) to head (5195b3a).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6623      +/-   ##
==========================================
+ Coverage   79.69%   79.75%   +0.06%     
==========================================
  Files         228      228              
  Lines       17025    17040      +15     
==========================================
+ Hits        13568    13591      +23     
+ Misses       3457     3449       -8     
Flag Coverage Δ
unittests 79.75% <100.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Collaborator

@victordibia victordibia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the example, tested, looks good.
Should we add somewhere in the docs that serializing the graph will not include conditional functions.

graph (python)

DiGraph(nodes={'A': DiGraphNode(name='A', edges=[DiGraphEdge(target='B', condition=None, condition_function=<function <lambda> at 0x1109f5bc0>), DiGraphEdge(target='C', condition=None, condition_function=<function <lambda> at 0x1109f59e0>)], activation='all'), 'B': DiGraphNode(name='B', edges=[], activation='all'), 'C': DiGraphNode(name='C', edges=[], activation='all')}, default_start_node=None)

graph.model_dump()

{'nodes': {'A': {'name': 'A',
   'edges': [{'target': 'B', 'condition': None},
    {'target': 'C', 'condition': None}],
   'activation': 'all'},
  'B': {'name': 'B', 'edges': [], 'activation': 'all'},
  'C': {'name': 'C', 'edges': [], 'activation': 'all'}},
 'default_start_node': None}

@gm3000
Copy link

gm3000 commented Jun 4, 2025

what is the difference with "builder.add_conditional_edges(agent_b, {"APPROVE": agent_c, "REJECT": agent_a})" that I found in the
GraphFlow description

@gm3000
Copy link

gm3000 commented Jun 4, 2025

what is the difference with "builder.add_conditional_edges(agent_b, {"APPROVE": agent_c, "REJECT": agent_a})" that I found in the GraphFlow description

I see, you added a callable condition, but how to persist the callable?

@ekzhu ekzhu linked an issue Jun 4, 2025 that may be closed by this pull request
1 task
@ekzhu
Copy link
Collaborator Author

ekzhu commented Jun 4, 2025

what is the difference with "builder.add_conditional_edges(agent_b, {"APPROVE": agent_c, "REJECT": agent_a})" that I found in the GraphFlow description

add_conditional_edges can only support keyword conditions because its input parameter type is constrained to a dictionary with the key as keywords. So this PR added a deprecation notice to this method, and likely we will change the method signature in the future.

@ekzhu
Copy link
Collaborator Author

ekzhu commented Jun 4, 2025

what is the difference with "builder.add_conditional_edges(agent_b, {"APPROVE": agent_c, "REJECT": agent_a})" that I found in the GraphFlow description

I see, you added a callable condition, but how to persist the callable?

It won't serialize the callable. This is the issue we can address in a future PR.

@ekzhu ekzhu enabled auto-merge (squash) June 4, 2025 22:36
@ekzhu ekzhu merged commit b31b4e5 into main Jun 4, 2025
63 checks passed
@ekzhu ekzhu deleted the ekzhu-conditional-edge branch June 4, 2025 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GraphFlow should support custom conditional expression in edges

5 participants