Skip to content

Python: Adding support for nested workflows - #460

Merged
Eric Zhu (ekzhu) merged 37 commits into
mainfrom
bentho/sub-workflows
Aug 23, 2025
Merged

Eric Zhu (ekzhu) merged 37 commits into
mainfrom
bentho/sub-workflows

Conversation

@alliscode

Copy link
Copy Markdown
Member

Add Sub-Workflows Support to Agent Framework

Summary

This PR introduces hierarchical workflow composition through sub-workflows, enabling workflows to execute other
workflows as executors within their execution graph. Sub-workflows can make external requests that are
automatically routed to parent workflows for interception and handling.

Key Features

  • Hierarchical Workflow Composition: WorkflowExecutor class enables embedding workflows as executors within
    other workflows
  • Request Interception: Parent workflows can intercept sub-workflow requests using the @intercepts_request
    decorator
  • Automatic Message Routing: SubWorkflowRequestInfo messages are automatically routed between parent and
    sub-workflows
  • External Request Handling: Seamless integration with existing RequestInfoExecutor for external data
    requests
  • Type-Safe Response Correlation: RequestResponse[TRequest, TResponse] pattern with automatic correlation
    tracking

Implementation Details

Core Components

  1. WorkflowExecutor: Wraps a workflow to make it behave as an executor, enabling hierarchical composition
  2. SubWorkflowRequestInfo/SubWorkflowResponse: Message types for routing requests and responses between
    workflow layers
  3. @intercepts_request decorator: Allows parent workflows to intercept and handle specific request types from
    sub-workflows
  4. RequestResponse pattern: Type-safe response handling with .handled() and .forward() methods

Message Flow

Sub-Workflow → SubWorkflowRequestInfo → Parent Workflow Interceptor
↓ (if not intercepted)
RequestInfoExecutor → External Handler
↓
SubWorkflowResponse → Sub-Workflow

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
  • I didn't break anyone 😄

Copilot AI review requested due to automatic review settings August 20, 2025 21:30
@eavanvalkenburg Eduard van Valkenburg (eavanvalkenburg) added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Aug 20, 2025
@alliscode Ben Thomas (alliscode) changed the title bentho/sub workflows Adding support for nested workflows Aug 20, 2025
@github-actions github-actions Bot changed the title Adding support for nested workflows Python: bentho/sub workflows Aug 20, 2025

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 hierarchical workflow composition through sub-workflows, enabling workflows to execute other workflows as executors within their execution graph. The implementation includes support for external request interception, where parent workflows can intercept and handle sub-workflow requests before they reach external services.

Key changes:

  • Sub-workflow execution: New WorkflowExecutor class wraps workflows to make them behave as executors
  • Request interception: @intercepts_request decorator allows parent workflows to conditionally handle or forward requests from sub-workflows
  • Message routing infrastructure: Automatic routing between parent and sub-workflows via SubWorkflowRequestInfo and SubWorkflowResponse message types

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
subflow_design.md Comprehensive design document analyzing 6 implementation approaches for sub-workflows
python/samples/getting_started/workflow/ Three sample files demonstrating basic sub-workflows, request interception, and simple composition patterns
python/packages/workflow/tests/ Unit tests covering sub-workflow functionality, request interception, and edge cases
python/packages/workflow/examples/ Complete working example showing email validation with domain checking
agent_framework_workflow/_executor.py Core implementation of WorkflowExecutor, request interception decorators, and message types
agent_framework_workflow/_runner.py Message routing logic for handling sub-workflow requests and responses
agent_framework_workflow/_workflow.py Workflow modifications to support RequestInfoExecutor discovery
agent_framework_workflow/_validation.py Validation updates for single-executor workflows and interceptor output types
docs/design/sub_workflows_guide.md Comprehensive user guide with examples and best practices
Comments suppressed due to low confidence (2)

python/packages/workflow/agent_framework_workflow/_executor.py:149

  • This assignment inside the loop will overwrite the value on each iteration. It should be moved outside the loop: move self.expected_result_count = len(emails) before the for loop.
                # Check additional condition

python/packages/workflow/agent_framework_workflow/_executor.py:140

  • This field declaration without initialization will cause AttributeError when accessed before being set. Initialize it with a default value: self.expected_result_count: int = 0
                if hasattr(request.data, "__class__") and request.data.__class__.__name__ == request_type:

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread python/packages/workflow/agent_framework_workflow/_workflow_context.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_validation.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py Outdated
Comment thread python/samples/getting_started/workflow/step_09_intercept_sub_workflow.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py Outdated
Comment thread python/samples/getting_started/workflow/step_09_intercept_sub_workflow.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_runner.py
Comment thread docs/design/sub_workflows_guide.md Outdated
Comment thread docs/design/sub_workflows_guide.md Outdated
Comment thread python/packages/workflow/agent_framework_workflow/_executor.py Outdated
@eavanvalkenburg

Eduard van Valkenburg (eavanvalkenburg) commented Aug 21, 2025 •

Copy link
Copy Markdown
Member

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/workflow/agent_framework_workflow
   _executor.py3385882%98, 119, 137, 139, 145, 163, 169, 182, 212, 224, 235, 237–238, 314–315, 324, 328, 386, 542, 548, 561, 563–565, 568, 572, 575, 648–652, 657, 659–662, 666–668, 670, 674, 676–677, 782, 851, 901–902, 905–908, 928, 956–957, 960, 965, 968
   _runner.py2243484%94–96, 98, 149, 208, 230–231, 271–273, 288–292, 296, 300–301, 322–323, 335–336, 347–349, 353, 360–362, 367–368, 397, 416
   _typing_utils.py311067%18, 30, 38–40, 66, 68, 74–75, 78
   _validation.py3062990%102, 146, 190, 201–202, 207, 229, 236, 331–332, 341, 400, 402, 472, 475, 533, 537, 646–647, 672, 674, 681–682, 685–686, 690–693
   _workflow.py1993482%57, 151, 215, 224–225, 237, 251, 331–333, 366, 386–387, 389–391, 406–408, 416–417, 426–432, 437, 439, 554–556, 558
TOTAL508569586% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
629 40 💤 0 ❌ 0 🔥 12.112s ⏱️

@alliscode Ben Thomas (alliscode) changed the title Python: bentho/sub workflows Python: Adding support for nested workflows Aug 21, 2025

@ekzhu Eric Zhu (ekzhu) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I will clean up and resolve the conflicts.

@ekzhu

Eric Zhu (ekzhu) commented Aug 23, 2025 •

Copy link
Copy Markdown
Contributor

I noticed it currently doesn't automatically forward sub-workflow's request info event externally when there is no interceptor or request info executor in the parent workflow. I added a warning for this. What is the reason for not automatically surface the sub workflow's RequestInfoEvent?

logger.warning(
f"Sub-workflow request of type '{sub_request.data.__class__.__name__}' "
f"from sub-workflow '{sub_request.sub_workflow_id}' could not be handled: "
f"no RequestInfoExecutor found in the workflow. Add a RequestInfoExecutor "
f"to handle external requests or add an @intercepts_request handler."
)

@ekzhu
Eric Zhu (ekzhu) added this pull request to the merge queue Aug 23, 2025
Merged via the queue into main with commit b0b3fd1 Aug 23, 2025
@crickman
Chris (crickman) deleted the bentho/sub-workflows branch August 26, 2025 20:23
Reuben Bond (ReubenBond) pushed a commit to ReubenBond/agent-framework that referenced this pull request Oct 28, 2025
* Adding design documents and data flow descriptions for sub-workflows

* Updating docs.

* Sub-workflow implementation microsoft#1. Stuck because of singleton RequestInfoExecutor, going to make a change to remove that restrivtion.

* Removed the singleton restriction on RequestInfoExecutor so enable sub-workflows.

* Scenarios seem to be working.

* Sample improved.

* going to have intern add generic response wrappers.

* Wrapped responses working.

* Non-hardcoded routing is working.

* Sample showing external approved and not approved.

* Cleaning up.

* Updating some samples and user guide.

* Removing old design doc.

* Cleaning up.

* Adding python-package-setup.md back.

* Update python/packages/workflow/agent_framework_workflow/_executor.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update python/packages/workflow/agent_framework_workflow/_validation.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Removing prints.

* Fixing lint and type issues.

* Fixing lint and type issues.

* Update python/packages/workflow/agent_framework_workflow/_executor.py

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>

* Adding type hints to intercepts decorator.

* Removing unused files.

* Fixing issue with sample 5 groupchat with hil.

* Removing redundent samples.

* Updates to ensure no conflicting request interceptors and to support a subflow with multiple requests in a single super step.

* Fixing pypi errors.

* clean up samples

* update samples to make it more clear

* warning for unhandled request info from sub workflow

* add logger info

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants