@@ -16,7 +16,7 @@ internal static class WorkflowFactory
1616 internal static Workflow BuildWorkflow ( IChatClient chatClient )
1717 {
1818 // Create executors
19- var startExecutor = new ConcurrentStartExecutor ( ) ;
19+ var startExecutor = new ChatForwardingExecutor ( "Start" ) ;
2020 var aggregationExecutor = new ConcurrentAggregationExecutor ( ) ;
2121 AIAgent frenchAgent = GetLanguageAgent ( "French" , chatClient ) ;
2222 AIAgent englishAgent = GetLanguageAgent ( "English" , chatClient ) ;
@@ -38,34 +38,11 @@ internal static Workflow BuildWorkflow(IChatClient chatClient)
3838 private static ChatClientAgent GetLanguageAgent ( string targetLanguage , IChatClient chatClient ) =>
3939 new ( chatClient , instructions : $ "You're a helpful assistant who always responds in { targetLanguage } .", name : $ "{ targetLanguage } Agent") ;
4040
41- /// <summary>
42- /// Executor that starts the concurrent processing by sending messages to the agents.
43- /// </summary>
44- private sealed class ConcurrentStartExecutor ( ) :
45- Executor < List < ChatMessage > > ( "ConcurrentStartExecutor" )
46- {
47- /// <summary>
48- /// Starts the concurrent processing by sending messages to the agents.
49- /// </summary>
50- /// <param name="message">The user message to process</param>
51- /// <param name="context">Workflow context for accessing workflow services and adding events</param>
52- /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.
53- /// The default is <see cref="CancellationToken.None"/>.</param>
54- public override async ValueTask HandleAsync ( List < ChatMessage > message , IWorkflowContext context , CancellationToken cancellationToken = default )
55- {
56- // Broadcast the message to all connected agents. Receiving agents will queue
57- // the message but will not start processing until they receive a turn token.
58- await context . SendMessageAsync ( message , cancellationToken : cancellationToken ) ;
59- // Broadcast the turn token to kick off the agents.
60- await context . SendMessageAsync ( new TurnToken ( emitEvents : true ) , cancellationToken : cancellationToken ) ;
61- }
62- }
63-
6441 /// <summary>
6542 /// Executor that aggregates the results from the concurrent agents.
6643 /// </summary>
6744 private sealed class ConcurrentAggregationExecutor ( ) :
68- Executor < ChatMessage > ( "ConcurrentAggregationExecutor" )
45+ Executor < ChatMessage > ( "ConcurrentAggregationExecutor" ) , IResettableExecutor
6946 {
7047 private readonly List < ChatMessage > _messages = [ ] ;
7148
@@ -86,5 +63,12 @@ public override async ValueTask HandleAsync(ChatMessage message, IWorkflowContex
8663 await context . YieldOutputAsync ( formattedMessages , cancellationToken ) ;
8764 }
8865 }
66+
67+ /// <inheritdoc/>
68+ public ValueTask ResetAsync ( )
69+ {
70+ this . _messages . Clear ( ) ;
71+ return default ;
72+ }
8973 }
9074}
0 commit comments