Copilot c23b9454a8
Fix GraphFlow to support multiple task execution without explicit reset (#6747)
## Problem

When using GraphFlow with a termination condition, the second task
execution would immediately terminate without running any agents. The
first task would run successfully, but subsequent tasks would skip all
agents and go directly to the stop agent.

This was demonstrated by the following issue:

```python
# First task runs correctly
result1 = await team.run(task="First task")  #  Works fine

# Second task fails immediately  
result2 = await team.run(task="Second task")  #  Only user + stop messages
```

## Root Cause

The `GraphFlowManager` was not resetting its execution state when
termination occurred. After the first task completed:

1. The `_ready` queue was empty (all nodes had been processed)
2. The `_remaining` and `_enqueued_any` tracking structures remained in
"completed" state
3. The `_message_thread` retained history from the previous task

This left the graph in a "completed" state, causing subsequent tasks to
immediately trigger the stop agent instead of executing the workflow.

## Solution

Added an override of the `_apply_termination_condition` method in
`GraphFlowManager` to automatically reset the graph execution state when
termination occurs:

```python
async def _apply_termination_condition(
    self, delta: Sequence[BaseAgentEvent | BaseChatMessage], increment_turn_count: bool = False
) -> bool:
    # Call the base implementation first
    terminated = await super()._apply_termination_condition(delta, increment_turn_count)
    
    # If terminated, reset the graph execution state and message thread for the next task
    if terminated:
        self._remaining = {target: Counter(groups) for target, groups in self._graph.get_remaining_map().items()}
        self._enqueued_any = {n: {g: False for g in self._enqueued_any[n]} for n in self._enqueued_any}
        self._ready = deque([n for n in self._graph.get_start_nodes()])
        # Clear the message thread to start fresh for the next task
        self._message_thread.clear()
    
    return terminated
```

This ensures that when a task completes (termination condition is met),
the graph is automatically reset to its initial state ready for the next
task.

## Testing

Added a comprehensive test case
`test_digraph_group_chat_multiple_task_execution` that validates:
- Multiple tasks can be run sequentially without explicit reset calls
- All agents are executed the expected number of times  
- Both tasks produce the correct number of messages
- The fix works with various termination conditions
(MaxMessageTermination, TextMentionTermination)

## Result

GraphFlow now works like SelectorGroupChat where multiple tasks can be
run sequentially without explicit resets between them:

```python
# Both tasks now work correctly
result1 = await team.run(task="First task")   #  5 messages, all agents called
result2 = await team.run(task="Second task")  #  5 messages, all agents called again
```

Fixes #6746.

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `esm.ubuntu.com`
>   - Triggering command: `/usr/lib/apt/methods/https` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to my [firewall allow
list](https://gh.io/copilot/firewall-config)
>
> </details>



<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a
$200 gift card! Click
[here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to
start the survey.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ekzhu <320302+ekzhu@users.noreply.github.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-07-05 23:32:50 -07:00
..
2025-03-04 09:56:49 -08:00
2025-04-21 21:51:22 -07:00
2025-07-01 08:13:46 +09:00

AutoGen Python packages

0.4 Docs PyPi autogen-core PyPi autogen-agentchat PyPi autogen-ext

This directory works as a single uv workspace containing all project packages. See packages to discover all project packages.

Migrating from 0.2.x?

Please refer to the migration guide for how to migrate your code from 0.2.x to 0.4.x.

Development

TL;DR, run all checks with:

uv sync --all-extras
source .venv/bin/activate
poe check

Setup

uv is a package manager that assists in creating the necessary environment and installing packages to run AutoGen.

To upgrade uv to the latest version, run:

uv self update

Virtual Environment

During development, you may need to test changes made to any of the packages.
To do so, create a virtual environment where the AutoGen packages are installed based on the current state of the directory.
Run the following commands at the root level of the Python directory:

uv sync --all-extras
source .venv/bin/activate
  • uv sync --all-extras will create a .venv directory at the current level and install packages from the current directory along with any other dependencies. The all-extras flag adds optional dependencies.
  • source .venv/bin/activate activates the virtual environment.

Common Tasks

To create a pull request (PR), ensure the following checks are met. You can run each check individually:

  • Format: poe format
  • Lint: poe lint
  • Test: poe test
  • Mypy: poe mypy
  • Pyright: poe pyright
  • Build docs: poe --directory ./packages/autogen-core/ docs-build
  • Auto rebuild+serve docs: poe --directory ./packages/autogen-core/ docs-serve
  • Check samples in python/samples: poe samples-code-check Alternatively, you can run all the checks with:
  • poe check

Note

These need to be run in the virtual environment.

Syncing Dependencies

When you pull new changes, you may need to update the dependencies. To do so, first make sure you are in the virtual environment, and then in the python directory, run:

uv sync --all-extras

This will update the dependencies in the virtual environment.

Creating a New Package

To create a new package, similar to autogen-core or autogen-chat, use the following:

uv sync --python 3.12
source .venv/bin/activate
cookiecutter ./templates/new-package/