From 6a2343c75779a45be1380518c6465e6f0cef049c Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Sat, 11 Nov 2023 23:16:52 -0600 Subject: [PATCH] SignalR --- .../Agents/Enums/AgentRole.cs | 14 +++ .../BotSharp.Abstraction/Planning/IPlaner.cs | 1 + .../BotSharp.OpenAPI/BotSharp.OpenAPI.csproj | 1 + .../BotSharp.OpenAPI/ChatHub.cs | 47 ++++++++++ .../Controllers/ChatHubController.cs | 85 +++++++++++++++++++ 5 files changed, 148 insertions(+) create mode 100644 src/Infrastructure/BotSharp.OpenAPI/ChatHub.cs create mode 100644 src/Infrastructure/BotSharp.OpenAPI/Controllers/ChatHubController.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentRole.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentRole.cs index f9547d5a..4cab43d6 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentRole.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/Enums/AgentRole.cs @@ -3,7 +3,21 @@ namespace BotSharp.Abstraction.Agents.Enums; public class AgentRole { public const string System = "system"; + + /// + /// AI Assistant + /// public const string Assistant = "assistant"; + + /// + /// Client + /// public const string User = "user"; + public const string Function = "function"; + + /// + /// Customer service representative (CSR) + /// + public const string CSR = "csr"; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Planning/IPlaner.cs b/src/Infrastructure/BotSharp.Abstraction/Planning/IPlaner.cs index c1f3a9d7..3d7996a1 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Planning/IPlaner.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Planning/IPlaner.cs @@ -4,6 +4,7 @@ namespace BotSharp.Abstraction.Planning; /// /// Task breakdown and execution plan +/// https://www.promptingguide.ai/techniques/cot /// public interface IPlaner { diff --git a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj index cef8a0e6..f0de437a 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj +++ b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Infrastructure/BotSharp.OpenAPI/ChatHub.cs b/src/Infrastructure/BotSharp.OpenAPI/ChatHub.cs new file mode 100644 index 00000000..2131a412 --- /dev/null +++ b/src/Infrastructure/BotSharp.OpenAPI/ChatHub.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.SignalR; + +namespace BotSharp.OpenAPI; + +public class ChatHub : Hub +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + private readonly IUserIdentity _user; + + public ChatHub(IServiceProvider services, + ILogger logger, + IUserIdentity user) + { + _services = services; + _logger = logger; + _user = user; + } + + public async Task OnMessageReceivedFromClient(string message) + { + // await Clients.User(_user.Id).SendAsync("ReceiveMessage", message); + } + + /// + /// Received message from client + /// + /// + /// + /// + public async Task SendMessage(string user, string message) + { + // await Clients.User(_user.Id).SendAsync("ReceiveMessage", message); + } + + public async Task SendMessageToCaller(string user, string message) + => await Clients.Caller.SendAsync("ReceiveMessage", user, message); + + public async Task SendMessageToGroup(string user, string message) + => await Clients.Group("SignalR Users").SendAsync("ReceiveMessage", user, message); + + public override Task OnConnectedAsync() + { + Console.WriteLine($"ChatHub: {""} connected in {Context.ConnectionId}"); + return base.OnConnectedAsync(); + } +} diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ChatHubController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ChatHubController.cs new file mode 100644 index 00000000..20d6e807 --- /dev/null +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ChatHubController.cs @@ -0,0 +1,85 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.ApiAdapters; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.OpenAPI.ViewModels.Conversations; +using Microsoft.AspNetCore.SignalR; + +namespace BotSharp.OpenAPI.Controllers; + +[Authorize] +[ApiController] +public class ChatHubController : ControllerBase, IApiAdapter +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + private readonly IHubContext _chatHub; + private readonly IUserIdentity _user; + + public ChatHubController(IServiceProvider services, + ILogger logger, + IHubContext chatHub, + IUserIdentity user) + { + _services = services; + _logger = logger; + _chatHub = chatHub; + _user = user; + } + + [HttpPost("/chat-hub/client/{agentId}/{conversationId}")] + public async Task OnMessageReceivedFromClient([FromRoute] string agentId, + [FromRoute] string conversationId, + [FromBody] NewMessageModel input) + { + var conv = _services.GetRequiredService(); + conv.SetConversationId(conversationId, input.States); + conv.States.SetState("channel", input.Channel); + + var response = new MessageResponseModel(); + var inputMsg = new RoleDialogModel("user", input.Text); + await conv.SendMessage(agentId, inputMsg, + async msg => + { + response.Text = msg.Content; + response.Function = msg.FunctionName; + response.RichContent = msg.RichContent; + response.Instruction = msg.Instruction; + response.Data = msg.Data; + }, + async fnExecuting => + { + + }, + async fnExecuted => + { + + }); + + var state = _services.GetRequiredService(); + response.States = state.GetStates(); + response.MessageId = inputMsg.MessageId; + + // Update console conversation UI for CSR + await _chatHub.Clients.All.SendAsync("OnMessageReceivedFromClient", new RoleDialogModel(AgentRole.User, input.Text) + { + + }); + + await _chatHub.Clients.All.SendAsync("OnMessageReceivedFromAssistant", new RoleDialogModel(AgentRole.Assistant, response.Text) + { + + }); + } + + [HttpPost("/chat-hub/csr/{agentId}/{conversationId}")] + public async Task OnMessageReceivedFromCsr([FromRoute] string agentId, + [FromRoute] string conversationId, + [FromBody] NewMessageModel input) + { + // Update console conversation UI for User + await _chatHub.Clients.All.SendAsync("OnMessageReceivedFromCsr", new RoleDialogModel(AgentRole.CSR, input.Text) + { + + }); + } +}