Skip to content

Commit e878be5

Browse files
[.Net] refactor over streaming version api (#2461)
* update * update * fix comment
1 parent 4711d7b commit e878be5

39 files changed

+255
-394
lines changed

dotnet/sample/AutoGen.BasicSamples/CodeSnippet/AgentCodeSnippet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public async Task ChatWithAnAgent(IStreamingAgent agent)
1919

2020
#region ChatWithAnAgent_GenerateStreamingReplyAsync
2121
var textMessage = new TextMessage(Role.User, "Hello");
22-
await foreach (var streamingReply in await agent.GenerateStreamingReplyAsync([message]))
22+
await foreach (var streamingReply in agent.GenerateStreamingReplyAsync([message]))
2323
{
2424
if (streamingReply is TextMessageUpdate update)
2525
{

dotnet/sample/AutoGen.BasicSamples/CodeSnippet/BuildInMessageCodeSnippet.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public async Task StreamingCallCodeSnippetAsync()
1111
IStreamingAgent agent = default;
1212
#region StreamingCallCodeSnippet
1313
var helloTextMessage = new TextMessage(Role.User, "Hello");
14-
var reply = await agent.GenerateStreamingReplyAsync([helloTextMessage]);
14+
var reply = agent.GenerateStreamingReplyAsync([helloTextMessage]);
1515
var finalTextMessage = new TextMessage(Role.Assistant, string.Empty, from: agent.Name);
1616
await foreach (var message in reply)
1717
{
@@ -24,7 +24,7 @@ public async Task StreamingCallCodeSnippetAsync()
2424
#endregion StreamingCallCodeSnippet
2525

2626
#region StreamingCallWithFinalMessage
27-
reply = await agent.GenerateStreamingReplyAsync([helloTextMessage]);
27+
reply = agent.GenerateStreamingReplyAsync([helloTextMessage]);
2828
TextMessage finalMessage = null;
2929
await foreach (var message in reply)
3030
{

dotnet/sample/AutoGen.BasicSamples/CodeSnippet/MistralAICodeSnippet.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public async Task CreateMistralAIClientAsync()
3838
#endregion create_mistral_agent
3939

4040
#region streaming_chat
41-
var reply = await agent.GenerateStreamingReplyAsync(
41+
var reply = agent.GenerateStreamingReplyAsync(
4242
messages: [new TextMessage(Role.User, "Hello, how are you?")]
4343
);
4444

@@ -75,7 +75,7 @@ public async Task MistralAIChatAgentGetWeatherToolUsageAsync()
7575
#endregion create_get_weather_function_call_middleware
7676

7777
#region register_function_call_middleware
78-
agent = agent.RegisterMiddleware(functionCallMiddleware);
78+
agent = agent.RegisterStreamingMiddleware(functionCallMiddleware);
7979
#endregion register_function_call_middleware
8080

8181
#region send_message_with_function_call

dotnet/sample/AutoGen.BasicSamples/CodeSnippet/OpenAICodeSnippet.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public async Task CreateOpenAIChatAgentAsync()
6060
#endregion create_openai_chat_agent
6161

6262
#region create_openai_chat_agent_streaming
63-
var streamingReply = await openAIChatAgent.GenerateStreamingReplyAsync(new[] { chatMessageContent });
63+
var streamingReply = openAIChatAgent.GenerateStreamingReplyAsync(new[] { chatMessageContent });
6464

6565
await foreach (var streamingMessage in streamingReply)
6666
{
@@ -123,7 +123,7 @@ public async Task OpenAIChatAgentGetWeatherFunctionCallAsync()
123123
{ functions.GetWeatherFunctionContract.Name, functions.GetWeatherWrapper } // GetWeatherWrapper is a wrapper function for GetWeather, which is also auto-generated
124124
});
125125

126-
openAIChatAgent = openAIChatAgent.RegisterMiddleware(functionCallMiddleware);
126+
openAIChatAgent = openAIChatAgent.RegisterStreamingMiddleware(functionCallMiddleware);
127127
#endregion create_function_call_middleware
128128

129129
#region chat_agent_send_function_call

dotnet/sample/AutoGen.BasicSamples/CodeSnippet/SemanticKernelCodeSnippet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public async Task CreateSemanticKernelAgentAsync()
4949
#endregion create_semantic_kernel_agent
5050

5151
#region create_semantic_kernel_agent_streaming
52-
var streamingReply = await semanticKernelAgent.GenerateStreamingReplyAsync(new[] { chatMessageContent });
52+
var streamingReply = semanticKernelAgent.GenerateStreamingReplyAsync(new[] { chatMessageContent });
5353

5454
await foreach (var streamingMessage in streamingReply)
5555
{

dotnet/sample/AutoGen.BasicSamples/Example02_TwoAgent_MathChat.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@ public static async Task RunAsync()
1818
var teacher = new AssistantAgent(
1919
name: "teacher",
2020
systemMessage: @"You are a teacher that create pre-school math question for student and check answer.
21-
If the answer is correct, you terminate conversation by saying [TERMINATE].
21+
If the answer is correct, you stop the conversation by saying [COMPLETE].
2222
If the answer is wrong, you ask student to fix it.",
2323
llmConfig: new ConversableAgentConfig
2424
{
2525
Temperature = 0,
2626
ConfigList = [gpt35],
2727
})
28-
.RegisterPostProcess(async (_, reply, _) =>
28+
.RegisterMiddleware(async (msgs, option, agent, _) =>
2929
{
30-
if (reply.GetContent()?.ToLower().Contains("terminate") is true)
30+
var reply = await agent.GenerateReplyAsync(msgs, option);
31+
if (reply.GetContent()?.ToLower().Contains("complete") is true)
3132
{
3233
return new TextMessage(Role.Assistant, GroupChatExtension.TERMINATE, from: reply.From);
3334
}

dotnet/sample/AutoGen.BasicSamples/Example07_Dynamic_GroupChat_Calculate_Fibonacci.cs

+6-15
Original file line numberDiff line numberDiff line change
@@ -85,26 +85,16 @@ public static async Task<IAgent> CreateRunnerAgentAsync(InteractiveService servi
8585
systemMessage: "You run dotnet code",
8686
defaultReply: "No code available.")
8787
.RegisterDotnetCodeBlockExectionHook(interactiveService: service)
88-
.RegisterReply(async (msgs, _) =>
88+
.RegisterMiddleware(async (msgs, option, agent, _) =>
8989
{
90-
if (msgs.Count() == 0)
90+
if (msgs.Count() == 0 || msgs.All(msg => msg.From != "coder"))
9191
{
9292
return new TextMessage(Role.Assistant, "No code available. Coder please write code");
9393
}
94-
95-
return null;
96-
})
97-
.RegisterPreProcess(async (msgs, _) =>
98-
{
99-
// retrieve the most recent message from coder
100-
var coderMsg = msgs.LastOrDefault(msg => msg.From == "coder");
101-
if (coderMsg is null)
102-
{
103-
return Enumerable.Empty<IMessage>();
104-
}
10594
else
10695
{
107-
return new[] { coderMsg };
96+
var coderMsg = msgs.Last(msg => msg.From == "coder");
97+
return await agent.GenerateReplyAsync([coderMsg], option);
10898
}
10999
})
110100
.RegisterPrintMessage();
@@ -122,8 +112,9 @@ public static async Task<IAgent> CreateAdminAsync()
122112
systemMessage: "You are group admin, terminate the group chat once task is completed by saying [TERMINATE] plus the final answer",
123113
temperature: 0,
124114
config: gpt3Config)
125-
.RegisterPostProcess(async (_, reply, _) =>
115+
.RegisterMiddleware(async (msgs, option, agent, _) =>
126116
{
117+
var reply = await agent.GenerateReplyAsync(msgs, option);
127118
if (reply is TextMessage textMessage && textMessage.Content.Contains("TERMINATE") is true)
128119
{
129120
var content = $"{textMessage.Content}\n\n {GroupChatExtension.TERMINATE}";

dotnet/sample/AutoGen.BasicSamples/Example10_SemanticKernel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static async Task RunAsync()
6262
Console.WriteLine((reply as IMessage<ChatMessageContent>).Content.Items[0].As<TextContent>().Text);
6363

6464
var skAgentWithMiddleware = skAgent
65-
.RegisterMessageConnector()
65+
.RegisterMessageConnector() // Register the message connector to support more AutoGen built-in message types
6666
.RegisterPrintMessage();
6767

6868
// Now the skAgentWithMiddleware supports more IMessage types like TextMessage, ImageMessage or MultiModalMessage

dotnet/sample/AutoGen.BasicSamples/Example13_OpenAIAgent_JsonMode.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public static async Task RunAsync()
2828
systemMessage: "You are a helpful assistant designed to output JSON.",
2929
seed: 0, // explicitly set a seed to enable deterministic output
3030
responseFormat: ChatCompletionsResponseFormat.JsonObject) // set response format to JSON object to enable JSON mode
31-
.RegisterMessageConnector();
31+
.RegisterMessageConnector()
32+
.RegisterPrintMessage();
3233
#endregion create_agent
3334

3435
#region chat_with_agent
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Program.cs
33

4-
using AutoGen.BasicSample;
5-
await Example14_MistralClientAgent_TokenCount.RunAsync();
4+
await Example02_TwoAgent_MathChat.RunAsync();

dotnet/src/AutoGen.Core/Agent/IMiddlewareAgent.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public interface IMiddlewareAgent : IAgent
2323
void Use(IMiddleware middleware);
2424
}
2525

26-
public interface IMiddlewareStreamAgent : IMiddlewareAgent, IStreamingAgent
26+
public interface IMiddlewareStreamAgent : IStreamingAgent
2727
{
2828
/// <summary>
2929
/// Get the inner agent.
@@ -44,7 +44,11 @@ public interface IMiddlewareAgent<out T> : IMiddlewareAgent
4444
T TAgent { get; }
4545
}
4646

47-
public interface IMiddlewareStreamAgent<out T> : IMiddlewareStreamAgent, IMiddlewareAgent<T>
47+
public interface IMiddlewareStreamAgent<out T> : IMiddlewareStreamAgent
4848
where T : IStreamingAgent
4949
{
50+
/// <summary>
51+
/// Get the typed inner agent.
52+
/// </summary>
53+
T TStreamingAgent { get; }
5054
}

dotnet/src/AutoGen.Core/Agent/IStreamingAgent.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System.Collections.Generic;
55
using System.Threading;
6-
using System.Threading.Tasks;
76

87
namespace AutoGen.Core;
98

@@ -12,7 +11,7 @@ namespace AutoGen.Core;
1211
/// </summary>
1312
public interface IStreamingAgent : IAgent
1413
{
15-
public Task<IAsyncEnumerable<IStreamingMessage>> GenerateStreamingReplyAsync(
14+
public IAsyncEnumerable<IStreamingMessage> GenerateStreamingReplyAsync(
1615
IEnumerable<IMessage> messages,
1716
GenerateReplyOptions? options = null,
1817
CancellationToken cancellationToken = default);

dotnet/src/AutoGen.Core/Agent/MiddlewareAgent.cs

+15-11
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,25 @@ namespace AutoGen.Core;
1414
/// </summary>
1515
public class MiddlewareAgent : IMiddlewareAgent
1616
{
17-
private readonly IAgent _agent;
17+
private IAgent _agent;
1818
private readonly List<IMiddleware> middlewares = new();
1919

2020
/// <summary>
2121
/// Create a new instance of <see cref="MiddlewareAgent"/>
2222
/// </summary>
2323
/// <param name="innerAgent">the inner agent where middleware will be added.</param>
2424
/// <param name="name">the name of the agent if provided. Otherwise, the name of <paramref name="innerAgent"/> will be used.</param>
25-
public MiddlewareAgent(IAgent innerAgent, string? name = null)
25+
public MiddlewareAgent(IAgent innerAgent, string? name = null, IEnumerable<IMiddleware>? middlewares = null)
2626
{
2727
this.Name = name ?? innerAgent.Name;
2828
this._agent = innerAgent;
29+
if (middlewares != null && middlewares.Any())
30+
{
31+
foreach (var middleware in middlewares)
32+
{
33+
this.Use(middleware);
34+
}
35+
}
2936
}
3037

3138
/// <summary>
@@ -55,13 +62,7 @@ public Task<IMessage> GenerateReplyAsync(
5562
GenerateReplyOptions? options = null,
5663
CancellationToken cancellationToken = default)
5764
{
58-
IAgent agent = this._agent;
59-
foreach (var middleware in this.middlewares)
60-
{
61-
agent = new DelegateAgent(middleware, agent);
62-
}
63-
64-
return agent.GenerateReplyAsync(messages, options, cancellationToken);
65+
return _agent.GenerateReplyAsync(messages, options, cancellationToken);
6566
}
6667

6768
/// <summary>
@@ -71,15 +72,18 @@ public Task<IMessage> GenerateReplyAsync(
7172
/// </summary>
7273
public void Use(Func<IEnumerable<IMessage>, GenerateReplyOptions?, IAgent, CancellationToken, Task<IMessage>> func, string? middlewareName = null)
7374
{
74-
this.middlewares.Add(new DelegateMiddleware(middlewareName, async (context, agent, cancellationToken) =>
75+
var middleware = new DelegateMiddleware(middlewareName, async (context, agent, cancellationToken) =>
7576
{
7677
return await func(context.Messages, context.Options, agent, cancellationToken);
77-
}));
78+
});
79+
80+
this.Use(middleware);
7881
}
7982

8083
public void Use(IMiddleware middleware)
8184
{
8285
this.middlewares.Add(middleware);
86+
_agent = new DelegateAgent(middleware, _agent);
8387
}
8488

8589
public override string ToString()

0 commit comments

Comments
 (0)