From b6c0d47b02c8875bd31d6cbe98e9448eb3b68f0f Mon Sep 17 00:00:00 2001 From: hchen Date: Mon, 7 Aug 2023 12:48:09 -0500 Subject: [PATCH] Add onFunctionExecuting to SendMessage. --- .../Conversations/IConversationService.cs | 2 +- .../Conversations/ConversationController.cs | 3 ++ .../Services/ConversationService.cs | 6 ++- .../Providers/ChatCompletionProvider.cs | 13 ++++- .../Controllers/WebhookController.cs | 50 +++++++++++++++++-- .../MessagingModels/SenderActionEnum.cs | 13 +++++ .../MessagingModels/SendingMessageRequest.cs | 3 ++ .../WeChatBackgroundService.cs | 3 ++ 8 files changed, 85 insertions(+), 8 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SenderActionEnum.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 409c5e8e..42de95f7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -8,7 +8,7 @@ public interface IConversationService Task GetConversation(string id); Task> GetConversations(); Task DeleteConversation(string id); - Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func onMessageReceived); + Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func onMessageReceived, Func onFunctionExecuting); Task SendMessage(string agentId, string conversationId, List wholeDialogs, Func onMessageReceived); List GetDialogHistory(string agentId, string conversationId, int lastCount = 20); Task CleanHistory(string agentId); diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs b/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs index 7d8ae3f9..4c1090f6 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs @@ -51,6 +51,9 @@ public class ConversationController : ControllerBase, IApiAdapter await conv.SendMessage(agentId, conversationId, new RoleDialogModel("user", input.Text), async msg => { response.Text += msg.Content; + }, async fn => + { + }); return response; diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index e09a33f5..7607a634 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -67,7 +67,9 @@ public class ConversationService : IConversationService return record.ToConversation(); } - public async Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, Func onMessageReceived) + public async Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog, + Func onMessageReceived, + Func onFunctionExecuting) { _storage.Append(agentId, conversationId, lastDalog); @@ -81,6 +83,8 @@ public class ConversationService : IConversationService var functions = _services.GetServices().Where(x => x.Name == msg.FunctionName); foreach (var fn in functions) { + await onFunctionExecuting(msg); + msg.ExecutionResult = await fn.Execute(msg.Content); var result = msg.ExecutionResult.Replace("\r", " ").Replace("\n", " "); diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index 49cae228..3b172314 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -5,6 +5,7 @@ using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.MLTasks; using BotSharp.Plugin.AzureOpenAI.Settings; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Text.Json; @@ -15,10 +16,12 @@ namespace BotSharp.Plugin.AzureOpenAI.Providers; public class ChatCompletionProvider : IChatCompletion { private readonly AzureOpenAiSettings _settings; + private readonly ILogger _logger; - public ChatCompletionProvider(AzureOpenAiSettings settings) + public ChatCompletionProvider(AzureOpenAiSettings settings, ILogger logger) { _settings = settings; + _logger = logger; } public string GetChatCompletions(Agent agent, List conversations) @@ -38,6 +41,8 @@ public class ChatCompletionProvider : IChatCompletion output += message.Content; } + _logger.LogInformation(output); + return output.Trim(); } @@ -124,6 +129,9 @@ public class ChatCompletionProvider : IChatCompletion choice = response.Value.Choices[0]; message = choice.Message; + + _logger.LogInformation(message.Content); + await onMessageReceived(new RoleDialogModel(ChatRole.Assistant.ToString(), message.Content)); return true; @@ -161,6 +169,9 @@ public class ChatCompletionProvider : IChatCompletion continue; Console.Write(message.Content); output += message.Content; + + _logger.LogInformation(message.Content); + await onMessageReceived(new RoleDialogModel(message.Role.ToString(), message.Content)); } diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs index 8b07cc42..b666bf07 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/Controllers/WebhookController.cs @@ -14,6 +14,7 @@ using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; +using Refit; namespace BotSharp.Plugin.MetaMessenger.Controllers; @@ -58,7 +59,6 @@ public class WebhookController : ControllerBase // TODO validate request // https://developers.facebook.com/docs/messenger-platform/webhooks#verification-requests - try { // received message @@ -69,10 +69,6 @@ public class WebhookController : ControllerBase string content = ""; var sessionId = req.Entry[0].Messaging[0].Sender.Id; var input = req.Entry[0].Messaging[0].Message.Text; - var result = await conv.SendMessage(agentId, sessionId, new RoleDialogModel("user", input), async msg => - { - content = msg.Content; - }); var setting = _services.GetRequiredService(); var messenger = _services.GetRequiredService(); @@ -80,14 +76,58 @@ public class WebhookController : ControllerBase { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }; + + // Marking seen + /*await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest + { + AccessToken = setting.PageAccessToken, + Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt), + SenderAction = SenderActionEnum.MarkSeen + });*/ + + // Typing on + await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest + { + AccessToken = setting.PageAccessToken, + Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt), + SenderAction = SenderActionEnum.TypingOn + }); + + // Go to LLM + var result = await conv.SendMessage(agentId, sessionId, new RoleDialogModel("user", input), async msg => + { + content = msg.Content; + }, async fn => + { + await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest + { + AccessToken = setting.PageAccessToken, + Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt), + Message = JsonSerializer.Serialize(new { Text = "I'm pulling the relevent information, please wait a second ..." }, jsonOpt) + }); + }); + + // Response to user await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest { AccessToken = setting.PageAccessToken, Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt), Message = JsonSerializer.Serialize(new { Text = content }, jsonOpt) }); + + // Typing off + await messenger.SendMessage(setting.ApiVersion, setting.PageId, new SendingMessageRequest + { + AccessToken = setting.PageAccessToken, + Recipient = JsonSerializer.Serialize(new { Id = sessionId }, jsonOpt), + SenderAction = SenderActionEnum.TypingOff + }); } } + catch (ApiException ex) + { + Console.WriteLine(ex.Content); + } catch (Exception ex) { Console.WriteLine(ex.ToString()); diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SenderActionEnum.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SenderActionEnum.cs new file mode 100644 index 00000000..ad24e33d --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SenderActionEnum.cs @@ -0,0 +1,13 @@ +using System.Runtime.Serialization; + +namespace BotSharp.Plugin.MetaMessenger.MessagingModels; + +public enum SenderActionEnum +{ + [EnumMember(Value = "typing_on")] + TypingOn, + [EnumMember(Value = "typing_off")] + TypingOff, + [EnumMember(Value = "mark_seen")] + MarkSeen +} diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SendingMessageRequest.cs b/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SendingMessageRequest.cs index 1eb33e66..1419856f 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SendingMessageRequest.cs +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/MessagingModels/SendingMessageRequest.cs @@ -24,4 +24,7 @@ public class SendingMessageRequest [AliasAs("messaging_type")] public string MessagingType { get; set; } = "RESPONSE"; + + [AliasAs("sender_action")] + public SenderActionEnum? SenderAction { get; set; } } diff --git a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs index 1b72e2f9..5823e813 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs +++ b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs @@ -59,6 +59,9 @@ namespace BotSharp.Plugin.WeChat var result = await conversationService.SendMessage(AgentId, latestConversationId, new RoleDialogModel("user", message), async msg => { await ReplyTextMessageAsync(openid, msg.Content); + }, async fn => + { + }); }