diff --git a/.gitignore b/.gitignore index c2795885..6e15e1e8 100644 --- a/.gitignore +++ b/.gitignore @@ -283,12 +283,5 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs -/BotSharp.WebHost/App_Data/BotSharp.db -/BotSharp.UI -/BotSharp.WebHost/App_Data/Projects -/BotSharp.WebHost/PublishOutput -/Data +data /docs/_build -*.RestApi.xml -/BotSharp.WebHost/App_Data/AgentStorage -/BotSharp.WebHost/App_Data/SessionStorage diff --git a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs index abef9c46..be1f0b6a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs @@ -9,6 +9,8 @@ public interface IAgentService { Task CreateAgent(Agent agent); Task> GetAgents(); + Task GetAgent(string id); Task DeleteAgent(string id); Task UpdateAgent(Agent agent); + string GetAgentDataDir(string agentId); } diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj index f8f906a2..1419d509 100644 --- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj +++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj @@ -22,4 +22,8 @@ + + + + diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IChatServiceZone.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IChatServiceZone.cs deleted file mode 100644 index 10b66e01..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IChatServiceZone.cs +++ /dev/null @@ -1,11 +0,0 @@ -using BotSharp.Abstraction.Infrastructures.ContentTransfers; - -namespace BotSharp.Abstraction.Conversations; - -/// -/// IChatServiceZone is used to manage the chat function. -/// When user send message to controller, all the registered service zone will process the message respectively. -/// -public interface IChatServiceZone : IServiceZone -{ -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 31f69eee..72d2b3ae 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -1,10 +1,14 @@ -using BotSharp.Abstraction.Models; +using BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Abstraction.Conversations; public interface IConversationService { - void AddDialog(RoleDialogModel dialog); - List GetDialogHistory(string sessionId); - void CleanHistory(); + Task NewConversation(Conversation conversation); + Task> GetConversations(); + Task DeleteConversation(string id); + Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog); + Task SendMessage(string agentId, string conversationId, List wholeDialogs); + List GetDialogHistory(string agentId, string conversationId); + Task CleanHistory(string agentId); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs new file mode 100644 index 00000000..5b99d40a --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStorage.cs @@ -0,0 +1,10 @@ +using BotSharp.Abstraction.Conversations.Models; + +namespace BotSharp.Abstraction.Conversations; + +public interface IConversationStorage +{ + void InitStorage(string agentId, string conversationId); + void Append(string agentId, string conversationId, RoleDialogModel dialog); + List GetDialogs(string agentId, string conversationId); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs deleted file mode 100644 index 8e869182..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using BotSharp.Abstraction.Conversations.Models; - -namespace BotSharp.Abstraction.Conversations; - -public interface ISessionService -{ - Task NewSession(Session sess); - Task> GetSessions(); - Task DeleteSession(string sessionId); -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Session.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs similarity index 93% rename from src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Session.cs rename to src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs index 1048c807..13ee65af 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Session.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs @@ -1,11 +1,12 @@ namespace BotSharp.Abstraction.Conversations.Models; -public class Session +public class Conversation { public string Id { get; set; } = string.Empty; public string AgentId { get; set; } = string.Empty; public string UserId { get; set; } = string.Empty; public string Title { get; set; } = string.Empty; + public DateTime UpdatedTime { get; set; } = DateTime.UtcNow; public DateTime CreatedTime { get; set; } = DateTime.UtcNow; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/MessageModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/MessageModel.cs deleted file mode 100644 index 0a625d68..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/MessageModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Abstraction.Conversations.Models; - -public class MessageModel -{ - public string From { get; set; } - public string Content { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs new file mode 100644 index 00000000..250d5c06 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -0,0 +1,15 @@ +namespace BotSharp.Abstraction.Conversations.Models; + +public class RoleDialogModel +{ + /// + /// user, system, assistant + /// + public string Role { get; set; } + public string Text { get; set; } + + public override string ToString() + { + return $"{Role}: {Text}"; + } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs index 6cff24b5..8b095147 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs @@ -2,5 +2,5 @@ namespace BotSharp.Abstraction.Conversations.Settings; public class ConversationSetting { - + public string ChatCompletion { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/ContentContainer.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/ContentContainer.cs deleted file mode 100644 index 6c7b3f13..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/ContentContainer.cs +++ /dev/null @@ -1,12 +0,0 @@ -using BotSharp.Abstraction.Models; - -namespace BotSharp.Abstraction.Infrastructures.ContentTransmitters; - -public class ContentContainer -{ - public string UserId { get; set; } - public string SessionId { get; set; } - public string AgentId { get; set; } - public List Conversations { get; set; } - public RoleDialogModel Output { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IContentTransfer.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IContentTransfer.cs deleted file mode 100644 index 984ae7c2..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IContentTransfer.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BotSharp.Abstraction.Infrastructures.ContentTransfers; - -namespace BotSharp.Abstraction.Infrastructures.ContentTransmitters; - -public interface IContentTransfer -{ - Task Transport(ContentContainer input); -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IServiceZone.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IServiceZone.cs deleted file mode 100644 index 290cecdf..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/IServiceZone.cs +++ /dev/null @@ -1,9 +0,0 @@ -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; - -namespace BotSharp.Abstraction.Infrastructures.ContentTransfers; - -public interface IServiceZone -{ - int Priority { get; } - Task Serving(ContentContainer content); -} diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/TransportResult.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/TransportResult.cs deleted file mode 100644 index e846ecc2..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/ContentTransfers/TransportResult.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Abstraction.Infrastructures.ContentTransfers; - -public class TransportResult -{ - public bool IsSuccess { get; set; } - public List Messages { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs index 34da1287..c7808ce4 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/IChatCompletion.cs @@ -1,8 +1,9 @@ -using BotSharp.Abstraction.Models; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Abstraction.MLTasks; public interface IChatCompletion { - Task GetChatCompletionsAsync(List conversations); + Task GetChatCompletionsAsync(Agent agent, List conversations); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Models/RoleDialogModel.cs deleted file mode 100644 index 81834102..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/Models/RoleDialogModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Abstraction.Models; - -public class RoleDialogModel -{ - public string Role { get; set; } - public string Text { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Core/Agents/AgentController.cs b/src/Infrastructure/BotSharp.Core/Agents/AgentController.cs index 8bbf6e99..d668345e 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/AgentController.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/AgentController.cs @@ -1,4 +1,3 @@ -using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.ApiAdapters; using BotSharp.Core.Agents.ViewModels; using Microsoft.AspNetCore.Authorization; diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.ChatServing.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.ChatServing.cs deleted file mode 100644 index ffc3ae04..00000000 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.ChatServing.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace BotSharp.Core.Agents.Services; - -public partial class AgentService : IChatServiceZone -{ - public int Priority => 10; - - /// - /// Prepare agent profile and configurations - /// - /// - /// - public async Task Serving(ContentContainer content) - { - - } -} diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs index 0d3e2712..9793b343 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.GetAgents.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents.Models; +using System.IO; namespace BotSharp.Core.Agents.Services; @@ -12,4 +13,20 @@ public partial class AgentService select agent.ToAgent(); return query.ToList(); } + + public async Task GetAgent(string id) + { + var db = _services.GetRequiredService(); + var query = from agent in db.Agent + where agent.OwnerId == _user.Id && agent.Id == id + select agent.ToAgent(); + + var profile = query.FirstOrDefault(); + var dir = GetAgentDataDir(id); + + profile.Instruction = File.ReadAllText(Path.Combine(dir, "instruction.txt")); + profile.Samples = File.ReadAllText(Path.Combine(dir, "samples.txt")); + + return profile; + } } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs index 42179abd..9dd50308 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.UpdateAgent.cs @@ -14,8 +14,6 @@ public partial class AgentService record.Name = agent.Name; record.Description = agent.Description; - record.Instruction = agent.Instruction; - record.Samples = agent.Samples; record.UpdatedDateTime = DateTime.UtcNow; }); } diff --git a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs index 2cb3725c..6a53d291 100644 --- a/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs +++ b/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.cs @@ -1,3 +1,5 @@ +using System.IO; + namespace BotSharp.Core.Agents.Services; public partial class AgentService : IAgentService @@ -10,4 +12,14 @@ public partial class AgentService : IAgentService _services = services; _user = user; } + + public string GetAgentDataDir(string agentId) + { + var dir = Path.Combine("data", agentId); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + return dir; + } } diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 2ae1a0c7..35ee23b2 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Settings; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; @@ -11,14 +12,14 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + var convsationSettings = new ConversationSetting(); + config.Bind("Conversation", convsationSettings); + services.AddSingleton((IServiceProvider x) => convsationSettings); + services.AddScoped(); services.AddScoped(); - services.AddScoped(); - RegisterRepository(services, config); RegisterPlugins(services, config); @@ -46,17 +47,11 @@ public static class BotSharpServiceCollectionExtensions { var databaseSettings = new DatabaseSettings(); config.Bind("Database", databaseSettings); - services.AddSingleton((IServiceProvider x) => - { - return databaseSettings; - }); + services.AddSingleton((IServiceProvider x) => databaseSettings); var myDatabaseSettings = new MyDatabaseSettings(); config.Bind("Database", myDatabaseSettings); - services.AddSingleton((IServiceProvider x) => - { - return databaseSettings; - }); + services.AddSingleton((IServiceProvider x) => databaseSettings); services.AddScoped((IServiceProvider x) => { diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs b/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs index 441164bc..6b70558b 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/ConversationController.cs @@ -21,50 +21,39 @@ public class ConversationController : ControllerBase, IApiAdapter } [HttpPost("/conversation/{agentId}")] - public async Task NewSession([FromRoute] string agentId) + public async Task NewConversation([FromRoute] string agentId) { - var service = _services.GetRequiredService(); - var sess = new Session + var service = _services.GetRequiredService(); + var sess = new Conversation { AgentId = agentId }; - sess = await service.NewSession(sess); - return SessionViewModel.FromSession(sess); + sess = await service.NewConversation(sess); + return ConversationViewModel.FromSession(sess); } - [HttpDelete("/conversation/{agentId}/{sessionId}")] - public async Task DeleteSession([FromRoute] string agentId, [FromRoute] string sessionId) + [HttpDelete("/conversation/{agentId}/{conversationId}")] + public async Task DeleteConversation([FromRoute] string agentId, [FromRoute] string conversationId) { - var service = _services.GetRequiredService(); + var service = _services.GetRequiredService(); } - [HttpPost("/conversation/{agentId}/{sessionId}")] + [HttpPost("/conversation/{agentId}/{conversationId}")] public async Task SendMessage([FromRoute] string agentId, - [FromRoute] string sessionId, + [FromRoute] string conversationId, [FromBody] NewMessageModel input) { - var transmitter = _services.GetRequiredService(); + var conv = _services.GetRequiredService(); - var container = new ContentContainer + var result = await conv.SendMessage(agentId, conversationId, new RoleDialogModel { - AgentId = agentId, - SessionId = sessionId, - Conversations = new List - { - new RoleDialogModel - { - Role = "user", - Text = input.Text - } - }, - UserId = _user.Id - }; - - var result = await transmitter.Transport(container); + Role = "user", + Text = input.Text + }); return new MessageResponseModel { - Content = result.IsSuccess ? container.Output.Text : result.Messages.First() + Content = result }; } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index f8357c5b..aaac8c91 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,52 +1,100 @@ -using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Models; -using System; -using System.Collections.Generic; -using System.Text; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Conversations.Settings; +using BotSharp.Abstraction.MLTasks; namespace BotSharp.Core.Conversations.Services; public class ConversationService : IConversationService { - Dictionary> _history; + private readonly IServiceProvider _services; + private readonly IUserIdentity _user; + private readonly ConversationSetting _settings; + private readonly IConversationStorage _storage; - public ConversationService() + public ConversationService(IServiceProvider services, + IUserIdentity user, + ConversationSetting settings, + IConversationStorage storage) { - _history = new Dictionary>(); + _services = services; + _user = user; + _settings = settings; + _storage = storage; } - public void AddDialog(RoleDialogModel dialog) - { - _history[Guid.Empty.ToString()].Add(dialog); - } - - public void CleanHistory() + public Task DeleteConversation(string id) { throw new NotImplementedException(); } - public void DeleteSession() + public async Task> GetConversations() + { + var db = _services.GetRequiredService(); + var query = from sess in db.Conversation + where sess.UserId == _user.Id + orderby sess.CreatedTime descending + select sess.ToConversation(); + return query.ToList(); + } + + public async Task NewConversation(Conversation sess) + { + var db = _services.GetRequiredService(); + + var record = ConversationRecord.FromConversation(sess); + record.Id = Guid.NewGuid().ToString(); + record.UserId = _user.Id; + record.Title = "New Conversation"; + + db.Transaction(delegate + { + db.Add(record); + }); + + _storage.InitStorage(sess.AgentId, record.Id); + + return record.ToConversation(); + } + + public async Task SendMessage(string agentId, string conversationId, RoleDialogModel lastDalog) + { + _storage.Append(agentId, conversationId, lastDalog); + + var wholeDialogs = GetDialogHistory(agentId, conversationId); + + var response = await SendMessage(agentId, conversationId, wholeDialogs); + + _storage.Append(agentId, conversationId, new RoleDialogModel + { + Role = "assistant", + Text = response + }); + + return response; + } + + public async Task SendMessage(string agentId, string conversationId, List wholeDialogs) + { + var agent = await _services.GetRequiredService().GetAgent(agentId); + var chat = GetChatCompletion(); + var response = await chat.GetChatCompletionsAsync(agent, wholeDialogs); + + return response; + } + + public IChatCompletion GetChatCompletion() + { + var completions = _services.GetServices(); + return completions.FirstOrDefault(x => x.GetType().FullName.Contains(_settings.ChatCompletion)); + } + + public Task CleanHistory(string agentId) { throw new NotImplementedException(); } - public List GetAllSessions() + public List GetDialogHistory(string agentId, string conversationId) { - throw new NotImplementedException(); - } - - public List GetDialogHistory() - { - return _history[Guid.Empty.ToString()]; - } - - public List GetDialogHistory(string sessionId) - { - throw new NotImplementedException(); - } - - public string NewSession() - { - throw new NotImplementedException(); + return _storage.GetDialogs(agentId, conversationId); } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs new file mode 100644 index 00000000..d486f947 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -0,0 +1,59 @@ +using BotSharp.Abstraction.Conversations.Models; +using System.IO; + +namespace BotSharp.Core.Conversations.Services; + +public class ConversationStorage : IConversationStorage +{ + private readonly IAgentService _agent; + public ConversationStorage(IAgentService agent) + { + _agent = agent; + } + + public void Append(string agentId, string conversationId, RoleDialogModel dialog) + { + var conversationFile = GetStorageFile(agentId, conversationId); + File.AppendAllText(conversationFile, $"{dialog.Role}: {dialog.Text}\n"); + } + + public List GetDialogs(string agentId, string conversationId) + { + var conversationFile = GetStorageFile(agentId, conversationId); + var dialogs = File.ReadAllLines(conversationFile); + return dialogs.Select(x => + { + var pos = x.IndexOf(':'); + var role = x.Substring(0, pos); + var text = x.Substring(pos + 1); + return new RoleDialogModel + { + Role = role, + Text = text + }; + }).ToList(); + } + + public void InitStorage(string agentId, string conversationId) + { + var dir = _agent.GetAgentDataDir(agentId); + var dialogDir = Path.Combine(dir, "conversations"); + if (!Directory.Exists(dialogDir)) + { + Directory.CreateDirectory(dialogDir); + } + + var conversationFile = Path.Combine(dialogDir, conversationId + ".txt"); + if (!File.Exists(conversationFile)) + { + File.WriteAllLines(conversationFile, new string[0]); + } + } + + private string GetStorageFile(string agentId, string conversationId) + { + var dir = _agent.GetAgentDataDir(agentId); + var dialogDir = Path.Combine(dir, "conversations"); + return Path.Combine(dialogDir, conversationId + ".txt"); + } +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/SessionService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/SessionService.cs deleted file mode 100644 index 071206d3..00000000 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/SessionService.cs +++ /dev/null @@ -1,49 +0,0 @@ -using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.Users; - -namespace BotSharp.Core.Conversations.Services; - -public class SessionService : ISessionService -{ - private readonly IServiceProvider _services; - private readonly IUserIdentity _user; - - public SessionService(IServiceProvider services, IUserIdentity user) - { - _services = services; - _user = user; - } - - public Task DeleteSession(string sessionId) - { - throw new NotImplementedException(); - } - - public async Task> GetSessions() - { - var db = _services.GetRequiredService(); - var query = from sess in db.Session - where sess.UserId == _user.Id - orderby sess.CreatedTime descending - select sess.ToSession(); - return query.ToList(); - } - - public async Task NewSession(Session sess) - { - var db = _services.GetRequiredService(); - - var record = SessionRecord.FromSession(sess); - record.Id = Guid.NewGuid().ToString(); - record.UserId = _user.Id; - record.Title = "New Session"; - - db.Transaction(delegate - { - db.Add(record); - }); - - return record.ToSession(); - } -} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationCreationModel.cs b/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationCreationModel.cs new file mode 100644 index 00000000..300254a3 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationCreationModel.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Core.Conversations.ViewModels; + +public class ConversationCreationModel +{ + +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionViewModel.cs b/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationViewModel.cs similarity index 79% rename from src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionViewModel.cs rename to src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationViewModel.cs index 267e8ffd..3289a1d5 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionViewModel.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/ConversationViewModel.cs @@ -2,7 +2,7 @@ using BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Core.Conversations.ViewModels; -public class SessionViewModel +public class ConversationViewModel { public string Id { get; set; } public string AgentId { get; set; } @@ -10,9 +10,9 @@ public class SessionViewModel public DateTime UpdatedTime { get; set; } = DateTime.UtcNow; public DateTime CreatedTime { get; set; } = DateTime.UtcNow; - public static SessionViewModel FromSession(Session sess) + public static ConversationViewModel FromSession(Conversation sess) { - return new SessionViewModel + return new ConversationViewModel { Id = sess.Id, AgentId = sess.AgentId, diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionCreationModel.cs b/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionCreationModel.cs deleted file mode 100644 index 9f0bd890..00000000 --- a/src/Infrastructure/BotSharp.Core/Conversations/ViewModels/SessionCreationModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -using BotSharp.Abstraction.Conversations.Models; - -namespace BotSharp.Core.Conversations.ViewModels; - -public class SessionCreationModel -{ - -} diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/ContentTransfer.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/ContentTransfer.cs deleted file mode 100644 index 07690c4c..00000000 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/ContentTransfer.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace BotSharp.Core.Infrastructures; - -public class ContentTransfer : IContentTransfer -{ - private readonly IServiceProvider _services; - - public ContentTransfer(IServiceProvider services) - { - _services = services; - } - - public async Task Transport(ContentContainer input) - { - input.Output = new RoleDialogModel(); - - var result = new TransportResult - { - IsSuccess = true, - Messages = new List() - }; - - var zones = _services.GetServices() - .OrderBy(x => x.Priority) - .ToList(); - - foreach (var zone in zones) - { - try - { - await zone.Serving(input); - } - catch (Exception ex) - { - result.IsSuccess = false; - result.Messages.Add(ex.Message); - } - } - - return result; - } -} diff --git a/src/Infrastructure/BotSharp.Core/Plugins/Knowledges/Services/KnowledgeService.cs b/src/Infrastructure/BotSharp.Core/Plugins/Knowledges/Services/KnowledgeService.cs index 9e0113f0..2c2d28ff 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/Knowledges/Services/KnowledgeService.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/Knowledges/Services/KnowledgeService.cs @@ -9,14 +9,17 @@ public class KnowledgeService : IKnowledgeService { private readonly IServiceProvider _services; private readonly KnowledgeBaseSettings _settings; + private readonly IAgentService _agentService; private readonly ITextChopper _textChopper; public KnowledgeService(IServiceProvider services, KnowledgeBaseSettings settings, + IAgentService agentService, ITextChopper textChopper) { _services = services; _settings = settings; + _agentService = agentService; _textChopper = textChopper; } @@ -30,13 +33,8 @@ public class KnowledgeService : IKnowledgeService }); // Store chunks in local file system - var knowledgeStoreDir = Path.Combine("knowledge_base"); - if (!Directory.Exists(knowledgeStoreDir)) - { - Directory.CreateDirectory(knowledgeStoreDir); - } - - var knowledgePath = Path.Combine(knowledgeStoreDir, knowledge.AgentId + ".txt"); + var agentDataDir = _agentService.GetAgentDataDir(knowledge.AgentId); + var knowledgePath = Path.Combine(agentDataDir, "knowledge.txt"); File.WriteAllLines(knowledgePath, lines); var db = GetVectorDb(); @@ -57,7 +55,8 @@ public class KnowledgeService : IKnowledgeService var vector = textEmbedding.GetVector(retrievalModel.Question); // Scan local knowledge directory - var chunks = File.ReadAllLines(Path.Combine("knowledge_base", retrievalModel.AgentId + ".txt")); + var agentDataDir = _agentService.GetAgentDataDir(retrievalModel.AgentId); + var chunks = File.ReadAllLines(Path.Combine(agentDataDir, "knowledge.txt")); // Vector search var result = await GetVectorDb().Search(retrievalModel.AgentId, vector); diff --git a/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/ChatCompletionProvider.cs b/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/ChatCompletionProvider.cs index 48a853a0..915f9608 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/ChatCompletionProvider.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/ChatCompletionProvider.cs @@ -1,9 +1,12 @@ +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.MLTasks; using LLama; using System.IO; namespace BotSharp.Core.Plugins.LLamaSharp; -public class ChatCompletionProvider : IChatServiceZone +public class ChatCompletionProvider : IChatCompletion { private readonly IChatModel _model; private readonly LlamaSharpSettings _settings; @@ -42,6 +45,21 @@ public class ChatCompletionProvider : IChatServiceZone Console.WriteLine(); } + public Task GetChatCompletionsAsync(Agent agent, List conversations) + { + string totalResponse = ""; + var prompt = GetInstruction(); + var content = string.Join("\n ", conversations.Select(x => $"{x.Role}: {x.Text.Replace("user:", "")}")).Trim(); + content += "\n assistant: "; + foreach (var response in _model.Chat(content, prompt, "UTF-8")) + { + Console.Write(response); + totalResponse += response; + } + + return Task.FromResult(totalResponse); + } + public List GetChatSamples() { var samples = new List(); @@ -80,19 +98,4 @@ public class ChatCompletionProvider : IChatServiceZone return instruction; } - - public async Task Serving(ContentContainer content) - { - string output = ""; - var prompt = GetInstruction(); - var conversations = string.Join("\n ", content.Conversations.Select(x => $"{x.Role}: {x.Text.Replace("user:", "")}")).Trim(); - conversations += "\n assistant: "; - foreach (var response in _model.Chat(conversations, prompt, "UTF-8")) - { - Console.Write(response); - output += response; - } - - Console.WriteLine(); - } } diff --git a/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/LLamaSharpPlugin.cs b/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/LLamaSharpPlugin.cs index b01f913d..0a882cff 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/LLamaSharpPlugin.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/LLamaSharp/LLamaSharpPlugin.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.Configuration; namespace BotSharp.Core.Plugins.LLamaSharp; @@ -10,6 +11,6 @@ public class LLamaSharpPlugin : IBotSharpPlugin config.Bind("LlamaSharp", llamaSharpSettings); services.AddSingleton(x => llamaSharpSettings); - services.AddScoped(); + services.AddScoped(); } } diff --git a/src/Infrastructure/BotSharp.Core/Plugins/MemVecDb/MemVectorDatabase.cs b/src/Infrastructure/BotSharp.Core/Plugins/MemVecDb/MemVectorDatabase.cs index 95b611fd..b81742b2 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/MemVecDb/MemVectorDatabase.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/MemVecDb/MemVectorDatabase.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.VectorStorage; +using Tensorflow; using Tensorflow.NumPy; namespace BotSharp.Core.Plugins.MemVecDb; @@ -21,15 +22,17 @@ public class MemVectorDatabase : IVectorDb public Task> Search(string collectionName, float[] vector, int limit = 10) { - var cosineList = new List(); + var similarities = new float[_vectors[collectionName].Count]; for (int i = 0; i < _vectors[collectionName].Count; i++) { - var p = CalCosineSimilarity(vector, _vectors[collectionName][i].Vector); - cosineList.Add(p); + similarities[i] = CalCosineSimilarity(vector, _vectors[collectionName][i].Vector); } - var similarities = cosineList.ToArray(); + var indice = np.argsort(similarities).ToArray() - .Reverse().Take(limit).ToList(); + .Reverse() + .Take(limit) + .ToList(); + return Task.FromResult(indice); } @@ -44,24 +47,8 @@ public class MemVectorDatabase : IVectorDb return Task.CompletedTask; } - private double CalCosineSimilarity(float[] vector1, float[] vector2) + private float CalCosineSimilarity(float[] a, float[] b) { - NDArray a = vector1; - NDArray b = vector2; - double num = np.dot(a, b); - if(num == 0) - { - return 0.0; - } - - b = np.square(a); - var x = np.sqrt(np.sum(b)); - var x3 = np.sum(np.square(vector2)); - double num2 = np.sqrt(x) * np.sqrt(x3); - if(num2 == 0) - { - return 0.0; - } - return num / num2; + return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)); } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/AgentDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/AgentDbContext.cs index 1c0d1c96..a7dcdd31 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/AgentDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/AgentDbContext.cs @@ -4,5 +4,5 @@ public class AgentDbContext : Database { public IQueryable User => Table(); public IQueryable Agent => Table(); - public IQueryable Session => Table(); + public IQueryable Conversation => Table(); } diff --git a/src/Infrastructure/BotSharp.Core/Repository/Collections/Conversation.cs b/src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs similarity index 83% rename from src/Infrastructure/BotSharp.Core/Repository/Collections/Conversation.cs rename to src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs index e61f5813..c32f9a2e 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/Collections/Conversation.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/Collections/ConversationCollection.cs @@ -5,7 +5,7 @@ using MongoDB.Bson.Serialization.IdGenerators; namespace BotSharp.Core.Repository.Collections; -public class Conversation : IMongoDbCollection +public class ConversationCollection : IMongoDbCollection { [BsonId(IdGenerator = typeof(ObjectIdGenerator))] public ObjectId Id { get; set; } @@ -15,7 +15,7 @@ public class Conversation : IMongoDbCollection public string Model { get; set; } public string Title { get; set; } - public List Messages { get; set; } + public List Messages { get; set; } public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs b/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs index c44fdc3c..eb5e3f42 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/DbTables/AgentRecord.cs @@ -18,18 +18,6 @@ public class AgentRecord : DbRecord, IAgentTable [MaxLength(512)] public string Description { get; set; } - /// - /// Instruction - /// - [StringLength(int.MaxValue)] - public string Instruction { get; set; } - - /// - /// Samples - /// - [StringLength(int.MaxValue)] - public string Samples { get; set; } - [Required] public DateTime CreatedDateTime { get; set; } diff --git a/src/Infrastructure/BotSharp.Core/Repository/DbTables/SessionRecord.cs b/src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs similarity index 64% rename from src/Infrastructure/BotSharp.Core/Repository/DbTables/SessionRecord.cs rename to src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs index eb37bcd0..a3b75cc2 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/DbTables/SessionRecord.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/DbTables/ConversationRecord.cs @@ -4,8 +4,8 @@ using System.ComponentModel.DataAnnotations.Schema; namespace BotSharp.Core.Repository.DbTables; -[Table("Session")] -public class SessionRecord : DbRecord, IAgentTable +[Table("Conversation")] +public class ConversationRecord : DbRecord, IAgentTable { [Required] [MaxLength(36)] @@ -24,22 +24,22 @@ public class SessionRecord : DbRecord, IAgentTable [Required] public DateTime CreatedTime { get; set; } = DateTime.UtcNow; - public static SessionRecord FromSession(Session sess) + public static ConversationRecord FromConversation(Conversation conv) { - return new SessionRecord + return new ConversationRecord { - AgentId = sess.AgentId, - UserId = sess.UserId, - Id = sess.Id, - Title = sess.Title, - CreatedTime = sess.CreatedTime, - UpdatedTime = sess.UpdatedTime + AgentId = conv.AgentId, + UserId = conv.UserId, + Id = conv.Id, + Title = conv.Title, + CreatedTime = conv.CreatedTime, + UpdatedTime = conv.UpdatedTime }; } - public Session ToSession() + public Conversation ToConversation() { - return new Session + return new Conversation { Id = Id, Title = Title, diff --git a/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs index 389bb2eb..c92e6f9b 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs @@ -1,11 +1,10 @@ using BotSharp.Core.Repository.Collections; -using EntityFrameworkCore.BootKit; using MongoDB.Driver; namespace BotSharp.Core.Repository; public class MongoDbContext : Database { - public IMongoCollection Conversations - => Collection("conversations"); + public IMongoCollection Conversations + => Collection("conversations"); } diff --git a/src/Infrastructure/BotSharp.Core/Using.cs b/src/Infrastructure/BotSharp.Core/Using.cs index b5929e45..28976df7 100644 --- a/src/Infrastructure/BotSharp.Core/Using.cs +++ b/src/Infrastructure/BotSharp.Core/Using.cs @@ -8,11 +8,8 @@ global using BotSharp.Abstraction.Plugins; global using EntityFrameworkCore.BootKit; global using BotSharp.Abstraction.Agents; global using BotSharp.Abstraction.Conversations; -global using BotSharp.Abstraction.Infrastructures.ContentTransmitters; -global using BotSharp.Abstraction.Infrastructures.ContentTransfers; global using BotSharp.Abstraction.Knowledges; global using BotSharp.Abstraction.Users; -global using BotSharp.Abstraction.Models; global using BotSharp.Core.Repository; global using BotSharp.Core.Repository.Abstraction; global using BotSharp.Core.Repository.DbTables; diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs index 43419eaa..49aa3bde 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs @@ -1,8 +1,6 @@ -using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Plugins; using BotSharp.Plugin.AzureOpenAI.Providers; -using BotSharp.Plugin.AzureOpenAI.Services; using BotSharp.Plugin.AzureOpenAI.Settings; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -19,6 +17,5 @@ public class AzureOpenAiPlugin : IBotSharpPlugin services.AddSingleton(); services.AddScoped(); - services.AddScoped(); } } \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs index 38cc1bee..ee0a1359 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -1,9 +1,8 @@ using Azure; using Azure.AI.OpenAI; -using BotSharp.Abstraction.Infrastructures.ContentTransfers; -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; -using BotSharp.Abstraction.Models; using BotSharp.Plugin.AzureOpenAI.Settings; using System; using System.Collections.Generic; @@ -21,7 +20,7 @@ public class ChatCompletionProvider : IChatCompletion _settings = settings; } - public async Task GetChatCompletionsAsync(List conversations, + /*public async Task GetChatCompletionsAsync(List conversations, Func onChunkReceived) { var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey)); @@ -44,14 +43,14 @@ public class ChatCompletionProvider : IChatCompletion } Console.WriteLine(); - } + }*/ - public List GetChatSamples() + public List GetChatSamples(string sampleText) { var samples = new List(); - if (!string.IsNullOrEmpty(_settings.ChatSampleFile)) + if (!string.IsNullOrEmpty(sampleText)) { - var lines = File.ReadAllLines(_settings.ChatSampleFile); + var lines = sampleText.Split('\n'); for (int i = 0; i < lines.Length; i++) { var line = lines[i]; @@ -68,19 +67,11 @@ public class ChatCompletionProvider : IChatCompletion return samples; } - public string GetInstruction() - { - if (!string.IsNullOrEmpty(_settings.InstructionFile)) - { - return File.ReadAllText(_settings.InstructionFile); - } - return string.Empty; - } - public async Task GetChatCompletionsAsync(List conversations) + public async Task GetChatCompletionsAsync(Agent agent, List conversations) { var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey)); - var chatCompletionsOptions = PrepareOptions(conversations); + var chatCompletionsOptions = PrepareOptions(agent, conversations); var response = await client.GetChatCompletionsStreamingAsync(_settings.DeploymentModel.ChatCompletionModel, chatCompletionsOptions); using StreamingChatCompletions streaming = response.Value; @@ -100,18 +91,17 @@ public class ChatCompletionProvider : IChatCompletion return output; } - private ChatCompletionsOptions PrepareOptions(List conversations) + private ChatCompletionsOptions PrepareOptions(Agent agent, List conversations) { - var prompt = GetInstruction(); var chatCompletionsOptions = new ChatCompletionsOptions() { Messages = { - new ChatMessage(ChatRole.System, prompt) + new ChatMessage(ChatRole.System, agent.Instruction) } }; - foreach (var message in GetChatSamples()) + foreach (var message in GetChatSamples(agent.Samples)) { chatCompletionsOptions.Messages.Add(new ChatMessage(message.Role, message.Text)); } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Services/ChatService.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Services/ChatService.cs deleted file mode 100644 index 71f57a08..00000000 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Services/ChatService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Azure.AI.OpenAI; -using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; -using BotSharp.Abstraction.MLTasks; -using BotSharp.Abstraction.Models; -using System.Threading.Tasks; - -namespace BotSharp.Plugin.AzureOpenAI.Services; - -public class ChatService : IChatServiceZone -{ - private readonly IChatCompletion _chatCompletion; - - public ChatService(IChatCompletion chatCompletion) - { - _chatCompletion = chatCompletion; - } - - public int Priority => 100; - - public async Task Serving(ContentContainer content) - { - var output = await _chatCompletion.GetChatCompletionsAsync(content.Conversations); - - content.Output = new RoleDialogModel - { - Role = ChatRole.Assistant.ToString(), - Text = output - }; - } -} diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs index 61823d00..18975e5b 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/ChatbotUiController.cs @@ -13,8 +13,9 @@ using System; using Azure.AI.OpenAI; using BotSharp.Abstraction.ApiAdapters; using BotSharp.Plugin.ChatbotUI.ViewModels; -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; using Microsoft.Extensions.DependencyInjection; +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Plugin.ChatbotUI.Controllers; @@ -64,22 +65,11 @@ public class ChatbotUiController : ControllerBase, IApiAdapter Text = x.Content }).ToList(); - /*await _chatCompletionProvider.GetChatCompletionsAsync(conversations, - async content => - { - await OnChunkReceived(outputStream, content); - });*/ + var conv = _services.GetRequiredService(); - var transmitter = _services.GetRequiredService(); + var result = await conv.SendMessage("", "", conversations.Last()); - var container = new ContentContainer - { - Conversations = conversations - }; - - var result = await transmitter.Transport(container); - - await OnChunkReceived(outputStream, container.Output.Text); + await OnChunkReceived(outputStream, result); await OnEventCompleted(outputStream); } diff --git a/src/Plugins/BotSharp.Plugin.WeChat/BotSharpMessageHandler.cs b/src/Plugins/BotSharp.Plugin.WeChat/BotSharpMessageHandler.cs index d12a6f45..14210fef 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/BotSharpMessageHandler.cs +++ b/src/Plugins/BotSharp.Plugin.WeChat/BotSharpMessageHandler.cs @@ -1,6 +1,3 @@ -using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; -using BotSharp.Abstraction.Models; using Microsoft.Extensions.DependencyInjection; using Senparc.NeuChar.App.AppStore; using Senparc.NeuChar.Entities; diff --git a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs index 09aac562..d1ed3109 100644 --- a/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs +++ b/src/Plugins/BotSharp.Plugin.WeChat/WeChatBackgroundService.cs @@ -1,5 +1,5 @@ using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Infrastructures.ContentTransmitters; +using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -22,41 +22,23 @@ namespace BotSharp.Plugin.WeChat ILogger logger) { - this._service = service; - this._logger = logger; - this._queue = Channel.CreateUnbounded(); + _service = service; + _logger = logger; + _queue = Channel.CreateUnbounded(); } private async Task HandleTextMessageAsync(string openid, string message) { var scoped = _service.CreateScope().ServiceProvider; var conversationService = scoped.GetRequiredService(); - var contentTransfer = scoped.GetRequiredService(); - var conversations = conversationService.GetDialogHistory(openid); - conversations.Add(new RoleDialogModel + var result = await conversationService.SendMessage(openid, Guid.Empty.ToString(), new RoleDialogModel { - Role = "User", + Role = "user", Text = message, }); - var container = new ContentContainer - { - Conversations = conversations - }; - - var result = await contentTransfer.Transport(container); - - if (result.IsSuccess) - { - var output = container.Output.Text.Trim(); - await ReplyTextMessageAsync(openid, output); - conversationService.AddDialog(new RoleDialogModel() - { - Role = "Assistant", - Text = output, - }); - } + await ReplyTextMessageAsync(openid, result); } private async Task ReplyTextMessageAsync(string openid, string content) diff --git a/src/WebStarter/Prompts/chat-samples.txt b/src/WebStarter/Prompts/chat-samples.txt deleted file mode 100644 index 313d48b7..00000000 --- a/src/WebStarter/Prompts/chat-samples.txt +++ /dev/null @@ -1,2 +0,0 @@ -user: Hi -assistant: Hello, I'm a AI assistant to help you schedule meeting. \ No newline at end of file diff --git a/src/WebStarter/Prompts/chat-with-bob.txt b/src/WebStarter/Prompts/chat-with-bob.txt deleted file mode 100644 index ad494d83..00000000 --- a/src/WebStarter/Prompts/chat-with-bob.txt +++ /dev/null @@ -1,7 +0,0 @@ -Transcript of a dialog, where the User interacts with an Assistant named Bob. Bob is helpful, kind, honest, good at writing, and never fails to answer the User's requests immediately and with precision. - -User: Hello, Bob. -Bob: Hello. How may I help you today? -User: Please tell me the largest city in Europe. -Bob: Sure. The largest city in Europe is Moscow, the capital of Russia. -User: \ No newline at end of file diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 63ac1254..5dfc1631 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -8,25 +8,22 @@ + + + + + + + + - - - - - - - PreserveNewest - - - PreserveNewest - diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index e183aba7..4c479f32 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -14,7 +14,7 @@ }, "Conversation": { - + "ChatCompletion": "AzureOpenAI.Providers.ChatCompletionProvider" }, "LlamaSharp": { @@ -48,7 +48,7 @@ "Master": "mongodb://localhost:27017/chat-ui" }, "Agent": { - "Master": "Data Source=(localdb)\\ProjectModels;Initial Catalog=Agent;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False", + "Master": "Data Source=(localdb)\\ProjectModels;Initial Catalog=BotSharp;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False", "Slavers": [] }, "UseCamelCase": true, @@ -70,7 +70,7 @@ "KnowledgeBase": { "VectorDb": "MemVectorDatabase", "TextEmbedding": "fastTextEmbeddingProvider", - "TextCompletion": "TextCompletionProvider" + "TextCompletion": "AzureOpenAI.Providers.TextCompletionProvider" }, "PluginLoader": {