diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ChatEvent.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ChatEvent.cs index 0d68fef7d..b81cf3fda 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ChatEvent.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/ChatEvent.cs @@ -5,6 +5,7 @@ public static class ChatEvent public const string OnConversationInitFromClient = nameof(OnConversationInitFromClient); public const string OnMessageReceivedFromClient = nameof(OnMessageReceivedFromClient); public const string OnMessageReceivedFromAssistant = nameof(OnMessageReceivedFromAssistant); + public const string OnIntermediateMessageReceivedFromAssistant = nameof(OnIntermediateMessageReceivedFromAssistant); public const string OnMessageDeleted = nameof(OnMessageDeleted); public const string OnNotificationGenerated = nameof(OnNotificationGenerated); diff --git a/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileSelectContext.cs b/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileSelectContext.cs index 43d4f7797..0a9f6f1dc 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileSelectContext.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Files/Models/FileSelectContext.cs @@ -16,7 +16,4 @@ public class FileSelectItem [JsonPropertyName("file_source")] public string FileSource { get; set; } - - [JsonPropertyName("file_name")] - public string? FileName { get; set; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/MessageHub/Models/HubObserveData.cs b/src/Infrastructure/BotSharp.Abstraction/MessageHub/Models/HubObserveData.cs index d345ab86d..1450ff617 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MessageHub/Models/HubObserveData.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MessageHub/Models/HubObserveData.cs @@ -2,5 +2,13 @@ namespace BotSharp.Abstraction.MessageHub.Models; public class HubObserveData : ObserveDataBase where TData : class, new() { + /// + /// The observed data + /// public TData Data { get; set; } = null!; + + /// + /// Whether to save the observed data To Db + /// + public bool SaveDataToDb { get; set; } } diff --git a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs index 6465b88e5..8b0411fe8 100644 --- a/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs +++ b/src/Infrastructure/BotSharp.Core/Demo/Functions/GetWeatherFn.cs @@ -36,6 +36,17 @@ public async Task Execute(RoleDialogModel message) await Task.Delay(1500); +#if DEBUG + var temp = RoleDialogModel.From(message, AgentRole.Assistant, $"Here is your weather in {args?.City}"); + messageHub.Push(new() + { + EventName = ChatEvent.OnIntermediateMessageReceivedFromAssistant, + Data = temp, + RefId = conv.ConversationId, + SaveDataToDb = true + }); +#endif + message.Indication = $"Still working on it... Hold on, {args?.City}"; messageHub.Push(new() { diff --git a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Pdf.cs b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Pdf.cs index 6478488cc..723dd2ca5 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Pdf.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.Pdf.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Instructs.Models; using BotSharp.Abstraction.Instructs; +using BotSharp.Abstraction.Files.Converters; namespace BotSharp.Core.Files.Services; @@ -22,13 +23,16 @@ public async Task ReadPdf(string text, List files, In { var provider = options?.Provider ?? "openai"; var pdfFiles = await DownloadAndSaveFiles(sessionDir, files); - var targetFiles = pdfFiles; - if (provider != "google-ai") + + var converter = GetImageConverter(options?.ImageConvertProvider); + if (converter == null && provider == "openai") { - targetFiles = await ConvertPdfToImages(pdfFiles, options); + var fileCoreSettings = _services.GetRequiredService(); + converter = GetImageConverter(fileCoreSettings?.ImageConverter?.Provider); } + targetFiles = await ConvertPdfToImages(converter, pdfFiles); if (targetFiles.IsNullOrEmpty()) { return content; @@ -115,15 +119,12 @@ private async Task> DownloadAndSaveFiles(string dir, List> ConvertPdfToImages(IEnumerable files, InstructOptions? options = null) + private async Task> ConvertPdfToImages(IImageConverter converter, IEnumerable files) { var images = new List(); - var settings = _services.GetRequiredService(); - - var converter = GetImageConverter(options?.ImageConvertProvider); if (converter == null || files.IsNullOrEmpty()) { - return images; + return files; } foreach (var file in files) diff --git a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.cs b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.cs index 76c439fae..5f74bc1b4 100644 --- a/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.cs +++ b/src/Infrastructure/BotSharp.Core/Files/Services/Instruct/FileInstructService.cs @@ -91,9 +91,7 @@ private string BuildFileName(string? name, string? extension, string defaultName private IImageConverter? GetImageConverter(string? provider) { - var settings = _services.GetRequiredService(); - var convertProvider = provider ?? settings?.ImageConverter?.Provider; - var converter = _services.GetServices().FirstOrDefault(x => x.Provider == convertProvider); + var converter = _services.GetServices().FirstOrDefault(x => x.Provider == provider); return converter; } #endregion diff --git a/src/Infrastructure/BotSharp.Core/Instructs/Functions/ExecuteTemplateFn.cs b/src/Infrastructure/BotSharp.Core/Instructs/Functions/ExecuteTemplateFn.cs index 9173b587d..b81c56910 100644 --- a/src/Infrastructure/BotSharp.Core/Instructs/Functions/ExecuteTemplateFn.cs +++ b/src/Infrastructure/BotSharp.Core/Instructs/Functions/ExecuteTemplateFn.cs @@ -61,17 +61,6 @@ private async Task GetAiResponse(Agent agent, string templateName) new(AgentRole.User, text) }); - await HookEmitter.Emit(_services, async hook => - await hook.OnResponseGenerated(new InstructResponseModel - { - AgentId = agent.Id, - TemplateName = templateName, - Provider = completion.Provider, - Model = completion.Model, - UserMessage = text, - CompletionText = response.Content - }), agent.Id); - return response.Content; } catch (Exception ex) diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid index 1ada18504..e9fe5e0cc 100644 --- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid +++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid @@ -1,5 +1,5 @@ You're {{router.name}} ({{router.description}}). -You can understand messages sent by users in different languages, and route the request to appropriate agent. +You can route the request to appropriate agent. Default language is English(US). Follow these steps to handle user request: 1. Read the [CONVERSATION] content. 2. Determine which agent is suitable to handle this conversation. Try to minimize the routing of human service. diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Helpers/EventEmitter.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Helpers/EventEmitter.cs index 7c2b40778..821b173e3 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Helpers/EventEmitter.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Helpers/EventEmitter.cs @@ -3,9 +3,9 @@ namespace BotSharp.Plugin.ChatHub.Helpers; -public class EventEmitter +internal class EventEmitter { - public static async Task SendChatEvent( + internal static async Task SendChatEvent( IServiceProvider services, ILogger logger, string @event, diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Observers/ChatHubObserver.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Observers/ChatHubObserver.cs index 03a56d47b..3d8bf7886 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Observers/ChatHubObserver.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Observers/ChatHubObserver.cs @@ -121,6 +121,32 @@ public override void OnNext(HubObserveData value) _logger.LogCritical($"Receiving {value.EventName} ({value.Data.Indication}) in {nameof(ChatHubObserver)} - {conv.ConversationId}"); #endif break; + case ChatEvent.OnIntermediateMessageReceivedFromAssistant: + if (!AllowSendingMessage()) return; + + model = new ChatResponseDto + { + ConversationId = conv.ConversationId, + MessageId = message.MessageId, + MessageLabel = message.MessageLabel, + Text = !string.IsNullOrEmpty(message.SecondaryContent) ? message.SecondaryContent : message.Content, + Function = message.FunctionName, + RichContent = message.SecondaryRichContent ?? message.RichContent, + Data = message.Data, + Sender = new() + { + FirstName = "AI", + LastName = "Assistant", + Role = AgentRole.Assistant + } + }; + + if (value.SaveDataToDb) + { + var storage = _services.GetRequiredService(); + storage.Append(conv.ConversationId, message); + } + break; } SendEvent(value.EventName, model.ConversationId, model); diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/BotSharp.Plugin.ExcelHandler.csproj b/src/Plugins/BotSharp.Plugin.ExcelHandler/BotSharp.Plugin.ExcelHandler.csproj index 51355e9c6..5a30ca72a 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/BotSharp.Plugin.ExcelHandler.csproj +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/BotSharp.Plugin.ExcelHandler.csproj @@ -34,7 +34,6 @@ - diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs index 3530a8edd..822a94fe6 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Functions/ReadExcelFn.cs @@ -1,4 +1,3 @@ -using BotSharp.Plugin.ExcelHandler.Settings; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Linq.Dynamic.Core; @@ -32,7 +31,7 @@ public ReadExcelFn( _options = options; _settings = settings; _fileStorage = fileStorage; - _dbService = dbServices.FirstOrDefault(x => x.Provider == _settings.DbProvider); + _dbService = dbServices.FirstOrDefault(x => x.Provider == _settings.Database?.Provider); } public async Task Execute(RoleDialogModel message) diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs index 87d7e54cb..8d491ab3b 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/MySqlService.cs @@ -1,9 +1,8 @@ -using System.Data; -using System.Text.RegularExpressions; -using BotSharp.Plugin.SqlDriver.Settings; using MySql.Data.MySqlClient; using Newtonsoft.Json; using NPOI.SS.UserModel; +using System.Data; +using System.Text.RegularExpressions; namespace BotSharp.Plugin.ExcelHandler.Services; @@ -11,6 +10,7 @@ public class MySqlService : IDbService { private readonly IServiceProvider _services; private readonly ILogger _logger; + private readonly ExcelHandlerSettings _settings; private string _mysqlConnection = ""; private double _excelRowSize = 0; @@ -23,10 +23,12 @@ public class MySqlService : IDbService public MySqlService( IServiceProvider services, - ILogger logger) + ILogger logger, + ExcelHandlerSettings settings) { _services = services; _logger = logger; + _settings = settings; } public string Provider => "mysql"; @@ -250,8 +252,7 @@ private MySqlConnection GetDbConnection() private void InitializeDatabase() { - var sqlSettings = _services.GetRequiredService(); - _mysqlConnection = sqlSettings.MySqlTempConnectionString; + _mysqlConnection = _settings.Database.ConnectionString; var databaseName = GetDatabaseName(_mysqlConnection); _logger.LogInformation($"Connected to MySQL database {databaseName}"); } diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/SqliteService.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/SqliteService.cs index b02d7a5fb..e301ec5b2 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/SqliteService.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Services/SqliteService.cs @@ -1,4 +1,3 @@ -using BotSharp.Plugin.SqlDriver.Settings; using Microsoft.Data.Sqlite; using NPOI.SS.UserModel; @@ -8,6 +7,7 @@ public class SqliteService : IDbService { private readonly IServiceProvider _services; private readonly ILogger _logger; + private readonly ExcelHandlerSettings _settings; private string _dbFilePath = string.Empty; private SqliteConnection _inMemoryDbConnection = null; @@ -20,10 +20,12 @@ public class SqliteService : IDbService public SqliteService( IServiceProvider services, - ILogger logger) + ILogger logger, + ExcelHandlerSettings settings) { _services = services; _logger = logger; + _settings = settings; } public string Provider => "sqlite"; @@ -251,8 +253,7 @@ private SqliteConnection GetPhysicalDbConnection() { if (string.IsNullOrEmpty(_dbFilePath)) { - var sqlSettings = _services.GetRequiredService(); - _dbFilePath = sqlSettings.SqlLiteConnectionString; + _dbFilePath = _settings.Database.ConnectionString; } var dbConnection = new SqliteConnection($"Data Source={_dbFilePath};Mode=ReadWrite"); diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Settings/ExcelHandlerSettings.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Settings/ExcelHandlerSettings.cs index a8aa9e978..d68af4b3d 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Settings/ExcelHandlerSettings.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Settings/ExcelHandlerSettings.cs @@ -2,5 +2,11 @@ namespace BotSharp.Plugin.ExcelHandler.Settings; public class ExcelHandlerSettings { - public string DbProvider { get; set; } = "mysql"; + public DatabaseSettings Database { get; set; } } + +public class DatabaseSettings +{ + public string Provider { get; set; } = "mysql"; + public string ConnectionString { get; set; } +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.ExcelHandler/Using.cs b/src/Plugins/BotSharp.Plugin.ExcelHandler/Using.cs index 6f5a0c335..1c338f5f6 100644 --- a/src/Plugins/BotSharp.Plugin.ExcelHandler/Using.cs +++ b/src/Plugins/BotSharp.Plugin.ExcelHandler/Using.cs @@ -26,6 +26,7 @@ global using BotSharp.Plugin.ExcelHandler.LlmContexts; global using BotSharp.Plugin.ExcelHandler.Models; global using BotSharp.Plugin.ExcelHandler.Services; +global using BotSharp.Plugin.ExcelHandler.Settings; global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.DependencyInjection; diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs b/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs index bff2c48c8..67acab47c 100644 --- a/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs +++ b/src/Plugins/BotSharp.Plugin.SqlDriver/Settings/SqlDriverSetting.cs @@ -5,11 +5,9 @@ public class SqlDriverSetting public string DatabaseType { get; set; } = "mysql"; public string MySqlConnectionString { get; set; } = null!; public string MySqlExecutionConnectionString { get; set; } = null!; - public string MySqlTempConnectionString { get; set; } = null!; public string MySqlMetaConnectionString { get; set; } = null!; public string SqlServerConnectionString { get; set; } = null!; public string SqlServerExecutionConnectionString { get; set; } = null!; - public string SqlLiteConnectionString { get; set; } = null!; public string RedshiftConnectionString { get; set; } = null!; public bool ExecuteSqlSelectAutonomous { get; set; } = false; public bool FormattingResult { get; set; } = true; diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index a6d523054..c55e9e2c1 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -472,7 +472,10 @@ }, "ExcelHandler": { - "DbProvider": "mysql" + "Database": { + "Provider": "mysql", + "ConnectionString": "" + } }, "HttpHandler": {