diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj index 80a83846..fc457ebd 100644 --- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj +++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj @@ -4,7 +4,7 @@ netstandard2.1 enable 10.0 - 0.10.0 + 0.10.1 Icon.png diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 6f56d00b..80cd6984 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -1,4 +1,3 @@ -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.MLTasks; namespace BotSharp.Abstraction.Conversations; diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs new file mode 100644 index 00000000..0adb2be8 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/IInstructService.cs @@ -0,0 +1,10 @@ +namespace BotSharp.Abstraction.Instructs; + +public interface IInstructService +{ + Task ExecuteInstructionRecursively(Agent agent, + List wholeDialogs, + Func onMessageReceived, + Func onFunctionExecuting, + Func onFunctionExecuted); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs new file mode 100644 index 00000000..f89bb8e0 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Instructs/Models/InstructResult.cs @@ -0,0 +1,8 @@ +namespace BotSharp.Abstraction.Instructs.Models; + +public class InstructResult +{ + public string Text { get; set; } + public string Function { get; set; } + public object Data { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 0d089123..98079d96 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -4,7 +4,7 @@ netstandard2.1 10.0 false - 0.10.0 + 0.10.1 diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs index 7b22c5d9..798f59c3 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs @@ -10,6 +10,8 @@ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using BotSharp.Abstraction.Routing.Settings; using BotSharp.Abstraction.Templating; +using BotSharp.Core.Instructs; +using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Routing; using BotSharp.Core.Routing.Services; @@ -58,7 +60,6 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); // Register function callback services.AddScoped(); @@ -73,6 +74,8 @@ public static class BotSharpServiceCollectionExtensions services.AddScoped(); } + services.AddScoped(); + return services; } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs index 02a81350..fbd879ed 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.CallFunctions.cs @@ -1,4 +1,3 @@ -using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Functions; namespace BotSharp.Core.Conversations.Services; diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.CallFunctions.cs b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.CallFunctions.cs new file mode 100644 index 00000000..025b11e8 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.CallFunctions.cs @@ -0,0 +1,50 @@ +using BotSharp.Abstraction.Functions; + +namespace BotSharp.Core.Instructs; + +public partial class InstructService +{ + private async Task CallFunctions(RoleDialogModel msg) + { + var hooks = _services.GetServices() + .OrderBy(x => x.Priority).ToList(); + + // Invoke functions + var functions = _services.GetServices() + .Where(x => x.Name == msg.FunctionName) + .ToList(); + + if (functions.Count == 0) + { + msg.Content = $"Can't find function implementation of {msg.FunctionName}."; + _logger.LogError(msg.Content); + return; + } + + foreach (var fn in functions) + { + // Before executing functions + foreach (var hook in hooks) + { + await hook.OnFunctionExecuting(msg); + } + + try + { + // Execute function + await fn.Execute(msg); + } + catch (Exception ex) + { + msg.ExecutionResult = ex.Message; + _logger.LogError(msg.ExecutionResult); + } + + // After functions have been executed + foreach (var hook in hooks) + { + await hook.OnFunctionExecuted(msg); + } + } + } +} diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs new file mode 100644 index 00000000..c3ad6346 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs @@ -0,0 +1,84 @@ +using BotSharp.Abstraction.Agents.Enums; +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.Instructs; +using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Templating; + +namespace BotSharp.Core.Instructs; + +public partial class InstructService : IInstructService +{ + private readonly IServiceProvider _services; + private readonly ILogger _logger; + + public InstructService(IServiceProvider services, ILogger logger) + { + _services = services; + _logger = logger; + } + + public async Task ExecuteInstructionRecursively(Agent agent, + List wholeDialogs, + Func onMessageReceived, + Func onFunctionExecuting, + Func onFunctionExecuted) + { + var chatCompletion = GetChatCompletion(); + + var result = await chatCompletion.GetChatCompletionsAsync(agent, wholeDialogs, async msg => + { + await onMessageReceived(msg); + }, async fn => + { + var preAgentId = agent.Id; + + await HandleFunctionMessage(fn, onFunctionExecuting, onFunctionExecuted); + + // Function executed has exception + if (fn.ExecutionResult == null || fn.StopCompletion) + { + await onMessageReceived(new RoleDialogModel(AgentRole.Assistant, fn.Content)); + return; + } + + fn.Content = fn.FunctionArgs.Replace("\r", " ").Replace("\n", " ").Trim() + " => " + fn.ExecutionResult; + + // Find response template + var templateService = _services.GetRequiredService(); + var response = await templateService.RenderFunctionResponse(agent.Id, fn); + if (!string.IsNullOrEmpty(response)) + { + await onMessageReceived(new RoleDialogModel(AgentRole.Assistant, response)); + return; + } + + // After function is executed, pass the result to LLM to get a natural response + wholeDialogs.Add(fn); + + await ExecuteInstructionRecursively(agent, + wholeDialogs, + onMessageReceived, + onFunctionExecuting, + onFunctionExecuted); + }); + + return result; + } + + private async Task HandleFunctionMessage(RoleDialogModel msg, + Func onFunctionExecuting, + Func onFunctionExecuted) + { + // Call functions + await onFunctionExecuting(msg); + await CallFunctions(msg); + await onFunctionExecuted(msg); + } + + public IChatCompletion GetChatCompletion() + { + var completions = _services.GetServices(); + var settings = _services.GetRequiredService(); + return completions.FirstOrDefault(x => x.GetType().FullName.EndsWith(settings.ChatCompletion)); + } +} diff --git a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj index 316f4488..f8fbe32d 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj +++ b/src/Infrastructure/BotSharp.OpenAPI/BotSharp.OpenAPI.csproj @@ -4,7 +4,7 @@ net6.0 enable enable - 0.10.0 + 0.10.1 diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs new file mode 100644 index 00000000..798d4786 --- /dev/null +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs @@ -0,0 +1,54 @@ +using BotSharp.Abstraction.Agents.Models; +using BotSharp.Abstraction.ApiAdapters; +using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Instructs; +using BotSharp.Abstraction.Instructs.Models; +using BotSharp.OpenAPI.ViewModels.Conversations; + +namespace BotSharp.OpenAPI.Controllers; + +[Authorize] +[ApiController] +public class InstructModeController : ControllerBase, IApiAdapter +{ + private readonly IServiceProvider _services; + private readonly IUserIdentity _user; + + public InstructModeController(IServiceProvider services, + IUserIdentity user) + { + _services = services; + _user = user; + } + + [HttpPost("/instruct/{agentId}")] + public async Task NewConversation([FromRoute] string agentId, + [FromBody] NewMessageModel input) + { + var response = new InstructResult(); + var instructor = _services.GetRequiredService(); + var agentService = _services.GetRequiredService(); + Agent agent = await agentService.LoadAgent(agentId); + + await instructor.ExecuteInstructionRecursively(agent, + new List + { + new RoleDialogModel("user", input.Text) + }, + async msg => + { + response.Text = msg.Content; + }, + async fnExecuting => + { + + }, + async fnExecuted => + { + response.Function = fnExecuted.FunctionName; + response.Data = fnExecuted.ExecutionData; + }); + + return response; + } +} diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj b/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj index 05ba639e..8894d113 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/BotSharp.Plugin.AzureOpenAI.csproj @@ -4,7 +4,7 @@ netstandard2.1 enable 10 - 0.10.0 + 0.10.1 diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj b/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj index d69c44a5..86e8c9ce 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/BotSharp.Plugin.ChatbotUI.csproj @@ -4,7 +4,7 @@ netstandard2.1 enable 10 - 0.10.0 + 0.10.1 diff --git a/src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md b/src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md index bd204927..aca52922 100644 --- a/src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md +++ b/src/Plugins/BotSharp.Plugin.ChatbotUI/Chatbot-UI.md @@ -1,8 +1,9 @@ # Chatbot UI -[Chatbot UI](https://github.com/mckaywrigley/chatbot-ui) is an open source chat UI for AI models. +[Chatbot UI](https://github.com/SciSharp/chatbot-ui) is an open source chat UI for AI models. ```shell -git clone https://github.com/mckaywrigley/chatbot-ui +git clone https://github.com/SciSharp/chatbot-ui +cd chatbot-ui (change dir to chatbot-ui to find the package.json) npm i npm run dev ``` diff --git a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj index 915bebbb..6b57677e 100644 --- a/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj +++ b/src/Plugins/BotSharp.Plugin.MetaAI/BotSharp.Plugin.MetaAI.csproj @@ -4,7 +4,7 @@ netstandard2.1 enable 10 - 0.9.0 + 0.10.1 diff --git a/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj b/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj index fe2e95fd..30132b08 100644 --- a/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj +++ b/src/Plugins/BotSharp.Plugin.MetaMessenger/BotSharp.Plugin.MetaMessenger.csproj @@ -3,7 +3,7 @@ netstandard2.1 10 - 0.9.0 + 0.10.1 diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj index fb145e8d..82861f2e 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/BotSharp.Plugin.RoutingSpeeder.csproj @@ -4,10 +4,11 @@ netstandard2.1 enable 10 - 0.11.0 + 0.10.1 + diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Controllers/RoutingSpeederController.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Controllers/RoutingSpeederController.cs new file mode 100644 index 00000000..67cb0c40 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Controllers/RoutingSpeederController.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading.Tasks; +using BotSharp.Plugin.RoutingSpeeder.Providers; +using BotSharp.Plugin.RoutingSpeeder.Providers.Models; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.DependencyInjection; + +namespace BotSharp.Plugin.RoutingSpeeder.Controllers; + +[AllowAnonymous] +public class RoutingSpeederController : ControllerBase +{ + private readonly IServiceProvider _service; + public RoutingSpeederController(IServiceProvider service) + { + _service = service; + } + + [HttpPost("/routing-speeder/classifier/train")] + public IActionResult TrainIntentClassifier(TrainingParams trainingParams) + { + var intentClassifier = _service.GetRequiredService(); + intentClassifier.InitClassifer(trainingParams.Inference); + intentClassifier.Train(trainingParams); + return Ok(intentClassifier.Labels); + } + +} diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/IntentClassifier.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/IntentClassifier.cs index 3c3a33f2..440bebf0 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/IntentClassifier.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/IntentClassifier.cs @@ -11,31 +11,46 @@ using Tensorflow.Keras.Callbacks; using System.Text.RegularExpressions; using BotSharp.Plugin.RoutingSpeeder.Settings; using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Knowledges.Settings; using BotSharp.Plugin.RoutingSpeeder.Providers.Models; using Microsoft.Extensions.DependencyInjection; using System.Linq; using Tensorflow.Keras; -using BotSharp.Abstraction.Knowledges.Settings; using System.Numerics; using Newtonsoft.Json; using Tensorflow.Keras.Layers; using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Knowledges; namespace BotSharp.Plugin.RoutingSpeeder.Providers; public class IntentClassifier { private readonly IServiceProvider _services; + private KnowledgeBaseSettings _knowledgeBaseSettings; Model _model; public Model model => _model; private bool _isModelReady; public bool isModelReady => _isModelReady; private ClassifierSetting _settings; - public IntentClassifier(IServiceProvider services, ClassifierSetting settings) + private string[] _labels; + + public string[] Labels => GetLabels(); + + private int _numLabels + { + get + { + return Labels.Length; + } + } + + public IntentClassifier(IServiceProvider services, ClassifierSetting settings, KnowledgeBaseSettings knowledgeBaseSettings) { _services = services; _settings = settings; + _knowledgeBaseSettings = knowledgeBaseSettings; } private void Reset() @@ -50,17 +65,16 @@ public class IntentClassifier { return; } - - var vector = _services.GetRequiredService(); - var labels = GetLabels(); + var vector = _services.GetServices() + .FirstOrDefault(x => x.GetType().FullName.EndsWith(_knowledgeBaseSettings.TextEmbedding)); var layers = new List { keras.layers.InputLayer((vector.Dimension), name: "Input"), keras.layers.Dense(256, activation:"relu"), keras.layers.Dense(256, activation:"relu"), - keras.layers.Dense(labels.Length, activation: keras.activations.Softmax) + keras.layers.Dense(_numLabels, activation: keras.activations.Softmax) }; _model = keras.Sequential(layers); @@ -90,7 +104,7 @@ public class IntentClassifier var callbacks = new List() { earlyStop }; - var weights = LoadWeights(); + var weights = LoadWeights(trainingParams.Inference); _model.fit(x, y, batch_size: trainingParams.BatchSize, @@ -104,42 +118,27 @@ public class IntentClassifier _isModelReady = true; } - public string LoadWeights() + public string LoadWeights(bool inference = true) { var agentService = _services.CreateScope().ServiceProvider.GetRequiredService(); var weightsFile = Path.Combine(agentService.GetDataDir(), _settings.MODEL_DIR, $"intent-classifier.h5"); - if (File.Exists(weightsFile)) + + if (File.Exists(weightsFile) && inference) { _model.load_weights(weightsFile); _isModelReady = true; Console.WriteLine($"Successfully load the weights!"); + } else { - Console.WriteLine("No available weights."); + var logInfo = inference ? "No available weights." : "Will implement model training process and write trained weights into local"; + Console.WriteLine(logInfo); } return weightsFile; } - public (NDArray x, NDArray y) Vectorize(List items) - { - var vector = _services.GetRequiredService(); - - var x = np.zeros((items.Count, vector.Dimension), dtype: np.float32); - var y = np.zeros((items.Count, 1), dtype: np.float32); - - for (int i = 0; i < items.Count; i++) - { - x[i] = vector.GetVector(TextClean(items[i].text)); - if (_settings.LabelMappingDict.ContainsKey(items[i].label)) - { - y[i] = _settings.LabelMappingDict[items[i].label]; - } - } - return (x, y); - } - public NDArray GetTextEmbedding(string text) { var knowledgeSettings = _services.GetRequiredService(); @@ -164,10 +163,10 @@ public class IntentClassifier var vector = _services.GetRequiredService(); - var vectorList = new List(); var labelList = new List(); + foreach (var filePath in GetFiles()) { var texts = File.ReadAllLines(filePath, Encoding.UTF8).Select(x => TextClean(x)).ToList(); @@ -192,19 +191,24 @@ public class IntentClassifier return (x, y); } - public string[] GetFiles() + public string[] GetFiles(string prefix = "intent") { var agentService = _services.CreateScope().ServiceProvider.GetRequiredService(); string rootDirectory = Path.Combine(agentService.GetDataDir(), _settings.RAW_DATA_DIR); - return Directory.GetFiles(rootDirectory).OrderBy(x => x).ToArray(); + return Directory.GetFiles(rootDirectory).Where(x => Path.GetFileNameWithoutExtension(x).StartsWith(prefix)).OrderBy(x => x).ToArray(); } public string[] GetLabels() { - var agentService = _services.CreateScope().ServiceProvider.GetRequiredService(); - string rootDirectory = Path.Combine(agentService.GetDataDir(), _settings.MODEL_DIR, _settings.LABEL_FILE_NAME); - var labelText = File.ReadAllLines(rootDirectory); - return labelText.OrderBy(x => x).ToArray(); + if (_labels == null) + { + var agentService = _services.CreateScope().ServiceProvider.GetRequiredService(); + string rootDirectory = Path.Combine(agentService.GetDataDir(), _settings.MODEL_DIR, _settings.LABEL_FILE_NAME); + var labelText = File.ReadAllLines(rootDirectory); + _labels = labelText.OrderBy(x => x).ToArray(); + } + + return _labels; } public string TextClean(string text) @@ -235,24 +239,22 @@ public class IntentClassifier return string.Empty; } - var prediction = GetLabels()[probLabel[0]]; + var prediction = _labels[probLabel[0]]; return prediction; } - public void InitClassifer() + public void InitClassifer(bool inference = true) { Reset(); Build(); - LoadWeights(); + LoadWeights(inference); } - public void Train() + public void Train(TrainingParams trainingParams) { - var trainingParams = new TrainingParams(); Reset(); (var x, var y) = PrepareLoadData(); Build(); Fit(x, y, trainingParams); - } } diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/Models/TrainingParams.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/Models/TrainingParams.cs index f3c822ac..4cd9829c 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/Models/TrainingParams.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/Providers/Models/TrainingParams.cs @@ -10,4 +10,5 @@ public class TrainingParams public int Epochs { get; set; } = 10; public int BatchSize { get; set; } = 16; public float LearningRate { get; set; } = 1.0e-4f; + public bool Inference { get; set; } = false; } diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs index 869afe94..4b8c3bc5 100644 --- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs +++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs @@ -1,8 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; -using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.DependencyInjection; using System; using System.Linq; @@ -10,7 +8,6 @@ using System.Threading.Tasks; using BotSharp.Plugin.RoutingSpeeder.Settings; using BotSharp.Abstraction.Templating; using BotSharp.Plugin.RoutingSpeeder.Providers; -using System.Runtime.InteropServices; using BotSharp.Abstraction.Agents; using System.IO; using BotSharp.Abstraction.Routing.Settings; @@ -59,16 +56,20 @@ public class RoutingConversationHook: ConversationHookBase var agentService = _services.CreateScope().ServiceProvider.GetRequiredService(); var rootDataPath = agentService.GetDataDir(); - string rawDataDir = Path.Combine(rootDataPath, "raw_data", $"{message.CurrentAgentId}.txt"); - var lastThreeDialogs = _dialogs.Where(x => x.Role == AgentRole.User).Select(x => x.Content).Reverse().Take(3).ToArray(); + string rawDataDir = Path.Combine(rootDataPath, "raw_data", $"agent.{message.CurrentAgentId}.txt"); + var lastThreeDialogs = _dialogs.Where(x => x.Role == AgentRole.User || x.Role == AgentRole.Assistant) + .Select(x => x.Content.Replace('\r', ' ').Replace('\n', ' ')) + .TakeLast(3) + .ToArray(); + var content = string.Join(' ', lastThreeDialogs) + Environment.NewLine; if (!File.Exists(rawDataDir)) { - await File.WriteAllLinesAsync(rawDataDir, lastThreeDialogs); + await File.WriteAllTextAsync(rawDataDir, content); } else { - await File.AppendAllLinesAsync(rawDataDir, lastThreeDialogs); + await File.AppendAllTextAsync(rawDataDir, content); } } } diff --git a/src/WebStarter/data/models/intent-classifier.h5 b/src/WebStarter/data/models/intent-classifier.h5 index 13f2ebed..e4be7ee5 100644 Binary files a/src/WebStarter/data/models/intent-classifier.h5 and b/src/WebStarter/data/models/intent-classifier.h5 differ