3
3
4
4
using System . Text ;
5
5
using System . Text . Json ;
6
- using AutoGen ;
7
6
using AutoGen . BasicSample ;
8
7
using AutoGen . Core ;
9
8
using AutoGen . DotnetInteractive ;
10
9
using AutoGen . OpenAI ;
11
10
using AutoGen . OpenAI . Extension ;
11
+ using Azure . AI . OpenAI ;
12
12
using FluentAssertions ;
13
13
14
14
public partial class Example07_Dynamic_GroupChat_Calculate_Fibonacci
@@ -49,10 +49,11 @@ public async Task<string> ReviewCodeBlock(
49
49
#endregion reviewer_function
50
50
51
51
#region create_coder
52
- public static async Task < IAgent > CreateCoderAgentAsync ( )
52
+ public static async Task < IAgent > CreateCoderAgentAsync ( OpenAIClient client , string deployModel )
53
53
{
54
- var gpt3Config = LLMConfiguration . GetAzureOpenAIGPT3_5_Turbo ( ) ;
55
- var coder = new GPTAgent (
54
+ var coder = new OpenAIChatAgent (
55
+ openAIClient : client ,
56
+ modelName : deployModel ,
56
57
name : "coder" ,
57
58
systemMessage : @"You act as dotnet coder, you write dotnet code to resolve task. Once you finish writing code, ask runner to run the code for you.
58
59
@@ -70,8 +71,8 @@ public static async Task<IAgent> CreateCoderAgentAsync()
70
71
```
71
72
72
73
If your code is incorrect, runner will tell you the error message. Fix the error and send the code again." ,
73
- config : gpt3Config ,
74
74
temperature : 0.4f )
75
+ . RegisterMessageConnector ( )
75
76
. RegisterPrintMessage ( ) ;
76
77
77
78
return coder ;
@@ -81,9 +82,8 @@ public static async Task<IAgent> CreateCoderAgentAsync()
81
82
#region create_runner
82
83
public static async Task < IAgent > CreateRunnerAgentAsync ( InteractiveService service )
83
84
{
84
- var runner = new AssistantAgent (
85
+ var runner = new DefaultReplyAgent (
85
86
name : "runner" ,
86
- systemMessage : "You run dotnet code" ,
87
87
defaultReply : "No code available." )
88
88
. RegisterDotnetCodeBlockExectionHook ( interactiveService : service )
89
89
. RegisterMiddleware ( async ( msgs , option , agent , _ ) =>
@@ -105,45 +105,38 @@ public static async Task<IAgent> CreateRunnerAgentAsync(InteractiveService servi
105
105
#endregion create_runner
106
106
107
107
#region create_admin
108
- public static async Task < IAgent > CreateAdminAsync ( )
108
+ public static async Task < IAgent > CreateAdminAsync ( OpenAIClient client , string deployModel )
109
109
{
110
- var gpt3Config = LLMConfiguration . GetAzureOpenAIGPT3_5_Turbo ( ) ;
111
- var admin = new GPTAgent (
110
+ var admin = new OpenAIChatAgent (
111
+ openAIClient : client ,
112
+ modelName : deployModel ,
112
113
name : "admin" ,
113
- systemMessage : "You are group admin, terminate the group chat once task is completed by saying [TERMINATE] plus the final answer" ,
114
- temperature : 0 ,
115
- config : gpt3Config )
116
- . RegisterMiddleware ( async ( msgs , option , agent , _ ) =>
117
- {
118
- var reply = await agent . GenerateReplyAsync ( msgs , option ) ;
119
- if ( reply is TextMessage textMessage && textMessage . Content . Contains ( "TERMINATE" ) is true )
120
- {
121
- var content = $ "{ textMessage . Content } \n \n { GroupChatExtension . TERMINATE } ";
122
-
123
- return new TextMessage ( Role . Assistant , content , from : reply . From ) ;
124
- }
125
-
126
- return reply ;
127
- } ) ;
114
+ temperature : 0 )
115
+ . RegisterMessageConnector ( )
116
+ . RegisterPrintMessage ( ) ;
128
117
129
118
return admin ;
130
119
}
131
120
#endregion create_admin
132
121
133
122
#region create_reviewer
134
- public static async Task < IAgent > CreateReviewerAgentAsync ( )
123
+ public static async Task < IAgent > CreateReviewerAgentAsync ( OpenAIClient openAIClient , string deployModel )
135
124
{
136
125
var gpt3Config = LLMConfiguration . GetAzureOpenAIGPT3_5_Turbo ( ) ;
137
126
var functions = new Example07_Dynamic_GroupChat_Calculate_Fibonacci ( ) ;
138
- var reviewer = new GPTAgent (
139
- name : "code_reviewer" ,
140
- systemMessage : @"You review code block from coder" ,
141
- config : gpt3Config ,
142
- functions : [ functions . ReviewCodeBlockFunctionContract . ToOpenAIFunctionDefinition ( ) ] ,
127
+ var functionCallMiddleware = new FunctionCallMiddleware (
128
+ functions : [ functions . ReviewCodeBlockFunctionContract ] ,
143
129
functionMap : new Dictionary < string , Func < string , Task < string > > > ( )
144
130
{
145
- { nameof ( ReviewCodeBlock ) , functions . ReviewCodeBlockWrapper } ,
146
- } )
131
+ { nameof ( functions . ReviewCodeBlock ) , functions . ReviewCodeBlockWrapper } ,
132
+ } ) ;
133
+ var reviewer = new OpenAIChatAgent (
134
+ openAIClient : openAIClient ,
135
+ name : "code_reviewer" ,
136
+ systemMessage : @"You review code block from coder" ,
137
+ modelName : deployModel )
138
+ . RegisterMessageConnector ( )
139
+ . RegisterStreamingMiddleware ( functionCallMiddleware )
147
140
. RegisterMiddleware ( async ( msgs , option , innerAgent , ct ) =>
148
141
{
149
142
var maxRetry = 3 ;
@@ -229,16 +222,19 @@ public static async Task RunWorkflowAsync()
229
222
Directory . CreateDirectory ( workDir ) ;
230
223
}
231
224
225
+ var config = LLMConfiguration . GetAzureOpenAIGPT3_5_Turbo ( ) ;
226
+ var openaiClient = new OpenAIClient ( new Uri ( config . Endpoint ) , new Azure . AzureKeyCredential ( config . ApiKey ) ) ;
227
+
232
228
using var service = new InteractiveService ( workDir ) ;
233
229
var dotnetInteractiveFunctions = new DotnetInteractiveFunction ( service ) ;
234
230
235
231
await service . StartAsync ( workDir , default ) ;
236
232
237
233
#region create_workflow
238
- var reviewer = await CreateReviewerAgentAsync ( ) ;
239
- var coder = await CreateCoderAgentAsync ( ) ;
234
+ var reviewer = await CreateReviewerAgentAsync ( openaiClient , config . DeploymentName ) ;
235
+ var coder = await CreateCoderAgentAsync ( openaiClient , config . DeploymentName ) ;
240
236
var runner = await CreateRunnerAgentAsync ( service ) ;
241
- var admin = await CreateAdminAsync ( ) ;
237
+ var admin = await CreateAdminAsync ( openaiClient , config . DeploymentName ) ;
242
238
243
239
var admin2CoderTransition = Transition . Create ( admin , coder ) ;
244
240
var coder2ReviewerTransition = Transition . Create ( coder , reviewer ) ;
@@ -335,39 +331,42 @@ public static async Task RunAsync()
335
331
Directory . CreateDirectory ( workDir ) ;
336
332
}
337
333
334
+ var config = LLMConfiguration . GetAzureOpenAIGPT3_5_Turbo ( ) ;
335
+ var openaiClient = new OpenAIClient ( new Uri ( config . Endpoint ) , new Azure . AzureKeyCredential ( config . ApiKey ) ) ;
336
+
338
337
using var service = new InteractiveService ( workDir ) ;
339
338
var dotnetInteractiveFunctions = new DotnetInteractiveFunction ( service ) ;
340
339
341
340
await service . StartAsync ( workDir , default ) ;
342
341
#region create_group_chat
343
- var reviewer = await CreateReviewerAgentAsync ( ) ;
344
- var coder = await CreateCoderAgentAsync ( ) ;
342
+ var reviewer = await CreateReviewerAgentAsync ( openaiClient , config . DeploymentName ) ;
343
+ var coder = await CreateCoderAgentAsync ( openaiClient , config . DeploymentName ) ;
345
344
var runner = await CreateRunnerAgentAsync ( service ) ;
346
- var admin = await CreateAdminAsync ( ) ;
345
+ var admin = await CreateAdminAsync ( openaiClient , config . DeploymentName ) ;
347
346
var groupChat = new GroupChat (
348
347
admin : admin ,
349
348
members :
350
349
[
351
- admin ,
352
350
coder ,
353
351
runner ,
354
352
reviewer ,
355
353
] ) ;
356
354
357
- admin . SendIntroduction ( "Welcome to my group, work together to resolve my task" , groupChat ) ;
358
355
coder . SendIntroduction ( "I will write dotnet code to resolve task" , groupChat ) ;
359
356
reviewer . SendIntroduction ( "I will review dotnet code" , groupChat ) ;
360
357
runner . SendIntroduction ( "I will run dotnet code once the review is done" , groupChat ) ;
361
358
362
- var groupChatManager = new GroupChatManager ( groupChat ) ;
363
- var conversationHistory = await admin . InitiateChatAsync ( groupChatManager , "What's the 39th of fibonacci number?" , maxRound : 10 ) ;
364
-
365
- // the last message is from admin, which is the termination message
366
- var lastMessage = conversationHistory . Last ( ) ;
367
- lastMessage . From . Should ( ) . Be ( "admin" ) ;
368
- lastMessage . IsGroupChatTerminateMessage ( ) . Should ( ) . BeTrue ( ) ;
369
- lastMessage . Should ( ) . BeOfType < TextMessage > ( ) ;
370
- lastMessage . GetContent ( ) . Should ( ) . Contain ( the39thFibonacciNumber . ToString ( ) ) ;
359
+ var task = "What's the 39th of fibonacci number?" ;
360
+ var taskMessage = new TextMessage ( Role . User , task ) ;
361
+ await foreach ( var message in groupChat . SendAsync ( [ taskMessage ] , maxRound : 10 ) )
362
+ {
363
+ // teminate chat if message is from runner and run successfully
364
+ if ( message . From == "runner" && message . GetContent ( ) . Contains ( the39thFibonacciNumber . ToString ( ) ) )
365
+ {
366
+ Console . WriteLine ( $ "The 39th of fibonacci number is { the39thFibonacciNumber } ") ;
367
+ break ;
368
+ }
369
+ }
371
370
#endregion create_group_chat
372
371
}
373
372
}
0 commit comments