.NET: [BREAKING] Implement Polymorphic Routing (#3792)

* feat: Implement Polymorphic Routing

* feat: Add support for Send/Yield annotations with basic Executor

* Adds annotations to Declarative workflow executors

* fix: Address PR Comments

* Implicit filter in collection loops
* Remove debug / usused / superfluous code
* Fix ProtocolBuilder implicit output registrations
* Fix logic error in ExecuteRouteGeneratorTests.ClassWithManualConfigureProtocol_DoesNotGenerate

* fix: Solidify type checks and send/yield type registrations

* fix: Suppress generation of TurnTokens out of AggregateTurnMessagesExecutor

* Fixes an issue where ConcurrentEndExecutor is not expecting TurnTokens.

* fix: Add ProtocolBuilder support for chained-delegation

* Updates Declarative pacakge to rely on chained-delegation Send/Yield registration
* Renames DeclarativeActionExectuor's new ExecuteAsync to ExecuteActionAsync to avoid colliding with Executor.ExecutoeAsync

* fix: Address PR Comments

* Fixes type mapping in FanInEdgeRunner
* Fixes and expalins send/yield type registration in FunctionExecutor

* fixup: build-break

* fix: Add missing SendsMesage declaration to InvokeAzureAgentExecutor
This commit is contained in:
Jacob Alber
2026-02-19 14:09:03 +00:00
committed by GitHub
parent b05fc9e849
commit 6a3d22598f
82 changed files with 1581 additions and 819 deletions
@@ -11,7 +11,7 @@ namespace Microsoft.Agents.AI.Workflows.Generators.Models;
/// <param name="GenericParameters">The generic type parameters of the class (e.g., "&lt;T, U&gt;"), or null if not generic.</param>
/// <param name="IsNested">Whether the class is nested inside another class.</param>
/// <param name="ContainingTypeChain">The chain of containing types for nested classes (e.g., "OuterClass.InnerClass"). Empty string if not nested.</param>
/// <param name="BaseHasConfigureRoutes">Whether the base class has a ConfigureRoutes method that should be called.</param>
/// <param name="BaseHasConfigureProtocol">Whether the base class has a ConfigureRoutes method that should be called.</param>
/// <param name="Handlers">The list of handler methods to register.</param>
/// <param name="ClassSendTypes">The types declared via class-level [SendsMessage] attributes.</param>
/// <param name="ClassYieldTypes">The types declared via class-level [YieldsOutput] attributes.</param>
@@ -21,19 +21,20 @@ internal sealed record ExecutorInfo(
string? GenericParameters,
bool IsNested,
string ContainingTypeChain,
bool BaseHasConfigureRoutes,
bool BaseHasConfigureProtocol,
ImmutableEquatableArray<HandlerInfo> Handlers,
ImmutableEquatableArray<string> ClassSendTypes,
ImmutableEquatableArray<string> ClassYieldTypes)
{
/// <summary>
/// Gets whether any protocol type overrides should be generated.
/// Gets whether any "Sent" message type registrations should be generated.
/// </summary>
public bool ShouldGenerateProtocolOverrides =>
!this.ClassSendTypes.IsEmpty ||
!this.ClassYieldTypes.IsEmpty ||
this.HasHandlerWithSendTypes ||
this.HasHandlerWithYieldTypes;
public bool ShouldGenerateSentMessageRegistrations => !this.ClassSendTypes.IsEmpty || this.HasHandlerWithSendTypes;
/// <summary>
/// Gets whether any "Yielded" output type registrations should be generated.
/// </summary>
public bool ShouldGenerateYieldedOutputRegistrations => !this.ClassYieldTypes.IsEmpty || this.HasHandlerWithYieldTypes;
/// <summary>
/// Gets whether any handler has explicit Send types.
@@ -22,7 +22,7 @@ internal sealed record MethodAnalysisResult(
string? GenericParameters,
bool IsNested,
string ContainingTypeChain,
bool BaseHasConfigureRoutes,
bool BaseHasConfigureProtocol,
ImmutableEquatableArray<string> ClassSendTypes,
ImmutableEquatableArray<string> ClassYieldTypes,