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

* return iasync iterator in sendasync function

* fix build error
This commit is contained in:
Xiaoyun Zhang 2024-08-19 22:34:04 -07:00 committed by GitHub
parent 77ae3c09a5
commit 00aed2e3ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 65 deletions

View File

@ -122,13 +122,12 @@ public class Anthropic_Agent_With_Prompt_Caching
new ChatMessage("user", [TextContent.CreateTextWithCacheControl(LongStory)]), new ChatMessage("user", [TextContent.CreateTextWithCacheControl(LongStory)]),
from: "user"); from: "user");
var history = var chatHistory = new List<IMessage>()
await userProxyAgent.SendMessageToGroupAsync {
(groupChat, new TextMessage(Role.User, "translate this text for me", from: userProxyAgent.Name),
"translate this text for me", messageEnvelope,
new List<IMessage>() };
{
messageEnvelope var history = await groupChat.SendAsync(chatHistory).ToArrayAsync();
});
} }
} }

View File

@ -130,7 +130,8 @@ You have access to the following functions. Use them if required:
await userProxyAgent.SendAsync( await userProxyAgent.SendAsync(
receiver: lmAgent, 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 #endregion lmstudio_function_call_example
} }
} }

View File

@ -120,22 +120,7 @@ public partial class TwoAgent_Fill_Application
modelName: gpt3Config.DeploymentName, modelName: gpt3Config.DeploymentName,
systemMessage: """You create polite prompt to ask user provide missing information""") systemMessage: """You create polite prompt to ask user provide missing information""")
.RegisterMessageConnector() .RegisterMessageConnector()
.RegisterPrintMessage() .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;
}
});
return chatAgent; return chatAgent;
} }
@ -191,9 +176,13 @@ public partial class TwoAgent_Fill_Application
var groupChatManager = new GroupChatManager(groupChat); 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 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 chatHistory = new List<IMessage> { initialMessage };
await foreach (var msg in userAgent.SendAsync(groupChatManager, chatHistory, maxRound: 30))
var lastMessage = chatHistory.Last(); {
Console.WriteLine(lastMessage.GetContent()); if (msg.GetContent().ToLower().Contains("application information is saved to database.") is true)
{
break;
}
}
} }
} }

View File

@ -120,22 +120,7 @@ public class FSM_Group_Chat
modelName: model, modelName: model,
systemMessage: """You create polite prompt to ask user provide missing information""") systemMessage: """You create polite prompt to ask user provide missing information""")
.RegisterMessageConnector() .RegisterMessageConnector()
.RegisterPrintMessage() .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;
}
});
#endregion Create_Assistant_Agent #endregion Create_Assistant_Agent
return chatAgent; return chatAgent;
} }
@ -193,9 +178,13 @@ public class FSM_Group_Chat
var initialMessage = await assistantAgent.SendAsync("Generate a greeting meesage for user and start the conversation by asking what's their name."); 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 chatHistory = new List<IMessage> { initialMessage };
await foreach (var msg in groupChat.SendAsync(chatHistory, maxRound: 30))
var lastMessage = chatHistory.Last(); {
Console.WriteLine(lastMessage.GetContent()); if (msg.GetContent().ToLower().Contains("application information is saved to database.") is true)
{
break;
}
}
} }
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// AgentExtension.cs // AgentExtension.cs
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -60,14 +61,14 @@ public static class AgentExtension
} }
/// <summary> /// <summary>
/// Send message to another agent. /// Send message to another agent and iterate over the responses.
/// </summary> /// </summary>
/// <param name="agent">sender agent.</param> /// <param name="agent">sender agent.</param>
/// <param name="receiver">receiver agent.</param> /// <param name="receiver">receiver agent.</param>
/// <param name="chatHistory">chat history.</param> /// <param name="chatHistory">chat history.</param>
/// <param name="maxRound">max conversation round.</param> /// <param name="maxRound">max conversation round.</param>
/// <returns>conversation history</returns> /// <returns>conversation history</returns>
public static async Task<IEnumerable<IMessage>> SendAsync( public static IAsyncEnumerable<IMessage> SendAsync(
this IAgent agent, this IAgent agent,
IAgent receiver, IAgent receiver,
IEnumerable<IMessage> chatHistory, IEnumerable<IMessage> chatHistory,
@ -78,21 +79,21 @@ public static class AgentExtension
{ {
var gc = manager.GroupChat; var gc = manager.GroupChat;
return await agent.SendMessageToGroupAsync(gc, chatHistory, maxRound, ct); return gc.SendAsync(chatHistory, maxRound, ct);
} }
var groupChat = new RoundRobinGroupChat( var groupChat = new RoundRobinGroupChat(
agents: new[] agents:
{ [
agent, agent,
receiver, receiver,
}); ]);
return await groupChat.CallAsync(chatHistory, maxRound, ct: ct); return groupChat.SendAsync(chatHistory, maxRound, cancellationToken: ct);
} }
/// <summary> /// <summary>
/// Send message to another agent. /// Send message to another agent and iterate over the responses.
/// </summary> /// </summary>
/// <param name="agent">sender agent.</param> /// <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="message">message to send. will be added to the end of <paramref name="chatHistory"/> if provided </param>
@ -100,7 +101,7 @@ public static class AgentExtension
/// <param name="chatHistory">chat history.</param> /// <param name="chatHistory">chat history.</param>
/// <param name="maxRound">max conversation round.</param> /// <param name="maxRound">max conversation round.</param>
/// <returns>conversation history</returns> /// <returns>conversation history</returns>
public static async Task<IEnumerable<IMessage>> SendAsync( public static IAsyncEnumerable<IMessage> SendAsync(
this IAgent agent, this IAgent agent,
IAgent receiver, IAgent receiver,
string message, string message,
@ -116,11 +117,12 @@ public static class AgentExtension
chatHistory = chatHistory ?? new List<IMessage>(); chatHistory = chatHistory ?? new List<IMessage>();
chatHistory = chatHistory.Append(msg); chatHistory = chatHistory.Append(msg);
return await agent.SendAsync(receiver, chatHistory, maxRound, ct); return agent.SendAsync(receiver, chatHistory, maxRound, ct);
} }
/// <summary> /// <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> /// </summary>
/// <param name="agent">sender agent</param> /// <param name="agent">sender agent</param>
/// <param name="receiver">receiver agent</param> /// <param name="receiver">receiver agent</param>
@ -144,10 +146,16 @@ public static class AgentExtension
chatHistory.Add(msg); 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, this IAgent agent,
IGroupChat groupChat, IGroupChat groupChat,
string msg, string msg,
@ -159,16 +167,18 @@ public static class AgentExtension
chatHistory = chatHistory ?? Enumerable.Empty<IMessage>(); chatHistory = chatHistory ?? Enumerable.Empty<IMessage>();
chatHistory = chatHistory.Append(chatMessage); 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 _, this IAgent _,
IGroupChat groupChat, IGroupChat groupChat,
IEnumerable<IMessage>? chatHistory = null, IEnumerable<IMessage>? chatHistory = null,
int maxRound = 10, int maxRound = 10,
CancellationToken ct = default) CancellationToken ct = default)
{ {
return await groupChat.CallAsync(chatHistory, maxRound, ct); chatHistory = chatHistory ?? Enumerable.Empty<IMessage>();
return groupChat.SendAsync(chatHistory, maxRound, ct);
} }
} }