Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[.Net] Enable step-by-step execution for two-agent conversation SendAsync API #3360

Merged
merged 6 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ You are a helpful AI assistant

await userProxyAgent.SendAsync(
receiver: lmAgent,
"Search the names of the five largest stocks in the US by market cap ");
"Search the names of the five largest stocks in the US by market cap ")
.ToArrayAsync();
#endregion lmstudio_function_call_example
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,7 @@ public static async Task<IAgent> CreateAssistantAgent()
modelName: gpt3Config.DeploymentName,
systemMessage: """You create polite prompt to ask user provide missing information""")
.RegisterMessageConnector()
.RegisterPrintMessage()
.RegisterMiddleware(async (msgs, option, agent, ct) =>
{
var lastReply = msgs.Last() ?? throw new Exception("No reply found.");
var reply = await agent.GenerateReplyAsync(msgs, option, ct);

// if application is complete, exit conversation by sending termination message
if (lastReply.GetContent().Contains("Application information is saved to database."))
{
return new TextMessage(Role.Assistant, GroupChatExtension.TERMINATE, from: agent.Name);
}
else
{
return reply;
}
});
.RegisterPrintMessage();

return chatAgent;
}
Expand Down Expand Up @@ -191,9 +176,13 @@ public static async Task RunAsync()
var groupChatManager = new GroupChatManager(groupChat);
var initialMessage = await assistantAgent.SendAsync("Generate a greeting meesage for user and start the conversation by asking what's their name.");

var chatHistory = await userAgent.SendAsync(groupChatManager, [initialMessage], maxRound: 30);

var lastMessage = chatHistory.Last();
Console.WriteLine(lastMessage.GetContent());
var chatHistory = new List<IMessage> { initialMessage };
await foreach (var msg in userAgent.SendAsync(groupChatManager, chatHistory, maxRound: 30))
{
if (msg.GetContent().ToLower().Contains("application information is saved to database.") is true)
{
break;
}
}
}
}
29 changes: 9 additions & 20 deletions dotnet/sample/AutoGen.BasicSamples/GettingStart/FSM_Group_Chat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,22 +120,7 @@ public static async Task<IAgent> CreateAssistantAgent(OpenAIClient openaiClient,
modelName: model,
systemMessage: """You create polite prompt to ask user provide missing information""")
.RegisterMessageConnector()
.RegisterPrintMessage()
.RegisterMiddleware(async (msgs, option, agent, ct) =>
{
var lastReply = msgs.Last() ?? throw new Exception("No reply found.");
var reply = await agent.GenerateReplyAsync(msgs, option, ct);

// if application is complete, exit conversation by sending termination message
if (lastReply.GetContent()?.Contains("Application information is saved to database.") is true)
{
return new TextMessage(Role.Assistant, GroupChatExtension.TERMINATE, from: agent.Name);
}
else
{
return reply;
}
});
.RegisterPrintMessage();
#endregion Create_Assistant_Agent
return chatAgent;
}
Expand Down Expand Up @@ -193,9 +178,13 @@ public static async Task RunAsync()

var initialMessage = await assistantAgent.SendAsync("Generate a greeting meesage for user and start the conversation by asking what's their name.");

var chatHistory = await userAgent.SendMessageToGroupAsync(groupChat, [initialMessage], maxRound: 30);

var lastMessage = chatHistory.Last();
Console.WriteLine(lastMessage.GetContent());
var chatHistory = new List<IMessage> { initialMessage };
await foreach (var msg in groupChat.SendAsync(chatHistory, maxRound: 30))
{
if (msg.GetContent().ToLower().Contains("application information is saved to database.") is true)
{
break;
}
}
}
}
42 changes: 26 additions & 16 deletions dotnet/src/AutoGen.Core/Extension/AgentExtension.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// AgentExtension.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
Expand Down Expand Up @@ -60,14 +61,14 @@ public static async Task<IMessage> SendAsync(
}

/// <summary>
/// Send message to another agent.
/// Send message to another agent and iterate over the responses.
/// </summary>
/// <param name="agent">sender agent.</param>
/// <param name="receiver">receiver agent.</param>
/// <param name="chatHistory">chat history.</param>
/// <param name="maxRound">max conversation round.</param>
/// <returns>conversation history</returns>
public static async Task<IEnumerable<IMessage>> SendAsync(
public static IAsyncEnumerable<IMessage> SendAsync(
this IAgent agent,
IAgent receiver,
IEnumerable<IMessage> chatHistory,
Expand All @@ -78,29 +79,29 @@ public static async Task<IEnumerable<IMessage>> SendAsync(
{
var gc = manager.GroupChat;

return await agent.SendMessageToGroupAsync(gc, chatHistory, maxRound, ct);
return gc.SendAsync(chatHistory, maxRound, ct);
}

var groupChat = new RoundRobinGroupChat(
agents: new[]
{
agents:
[
agent,
receiver,
});
]);

return await groupChat.CallAsync(chatHistory, maxRound, ct: ct);
return groupChat.SendAsync(chatHistory, maxRound, cancellationToken: ct);
}

/// <summary>
/// Send message to another agent.
/// Send message to another agent and iterate over the responses.
/// </summary>
/// <param name="agent">sender agent.</param>
/// <param name="message">message to send. will be added to the end of <paramref name="chatHistory"/> if provided </param>
/// <param name="receiver">receiver agent.</param>
/// <param name="chatHistory">chat history.</param>
/// <param name="maxRound">max conversation round.</param>
/// <returns>conversation history</returns>
public static async Task<IEnumerable<IMessage>> SendAsync(
public static IAsyncEnumerable<IMessage> SendAsync(
this IAgent agent,
IAgent receiver,
string message,
Expand All @@ -116,11 +117,12 @@ public static async Task<IEnumerable<IMessage>> SendAsync(
chatHistory = chatHistory ?? new List<IMessage>();
chatHistory = chatHistory.Append(msg);

return await agent.SendAsync(receiver, chatHistory, maxRound, ct);
return agent.SendAsync(receiver, chatHistory, maxRound, ct);
}

/// <summary>
/// Shortcut API to send message to another agent.
/// Shortcut API to send message to another agent and get all responses.
/// To iterate over the responses, use <see cref="SendAsync(IAgent, IAgent, string, IEnumerable{IMessage}?, int, CancellationToken)"/> or <see cref="SendAsync(IAgent, IAgent, IEnumerable{IMessage}, int, CancellationToken)"/>
/// </summary>
/// <param name="agent">sender agent</param>
/// <param name="receiver">receiver agent</param>
Expand All @@ -144,10 +146,16 @@ public static async Task<IEnumerable<IMessage>> InitiateChatAsync(
chatHistory.Add(msg);
}

return await agent.SendAsync(receiver, chatHistory, maxRound, ct);
await foreach (var msg in agent.SendAsync(receiver, chatHistory, maxRound, ct))
{
chatHistory.Add(msg);
}

return chatHistory;
}

public static async Task<IEnumerable<IMessage>> SendMessageToGroupAsync(
[Obsolete("use GroupChatExtension.SendAsync")]
public static IAsyncEnumerable<IMessage> SendMessageToGroupAsync(
this IAgent agent,
IGroupChat groupChat,
string msg,
Expand All @@ -159,16 +167,18 @@ public static async Task<IEnumerable<IMessage>> SendMessageToGroupAsync(
chatHistory = chatHistory ?? Enumerable.Empty<IMessage>();
chatHistory = chatHistory.Append(chatMessage);

return await agent.SendMessageToGroupAsync(groupChat, chatHistory, maxRound, ct);
return agent.SendMessageToGroupAsync(groupChat, chatHistory, maxRound, ct);
}

public static async Task<IEnumerable<IMessage>> SendMessageToGroupAsync(
[Obsolete("use GroupChatExtension.SendAsync")]
public static IAsyncEnumerable<IMessage> SendMessageToGroupAsync(
this IAgent _,
IGroupChat groupChat,
IEnumerable<IMessage>? chatHistory = null,
int maxRound = 10,
CancellationToken ct = default)
{
return await groupChat.CallAsync(chatHistory, maxRound, ct);
chatHistory = chatHistory ?? Enumerable.Empty<IMessage>();
return groupChat.SendAsync(chatHistory, maxRound, ct);
}
}
Loading