diff --git a/BotSharp.sln b/BotSharp.sln index 5bc75c0a..0cf4325e 100644 --- a/BotSharp.sln +++ b/BotSharp.sln @@ -73,7 +73,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.WebDriver", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.ChatHub", "src\Plugins\BotSharp.Plugin.ChatHub\BotSharp.Plugin.ChatHub.csproj", "{EDCD9C20-2D9D-4098-A16E-03F97B306CB8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Plugin.TelegramBots", "src\Plugins\BotSharp.Plugin.TelegramBots\BotSharp.Plugin.TelegramBots.csproj", "{DCA18996-4D3A-4E98-BCD0-1FB77C59253E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.TelegramBots", "src\Plugins\BotSharp.Plugin.TelegramBots\BotSharp.Plugin.TelegramBots.csproj", "{DCA18996-4D3A-4E98-BCD0-1FB77C59253E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotSharp.Logger", "src\Infrastructure\BotSharp.Logger\BotSharp.Logger.csproj", "{5CA3335E-E6AD-46FD-B277-29BBC3A16500}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -283,6 +285,14 @@ Global {DCA18996-4D3A-4E98-BCD0-1FB77C59253E}.Release|Any CPU.Build.0 = Release|Any CPU {DCA18996-4D3A-4E98-BCD0-1FB77C59253E}.Release|x64.ActiveCfg = Release|Any CPU {DCA18996-4D3A-4E98-BCD0-1FB77C59253E}.Release|x64.Build.0 = Release|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Debug|x64.ActiveCfg = Debug|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Debug|x64.Build.0 = Debug|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Release|Any CPU.Build.0 = Release|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Release|x64.ActiveCfg = Release|Any CPU + {5CA3335E-E6AD-46FD-B277-29BBC3A16500}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -320,6 +330,7 @@ Global {F06B22CB-B143-4680-8FFF-35B9E50E6C47} = {51AFE054-AE99-497D-A593-69BAEFB5106F} {EDCD9C20-2D9D-4098-A16E-03F97B306CB8} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00} {DCA18996-4D3A-4E98-BCD0-1FB77C59253E} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00} + {5CA3335E-E6AD-46FD-B277-29BBC3A16500} = {E29DC6C4-5E57-48C5-BCB0-6B8F84782749} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs index 7cad03ff..e37492f1 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Settings/ConversationSetting.cs @@ -7,4 +7,6 @@ public class ConversationSetting public bool EnableKnowledgeBase { get; set; } public bool ShowVerboseLog { get; set; } public int MaxRecursiveDepth { get; set; } = 3; + public bool EnableLlmCompletionLog { get; set; } + public bool EnableExecutionLog { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IContentGeneratingHook.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs similarity index 93% rename from src/Infrastructure/BotSharp.Abstraction/MLTasks/IContentGeneratingHook.cs rename to src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs index 603031b2..c82e2fc3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/IContentGeneratingHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/IContentGeneratingHook.cs @@ -1,4 +1,4 @@ -namespace BotSharp.Abstraction.MLTasks; +namespace BotSharp.Abstraction.Loggers; /// /// Model content generating hook, it can be used for logging, metrics and tracing. diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/IVerboseLogHook.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/IVerboseLogHook.cs new file mode 100644 index 00000000..9ebb5c66 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/IVerboseLogHook.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Abstraction.Loggers; + +public interface IVerboseLogHook +{ + void GenerateLog(string text); +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index ba8e9d84..c9ef8fee 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -38,8 +38,11 @@ public interface IBotSharpRepository List GetConversations(ConversationFilter filter); void UpdateConversationTitle(string conversationId, string title); List GetLastConversations(); - void AddExectionLogs(string conversationId, List logs); - List GetExectionLogs(string conversationId); + #endregion + + #region Execution Log + void AddExecutionLogs(string conversationId, List logs); + List GetExecutionLogs(string conversationId); #endregion #region LLM Completion Log diff --git a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs similarity index 97% rename from src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs rename to src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs index 7ba9dbb1..afa93e33 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharpServiceCollectionExtensions.cs +++ b/src/Infrastructure/BotSharp.Core/BotSharpCoreExtensions.cs @@ -22,9 +22,9 @@ using BotSharp.Core.Planning; namespace BotSharp.Core; -public static class BotSharpServiceCollectionExtensions +public static class BotSharpCoreExtensions { - public static IServiceCollection AddBotSharp(this IServiceCollection services, IConfiguration config) + public static IServiceCollection AddBotSharpCore(this IServiceCollection services, IConfiguration config) { services.AddScoped(); diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs b/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs index 9a222554..f70cb59f 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs @@ -21,6 +21,6 @@ public class ExecutionLogger : IExecutionLogger content = content.Replace("\r\n", " ").Replace("\n", " "); content = Regex.Replace(content, @"\s+", " "); var db = _services.GetRequiredService(); - db.AddExectionLogs(conversationId, new List { content }); + db.AddExecutionLogs(conversationId, new List { content }); } } diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index 48c1a780..e2062c0a 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -168,16 +168,6 @@ public class BotSharpDbContext : Database, IBotSharpRepository { throw new NotImplementedException(); } - - public void AddExectionLogs(string conversationId, List logs) - { - throw new NotImplementedException(); - } - - public List GetExectionLogs(string conversationId) - { - throw new NotImplementedException(); - } #endregion @@ -198,6 +188,19 @@ public class BotSharpDbContext : Database, IBotSharpRepository } #endregion + + #region Execution Log + public void AddExecutionLogs(string conversationId, List logs) + { + throw new NotImplementedException(); + } + + public List GetExecutionLogs(string conversationId) + { + throw new NotImplementedException(); + } + #endregion + #region LLM Completion Log public void SaveLlmCompletionLog(LlmCompletionLog log) { diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs index d03dd476..8b90ae79 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs @@ -6,8 +6,6 @@ using BotSharp.Abstraction.Agents.Models; using MongoDB.Driver; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Repositories.Filters; -using BotSharp.Abstraction.Utilities; -using BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Core.Repository; @@ -789,33 +787,6 @@ public class FileRepository : IBotSharpRepository .Select(g => g.OrderByDescending(x => x.CreatedTime).First()) .ToList(); } - - public void AddExectionLogs(string conversationId, List logs) - { - if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return; - - var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId); - if (!Directory.Exists(dir)) - { - Directory.CreateDirectory(dir); - } - - var file = Path.Combine(dir, "execution.log"); - File.AppendAllLines(file, logs); - } - - public List GetExectionLogs(string conversationId) - { - var logs = new List(); - if (string.IsNullOrEmpty(conversationId)) return logs; - - var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId); - if (!Directory.Exists(dir)) return logs; - - var file = Path.Combine(dir, "execution.log"); - logs = File.ReadAllLines(file)?.ToList() ?? new List(); - return logs; - } #endregion #region User @@ -843,6 +814,35 @@ public class FileRepository : IBotSharpRepository } #endregion + #region Execution Log + public void AddExecutionLogs(string conversationId, List logs) + { + if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return; + + var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + + var file = Path.Combine(dir, "execution.log"); + File.AppendAllLines(file, logs); + } + + public List GetExecutionLogs(string conversationId) + { + var logs = new List(); + if (string.IsNullOrEmpty(conversationId)) return logs; + + var dir = Path.Combine(_dbSettings.FileRepository, "conversations", conversationId); + if (!Directory.Exists(dir)) return logs; + + var file = Path.Combine(dir, "execution.log"); + logs = File.ReadAllLines(file)?.ToList() ?? new List(); + return logs; + } + #endregion + #region LLM Completion Log public void SaveLlmCompletionLog(LlmCompletionLog log) { @@ -855,6 +855,7 @@ public class FileRepository : IBotSharpRepository Directory.CreateDirectory(logDir); } + log.Id = Guid.NewGuid().ToString(); var index = GetLlmCompletionLogIndex(logDir, log.MessageId); var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log"); File.WriteAllText(file, JsonSerializer.Serialize(log, _options)); diff --git a/src/Infrastructure/BotSharp.Logger/BotSharp.Logger.csproj b/src/Infrastructure/BotSharp.Logger/BotSharp.Logger.csproj new file mode 100644 index 00000000..417d91fe --- /dev/null +++ b/src/Infrastructure/BotSharp.Logger/BotSharp.Logger.csproj @@ -0,0 +1,58 @@ + + + + netstandard2.1 + $(LangVersion) + $(BotSharpVersion) + $(GeneratePackageOnBuild) + + + + Haiping Chen + SciSharp STACK + LL Application Framework + + Open source LLM application framework to build scalable, flexible and robust AI system. + + git + https://github.com/SciSharp/BotSharp + Chatbot, Bot, LLM, AI, ChatGPT, OpenAI + Support dialogue status tracking. + Since 2018 Haiping Chen + https://github.com/SciSharp/BotSharp + https://raw.githubusercontent.com/SciSharp/BotSharp/master/docs/static/logos/BotSharp.png + https://raw.githubusercontent.com/SciSharp/BotSharp/master/LICENSE + Icon.png + enable + + + + TRACE;DEBUG + 1701;1702 + + + + TRACE; + 1701;1702 + + + + 1701;1702 + + + + 1701;1702 + + + + + True + \ + + + + + + + + diff --git a/src/Infrastructure/BotSharp.Logger/BotSharpLoggerExtensions.cs b/src/Infrastructure/BotSharp.Logger/BotSharpLoggerExtensions.cs new file mode 100644 index 00000000..06c9eb4c --- /dev/null +++ b/src/Infrastructure/BotSharp.Logger/BotSharpLoggerExtensions.cs @@ -0,0 +1,12 @@ +namespace BotSharp.Logger; + +public static class BotSharpLoggerExtensions +{ + public static IServiceCollection AddBotSharpLogger(this IServiceCollection services, IConfiguration config) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + return services; + } +} diff --git a/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs new file mode 100644 index 00000000..748dfce1 --- /dev/null +++ b/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs @@ -0,0 +1,39 @@ +public class CommonContentGeneratingHook : IContentGeneratingHook +{ + private readonly IServiceProvider _services; + + public CommonContentGeneratingHook(IServiceProvider services) + { + _services = services; + } + + /// + /// After content generated. + /// + /// + public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats) + { + SaveLlmCompletionLog(message, tokenStats); + await Task.CompletedTask; + } + + private void SaveLlmCompletionLog(RoleDialogModel message, TokenStatsModel tokenStats) + { + var convSettings = _services.GetRequiredService(); + if (!convSettings.EnableLlmCompletionLog) return; + + var db = _services.GetRequiredService(); + var state = _services.GetRequiredService(); + + var completionLog = new LlmCompletionLog + { + ConversationId = state.GetConversationId(), + MessageId = message.MessageId, + AgentId = message.CurrentAgentId, + Prompt = tokenStats.Prompt, + Response = message.Content + }; + + db.SaveLlmCompletionLog(completionLog); + } +} diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Hooks/TokenStatsConversationHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs similarity index 65% rename from src/Plugins/BotSharp.Plugin.AzureOpenAI/Hooks/TokenStatsConversationHook.cs rename to src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs index fc2c2827..c7e05d15 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Hooks/TokenStatsConversationHook.cs +++ b/src/Infrastructure/BotSharp.Logger/Hooks/TokenStatsConversationHook.cs @@ -1,15 +1,5 @@ -using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.MLTasks; -using System.Collections.Generic; -using System.Threading.Tasks; +namespace BotSharp.Logger.Hooks; -namespace BotSharp.Plugin.AzureOpenAI.Hooks; - -/// -/// Token statistics for Azure OpenAI -/// public class TokenStatsConversationHook : IContentGeneratingHook { private readonly ITokenStatistics _tokenStatistics; @@ -22,14 +12,15 @@ public class TokenStatsConversationHook : IContentGeneratingHook public async Task BeforeGenerating(Agent agent, List conversations) { _tokenStatistics.StartTimer(); + await Task.CompletedTask; } public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats) { _tokenStatistics.StopTimer(); - tokenStats.PromptCost = 0.0015f; tokenStats.CompletionCost = 0.002f; _tokenStatistics.AddToken(tokenStats); + await Task.CompletedTask; } } diff --git a/src/Infrastructure/BotSharp.Logger/Hooks/VerboseLogHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/VerboseLogHook.cs new file mode 100644 index 00000000..4ba21f8e --- /dev/null +++ b/src/Infrastructure/BotSharp.Logger/Hooks/VerboseLogHook.cs @@ -0,0 +1,20 @@ +namespace BotSharp.Logger.Hooks; + +public class VerboseLogHook : IVerboseLogHook +{ + private readonly ConversationSetting _convSettings; + private readonly ILogger _logger; + + public VerboseLogHook(ConversationSetting convSettings, ILogger logger) + { + _convSettings = convSettings; + _logger = logger; + } + + public void GenerateLog(string text) + { + if (!_convSettings.ShowVerboseLog) return; + + _logger.LogInformation(text); + } +} diff --git a/src/Infrastructure/BotSharp.Logger/Using.cs b/src/Infrastructure/BotSharp.Logger/Using.cs new file mode 100644 index 00000000..5115e776 --- /dev/null +++ b/src/Infrastructure/BotSharp.Logger/Using.cs @@ -0,0 +1,15 @@ +global using System; +global using System.Collections.Generic; +global using System.Text; +global using System.Threading.Tasks; +global using System.Linq; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Configuration; +global using Microsoft.Extensions.Logging; +global using BotSharp.Abstraction.Loggers; +global using BotSharp.Abstraction.Agents.Models; +global using BotSharp.Abstraction.Conversations.Models; +global using BotSharp.Abstraction.Conversations; +global using BotSharp.Abstraction.Repositories; +global using BotSharp.Abstraction.Conversations.Settings; +global using BotSharp.Logger.Hooks; \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs index 653be1b1..09c9d32e 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/AzureOpenAiPlugin.cs @@ -1,7 +1,6 @@ using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Plugins; using BotSharp.Abstraction.Utilities; -using BotSharp.Plugin.AzureOpenAI.Hooks; using BotSharp.Plugin.AzureOpenAI.Providers; using BotSharp.Plugin.AzureOpenAI.Settings; using Microsoft.Extensions.Configuration; @@ -30,6 +29,5 @@ public class AzureOpenAiPlugin : IBotSharpPlugin services.AddScoped(); 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 bc9b9866..1f6bb5fb 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/ChatCompletionProvider.cs @@ -1,4 +1,3 @@ -using Azure; using Azure.AI.OpenAI; using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents.Enums; @@ -6,9 +5,9 @@ using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Settings; +using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.MLTasks; using BotSharp.Plugin.AzureOpenAI.Settings; -using Microsoft.Extensions.Azure; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System; @@ -39,10 +38,11 @@ public class ChatCompletionProvider : IChatCompletion public RoleDialogModel GetChatCompletions(Agent agent, List conversations) { - var hooks = _services.GetServices().ToList(); + var contentHooks = _services.GetServices().ToList(); + var logHook = _services.GetService(); // Before chat completion hook - Task.WaitAll(hooks.Select(hook => + Task.WaitAll(contentHooks.Select(hook => hook.BeforeGenerating(agent, conversations)).ToArray()); var client = ProviderHelper.GetClient(_model, _settings); @@ -75,16 +75,13 @@ public class ChatCompletionProvider : IChatCompletion } } - var setting = _services.GetRequiredService(); - if (setting.ShowVerboseLog) - { - _logger.LogInformation(responseMessage.Role == AgentRole.Function ? + var log = responseMessage.Role == AgentRole.Function ? $"[{agent.Name}]: {responseMessage.FunctionName}({responseMessage.FunctionArgs})" : - $"[{agent.Name}]: {responseMessage.Content}"); - } + $"[{agent.Name}]: {responseMessage.Content}"; + logHook?.GenerateLog(log); // After chat completion hook - Task.WaitAll(hooks.Select(hook => + Task.WaitAll(contentHooks.Select(hook => hook.AfterGenerated(responseMessage, new TokenStatsModel { Prompt = prompt, @@ -195,6 +192,7 @@ public class ChatCompletionProvider : IChatCompletion protected (string, ChatCompletionsOptions) PrepareOptions(Agent agent, List conversations) { var agentService = _services.GetRequiredService(); + var logHook = _services.GetService(); var chatCompletionsOptions = new ChatCompletionsOptions(); @@ -250,11 +248,7 @@ public class ChatCompletionProvider : IChatCompletion // chatCompletionsOptions.PresencePenalty = 0; var prompt = GetPrompt(chatCompletionsOptions); - var convSetting = _services.GetRequiredService(); - if (convSetting.ShowVerboseLog) - { - _logger.LogInformation(prompt); - } + logHook?.GenerateLog(prompt); return (prompt, chatCompletionsOptions); } diff --git a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs index fc0cde2c..19510c33 100644 --- a/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/TextCompletionProvider.cs @@ -11,7 +11,7 @@ using BotSharp.Abstraction.Agents.Enums; using System.Linq; using System.Collections.Generic; using BotSharp.Abstraction.Agents.Models; -using BotSharp.Abstraction.Conversations.Settings; +using BotSharp.Abstraction.Loggers; namespace BotSharp.Plugin.AzureOpenAI.Providers; @@ -19,22 +19,20 @@ public class TextCompletionProvider : ITextCompletion { private readonly IServiceProvider _services; private readonly AzureOpenAiSettings _settings; - private readonly ILogger _logger; private string _model; public string Provider => "azure-openai"; public TextCompletionProvider(IServiceProvider services, - AzureOpenAiSettings settings, - ILogger logger) + AzureOpenAiSettings settings) { _services = services; _settings = settings; - _logger = logger; } public async Task GetCompletion(string text, string agentId, string messageId) { - var hooks = _services.GetServices().ToList(); + var contentHooks = _services.GetServices().ToList(); + var logHook = _services.GetService(); // Before chat completion hook var agent = new Agent() @@ -47,7 +45,7 @@ public class TextCompletionProvider : ITextCompletion MessageId = messageId }; - Task.WaitAll(hooks.Select(hook => + Task.WaitAll(contentHooks.Select(hook => hook.BeforeGenerating(agent, new List { @@ -65,12 +63,7 @@ public class TextCompletionProvider : ITextCompletion MaxTokens = 256, }; completionsOptions.StopSequences.Add($"{AgentRole.Assistant}:"); - - var setting = _services.GetRequiredService(); - if (setting.ShowVerboseLog) - { - _logger.LogInformation(text); - } + logHook?.GenerateLog(text); var state = _services.GetRequiredService(); var temperature = float.Parse(state.GetState("temperature", "0.5")); @@ -87,10 +80,7 @@ public class TextCompletionProvider : ITextCompletion completion += t.Text; }; - if (setting.ShowVerboseLog) - { - _logger.LogInformation(completion); - } + logHook?.GenerateLog(completion); // After chat completion hook var responseMessage = new RoleDialogModel(AgentRole.Assistant, completion) @@ -98,7 +88,7 @@ public class TextCompletionProvider : ITextCompletion CurrentAgentId = agentId, MessageId = messageId }; - Task.WaitAll(hooks.Select(hook => + Task.WaitAll(contentHooks.Select(hook => hook.AfterGenerated(responseMessage, new TokenStatsModel { Prompt = text, diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs index 569d5d42..175f810e 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/ChatCompletionProvider.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Routing; using BotSharp.Plugin.GoogleAI.Settings; diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs index 87c71e8f..c35df64f 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/TextCompletionProvider.cs @@ -1,5 +1,6 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations; +using BotSharp.Abstraction.Loggers; using BotSharp.Plugin.GoogleAI.Settings; using LLMSharp.Google.Palm; using Microsoft.Extensions.Logging; diff --git a/src/Plugins/BotSharp.Plugin.HuggingFace/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.HuggingFace/Providers/ChatCompletionProvider.cs index 8756c7b5..f620ffb8 100644 --- a/src/Plugins/BotSharp.Plugin.HuggingFace/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.HuggingFace/Providers/ChatCompletionProvider.cs @@ -1,6 +1,7 @@ using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Conversations.Settings; +using BotSharp.Abstraction.Loggers; using BotSharp.Plugin.HuggingFace.Services; using BotSharp.Plugin.HuggingFace.Settings; using Microsoft.Extensions.Logging; diff --git a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs index 9dc0d7e5..d114b5ee 100644 --- a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/ChatCompletionProvider.cs @@ -1,4 +1,5 @@ using BotSharp.Abstraction.Agents; +using BotSharp.Abstraction.Loggers; namespace BotSharp.Plugin.LLamaSharp.Providers; diff --git a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs index 9107d8a0..0fe0251d 100644 --- a/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.LLamaSharp/Providers/TextCompletionProvider.cs @@ -1,3 +1,5 @@ +using BotSharp.Abstraction.Loggers; + namespace BotSharp.Plugin.LLamaSharp.Providers; public class TextCompletionProvider : ITextCompletion diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs index 553ca34e..3e957bc4 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.cs @@ -4,7 +4,6 @@ using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Users.Models; -using BotSharp.Abstraction.Utilities; using BotSharp.Plugin.MongoStorage.Collections; using BotSharp.Plugin.MongoStorage.Models; @@ -782,30 +781,6 @@ public class MongoRepository : IBotSharpRepository UpdatedTime = c.UpdatedTime }).ToList(); } - - public void AddExectionLogs(string conversationId, List logs) - { - if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return; - - var filter = Builders.Filter.Eq(x => x.ConversationId, conversationId); - var update = Builders.Update - .SetOnInsert(x => x.Id, Guid.NewGuid().ToString()) - .PushEach(x => x.Logs, logs); - - _dc.ExectionLogs.UpdateOne(filter, update, _options); - } - - public List GetExectionLogs(string conversationId) - { - var logs = new List(); - if (string.IsNullOrEmpty(conversationId)) return logs; - - var filter = Builders.Filter.Eq(x => x.ConversationId, conversationId); - var logCollection = _dc.ExectionLogs.Find(filter).FirstOrDefault(); - - logs = logCollection?.Logs ?? new List(); - return logs; - } #endregion #region User @@ -863,6 +838,32 @@ public class MongoRepository : IBotSharpRepository } #endregion + #region Execution Log + public void AddExecutionLogs(string conversationId, List logs) + { + if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return; + + var filter = Builders.Filter.Eq(x => x.ConversationId, conversationId); + var update = Builders.Update + .SetOnInsert(x => x.Id, Guid.NewGuid().ToString()) + .PushEach(x => x.Logs, logs); + + _dc.ExectionLogs.UpdateOne(filter, update, _options); + } + + public List GetExecutionLogs(string conversationId) + { + var logs = new List(); + if (string.IsNullOrEmpty(conversationId)) return logs; + + var filter = Builders.Filter.Eq(x => x.ConversationId, conversationId); + var logCollection = _dc.ExectionLogs.Find(filter).FirstOrDefault(); + + logs = logCollection?.Logs ?? new List(); + return logs; + } + #endregion + #region LLM Completion Log public void SaveLlmCompletionLog(LlmCompletionLog log) { diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs index 13bca1e8..673e9e5d 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelChatCompletionProvider.cs @@ -3,6 +3,7 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; +using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.MLTasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; diff --git a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs index ee38d6f2..15791931 100644 --- a/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.SemanticKernel/SemanticKernelTextCompletionProvider.cs @@ -2,7 +2,7 @@ using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.MLTasks; +using BotSharp.Abstraction.Loggers; using Microsoft; using Microsoft.Extensions.DependencyInjection; using Microsoft.SemanticKernel; diff --git a/src/WebStarter/Program.cs b/src/WebStarter/Program.cs index b863638a..c8ba1a94 100644 --- a/src/WebStarter/Program.cs +++ b/src/WebStarter/Program.cs @@ -2,6 +2,7 @@ using BotSharp.Abstraction.Messaging; using BotSharp.Abstraction.Users; using BotSharp.Core; using BotSharp.Core.Users.Services; +using BotSharp.Logger; using BotSharp.Plugin.ChatHub; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; @@ -46,7 +47,8 @@ builder.Services.AddAuthentication(options => builder.Services.AddScoped(); // Add BotSharp -builder.Services.AddBotSharp(builder.Configuration); +builder.Services.AddBotSharpCore(builder.Configuration); +builder.Services.AddBotSharpLogger(builder.Configuration); builder.Services.AddCors(options => { diff --git a/src/WebStarter/WebStarter.csproj b/src/WebStarter/WebStarter.csproj index 0c4ab1d7..26af9b65 100644 --- a/src/WebStarter/WebStarter.csproj +++ b/src/WebStarter/WebStarter.csproj @@ -21,6 +21,7 @@ + @@ -45,6 +46,7 @@ + diff --git a/src/WebStarter/appsettings.json b/src/WebStarter/appsettings.json index 1309cde1..6dbcbc2c 100644 --- a/src/WebStarter/appsettings.json +++ b/src/WebStarter/appsettings.json @@ -34,7 +34,9 @@ "Conversation": { "DataDir": "conversations", - "ShowVerboseLog": false + "ShowVerboseLog": false, + "EnableLlmCompletionLog": false, + "EnableExecutionLog": true }, "LlamaSharp": { @@ -134,8 +136,9 @@ "PluginLoader": { "Assemblies": [ - "BotSharp.Core", "BotSharp.Plugin.MongoStorage", + "BotSharp.Core", + "BotSharp.Logger", "BotSharp.Plugin.AzureOpenAI", "BotSharp.Plugin.GoogleAI", "BotSharp.Plugin.MetaAI", diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs index 777192ed..d6ef22ae 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/SemanticKernelChatCompletionProviderTests.cs @@ -1,37 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Conversations.Models; -using BotSharp.Abstraction.MLTasks; -using BotSharp.Plugin.SemanticKernel; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.SemanticKernel; using Moq; -using Xunit; using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Models; -using System.Linq; -using System.Runtime; using BotSharp.Abstraction.Conversations; -using BotSharp.Abstraction.Models; using Microsoft.SemanticKernel.AI.ChatCompletion; using Microsoft.SemanticKernel.AI; -using Microsoft.SemanticKernel.Connectors.AI.OpenAI.AzureSdk; using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; +using BotSharp.Abstraction.Loggers; namespace BotSharp.Plugin.SemanticKernel.Tests { public class SemanticKernelChatCompletionProviderTests { - private readonly Mock _chatCompletionMock; + private readonly Mock _chatCompletionMock; private readonly Mock _servicesMock; private readonly Mock _tokenStatisticsMock; private readonly SemanticKernelChatCompletionProvider _provider; public SemanticKernelChatCompletionProviderTests() { - _chatCompletionMock = new Mock(); + _chatCompletionMock = new Mock(); _servicesMock = new Mock(); _tokenStatisticsMock = new Mock(); _provider = new SemanticKernelChatCompletionProvider(_chatCompletionMock.Object, _servicesMock.Object, _tokenStatisticsMock.Object); diff --git a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs index 8c927eb7..a8cb7236 100644 --- a/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs +++ b/tests/BotSharp.Plugin.SemanticKernel.UnitTests/Usings.cs @@ -1 +1,7 @@ +global using System; +global using System.Collections.Generic; +global using System.Threading.Tasks; +global using System.Linq; +global using System.Runtime; +global using BotSharp.Abstraction.Models; global using Xunit; \ No newline at end of file