## 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>