autogen-graph
Directed Graph-based execution engine for Autogen agents, with optional message filtering.
autogen-graph lets you design deterministic, conditional, and cyclic workflows between Autogen-compatible agents. It supports both graph-based execution control and message filtering to precisely govern when agents run and what messages they see.
💡 What Does This Provide?
Autogen’s default group chats use a broadcast model. While powerful, it lacks precision:
- Agents can't be triggered conditionally.
- Message history grows without control.
- Parallelism and loops require manual workarounds.
autogen-graph solves this by introducing:
🔹 1. Graph-Based Execution (DiGraph)
Define who runs next using a fluent API to build nodes and edges.
- Control execution order
- Support parallel fan-outs, joins, conditionals
- Handle loops with runtime-safe cycles
🔹 2. Message Filtering (MessageFilterAgent)
Control what messages each agent sees before they're invoked.
- Restrict to last N messages from a source
- Include only specific message types or senders
- Prevent irrelevant context from leaking
This decouples execution routing from message visibility.
✨ Features
- ✅ Directed graph with support for:
- ⏩ Sequential flows
- 🔀 Parallel branches and joins
- ♻️ Loops with runtime-safe cycles
- ❓ Conditional edge activation
- 🧹
MessageFilterAgentto control per-agent context - 🧪 Test-friendly with
ReplayChatCompletionClient - 📎 CLI-friendly with
Consolestreaming
🗖️ Quickstart: Graph-based Flow
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_graph import DiGraphGroupChat, AGGraphBuilder
import asyncio
model_client = OpenAIChatCompletionClient(model="gpt-4o")
# Define agents
poet = AssistantAgent(name="poet", model_client=model_client, system_message="Write a poem about the ocean.")
critic = AssistantAgent(name="critic", model_client=model_client, system_message="Critique the poem and say APPROVE or revise.")
improver = AssistantAgent(name="improve", model_client=model_client, system_message="Improve the poem.")
# Build the execution graph
builder = AGGraphBuilder()
builder.add_node(poet).add_node(critic).add_node(improver)
builder.add_edge(poet, critic).add_edge(critic, improver)
# Assemble team
team = DiGraphGroupChat(
participants=builder.get_participants(),
graph=builder.build(),
termination_condition=TextMentionTermination("APPROVE"),
)
async def main():
await Console(team.run_stream("Please write a poem about the ocean."))
asyncio.run(main())
🔍 Message Filtering Example
Use MessageFilterAgent to restrict what messages an agent receives:
from autogen_graph import MessageFilterAgent, MessageFilterConfig, PerSourceFilter
filtered_critic = MessageFilterAgent(
name="critic",
wrapped_agent=critic,
filter=MessageFilterConfig(
per_source=[
PerSourceFilter(source="poet", position="last", count=1), # only last poet message
PerSourceFilter(source="user", position="first", count=1), # only first user message
]
)
)
builder = AGGraphBuilder()
builder.add_node(poet).add_node(filtered_critic).add_node(improver)
builder.add_edge(poet, "critic").add_edge("critic", improver)
team = DiGraphGroupChat(
participants=builder.get_participants(),
graph=builder.build(),
termination_condition=TextMentionTermination("APPROVE"),
)
This ensures critic only sees the last message from poet and the first message from user.
🔁 Advanced Example: Conditional Loop + Filtered Summary
This example demonstrates:
- A loop between
generatorandreviewer(which exits when reviewer says "final") - A
summarizeragent that only sees the first user input and the last reviewer message
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_graph import (
DiGraphGroupChat, AGGraphBuilder,
MessageFilterAgent, MessageFilterConfig, PerSourceFilter,
)
model_client = OpenAIChatCompletionClient(model="gpt-4o")
# Agents
generator = AssistantAgent("generator", model_client=model_client, system_message="Generate a list of creative ideas.")
reviewer = AssistantAgent("reviewer", model_client=model_client, system_message="Review ideas and say LOOP or FINAL.")
summarizer_core = AssistantAgent("summary", model_client=model_client, system_message="Summarize the user request and the final feedback.")
# Filtered summarizer
filtered_summarizer = MessageFilterAgent(
name="summary",
wrapped_agent=summarizer_core,
filter=MessageFilterConfig(
per_source=[
PerSourceFilter(source="user", position="first", count=1),
PerSourceFilter(source="reviewer", position="last", count=1),
]
)
)
# Build graph with conditional loop
builder = AGGraphBuilder()
builder.add_node(generator).add_node(reviewer).add_node(filtered_summarizer)
builder.add_edge(generator, reviewer)
builder.add_edge(reviewer, generator, condition="LOOP")
builder.add_edge(reviewer, filtered_summarizer, condition="FINAL")
team = DiGraphGroupChat(
participants=builder.get_participants(),
graph=builder.build(),
termination_condition=TextMentionTermination("FINAL"),
)
import asyncio
async def main():
await Console(team.run_stream("Brainstorm ways to reduce plastic waste."))
asyncio.run(main())
This allows iteration until the reviewer says "FINAL", at which point the summary is generated with only the original prompt and final feedback.
🧠 Conceptual Summary
| Concept | Purpose | Component |
|---|---|---|
| Execution control | Decides when an agent runs | DiGraph, DiGraphGroupChat, AGGraphBuilder |
| Context filtering | Decides what messages an agent sees | MessageFilterAgent |
Both can be combined seamlessly.
🧪 Tests
pytest tests/
📁 Project Structure
src/autogen_graph/
├── _digraph_group_chat.py # Main graph runner
├── _graph_builder.py # Fluent graph builder
├── _message_filter_agent.py # Message filtering agent
├── __init__.py
📜 License
MIT © A Somaraju
🙌 Contributions
Welcome! Especially around:
- Graph editors or visualizations
- New agent container wrappers (e.g., summarizer)
- Message transformation logic
Metadata
Release files for autogen-graph 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| autogen_graph-0.1.2.tar.gz | 21.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| autogen_graph-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.2 kB
Release files / autogen_graph-0.1.2.tar.gz
| Download URL | autogen_graph-0.1.2.tar.gz |
|---|---|
| Size | 21.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f2b3f59653782aba2b86c55cb2be140a233a3b2c110b002d31bb4c2961b0a807
|
|
BLAKE2b-256 checksum How to use checksums |
6588fbfe316883fe568910453e209ee0cc81e249f6ca732144cd9f8c8b4831b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 17, 2025.
Transparency logRelease files / autogen_graph-0.1.2-py3-none-any.whl
| Download URL | autogen_graph-0.1.2-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f25ee37f8c577e114ca7c789c1686d8c853fdca9dd65073b4365c9b522010319
|
|
BLAKE2b-256 checksum How to use checksums |
f64d5d587ee934fc3705f3525bf8ab40130020fb33eb2a0e8070b680a5e59ce1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 17, 2025.
Transparency log