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)
+ {
+
+ });
+ }
+}