From 66bd6e53dd7d61a35a29bb6fa0c0046fede208e9 Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Fri, 2 Jun 2023 21:07:30 -0500 Subject: [PATCH] Adapt HuggingChat UI (WIP). --- BotSharp.sln | 11 ++++ .../Conversations/IConversationService.cs | 10 ++++ .../Conversations/ISessionService.cs | 10 ++++ .../Conversations/Models/SessionModel.cs | 7 +++ .../BotSharp.Abstraction/IPlatformMidware.cs | 2 + .../BotSharp.Abstraction/ITaskRouter.cs | 9 ---- .../BotSharpServiceCollectionExtensions.cs | 29 +++++++++++ .../Conversations/ConversationService.cs | 52 +++++++++++++++++++ .../Conversations/SessionService.cs | 32 ++++++++++++ .../Repository/DataContextHelper.cs | 28 ++++++++++ .../Repository/IMongoDbCollection.cs | 5 ++ .../Repository/MongoDbContext.cs | 7 +++ .../Repository/MyDatabaseSettings.cs | 9 ++++ .../BotSharp.Core/Services/PlatformMidware.cs | 6 +++ .../HuggingChatUI/HuggingChat-UI.md | 16 ++++++ .../HuggingChatUI/HuggingChatUI.csproj | 17 ++++++ .../HuggingChatUI/HuggingChatUiController.cs | 31 +++++++++++ .../ViewModels/ConversationCreationModel.cs | 6 +++ .../ViewModels/ConversationViewModel.cs | 6 +++ src/WebStarter/Program.cs | 15 ++++++ src/WebStarter/WebStarter.csproj | 1 + src/WebStarter/appsettings.json | 7 +++ 22 files changed, 307 insertions(+), 9 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs create mode 100644 src/Infrastructure/BotSharp.Abstraction/Conversations/Models/SessionModel.cs delete mode 100644 src/Infrastructure/BotSharp.Abstraction/ITaskRouter.cs create mode 100644 src/Infrastructure/BotSharp.Core/Conversations/ConversationService.cs create mode 100644 src/Infrastructure/BotSharp.Core/Conversations/SessionService.cs create mode 100644 src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs create mode 100644 src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs create mode 100644 src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs create mode 100644 src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs create mode 100644 src/UiAdapters/HuggingChatUI/HuggingChat-UI.md create mode 100644 src/UiAdapters/HuggingChatUI/HuggingChatUI.csproj create mode 100644 src/UiAdapters/HuggingChatUI/HuggingChatUiController.cs create mode 100644 src/UiAdapters/HuggingChatUI/ViewModels/ConversationCreationModel.cs create mode 100644 src/UiAdapters/HuggingChatUI/ViewModels/ConversationViewModel.cs diff --git a/BotSharp.sln b/BotSharp.sln index f3aa017a..f5b78235 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatbotUI", "src\UiAdapters EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Platform.LlamaSharp", "src\Platforms\BotSharp.Platform.LlamaSharp\BotSharp.Platform.LlamaSharp.csproj", "{0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HuggingChatUI", "src\UiAdapters\HuggingChatUI\HuggingChatUI.csproj", "{1340286B-2E39-4CE6-BFD2-0B6B124641D0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -109,6 +111,14 @@ Global {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Release|Any CPU.Build.0 = Release|Any CPU {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Release|x64.ActiveCfg = Release|Any CPU {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Release|x64.Build.0 = Release|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Debug|x64.Build.0 = Debug|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Release|Any CPU.Build.0 = Release|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Release|x64.ActiveCfg = Release|Any CPU + {1340286B-2E39-4CE6-BFD2-0B6B124641D0}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -122,6 +132,7 @@ Global {B874E946-AE39-4731-8DA5-16A99115D111} = {FFA662D3-B67B-478D-92FC-76DC5EB64412} {223895FB-EE4C-4225-8042-292352B43973} = {42226933-0A0D-48E8-85EC-AFE773A1F841} {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D} = {FFA662D3-B67B-478D-92FC-76DC5EB64412} + {1340286B-2E39-4CE6-BFD2-0B6B124641D0} = {42226933-0A0D-48E8-85EC-AFE773A1F841} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs new file mode 100644 index 00000000..31f69eee --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -0,0 +1,10 @@ +using BotSharp.Abstraction.Models; + +namespace BotSharp.Abstraction.Conversations; + +public interface IConversationService +{ + void AddDialog(RoleDialogModel dialog); + List GetDialogHistory(string sessionId); + void CleanHistory(); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs new file mode 100644 index 00000000..fa59ae28 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ISessionService.cs @@ -0,0 +1,10 @@ +using BotSharp.Abstraction.Conversations.Models; + +namespace BotSharp.Abstraction.Conversations; + +public interface ISessionService +{ + SessionModel NewSession(string userId); + List GetAllSessions(string userId); + void DeleteSession(string sessionId); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/SessionModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/SessionModel.cs new file mode 100644 index 00000000..5852c93d --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/SessionModel.cs @@ -0,0 +1,7 @@ +namespace BotSharp.Abstraction.Conversations.Models; + +public class SessionModel +{ + public string UserId { get; set; } = string.Empty; + public string SessionId { get; set; } = string.Empty; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs b/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs index 9ef270f1..cb58a3c5 100644 --- a/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs +++ b/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs @@ -1,9 +1,11 @@ +using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Models; namespace BotSharp.Abstraction; public interface IPlatformMidware { + ISessionService SessionService { get; } Task GetChatCompletionsAsync(List conversations, Func onChunkReceived); } diff --git a/src/Infrastructure/BotSharp.Abstraction/ITaskRouter.cs b/src/Infrastructure/BotSharp.Abstraction/ITaskRouter.cs deleted file mode 100644 index 546257ff..00000000 --- a/src/Infrastructure/BotSharp.Abstraction/ITaskRouter.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace BotSharp.Abstraction; - -public interface ITaskRouter -{ -} diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 0e9855d5..34cddefa 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -1,5 +1,10 @@ +using BotSharp.Abstraction.Conversations; +using BotSharp.Core.Conversations; +using BotSharp.Core.Repository; using BotSharp.Core.Services; +using EntityFrameworkCore.BootKit; using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace BotSharp.Core; @@ -9,6 +14,8 @@ public static class BotSharpServiceCollectionExtensions public static IServiceCollection AddBotSharp(this IServiceCollection services) { services.AddScoped(); + services.AddSingleton(); + return services; } @@ -25,4 +32,26 @@ public static class BotSharpServiceCollectionExtensions return app; } + + public static void RegisterRepository(this IServiceCollection services, IConfiguration config) + { + var databaseSettings = new DatabaseSettings(); + config.Bind("Database", databaseSettings); + services.AddSingleton((IServiceProvider x) => + { + return databaseSettings; + }); + + var myDatabaseSettings = new MyDatabaseSettings(); + config.Bind("Database", myDatabaseSettings); + services.AddSingleton((IServiceProvider x) => + { + return databaseSettings; + }); + + services.AddScoped((IServiceProvider x) => + { + return DataContextHelper.GetDbContext(myDatabaseSettings, x); + }); + } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/ConversationService.cs new file mode 100644 index 00000000..507d0db5 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Conversations/ConversationService.cs @@ -0,0 +1,52 @@ +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace BotSharp.Core.Conversations; + +public class ConversationService : IConversationService +{ + Dictionary> _history; + + public ConversationService() + { + _history = new Dictionary>(); + } + + public void AddDialog(RoleDialogModel dialog) + { + _history[Guid.Empty.ToString()].Add(dialog); + } + + public void CleanHistory() + { + throw new NotImplementedException(); + } + + public void DeleteSession() + { + throw new NotImplementedException(); + } + + public List GetAllSessions() + { + 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(); + } +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/SessionService.cs b/src/Infrastructure/BotSharp.Core/Conversations/SessionService.cs new file mode 100644 index 00000000..d35e92e7 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Conversations/SessionService.cs @@ -0,0 +1,32 @@ +using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Conversations.Models; + +namespace BotSharp.Core.Conversations; + +public class SessionService : ISessionService +{ + Dictionary> _sessions; + + public SessionService() + { + _sessions = new Dictionary>(); + } + + public void DeleteSession(string sessionId) + { + throw new NotImplementedException(); + } + + public List GetAllSessions(string userId) + { + throw new NotImplementedException(); + } + + public SessionModel NewSession(string userId) + { + return new SessionModel + { + SessionId = Guid.NewGuid().ToString() + }; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs b/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs new file mode 100644 index 00000000..139a2199 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Repository/DataContextHelper.cs @@ -0,0 +1,28 @@ +using EntityFrameworkCore.BootKit; +using Microsoft.Data.SqlClient; + +namespace BotSharp.Core.Repository; + +public static class DataContextHelper +{ + public static T GetDbContext(MyDatabaseSettings settings, IServiceProvider serviceProvider) + where T : Database, new() + { + if (settings.Assemblies == null) + throw new Exception("Please set assemblies."); + + AppDomain.CurrentDomain.SetData("Assemblies", settings.Assemblies); + + var dc = new T(); + if (typeof(T) == typeof(DbContext4MongoDb)) + { + dc.BindDbContext(new DatabaseBind + { + ServiceProvider = serviceProvider, + MasterConnection = new MongoDbConnection("mongodb://user:password@localhost:27017"), + CreateDbIfNotExist = true + }); + } + return dc; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs b/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs new file mode 100644 index 00000000..a3bebd79 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Repository/IMongoDbCollection.cs @@ -0,0 +1,5 @@ +namespace BotSharp.Core.Repository; + +public interface IMongoDbCollection +{ +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs new file mode 100644 index 00000000..c2279b08 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Repository/MongoDbContext.cs @@ -0,0 +1,7 @@ +using EntityFrameworkCore.BootKit; + +namespace BotSharp.Core.Repository; + +public class MongoDbContext : Database +{ +} diff --git a/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs b/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs new file mode 100644 index 00000000..8227200e --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Repository/MyDatabaseSettings.cs @@ -0,0 +1,9 @@ +using EntityFrameworkCore.BootKit; + +namespace BotSharp.Core.Repository; + +public class MyDatabaseSettings : DatabaseSettings +{ + public string[] Assemblies { get; set; } + public DbConnectionSetting MongoDb { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs b/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs index 2bc58a21..211995e3 100644 --- a/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs +++ b/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Models; using Microsoft.Extensions.DependencyInjection; @@ -6,11 +7,16 @@ namespace BotSharp.Core.Services; public class PlatformMidware : IPlatformMidware { private readonly IServiceProvider _services; + private readonly ISessionService _sessionService; + public PlatformMidware(IServiceProvider services) { _services = services; + _sessionService = services.GetRequiredService(); } + public ISessionService SessionService => _sessionService; + public async Task GetChatCompletionsAsync(List conversations, Func onChunkReceived) { diff --git a/src/UiAdapters/HuggingChatUI/HuggingChat-UI.md b/src/UiAdapters/HuggingChatUI/HuggingChat-UI.md new file mode 100644 index 00000000..7b9c3733 --- /dev/null +++ b/src/UiAdapters/HuggingChatUI/HuggingChat-UI.md @@ -0,0 +1,16 @@ +# Chatbot UI +[HuggingChat UI](https://github.com/huggingface/chat-ui) is A chat interface using open source models, eg OpenAssistant.. + +```shell +git clone https://github.com/huggingface/chat-ui +npm i +npm run dev +``` + +* Rename `.env.local.example` to `.env.local` + +```shell +# Change host to BotSharp service +OPENAI_API_HOST=http://localhost:5500 +``` + diff --git a/src/UiAdapters/HuggingChatUI/HuggingChatUI.csproj b/src/UiAdapters/HuggingChatUI/HuggingChatUI.csproj new file mode 100644 index 00000000..ad4bc398 --- /dev/null +++ b/src/UiAdapters/HuggingChatUI/HuggingChatUI.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.1 + enable + 10 + + + + + + + + + + + diff --git a/src/UiAdapters/HuggingChatUI/HuggingChatUiController.cs b/src/UiAdapters/HuggingChatUI/HuggingChatUiController.cs new file mode 100644 index 00000000..ff1e7f90 --- /dev/null +++ b/src/UiAdapters/HuggingChatUI/HuggingChatUiController.cs @@ -0,0 +1,31 @@ +using BotSharp.Abstraction; +using HuggingChatUI.ViewModels; +using Microsoft.AspNetCore.Mvc; +using System; + +namespace HuggingChatUI; + +public class HuggingChatUiController : ControllerBase, IBotUiAdapter +{ + private readonly IPlatformMidware _platform; + public HuggingChatUiController(IPlatformMidware platform) + { + _platform = platform; + } + + [HttpPost("conversation")] + public ConversationViewModel NewSession([FromBody] ConversationCreationModel conversationCreationModel) + { + var session = _platform.SessionService.NewSession(""); + return new ConversationViewModel + { + ConversationId = session.SessionId.Replace("-", "").Substring(0, 24) + }; + } + + [HttpPost("conversation/{id}/summarize")] + public string SummarizeTitle([FromRoute] string id) + { + return "SummarizeTitle"; + } +} diff --git a/src/UiAdapters/HuggingChatUI/ViewModels/ConversationCreationModel.cs b/src/UiAdapters/HuggingChatUI/ViewModels/ConversationCreationModel.cs new file mode 100644 index 00000000..bc163860 --- /dev/null +++ b/src/UiAdapters/HuggingChatUI/ViewModels/ConversationCreationModel.cs @@ -0,0 +1,6 @@ +namespace HuggingChatUI.ViewModels; + +public class ConversationCreationModel +{ + public string Model { get; set; } +} diff --git a/src/UiAdapters/HuggingChatUI/ViewModels/ConversationViewModel.cs b/src/UiAdapters/HuggingChatUI/ViewModels/ConversationViewModel.cs new file mode 100644 index 00000000..34415754 --- /dev/null +++ b/src/UiAdapters/HuggingChatUI/ViewModels/ConversationViewModel.cs @@ -0,0 +1,6 @@ +namespace HuggingChatUI.ViewModels; + +public class ConversationViewModel +{ + public string ConversationId { get; set; } +} diff --git a/src/WebStarter/Program.cs b/src/WebStarter/Program.cs index 0ceaeabb..80e606ed 100644 --- a/src/WebStarter/Program.cs +++ b/src/WebStarter/Program.cs @@ -15,6 +15,17 @@ builder.Services.AddBotSharp(); builder.Services.AddLlamaSharp(builder.Configuration); // builder.Services.AddAzureOpenAi(builder.Configuration); +builder.Services.AddCors(options => +{ + options.AddPolicy("MyCorsPolicy", + builder => + { + builder.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader(); + }); +}); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -31,4 +42,8 @@ app.MapControllers(); // Use BotSharp app.UseBotSharp(); +#if DEBUG +app.UseCors("MyCorsPolicy"); +#endif + app.Run(); diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 4844661f..63354942 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -31,6 +31,7 @@ + diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 134053e0..4a5ae1b7 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -26,5 +26,12 @@ "InstructionFile": "Prompts\\chat-with-bob.txt", "ChatSampleFile": "Prompts\\chat-samples.txt", "DeploymentModel": "" + }, + + "Database": { + "MongoDb": { + "Master": "mongodb://localhost:27017" + }, + "Assemblies": [ "BotSharp.Core" ] } }