@@ -15,6 +15,7 @@ public class GroupChat : IGroupChat
15
15
private List < IAgent > agents = new List < IAgent > ( ) ;
16
16
private IEnumerable < IMessage > initializeMessages = new List < IMessage > ( ) ;
17
17
private Graph ? workflow = null ;
18
+ private readonly IOrchestrator orchestrator ;
18
19
19
20
public IEnumerable < IMessage > ? Messages { get ; private set ; }
20
21
@@ -36,6 +37,37 @@ public GroupChat(
36
37
this . initializeMessages = initializeMessages ?? new List < IMessage > ( ) ;
37
38
this . workflow = workflow ;
38
39
40
+ if ( admin is not null )
41
+ {
42
+ this . orchestrator = new RolePlayOrchestrator ( admin , workflow ) ;
43
+ }
44
+ else if ( workflow is not null )
45
+ {
46
+ this . orchestrator = new WorkflowOrchestrator ( workflow ) ;
47
+ }
48
+ else
49
+ {
50
+ this . orchestrator = new RoundRobinOrchestrator ( ) ;
51
+ }
52
+
53
+ this . Validation ( ) ;
54
+ }
55
+
56
+ /// <summary>
57
+ /// Create a group chat which uses the <paramref name="orchestrator"/> to decide the next speaker(s).
58
+ /// </summary>
59
+ /// <param name="members"></param>
60
+ /// <param name="orchestrator"></param>
61
+ /// <param name="initializeMessages"></param>
62
+ public GroupChat (
63
+ IEnumerable < IAgent > members ,
64
+ IOrchestrator orchestrator ,
65
+ IEnumerable < IMessage > ? initializeMessages = null )
66
+ {
67
+ this . agents = members . ToList ( ) ;
68
+ this . initializeMessages = initializeMessages ?? new List < IMessage > ( ) ;
69
+ this . orchestrator = orchestrator ;
70
+
39
71
this . Validation ( ) ;
40
72
}
41
73
@@ -64,12 +96,6 @@ private void Validation()
64
96
throw new Exception ( "All agents in the workflow must be in the group chat." ) ;
65
97
}
66
98
}
67
-
68
- // must provide one of admin or workflow
69
- if ( this . admin == null && this . workflow == null )
70
- {
71
- throw new Exception ( "Must provide one of admin or workflow." ) ;
72
- }
73
99
}
74
100
75
101
/// <summary>
@@ -81,6 +107,7 @@ private void Validation()
81
107
/// <param name="currentSpeaker">current speaker</param>
82
108
/// <param name="conversationHistory">conversation history</param>
83
109
/// <returns>next speaker.</returns>
110
+ [ Obsolete ( "Please use RolePlayOrchestrator or WorkflowOrchestrator" ) ]
84
111
public async Task < IAgent > SelectNextSpeakerAsync ( IAgent currentSpeaker , IEnumerable < IMessage > conversationHistory )
85
112
{
86
113
var agentNames = this . agents . Select ( x => x . Name ) . ToList ( ) ;
@@ -140,37 +167,40 @@ public void AddInitializeMessage(IMessage message)
140
167
}
141
168
142
169
public async Task < IEnumerable < IMessage > > CallAsync (
143
- IEnumerable < IMessage > ? conversationWithName = null ,
170
+ IEnumerable < IMessage > ? chatHistory = null ,
144
171
int maxRound = 10 ,
145
172
CancellationToken ct = default )
146
173
{
147
174
var conversationHistory = new List < IMessage > ( ) ;
148
- if ( conversationWithName != null )
175
+ conversationHistory . AddRange ( this . initializeMessages ) ;
176
+ if ( chatHistory != null )
149
177
{
150
- conversationHistory . AddRange ( conversationWithName ) ;
178
+ conversationHistory . AddRange ( chatHistory ) ;
151
179
}
180
+ var roundLeft = maxRound ;
152
181
153
- var lastSpeaker = conversationHistory . LastOrDefault ( ) ? . From switch
182
+ while ( roundLeft > 0 )
154
183
{
155
- null => this . agents . First ( ) ,
156
- _ => this . agents . FirstOrDefault ( x => x . Name == conversationHistory . Last ( ) . From ) ?? throw new Exception ( "The agent is not in the group chat" ) ,
157
- } ;
158
- var round = 0 ;
159
- while ( round < maxRound )
160
- {
161
- var currentSpeaker = await this . SelectNextSpeakerAsync ( lastSpeaker , conversationHistory ) ;
162
- var processedConversation = this . ProcessConversationForAgent ( this . initializeMessages , conversationHistory ) ;
163
- var result = await currentSpeaker . GenerateReplyAsync ( processedConversation ) ?? throw new Exception ( "No result is returned." ) ;
184
+ var orchestratorContext = new OrchestrationContext
185
+ {
186
+ Candidates = this . agents ,
187
+ ChatHistory = conversationHistory ,
188
+ } ;
189
+ var nextSpeaker = await this . orchestrator . GetNextSpeakerAsync ( orchestratorContext , ct ) ;
190
+ if ( nextSpeaker == null )
191
+ {
192
+ break ;
193
+ }
194
+
195
+ var result = await nextSpeaker . GenerateReplyAsync ( conversationHistory , cancellationToken : ct ) ;
164
196
conversationHistory . Add ( result ) ;
165
197
166
- // if message is terminate message, then terminate the conversation
167
- if ( result ? . IsGroupChatTerminateMessage ( ) ?? false )
198
+ if ( result . IsGroupChatTerminateMessage ( ) )
168
199
{
169
- break ;
200
+ return conversationHistory ;
170
201
}
171
202
172
- lastSpeaker = currentSpeaker ;
173
- round ++ ;
203
+ roundLeft -- ;
174
204
}
175
205
176
206
return conversationHistory ;
0 commit comments