Skip to content

.NET: [BREAKING] Implement Polymorphic Routing - #3792

Merged
Jacob Alber (lokitoth) merged 9 commits into
mainfrom
dev/dotnet_workflow/polymorphic_routing
Feb 19, 2026
Merged

.NET: [BREAKING] Implement Polymorphic Routing#3792
Jacob Alber (lokitoth) merged 9 commits into
mainfrom
dev/dotnet_workflow/polymorphic_routing

Conversation

@lokitoth

@lokitothJacob Alber (lokitoth) commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Motivation and Context

The initial implementation of the InProcess runtime relied on exact matches on handled types to determine routing. This was a result of the need to be able to go from a TypeId to a runtime Type after a checkpoint serialization/deserialization cycle, which loses type information. With the changes to provide a Source Generator rather than Reflection, and a more expressive ProtocolBuilder API to be able to define the types of sent messages and yielded outputs, we can switch the deserialization logic to rely on the source executor's information,

Description

Implements Polymorphic routing (closes#782, closes#3116)

  • [BREAKING] Changes ConfigureRoutes/ConfigureXYZTypes to ConfigureProtocol (closes.NET: Reconcile Executor Configure and ConfigureXYZ methods #3242)
  • [BREAKING] Adds check for outgoing messages and outputs to match registered types
  • Temporarily updates ReflectingExecutor (which is Obsolete) to properly register outgoing types
  • Update FunctionExecutor to register outgoing types and listen to [SendsMessage] and [YieldsOutput] attributes
  • TODO:
    • Add support for attributes-based outgoing types registration to Basic Executors
    • Update Declarative Workflows for missing type registrations (if any)

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.

@lokitothJacob Alber (lokitoth) added .NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows labels Feb 10, 2026
@lokitoth
Jacob Alber (lokitoth)force-pushed the dev/dotnet_workflow/polymorphic_routing branch from a0a5997 to 8e3d6d6CompareFebruary 10, 2026 09:54
@lokitoth
Jacob Alber (lokitoth)force-pushed the dev/dotnet_workflow/polymorphic_routing branch from 8e3d6d6 to 8e48befCompareFebruary 10, 2026 10:06
@lokitoth
Jacob Alber (lokitoth)force-pushed the dev/dotnet_workflow/polymorphic_routing branch from 8e48bef to 786d27eCompareFebruary 10, 2026 10:29
@lokitoth
Jacob Alber (lokitoth)force-pushed the dev/dotnet_workflow/polymorphic_routing branch from 786d27e to d95b528CompareFebruary 10, 2026 10:41
@lokitoth
Jacob Alber (lokitoth) marked this pull request as ready for review February 10, 2026 10:53
CopilotAI review requested due to automatic review settings February 10, 2026 10:53
@lokitothJacob Alber (lokitoth) moved this from In Progress to In Review in Agent FrameworkFeb 10, 2026

CopilotAI 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

Implements polymorphic routing and a new protocol-configuration model for .NET workflows by replacing ConfigureRoutes/ConfigureXYZTypes with a unified ConfigureProtocol + ProtocolBuilder pipeline, and updating runners, executors, generators, tests, and samples accordingly.

Changes:

  • Introduces ProtocolBuilder/extended ProtocolDescriptor and updates executors to declare routes + sent/yielded types via ConfigureProtocol.
  • Updates in-proc execution and edge chasing to support polymorphic routing across checkpoint serialization boundaries.
  • Updates source generator and test/samples to use partial executors and new protocol APIs.

Reviewed changes

Copilot reviewed 76 out of 76 changed files in this pull request and generated 14 comments.

Show a summary per file
FileDescription
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowVisualizerTests.csUpdate test executors to ConfigureProtocol.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/WorkflowBuilderSmokeTests.csUpdate smoke tests to ConfigureProtocol.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestingExecutor.csSwitch to attribute-based handlers.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/TestRunContext.csUse AttachRequestContext API.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/14_Subworkflow_SharedState.csConvert sample executors to generator model.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/09_Subworkflow_ExternalRequest.csAdd protocol declarations + error surfacing.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/08_Subworkflow_Simple.csAdd protocol declarations + error surfacing.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/03_Simple_Workflow_Loop.csReplace reflecting executors with new handlers.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/02_Simple_Workflow_Condition.csFail fast on WorkflowErrorEvent; update executors.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01a_Simple_Workflow_Sequential.csAdd illustrative (commented) workflow builder notes.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Sample/01_Simple_Workflow_Sequential.csUpdate sequential sample executors/protocol usage.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/RepresentationTests.csUpdate protocol description path.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/Microsoft.Agents.AI.Workflows.UnitTests.csprojAdd generator project as analyzer.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/InProcessStateTests.csMake test class partial for generator.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/ForwardMessageExecutor.csDeclare sent types via ProtocolBuilder.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/EdgeRunnerTests.csAdd CancellationToken to edge chase calls.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/DynamicRequestPortTests.csUse AttachRequestContext API.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/DynamicPortsExecutor.csMigrate port handler setup to ConfigureProtocol.
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests/AgentWorkflowBuilderTests.csFail fast on WorkflowErrorEvent.
dotnet/tests/Microsoft.Agents.AI.Workflows.Generators.UnitTests/SyntaxTreeFluentExtensions.csAdd fluent syntax-tree assertions.
dotnet/tests/Microsoft.Agents.AI.Workflows.Generators.UnitTests/ExecutorRouteGeneratorTests.csUpdate generator tests for new output format.
dotnet/tests/Microsoft.Agents.AI.Workflows.Declarative.UnitTests/ObjectModel/WorkflowActionExecutorTest.csRegister sent types for declarative executor.
dotnet/tests/Microsoft.Agents.AI.DevUI.UnitTests/DevUIIntegrationTests.csUpdate test executor to ConfigureProtocol.
dotnet/src/Microsoft.Agents.AI.Workflows/Workflow.csDescribe protocol incl. output executor yields.
dotnet/src/Microsoft.Agents.AI.Workflows/SubworkflowBinding.csPass workflow protocol into host executor.
dotnet/src/Microsoft.Agents.AI.Workflows/StatefulExecutor.csAdd protocol-based routing/type declarations.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/WorkflowHostExecutor.csForward protocol types for subworkflow host.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/RequestInfoExecutor.csDeclare outgoing request/response protocol types.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/OutputMessagesExecutor.csDeclare yielded chat output type.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffsStartExecutor.csUpdate options + declare sent types.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffsEndExecutor.csDeclare yielded messages type.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/HandoffAgentExecutor.csSwitch to typed executor return path.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/GroupChatHost.csMigrate host to ChatProtocolExecutor model.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/ConcurrentEndExecutor.csDeclare yielded chat output type.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIContentExternalHandler.csRefactor to work with ProtocolBuilder.
dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.csUse ProtocolBuilder for external handlers.
dotnet/src/Microsoft.Agents.AI.Workflows/RouteBuilder.csExpose output types for protocol building.
dotnet/src/Microsoft.Agents.AI.Workflows/Reflection/RouteBuilderExtensions.csExpose handler discovery helper.
dotnet/src/Microsoft.Agents.AI.Workflows/Reflection/ReflectingExecutor.csUpdate obsolete reflection executor protocol setup.
dotnet/src/Microsoft.Agents.AI.Workflows/ProtocolDescriptor.csExtend descriptor with Sends/Yields.
dotnet/src/Microsoft.Agents.AI.Workflows/ProtocolBuilder.csNew unified protocol configuration builder.
dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunnerContext.csEnforce declared send/yield types; pass cancellation.
dotnet/src/Microsoft.Agents.AI.Workflows/InProc/InProcessRunner.csTranslate message types via source protocol.
dotnet/src/Microsoft.Agents.AI.Workflows/FunctionExecutor.csAdd outgoing type registration + attributes.
dotnet/src/Microsoft.Agents.AI.Workflows/Executor.csNew protocol model + delayed request context.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/ResponseEdgeRunner.csAdd cancellation + runtime-type-based delivery.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/MessageRouter.csImplement polymorphic handler matching logic.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/FanOutEdgeRunner.csAdd cancellation + runtime-type-based target filtering.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/FanInEdgeState.csGroup released messages by source.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/FanInEdgeRunner.csMap portable types via source protocol translator.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/EdgeRunner.csAdd cancellation + runtime type helper methods.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/EdgeMap.csThread cancellation through edge preparation.
dotnet/src/Microsoft.Agents.AI.Workflows/Execution/DirectEdgeRunner.csUse runtime type for polymorphic delivery.
dotnet/src/Microsoft.Agents.AI.Workflows/Checkpointing/PortableMessageEnvelope.csPersist message source identity.
dotnet/src/Microsoft.Agents.AI.Workflows/ChatProtocolExecutor.csMove chat routing config to protocol builder.
dotnet/src/Microsoft.Agents.AI.Workflows/ChatProtocol.csUpdate chat protocol detection criteria.
dotnet/src/Microsoft.Agents.AI.Workflows/ChatForwardingExecutor.csUpdate forwarding executor protocol declarations.
dotnet/src/Microsoft.Agents.AI.Workflows/Attributes/YieldsOutputAttribute.csAllow method-level output declaration.
dotnet/src/Microsoft.Agents.AI.Workflows/Attributes/SendsMessageAttribute.csAllow method-level send declaration.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Models/MethodAnalysisResult.csRename configure flag to protocol variant.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Models/ExecutorInfo.csSplit generation conditions for Sends/Yields.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Generation/SourceBuilder.csGenerate ConfigureProtocol fluent chains.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/ExecutorRouteGenerator.csCombine IO-only analysis results.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Diagnostics/DiagnosticDescriptors.csRename diagnostic for ConfigureProtocol.
dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Analysis/SemanticAnalyzer.csDetect ConfigureProtocol and base chaining.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/RootExecutor.csRegister ActionExecutorResult as sent type.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Kit/ActionExecutor.csRegister ActionExecutorResult as sent type.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DelegateActionExecutor.csRegister ActionExecutorResult as sent type.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeWorkflowExecutor.csRegister ActionExecutorResult as sent type.
dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/Interpreter/DeclarativeActionExecutor.csRegister ActionExecutorResult as sent type.
dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/Program.csMake executor partial + use [MessageHandler].
dotnet/samples/GettingStarted/Workflows/_Foundational/08_WriterCriticWorkflow/08_WriterCriticWorkflow.csprojAdd generator as analyzer reference.
dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowHelper.csMake helper/executors partial + annotate handlers.
dotnet/samples/GettingStarted/Workflows/Observability/WorkflowAsAnAgent/WorkflowAsAnAgentObservability.csprojAdd generator as analyzer reference.
dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/Program.csMake executor partial + annotate handlers.
dotnet/samples/GettingStarted/Workflows/Agents/CustomAgentExecutors/CustomAgentExecutors.csprojAdd generator as analyzer reference.
Comments suppressed due to low confidence (2)

dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Analysis/SemanticAnalyzer.cs:413

 foreach (var member in classSymbol.GetMembers("ConfigureProtocol"))
{
if (member is IMethodSymbol method && !method.IsAbstract &&
SymbolEqualityComparer.Default.Equals(method.ContainingType, classSymbol))
{
return true;
}
}

dotnet/src/Microsoft.Agents.AI.Workflows.Generators/Analysis/SemanticAnalyzer.cs:440

 foreach (var member in baseType.GetMembers("ConfigureProtocol"))
{
if (member is IMethodSymbol method && !method.IsAbstract)
{
return true;
}
}

Comment threaddotnet/src/Microsoft.Agents.AI.Workflows/Executor.cs
Comment threaddotnet/src/Microsoft.Agents.AI.Workflows/ProtocolBuilder.cs
Comment threaddotnet/src/Microsoft.Agents.AI.Workflows/Execution/MessageRouter.cs Outdated
Comment threaddotnet/src/Microsoft.Agents.AI.Workflows/Execution/MessageRouter.cs Outdated
Comment threaddotnet/src/Microsoft.Agents.AI.Workflows/Executor.cs Outdated
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking changeUsage: [PRs], Target: all PRs that introduce changes that are not backward compatible.NETUsage: [Issues, PRs], Target: .NetworkflowsUsage: [Issues, PRs], Target: Workflows

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

.NET: Reconcile Executor Configure and ConfigureXYZ methods Support for polymorphic routing .NET: Route messages are not handled polymorphically

6 participants

@lokitoth@alliscode@markwallace-microsoft@westey-m@crickman