diff --git a/BotSharp.sln b/BotSharp.sln index 4c109be9..f3aa017a 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -23,11 +23,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebStarter", "src\WebStarte EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Platform.AzureAi", "src\Platforms\BotSharp.Platform.AureAi\BotSharp.Platform.AzureAi.csproj", "{B874E946-AE39-4731-8DA5-16A99115D111}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BotUIs", "BotUIs", "{42226933-0A0D-48E8-85EC-AFE773A1F841}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UiAdapters", "UiAdapters", "{42226933-0A0D-48E8-85EC-AFE773A1F841}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatbotUI", "src\BotUIs\ChatbotUI\ChatbotUI.csproj", "{E33CC7F2-225E-42A9-8B4A-EAA97930D820}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChatbotUI", "src\UiAdapters\ChatbotUI\ChatbotUI.csproj", "{223895FB-EE4C-4225-8042-292352B43973}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Platform.Local", "src\Platforms\BotSharp.Platform.Local\BotSharp.Platform.Local.csproj", "{7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Platform.LlamaSharp", "src\Platforms\BotSharp.Platform.LlamaSharp\BotSharp.Platform.LlamaSharp.csproj", "{0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -93,22 +93,22 @@ Global {B874E946-AE39-4731-8DA5-16A99115D111}.Release|Any CPU.Build.0 = Release|Any CPU {B874E946-AE39-4731-8DA5-16A99115D111}.Release|x64.ActiveCfg = Release|Any CPU {B874E946-AE39-4731-8DA5-16A99115D111}.Release|x64.Build.0 = Release|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Debug|x64.ActiveCfg = Debug|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Debug|x64.Build.0 = Debug|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Release|Any CPU.Build.0 = Release|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Release|x64.ActiveCfg = Release|Any CPU - {E33CC7F2-225E-42A9-8B4A-EAA97930D820}.Release|x64.Build.0 = Release|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Debug|x64.ActiveCfg = Debug|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Debug|x64.Build.0 = Debug|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Release|Any CPU.Build.0 = Release|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Release|x64.ActiveCfg = Release|Any CPU - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39}.Release|x64.Build.0 = Release|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Debug|Any CPU.Build.0 = Debug|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Debug|x64.ActiveCfg = Debug|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Debug|x64.Build.0 = Debug|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Release|Any CPU.ActiveCfg = Release|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Release|Any CPU.Build.0 = Release|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Release|x64.ActiveCfg = Release|Any CPU + {223895FB-EE4C-4225-8042-292352B43973}.Release|x64.Build.0 = Release|Any CPU + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Debug|x64.ActiveCfg = Debug|Any CPU + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Debug|x64.Build.0 = Debug|Any CPU + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -120,8 +120,8 @@ Global {36F5CEBD-31A8-4BEF-8BAA-BAC4E63E4815} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} {286C7DE5-1EBC-4D28-AB25-4FAAD4C31D2A} = {FFA662D3-B67B-478D-92FC-76DC5EB64412} {B874E946-AE39-4731-8DA5-16A99115D111} = {FFA662D3-B67B-478D-92FC-76DC5EB64412} - {E33CC7F2-225E-42A9-8B4A-EAA97930D820} = {42226933-0A0D-48E8-85EC-AFE773A1F841} - {7ECA0231-ECE5-416B-AC61-9B1A8DACCD39} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} + {223895FB-EE4C-4225-8042-292352B43973} = {42226933-0A0D-48E8-85EC-AFE773A1F841} + {0D2CA3E8-11A1-4CA4-B07B-4EF01378866D} = {FFA662D3-B67B-478D-92FC-76DC5EB64412} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/README.md b/README.md index a84b4422..482018e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# The Open Source AI Chatbot Platform Builder +# Chatbot Platform Builder +## Powered by LLM [![Discord](https://img.shields.io/discord/1106946823282761851?label=Discord)](https://discord.gg/qRVm82fKTS) [![QQ群聊](https://img.shields.io/static/v1?label=QQ&message=群聊&color=brightgreen)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=sN9VVMwbWjs5L0ATpizKKxOcZdEPMrp8&authKey=RLDw41bLTrEyEgZZi%2FzT4pYk%2BwmEFgFcrhs8ZbkiVY7a4JFckzJefaYNW6Lk4yPX&noverify=0&group_code=985366726) diff --git a/src/BotUIs/ChatbotUI/ChatbotUiController.cs b/src/BotUIs/ChatbotUI/ChatbotUiController.cs deleted file mode 100644 index 335b9525..00000000 --- a/src/BotUIs/ChatbotUI/ChatbotUiController.cs +++ /dev/null @@ -1,39 +0,0 @@ -using BotSharp.Abstraction; -using BotSharp.Abstraction.Models; -using ChatbotUI.ViewModels; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using System.Collections.Generic; - -namespace BotSharp.Platform.AzureAi.Controllers; - -[ApiController] -public class ChatbotUiController : ControllerBase, IBotUiAdapter -{ - private readonly ILogger _logger; - - public ChatbotUiController(ILogger logger) - { - _logger = logger; - } - - [HttpGet("/v1/models")] - [HttpGet("/openai/deployments")] - public OpenAiModels GetOpenAiModels() - { - return new OpenAiModels - { - Data = new List - { - new AiModel - { - Id = "gpt-3.5-turbo", - Model = "gpt-3.5-turbo", - Name = "Default (GPT-3.5)", - MaxLength = 4000, - TokenLimit = 4000 - } - } - }; - } -} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj index 6f642e0f..7ed8ddb0 100644 --- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj +++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj @@ -6,4 +6,10 @@ 10.0 + + + + + + diff --git a/src/Infrastructure/BotSharp.Abstraction/GlobalUsing.cs b/src/Infrastructure/BotSharp.Abstraction/GlobalUsing.cs new file mode 100644 index 00000000..13e227ca --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/GlobalUsing.cs @@ -0,0 +1,4 @@ +global using System; +global using System.Collections.Generic; +global using System.Text; +global using System.Threading.Tasks; \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/IChatCompletionHandler.cs b/src/Infrastructure/BotSharp.Abstraction/IChatCompletionHandler.cs new file mode 100644 index 00000000..2e7ef0bc --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/IChatCompletionHandler.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Abstraction; + +public interface IChatCompletionHandler +{ + Task GetChatCompletionsAsync(string text, Func onChunkReceived); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs b/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs new file mode 100644 index 00000000..423d15ce --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/IPlatformMidware.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Abstraction; + +public interface IPlatformMidware +{ + Task GetChatCompletionsAsync(string text, Func onChunkReceived); +} diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index ac1b55ff..ff8a1825 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -1,9 +1,9 @@ - + netstandard2.1 10.0 - true + false 0.4.0 @@ -56,8 +56,6 @@ - - diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs new file mode 100644 index 00000000..0e9855d5 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -0,0 +1,28 @@ +using BotSharp.Core.Services; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace BotSharp.Core; + +public static class BotSharpServiceCollectionExtensions +{ + public static IServiceCollection AddBotSharp(this IServiceCollection services) + { + services.AddScoped(); + return services; + } + + public static void ConfigureBotSharp(this IServiceCollection services) + { + } + + public static IApplicationBuilder UseBotSharp(this IApplicationBuilder app) + { + if (app == null) + { + throw new ArgumentNullException(nameof(app)); + } + + return app; + } +} diff --git a/src/Infrastructure/BotSharp.Core/GlobalUsing.cs b/src/Infrastructure/BotSharp.Core/GlobalUsing.cs new file mode 100644 index 00000000..b431e4ed --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/GlobalUsing.cs @@ -0,0 +1,6 @@ +global using System; +global using System.Collections.Generic; +global using System.Text; +global using System.Threading.Tasks; +global using BotSharp.Abstraction; +global using System.Linq; \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs b/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs new file mode 100644 index 00000000..287026e5 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Services/PlatformMidware.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace BotSharp.Core.Services; + +public class PlatformMidware : IPlatformMidware +{ + private readonly IServiceProvider _services; + public PlatformMidware(IServiceProvider services) + { + _services = services; + } + + public async Task GetChatCompletionsAsync(string text, Func onChunkReceived) + { + var handlers = _services.GetServices().ToList(); + for (int i = 0; i < handlers.Count(); i++) + { + var handler = handlers[i]; + await handler.GetChatCompletionsAsync(text, onChunkReceived); + } + } +} diff --git a/src/Platforms/BotSharp.Platform.AureAi/BotSharp.Platform.AzureAi.csproj b/src/Platforms/BotSharp.Platform.AureAi/BotSharp.Platform.AzureAi.csproj index 6e2feb47..864adce4 100644 --- a/src/Platforms/BotSharp.Platform.AureAi/BotSharp.Platform.AzureAi.csproj +++ b/src/Platforms/BotSharp.Platform.AureAi/BotSharp.Platform.AzureAi.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -7,7 +7,11 @@ - + + + + + diff --git a/src/Platforms/BotSharp.Platform.LlamaSharp/BotSharp.Platform.LlamaSharp.csproj b/src/Platforms/BotSharp.Platform.LlamaSharp/BotSharp.Platform.LlamaSharp.csproj new file mode 100644 index 00000000..e89f1bda --- /dev/null +++ b/src/Platforms/BotSharp.Platform.LlamaSharp/BotSharp.Platform.LlamaSharp.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.1 + enable + 10 + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Platforms/BotSharp.Platform.LlamaSharp/Handlers/ChatCompletionHandler.cs b/src/Platforms/BotSharp.Platform.LlamaSharp/Handlers/ChatCompletionHandler.cs new file mode 100644 index 00000000..af239da7 --- /dev/null +++ b/src/Platforms/BotSharp.Platform.LlamaSharp/Handlers/ChatCompletionHandler.cs @@ -0,0 +1,46 @@ +using BotSharp.Abstraction; +using BotSharp.Platform.LlamaSharp; +using LLama; +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace BotSharp.Platform.Local.Handlers; + +public class ChatCompletionHandler : IChatCompletionHandler +{ + private readonly IChatModel _model; + private readonly LlamaSharpSettings _settings; + + public ChatCompletionHandler(LlamaSharpSettings settings) + { + _settings = settings; + _model = new LLamaModel(new LLamaParams(model: _settings.ModelPath, + n_ctx: 512, + interactive: true, + repeat_penalty: 1.0f, + verbose_prompt: false)); + + if (!string.IsNullOrEmpty(settings.InstructionFile)) + { + var prompt = File.ReadAllText(settings.InstructionFile); + _model.InitChatPrompt(prompt, "UTF-8"); + } + + _model.InitChatAntiprompt(new string[] { "User:" }); + } + + public Task GetChatCompletionsAsync(string text, Func onChunkReceived) + { + string totalResponse = ""; + foreach (var response in _model.Chat(text, "", "UTF-8")) + { + Console.WriteLine(response); + totalResponse += response; + onChunkReceived(response, false); + } + onChunkReceived("", true); + return Task.CompletedTask; + } +} diff --git a/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharpSettings.cs b/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharpSettings.cs new file mode 100644 index 00000000..5d1f5c58 --- /dev/null +++ b/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharpSettings.cs @@ -0,0 +1,8 @@ +namespace BotSharp.Platform.LlamaSharp; + +public class LlamaSharpSettings +{ + public string ModelPath { get; set; } + public string InstructionFile { get; set; } + public int MaxContextLength { get; set; } = 512; +} diff --git a/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharplServiceCollectionExtensions.cs b/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharplServiceCollectionExtensions.cs new file mode 100644 index 00000000..47c03838 --- /dev/null +++ b/src/Platforms/BotSharp.Platform.LlamaSharp/LlamaSharplServiceCollectionExtensions.cs @@ -0,0 +1,22 @@ +using BotSharp.Abstraction; +using BotSharp.Platform.LlamaSharp; +using BotSharp.Platform.Local.Handlers; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace BotSharp.Core; + +public static class LlamaSharplServiceCollectionExtensions +{ + public static IServiceCollection AddLlamaSharp(this IServiceCollection services, IConfiguration config) + { + services.AddSingleton(x => + { + var settings = new LlamaSharpSettings(); + config.Bind("LlamaSharp", settings); + return settings; + }); + services.AddScoped(); + return services; + } +} \ No newline at end of file diff --git a/src/Platforms/BotSharp.Platform.Local/BotSharp.Platform.Local.csproj b/src/Platforms/BotSharp.Platform.Local/BotSharp.Platform.Local.csproj deleted file mode 100644 index 6e2feb47..00000000 --- a/src/Platforms/BotSharp.Platform.Local/BotSharp.Platform.Local.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - netstandard2.1 - enable - 10 - - - - - - - diff --git a/src/Platforms/BotSharp.Platform.OpenAi/BotSharp.Platform.OpenAi.csproj b/src/Platforms/BotSharp.Platform.OpenAi/BotSharp.Platform.OpenAi.csproj index 6e2feb47..736b7ffd 100644 --- a/src/Platforms/BotSharp.Platform.OpenAi/BotSharp.Platform.OpenAi.csproj +++ b/src/Platforms/BotSharp.Platform.OpenAi/BotSharp.Platform.OpenAi.csproj @@ -1,4 +1,4 @@ - + netstandard2.1 @@ -6,8 +6,4 @@ 10 - - - - diff --git a/src/BotUIs/ChatbotUI/Chatbot-UI.md b/src/UiAdapters/ChatbotUI/Chatbot-UI.md similarity index 100% rename from src/BotUIs/ChatbotUI/Chatbot-UI.md rename to src/UiAdapters/ChatbotUI/Chatbot-UI.md diff --git a/src/BotUIs/ChatbotUI/ChatbotUI.csproj b/src/UiAdapters/ChatbotUI/ChatbotUI.csproj similarity index 76% rename from src/BotUIs/ChatbotUI/ChatbotUI.csproj rename to src/UiAdapters/ChatbotUI/ChatbotUI.csproj index ad4bc398..46dae57d 100644 --- a/src/BotUIs/ChatbotUI/ChatbotUI.csproj +++ b/src/UiAdapters/ChatbotUI/ChatbotUI.csproj @@ -7,7 +7,9 @@ + + diff --git a/src/UiAdapters/ChatbotUI/ChatbotUiController.cs b/src/UiAdapters/ChatbotUI/ChatbotUiController.cs new file mode 100644 index 00000000..7a755dc5 --- /dev/null +++ b/src/UiAdapters/ChatbotUI/ChatbotUiController.cs @@ -0,0 +1,117 @@ +using BotSharp.Abstraction; +using BotSharp.Abstraction.Models; +using ChatbotUI.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System; +using Azure.AI.OpenAI; + +namespace BotSharp.Platform.AzureAi.Controllers; + +[ApiController] +public class ChatbotUiController : ControllerBase, IBotUiAdapter +{ + private readonly ILogger _logger; + private readonly IPlatformMidware _platform; + + public ChatbotUiController(ILogger logger, + IPlatformMidware platform) + { + _logger = logger; + _platform = platform; + } + + [HttpGet("/v1/models")] + [HttpGet("/openai/deployments")] + public OpenAiModels GetOpenAiModels() + { + return new OpenAiModels + { + Data = new List + { + new AiModel + { + Id = "gpt-3.5-turbo", + Model = "gpt-3.5-turbo", + Name = "Default (GPT-3.5)", + MaxLength = 4000, + TokenLimit = 4000 + } + } + }; + } + + [HttpPost("/v1/chat/completions")] + [HttpPost("/openai/deployments/one/chat/completions")] + public async Task SendMessage([FromBody] OpenAiMessageInput input, [FromQuery(Name = "api-version")] string apiVersion = "2023-03-15-preview") + { + Response.StatusCode = 200; + Response.Headers.Add(HeaderNames.ContentType, "text/event-stream"); + Response.Headers.Add(HeaderNames.CacheControl, "no-cache"); + Response.Headers.Add(HeaderNames.Connection, "keep-alive"); + var outputStream = Response.Body; + + await _platform.GetChatCompletionsAsync(input.Messages.Last().Content, async (content, end) => + { + if (end) + { + if (content.Length > 0) + { + await OnChunkReceived(outputStream, content); + } + + await OnEventCompleted(outputStream); + } + else + { + await OnChunkReceived(outputStream, content); + } + }); + } + + private async Task OnChunkReceived(Stream outputStream, string content) + { + + var response = new OpenAiChatOutput + { + Choices = new List + { + new OpenAiChoice + { + Delta = new ChatMessage(ChatRole.Assistant, content) + } + } + }; + var json = JsonConvert.SerializeObject(response, new JsonSerializerSettings + { + Formatting = Formatting.None, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + var buffer = Encoding.UTF8.GetBytes($"data:{json}\n"); + await outputStream.WriteAsync(buffer, 0, buffer.Length); + await Task.Delay(100); + + buffer = Encoding.UTF8.GetBytes("\n"); + await outputStream.WriteAsync(buffer, 0, buffer.Length); + } + + private async Task OnEventCompleted(Stream outputStream) + { + var buffer = Encoding.UTF8.GetBytes("data:[DONE]\n"); + await outputStream.WriteAsync(buffer, 0, buffer.Length); + + buffer = Encoding.UTF8.GetBytes("\n"); + await outputStream.WriteAsync(buffer, 0, buffer.Length); + + await outputStream.FlushAsync(); + } +} \ No newline at end of file diff --git a/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChatOutput.cs b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChatOutput.cs new file mode 100644 index 00000000..c9de4233 --- /dev/null +++ b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChatOutput.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace ChatbotUI.ViewModels; + +public class OpenAiChatOutput +{ + public List Choices { get; set; } +} diff --git a/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChoice.cs b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChoice.cs new file mode 100644 index 00000000..cc780949 --- /dev/null +++ b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiChoice.cs @@ -0,0 +1,11 @@ +using Azure.AI.OpenAI; +using System.Text.Json.Serialization; + +namespace ChatbotUI.ViewModels; + +public class OpenAiChoice +{ + [JsonPropertyName("finish_reason")] + public string FinishReason { get; set; } + public ChatMessage Delta { get; set; } +} diff --git a/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageBody.cs b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageBody.cs new file mode 100644 index 00000000..b508afd0 --- /dev/null +++ b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageBody.cs @@ -0,0 +1,7 @@ +namespace ChatbotUI.ViewModels; + +public class OpenAiMessageBody +{ + public string Role { get; set; } + public string Content { get; set; } +} diff --git a/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageInput.cs b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageInput.cs new file mode 100644 index 00000000..b59e0f11 --- /dev/null +++ b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiMessageInput.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.Json.Serialization; + +namespace ChatbotUI.ViewModels; + +public class OpenAiMessageInput +{ + public string Model { get; set; } = string.Empty; + public List Messages { get; set; } = new List(); + [JsonPropertyName("max_tokens")] + public int MaxTokens { get; set; } = 4000; + public bool Stream { get; set; } = true; + public float Temperature { get; set; } = 0.9f; + + public override string ToString() + { + return string.Join("\n", Messages.Select(x => x.Role + ": " + x.Content)); + } +} diff --git a/src/BotUIs/ChatbotUI/ViewModels/OpenAiModels.cs b/src/UiAdapters/ChatbotUI/ViewModels/OpenAiModels.cs similarity index 100% rename from src/BotUIs/ChatbotUI/ViewModels/OpenAiModels.cs rename to src/UiAdapters/ChatbotUI/ViewModels/OpenAiModels.cs diff --git a/src/WebStarter/Controllers/LlmAgentController.cs b/src/WebStarter/Controllers/LlmAgentController.cs deleted file mode 100644 index 864c08a9..00000000 --- a/src/WebStarter/Controllers/LlmAgentController.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace WebStarter.Controllers -{ - [ApiController] - [Route("[controller]")] - public class LlmAgentController : ControllerBase - { - private readonly ILogger _logger; - - public LlmAgentController(ILogger logger) - { - _logger = logger; - } - } -} \ No newline at end of file diff --git a/src/WebStarter/Program.cs b/src/WebStarter/Program.cs index 1fc4133a..dc8e0399 100644 --- a/src/WebStarter/Program.cs +++ b/src/WebStarter/Program.cs @@ -1,3 +1,5 @@ +using BotSharp.Core; + var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -8,9 +10,9 @@ builder.Services.AddSwaggerGen(); builder.Services.AddHttpContextAccessor(); -// Streaming response to Redis -// var multiplexer = ConnectionMultiplexer.Connect("192.168.0.26:6379"); -// builder.Services.AddSingleton(multiplexer); +// Add BotSharp +builder.Services.AddBotSharp(); +builder.Services.AddLlamaSharp(builder.Configuration); var app = builder.Build(); @@ -25,4 +27,7 @@ app.UseAuthorization(); app.MapControllers(); +// Use BotSharp +app.UseBotSharp(); + app.Run(); diff --git a/src/WebStarter/Prompts/chat-with-bob.txt b/src/WebStarter/Prompts/chat-with-bob.txt new file mode 100644 index 00000000..ad494d83 --- /dev/null +++ b/src/WebStarter/Prompts/chat-with-bob.txt @@ -0,0 +1,7 @@ +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 988b1b04..fec95e5d 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -7,15 +7,24 @@ 4fb8c9df-7975-4926-ba73-46c8ca440691 + + + + + + + PreserveNewest + + + - - - - + + + diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index ea367faa..d430d3f5 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -10,5 +10,11 @@ "OpenAi": { "userName": "", "password": "" + }, + + "LlamaSharp": { + "ModelPath": "C:\\Users\\haipi\\Downloads\\ggml-vic13b-q5_1.bin", + "InstructionFile": "Prompts\\chat-with-bob.txt", + "MaxContextLength": 512 } }