[BREAKING] Python: support fan-out node requests HITL as async#3754
[BREAKING] Python: support fan-out node requests HITL as async#3754moonbox3 wants to merge 4 commits intomicrosoft:mainfrom
Conversation
Python Test Coverage Report •
Python Unit Test Overview
|
|||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
This PR implements workflow-wide pausing at the superstep boundary when any parallel fan-out branch emits a request_info() (HITL) event, preventing other branches from continuing into subsequent supersteps while human input is pending (per #3539).
Changes:
- Add per-superstep HITL tracking in
RunnerContext(reset_superstep_request_info_tracking()/had_request_info_in_superstep()). - Update the workflow
Runnerto break after a superstep if anyrequest_infowas emitted during that superstep, preserving queued messages for the resume run. - Add a new regression test suite + a new getting-started sample and README entry documenting the behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/core/agent_framework/_workflows/_runner_context.py | Adds per-superstep boolean tracking for newly emitted request_info events. |
| python/packages/core/agent_framework/_workflows/_runner.py | Resets tracking at superstep start and pauses after the superstep if HITL occurred. |
| python/packages/core/tests/workflow/test_fan_out_hitl_pause.py | Adds tests covering fan-out pause behavior (streaming, non-streaming, typed requests, fan-in). |
| python/samples/getting_started/workflows/human-in-the-loop/fan_out_with_hitl_and_loop.py | New sample demonstrating pausing fan-out execution at a superstep boundary when HITL is requested. |
| python/samples/getting_started/workflows/README.md | Adds the new sample to the workflows sample index. |
|
Is this to prevent the situation where other branches can continue while one branch is blocked by a pending request (the one @eavanvalkenburg brought up)? If so, I don't think we should disallow that from happening. Instead, we should warn people of the possibility and let them know that the graph can lead to infinite loop. |
We synced offline: we will investigate how to allow the request info to be handled async as a workflow runs, so we don't need to block the workflow in this current way, shown in the PR. |
|
Going to support this behavior in a separate PR. |
Motivation and Context
request_info()during a superstep, the workflow now pauses at the superstep boundary instead of allowing parallel branches to continue processing.final outputs are the same, but outputs from non-HITL branches shift from the first
run()call to the resumerun()call.RunnerContextviareset_superstep_request_info_tracking()/had_request_info_in_superstep()to detect new HITL requests without false-positives frompre-existing pending requests or checkpoint restoration
Description
Contribution Checklist