Skip to content

.NET: feat: Refactor Handoff Orchestration and add HITL support#5174

Open
lokitoth wants to merge 1 commit intomainfrom
dev/dotnet_workflow/handoff_hitl
Open

.NET: feat: Refactor Handoff Orchestration and add HITL support#5174
lokitoth wants to merge 1 commit intomainfrom
dev/dotnet_workflow/handoff_hitl

Conversation

@lokitoth
Copy link
Copy Markdown
Member

@lokitoth lokitoth commented Apr 8, 2026

Motivation and Context

Due to needing special-case logic, the Handoff orchestration pattern implementation relies on a custom AIAgent hosting executor (HandoffAgentExecutor). While support for turn-interruption due to unserviced function calls (AIFunctionDeclaration-only) or tool approval demands was added to AIAgentHostExecutor, it was not implemented for HandoffAgentExecutor.

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.

@lokitoth lokitoth self-assigned this Apr 8, 2026
@lokitoth lokitoth added .NET workflows Related to Workflows in agent-framework labels Apr 8, 2026
Copilot AI review requested due to automatic review settings April 8, 2026 19:11
@lokitoth lokitoth moved this to In Progress in Agent Framework Apr 8, 2026
Copy link
Copy Markdown
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

Note

Copilot was unable to run its full agentic suite in this review.

Refactors the .NET handoff orchestration executors to use a stateful “ContinueTurn” pattern and adds HITL support for unserviced function calls and tool approval requests, aligning behavior with the existing AIAgentHostExecutor flow.

Changes:

  • Refactors HandoffAgentExecutor to be stateful, factory-instantiated, and able to surface/continue on pending FunctionCallContent + ToolApprovalRequestContent.
  • Extracts shared “unserviced request” collection/submission logic into AIAgentUnservicedRequestsCollector.
  • Fixes StatefulExecutor caching behavior to properly load state from checkpoint on first access.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/HandoffAgentExecutorTests.cs Updates executor construction to new signature.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.cs Adds HITL handoff tests and updates checkpointed run helpers to surface pending requests.
dotnet/src/Microsoft.Agents.AI.Workflows/StatefulExecutor.cs Fixes initial cache load from checkpoint; refactors protocol configuration path.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffsStartExecutor.cs Renames constants/class to “Handoff…” and propagates “previous agent” tracking.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffsEndExecutor.cs Renames to HandoffEndExecutor and updates persisted agent tracking field.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffState.cs Renames state fields to clarify semantics (requested target vs previous agent).
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffAgentExecutor.cs Major refactor to stateful + HITL support, plus checkpoint persistence for pending requests.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentUnservicedRequestsCollector.cs New helper to collect/submit pending external requests from agent outputs.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.cs Uses new collector; improves synthetic message metadata on resume.
dotnet/src/Microsoft.Agents.AI.Workflows/HandoffWorkflowBuilder.cs Switches to factory-based executor bindings and updates routing to renamed state fields.

* Change HandoffAgentExecutor to use factory-based instantiation
* Extract shared request collection logic in AIAgentUnservicedRequestsCollector
* Refactor HandoffAgentExecutor to use the "ContinueTurn" pattern as in AIAgentHostExecutor
@lokitoth lokitoth force-pushed the dev/dotnet_workflow/handoff_hitl branch from ccbfe66 to c3f0999 Compare April 8, 2026 19:35
@lokitoth lokitoth moved this from In Progress to In Review in Agent Framework Apr 8, 2026
{
if (this._userInputRequests.ContainsKey(userInputRequest.RequestId))
{
throw new InvalidOperationException($"ToolApprovalRequestContent with duplicate RequestId: ${userInputRequest.RequestId}");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
throw new InvalidOperationException($"ToolApprovalRequestContent with duplicate RequestId: ${userInputRequest.RequestId}");
throw new InvalidOperationException($"ToolApprovalRequestContent with duplicate RequestId: {userInputRequest.RequestId}");

{
if (this._functionCalls.ContainsKey(functionCall.CallId))
{
throw new InvalidOperationException($"FunctionCallContent with duplicate CallId: ${functionCall.CallId}");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
throw new InvalidOperationException($"FunctionCallContent with duplicate CallId: ${functionCall.CallId}");
throw new InvalidOperationException($"FunctionCallContent with duplicate CallId: {functionCall.CallId}");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET workflows Related to Workflows in agent-framework

Projects

Status: In Review

3 participants