Skip to content

Conversation

@moonbox3
Copy link
Contributor

@moonbox3 moonbox3 commented Oct 17, 2025

Motivation and Context

This PR introduces a comprehensive refactoring of the orchestration patterns (GroupChat, Handoff, Magentic) to eliminate code duplication, strengthen architectural consistency, and provide cleaner public APIs.

Architectural Improvements

  • Unified Base Class: Created BaseGroupChatOrchestrator with shared state management (conversation history, termination conditions, round tracking) that all orchestration patterns inherit from, eliminating ~200 lines of duplicated state logic.

  • Shared Utilities Module: Extracted common orchestration helpers into _orchestrator_helpers.py:

    • clean_conversation_for_handoff() - Removes tool-related content to prevent API errors during agent handoffs
    • check_round_limit() - Standardized round limit validation
    • create_completion_message() - Consistent completion message generation
    • prepare_participant_request() - Unified participant request construction
    • ParticipantRegistry - Clean interface for tracking participant executor IDs and routing info
  • Consistent Participant Handling: All three orchestration patterns now use the same participant registration and routing patterns, reducing special-case logic.

API Surface Cleanup (Breaking Changes)

  • Internal Type Naming: Renamed 17 internal implementation types with _ prefix (e.g., GroupChatRequestMessage_GroupChatRequestMessage, MagenticProgressLedger_MagenticProgressLedger) to clearly signal implementation details.

  • Reduced Public Exports: Orchestration package now exports only 16 types (down from ~28), exposing only what users need:

    • Builders: GroupChatBuilder, HandoffBuilder, MagenticBuilder
    • Public types for extensibility: GroupChatStateSnapshot, MagenticPlanReviewRequest, MagenticPlanReviewReply, etc.
    • Event types: MagenticOrchestratorMessageEvent, MagenticAgentDeltaEvent, etc.
  • Enhanced GroupChat API: Added select_speakers() as the primary API for function-based speaker selection, providing cleaner ergonomics than the previous set_speaker_selector() approach. The new method provides GroupChatStateSnapshot with full context (history, round index, participant names) and enforces mutual exclusivity with set_prompt_based_manager() at build time.

Type Safety and Consistency

  • Fixed Type Annotations:

    • Corrected termination_condition from Any to Callable[[list[ChatMessage]], bool] | None in BaseGroupChatOrchestrator (allows for asynchronous use as well)
    • Added proper type hints throughout shared utilities
    • Updated test files to use proper type casting instead of excessive type: ignore comments
  • Stub File Synchronization: Updated __init__.pyi to match cleaned __init__.py exports

Code Quality Improvements

  • Eliminated Duplication: Removed redundant implementations of:

    • Conversation history management (3 copies → 1 base class)
    • Round limit checking (3 copies → 1 helper function)
    • Participant request preparation (2 copies → 1 helper function)
    • Tool message cleaning for handoffs (inline code → reusable function)
  • Improved Testability: Internal types remain accessible for testing via direct imports from implementation modules with appropriate type: ignore[reportPrivateUsage] annotations.

  • Documentation Enhancements:

    • Comprehensive docstrings for all shared utilities
    • Updated GroupChatBuilder docstring with dual pattern examples (function-based and LLM-based selection)
    • Created new sample demonstrating select_speakers() API

Samples and Documentation

  • New Samples:

    • group_chat_simple_selector.py - Demonstrates function-based speaker selection with select_speakers()
    • (Existing samples updated to use new naming)
  • Updated README: Corrected orchestration sample links and descriptions (e.g., replaced non-existent group_chat.py reference with actual files group_chat_prompt_based_manager.py and group_chat_simple_selector.py)

The cleaner API surface and reduced code duplication provide a stronger foundation for future orchestration pattern development.

Description

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

@moonbox3 moonbox3 self-assigned this Oct 17, 2025
Copilot AI review requested due to automatic review settings October 17, 2025 07:31
@moonbox3 moonbox3 added squad: workflows Agent Framework Workflows Squad workflows Related to Workflows in agent-framework breaking change Introduces changes that are not backward compatible and may require updates to dependent code. labels Oct 17, 2025
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python labels Oct 17, 2025
@github-actions github-actions bot changed the title [BREAKING] Python: Intro group chat and refactor magentic. Fix as_agent() Python: [BREAKING] Python: Intro group chat and refactor magentic. Fix as_agent() Oct 17, 2025
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Oct 17, 2025

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework/_workflows
   _agent.py2284082%54, 62–65, 93–94, 243, 284–287, 293, 299, 303–304, 307–313, 317–318, 357, 364, 370–371, 377, 389, 421, 428, 449, 456, 460, 462–464, 471
   _agent_executor.py922078%81, 91–93, 112–113, 128, 162–163, 165–166, 181–182, 216–220, 226–227
   _base_group_chat_orchestrator.py721184%91, 167, 177, 184, 239, 250, 252–255, 265
   _concurrent.py1372681%50, 59–60, 68–69, 88–89, 94, 99, 124, 129, 134–135, 141, 163, 173, 180, 253–257, 259, 287, 291, 322
   _conversation_history.py311841%22, 33–47, 49–50
   _executor.py115496%202, 334, 349, 351
   _group_chat.py4075486%169–170, 301–311, 360, 374, 381, 385–387, 453, 462, 608, 619, 623, 692, 709, 889, 894, 1011, 1079, 1081–1082, 1084, 1220, 1314, 1340, 1342, 1346–1349, 1351, 1354–1355, 1370, 1403–1406, 1416, 1427, 1436–1438
   _handoff.py46014568%61–63, 70–71, 73, 75, 80–81, 83, 132, 140–145, 148–149, 163, 172, 191–194, 203–205, 216, 219, 229–240, 242, 248, 254, 281, 295–297, 332, 337–339, 375, 384–389, 391–392, 403, 420, 448, 455, 457–459, 471, 505, 537–539, 542–545, 547–549, 782, 788, 792, 798, 802, 814, 862, 865, 953, 958, 968, 974–977, 985–986, 990–992, 994–1004, 1006–1007, 1009, 1011, 1026–1027, 1030–1031, 1034, 1054–1060, 1062, 1068, 1102–1103, 1156–1157, 1268, 1276, 1285–1288, 1345, 1360, 1364, 1369–1370
   _magentic.py94427470%69–78, 83, 87–98, 322, 327, 344, 346, 361, 369–378, 457, 461, 475, 481, 496, 576, 589, 606, 615–616, 618–620, 622, 633, 700–704, 707–711, 791–794, 797–801, 803–805, 812, 851, 898, 934–936, 938, 1005, 1078, 1080–1081, 1089, 1125, 1134–1136, 1155, 1166, 1176–1177, 1179–1180, 1199, 1252, 1272, 1275, 1303, 1306, 1311, 1319–1323, 1329, 1357–1359, 1361, 1363, 1371–1374, 1376, 1380–1381, 1384–1387, 1389–1390, 1396–1398, 1401–1402, 1407–1408, 1416, 1424, 1439, 1451, 1463–1466, 1495–1496, 1501–1503, 1534, 1560, 1575, 1591, 1613, 1683, 1689–1690, 1704, 1706, 1709, 1711–1712, 1715–1716, 1720, 1723, 1744, 1781–1782, 1784, 1788–1790, 1806, 1817, 1827, 1871, 1876–1877, 2203–2204, 2208, 2223, 2228, 2231, 2291, 2302, 2313–2315, 2328–2329, 2334, 2345–2347, 2358–2360, 2372–2379, 2381–2382, 2390, 2398–2399, 2401–2403, 2405–2408, 2412–2420, 2424–2425, 2428–2432, 2434–2435, 2437–2439, 2441–2444, 2446–2448, 2450–2451, 2453–2455, 2468–2470, 2481–2484, 2495–2498, 2510–2513, 2522–2525, 2532–2533, 2540, 2544
   _message_utils.py18383%22, 33, 37
   _model_utils.py311261%19, 23, 35, 37–40, 47–51
   _orchestration_state.py27966%20, 28, 67, 80, 82–85, 87
   _orchestrator_helpers.py48687%95–96, 126, 128, 186, 190
   _participant_utils.py80495%40, 51, 57, 67
   _sequential.py78791%71, 80–81, 91, 143, 149, 172
   _typing_utils.py782271%25, 30–31, 33–35, 37, 50–51, 58–59, 64–68, 71–72, 119, 156, 161, 171
   _workflow.py2833089%95, 248–250, 252–253, 271, 295, 297, 463, 467, 500, 576, 611, 619, 627, 630–633, 642–643, 647, 649, 683, 726–728, 741, 806
   _workflow_context.py1801392%56–57, 65, 69, 83, 159, 184, 256, 352, 423, 437, 452, 465
TOTAL12293200983% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
1401 98 💤 0 ❌ 0 🔥 27.979s ⏱️

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a reusable group chat orchestration framework and refactors Magentic One to build on these shared primitives. The changes eliminate Magentic's bespoke workflow wrapper while maintaining compatibility, consolidate event plumbing through the standard workflow event stream, and add support for as_agent() to accept full conversation payloads.

Key changes:

  • Added GroupChat orchestration surface with protocols, builder, and executors for manager-directed multi-agent conversations
  • Refactored Magentic to use shared group chat infrastructure while preserving Magentic-specific behavior
  • Fixed as_agent() to properly handle conversation histories and improved type safety

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
python/packages/core/agent_framework/_workflows/_group_chat.py New comprehensive group chat orchestration framework with protocols, executors, and builders
python/packages/core/agent_framework/_workflows/_magentic.py Major refactor to build on group chat primitives while maintaining Magentic-specific functionality
python/packages/core/agent_framework/_workflows/_executor.py Fixed handler decorator return type annotation
python/packages/core/agent_framework/_workflows/init.py Added exports for new group chat components
python/packages/core/agent_framework/_workflows/init.pyi Updated type definitions for new group chat exports
python/samples/getting_started/workflows/orchestration/group_chat.py New sample demonstrating basic group chat usage
python/samples/getting_started/workflows/agents/*.py New samples showing workflows wrapped as agents
python/samples/getting_started/workflows/orchestration/magentic*.py Updated to use new event streaming approach
python/packages/core/tests/workflow/test_*.py Updated tests to reflect new event handling and API changes
python/samples/getting_started/workflows/README.md Added documentation for new samples

@moonbox3 moonbox3 changed the title Python: [BREAKING] Python: Intro group chat and refactor magentic. Fix as_agent() Python: [BREAKING] Python: Intro group chat and refactor magentic. Fix as_agent(). Standardize orchestration start msg types. Oct 20, 2025
@moonbox3 moonbox3 changed the title Python: [BREAKING] Python: Intro group chat and refactor magentic. Fix as_agent(). Standardize orchestration start msg types. Python: [BREAKING] Python: Intro group chat and refactor orchestrations. Fix as_agent(). Standardize orchestration start msg types. Oct 22, 2025
@ekzhu
Copy link
Contributor

ekzhu commented Oct 22, 2025

Before we stabilize the API we should run different orchestration patterns against the GAIA benchmark in the lab package.

@moonbox3 moonbox3 requested a review from TaoChenOSU October 22, 2025 23:20
@lokitoth
Copy link
Member

We should do a pass to make sure the semantics of GroupChat in .NET are consistent with the Python ones. I am not sure we handle the tools messages the same way.

@moonbox3 moonbox3 added this pull request to the merge queue Oct 25, 2025
Merged via the queue into microsoft:main with commit e3aad8e Oct 25, 2025
21 checks passed
ReubenBond pushed a commit to ReubenBond/agent-framework that referenced this pull request Oct 28, 2025
…ns. Fix as_agent(). Standardize orchestration start msg types. (microsoft#1538)

* Intro group chat and refactor magentic. Fix as_agent()

* Cleanup and improvements

* Add as_agent docstring clarification

* Standardize orchestration messages to use agent-style inputs.

* Simplify group chat constructs

* Further cleanup

* Add sk to af group chat migration sample. Update README.

* Improvements and simplifications

* consolidating shared orchestration logic

* Further clean up

* Add group chat sample

* Improve typing

* Fix test imports

* Fix readme links

* Cleanup per PR Feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Introduces changes that are not backward compatible and may require updates to dependent code. documentation Improvements or additions to documentation python squad: workflows Agent Framework Workflows Squad workflows Related to Workflows in agent-framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce GroupChatBuilder in workflow API

6 participants