Skip to main content

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
  • 🧹 MessageFilterAgent to control per-agent context
  • 🧪 Test-friendly with ReplayChatCompletionClient
  • 📎 CLI-friendly with Console streaming

🗖️ 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 generator and reviewer (which exits when reviewer says "final")
  • A summarizer agent 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)

Source distribution for autogen-graph 0.1.2
File Size Uploaded
autogen_graph-0.1.2.tar.gz 21.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for autogen-graph 0.1.2
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page