Skip to content

Conversation

@Shizoqua
Copy link

Why are these changes needed?

This PR fixes issue #7100 where run_stream() would continue processing all buffered messages from the queue even after the CancellationToken was cancelled, particularly when cancelled by signal handlers (e.g., SIGINT/Ctrl+C).

Problem:
When a CancellationToken is cancelled (especially by signal handlers), the run_stream() async iteration loop continues processing all buffered messages before checking the cancellation status. This makes applications appear unresponsive to user interruption, as the loop drains the entire message queue before stopping.

Root Cause:
In _base_group_chat.py, the run_stream() method has a while True: loop that only checks for cancellation when awaiting the next message from the queue. If there are buffered messages in _output_message_queue, they get processed and yielded even after the cancellation token is cancelled, because the cancellation check happens too late in the iteration cycle.

Solution:
Added a cancellation check immediately after receiving each message from the queue, before processing or yielding it. This ensures that if the cancellation token was cancelled, the loop breaks immediately without processing any remaining buffered messages.

Code Change:

# In _base_group_chat.py, run_stream() method (line ~549-554)
message = await message_future
# Check if cancellation token was cancelled before processing/yielding the message.
# This ensures that signal handlers (e.g., SIGINT/Ctrl+C) can stop iteration immediately
# even if there are buffered messages in the queue.
if cancellation_token is not None and cancellation_token.is_cancelled():
    break

This fix ensures that when a signal handler cancels the token, the iteration stops immediately on the next loop iteration, providing the expected responsive behavior for interactive CLI applications.

Related issue number

Fixes #7100

Related to:

Checks

  • I've included any doc changes needed for https://microsoft.github.io/autogen/. See https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md to build and test documentation locally.
    • No documentation changes needed - this is a bug fix that improves existing behavior
  • I've added tests (if relevant) corresponding to the changes introduced in this PR.
    • Added test_round_robin_group_chat_run_stream_cancellation() test in test_group_chat.py
    • Test verifies that stream stops immediately after cancellation
    • Existing cancellation test test_round_robin_group_chat_cancellation still passes (backward compatibility verified)
  • I've made sure all auto checks have passed.
    • ✅ Code formatted (poe format)
    • ✅ Code linted (poe lint)
    • ✅ Tests pass (pytest packages/autogen-agentchat/tests/test_group_chat.py::test_round_robin_group_chat_run_stream_cancellation)
    • ✅ No linter errors

Testing

New Test Added:

  • test_round_robin_group_chat_run_stream_cancellation() - Verifies that run_stream() stops immediately when CancellationToken is cancelled, preventing processing of buffered messages.

Test Results:

  • ✅ New test passes (both single_threaded and embedded runtime variants)
  • ✅ Existing cancellation test still passes (backward compatibility maintained)
  • ✅ All related run_stream tests continue to pass

Files Changed

  • python/packages/autogen-agentchat/src/autogen_agentchat/teams/_group_chat/_base_group_chat.py

    • Added cancellation check in run_stream() method (lines 550-554)
  • python/packages/autogen-agentchat/tests/test_group_chat.py

    • Added test_round_robin_group_chat_run_stream_cancellation() test (lines 766-818)

@Shizoqua
Copy link
Author

@microsoft-github-policy-service agree

…eration immediately

- Add cancellation token check before yielding messages in run_stream()
- Prevents processing buffered messages after cancellation token is cancelled
- Fixes issue where signal handlers (SIGINT/Ctrl+C) couldn't stop iteration immediately
- Add test_round_robin_group_chat_run_stream_cancellation to verify fix

The issue was that run_stream() would continue processing all buffered
messages from the queue even after the cancellation token was cancelled,
because the cancellation check only happened when awaiting the next message.
This fix adds a check after receiving each message to break immediately
if cancellation occurred.
@Shizoqua Shizoqua force-pushed the issue-7100-cancellation-token-fix branch from 95b0b44 to e572ce9 Compare December 1, 2025 01:55
@Shizoqua
Copy link
Author

Shizoqua commented Dec 1, 2025

@ekzhu Could you please review this PR when you have a chance? This fixes the cancellation token issue in run_stream() for group chat. Thanks!

@Shizoqua
Copy link
Author

Shizoqua commented Dec 5, 2025

Hi @victordibia i trust you are doing fine today, could you please review my PR and advice me on how to go.

@ekzhu
Copy link
Contributor

ekzhu commented Dec 6, 2025

@Shizoqua I am no longer the maintainer of this repo. Please follow up with @victordibia :D

@Shizoqua
Copy link
Author

Shizoqua commented Dec 6, 2025

thank you @ekzhu

@Shizoqua
Copy link
Author

Shizoqua commented Dec 7, 2025

Hi @victordibia, how are you doing today, i trust you are fine , i was wondering if you had a spare time to help review my PR and guide me on how to go forward.

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.

CancellationToken doesn't stop run_stream() iteration when cancelled by signal handler

2 participants