diff --git a/README.md b/README.md index 9924c4d1..68e60006 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![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) [![Apache 2.0](https://img.shields.io/hexpm/l/plug.svg)](https://raw.githubusercontent.com/Oceania2018/BotSharp/master/LICENSE) [![NuGet](https://img.shields.io/nuget/dt/BotSharp.Core.svg)](https://www.nuget.org/packages/BotSharp.Core) -[![Build status](https://ci.appveyor.com/api/projects/status/qx2dx5ca5hjqodm5?svg=true)](https://ci.appveyor.com/project/Haiping-Chen/botsharp) +[![build](https://github.com/SciSharp/BotSharp/actions/workflows/build.yml/badge.svg)](https://github.com/SciSharp/BotSharp/actions/workflows/build.yml) [![Documentation Status](https://readthedocs.org/projects/botsharp/badge/?version=latest)](https://botsharp.readthedocs.io/en/latest/?badge=latest) *"Conversation as a platform (CaaP) is the future, so it's perfect that we're already offering the whole toolkits to our .NET developers using the BotSharp AI BOT Platform Builder to build a CaaP. It opens up as much learning power as possible for your own robots and precisely control every step of the AI processing pipeline."* diff --git a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs index 9386dd8a..0e6b9ba3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Browsing/IWebBrowser.cs @@ -25,6 +25,7 @@ public interface IWebBrowser Task ExtractData(BrowserActionParams actionParams); Task EvaluateScript(string contextId, string script); Task CloseBrowser(string contextId); + Task IsBrowserClosed(string contextId); Task CloseCurrentPage(MessageInfo message); Task SendHttpRequest(MessageInfo message, HttpRequestParams actionParams); Task GetAttributeValue(MessageInfo message, ElementLocatingArgs location); diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs index df123922..a5563cf3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs @@ -6,7 +6,7 @@ namespace BotSharp.Abstraction.Conversations; /// /// Conversation state service to track the context in the conversation lifecycle /// -public interface IConversationStateService +public interface IConversationStateService : IDisposable { string GetConversationId(); Dictionary Load(string conversationId, bool isReadOnly = false); diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/LlmCompletionLog.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/LlmCompletionLog.cs index 02c5b312..5082387c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/LlmCompletionLog.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/LlmCompletionLog.cs @@ -7,5 +7,5 @@ public class LlmCompletionLog public string AgentId { get; set; } = string.Empty; public string Prompt { get; set; } = string.Empty; public string? Response { get; set; } - public DateTime CreateDateTime { get; set; } = DateTime.UtcNow; + public DateTime CreatedTime { get; set; } = DateTime.UtcNow; } diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderService.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderService.cs index 201f1342..2a06ece6 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/ILlmProviderService.cs @@ -8,4 +8,5 @@ public interface ILlmProviderService List GetProviders(); LlmModelSetting GetProviderModel(string provider, string id, bool? multiModal = null, bool? realTime = false, bool imageGenerate = false); List GetProviderModels(string provider); + List GetLlmConfigs(LlmConfigOptions? options = null); } diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmConfigOptions.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmConfigOptions.cs new file mode 100644 index 00000000..81668059 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmConfigOptions.cs @@ -0,0 +1,9 @@ +namespace BotSharp.Abstraction.MLTasks.Settings; + +public class LlmConfigOptions +{ + public LlmModelType? Type { get; set; } + public bool? MultiModal { get; set; } + public bool? RealTime { get; set; } + public bool? ImageGeneration { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs index b3a9d28e..705a9129 100644 --- a/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs +++ b/src/Infrastructure/BotSharp.Abstraction/MLTasks/Settings/LlmProviderSetting.cs @@ -2,11 +2,9 @@ namespace BotSharp.Abstraction.MLTasks.Settings; public class LlmProviderSetting { - public string Provider { get; set; } - = "azure-openai"; + public string Provider { get; set; } = "azure-openai"; - public List Models { get; set; } - = new List(); + public List Models { get; set; } = []; public override string ToString() { diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 06582d45..235c449b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -152,13 +152,6 @@ public interface IBotSharpRepository : IHaveServiceProvider => throw new NotImplementedException(); #endregion - #region Execution Log - void AddExecutionLogs(string conversationId, List logs) - => throw new NotImplementedException(); - List GetExecutionLogs(string conversationId) - => throw new NotImplementedException(); - #endregion - #region LLM Completion Log void SaveLlmCompletionLog(LlmCompletionLog log) => throw new NotImplementedException(); diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index ecc736f2..6bc7596c 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -1,4 +1,4 @@ - + $(TargetFramework) diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index a2b55d13..4d229866 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -22,12 +22,12 @@ namespace BotSharp.Core.Conversations.Services; /// /// Maintain the conversation state /// -public class ConversationStateService : IConversationStateService, IDisposable +public class ConversationStateService : IConversationStateService { private readonly ILogger _logger; private readonly IServiceProvider _services; private readonly IBotSharpRepository _db; - private readonly IConversationSideCar _sidecar; + private readonly IConversationSideCar? _sidecar; private string _conversationId; /// /// States in the current round of conversation @@ -41,15 +41,14 @@ public class ConversationStateService : IConversationStateService, IDisposable public ConversationStateService( IServiceProvider services, IBotSharpRepository db, - IConversationSideCar sidecar, ILogger logger) { _services = services; _db = db; - _sidecar = sidecar; _logger = logger; _curStates = new ConversationState(); _historyStates = new ConversationState(); + _sidecar = services.GetService(); } public string GetConversationId() => _conversationId; diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs b/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs index f70cb59f..c00ae098 100644 --- a/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs +++ b/src/Infrastructure/BotSharp.Core/Evaluations/ExecutionLogger.cs @@ -1,26 +1,25 @@ using BotSharp.Abstraction.Evaluations; -using BotSharp.Abstraction.Repositories; using System.Text.RegularExpressions; namespace BotSharp.Core.Evaluations; public class ExecutionLogger : IExecutionLogger { - private readonly BotSharpDatabaseSettings _dbSettings; private readonly IServiceProvider _services; + private readonly ILogger _logger; + public ExecutionLogger( - BotSharpDatabaseSettings dbSettings, - IServiceProvider services) + IServiceProvider services, + ILogger logger) { - _dbSettings = dbSettings; _services = services; + _logger = logger; } public void Append(string conversationId, string content) { content = content.Replace("\r\n", " ").Replace("\n", " "); content = Regex.Replace(content, @"\s+", " "); - var db = _services.GetRequiredService(); - db.AddExecutionLogs(conversationId, new List { content }); + _logger.LogInformation($"Execution Log: {content}"); } } diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs index e1934f60..6d62c227 100644 --- a/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs +++ b/src/Infrastructure/BotSharp.Core/Infrastructures/LlmProviderService.cs @@ -103,4 +103,50 @@ public class LlmProviderService : ILlmProviderService return modelSetting; } + + + public List GetLlmConfigs(LlmConfigOptions? options = null) + { + var settingService = _services.GetRequiredService(); + var providers = settingService.Bind>($"LlmProviders"); + var configs = new List(); + + if (providers.IsNullOrEmpty()) return configs; + + if (options == null) return providers ?? []; + + foreach (var provider in providers) + { + var models = provider.Models ?? []; + if (options.Type.HasValue) + { + models = models.Where(x => x.Type == options.Type.Value).ToList(); + } + + if (options.MultiModal.HasValue) + { + models = models.Where(x => x.MultiModal == options.MultiModal.Value).ToList(); + } + + if (options.ImageGeneration.HasValue) + { + models = models.Where(x => x.ImageGeneration == options.ImageGeneration.Value).ToList(); + } + + if (options.RealTime.HasValue) + { + models = models.Where(x => x.RealTime == options.RealTime.Value).ToList(); + } + + if (models.IsNullOrEmpty()) + { + continue; + } + + provider.Models = models; + configs.Add(provider); + } + + return configs; + } } diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InsturctionPlugin.cs b/src/Infrastructure/BotSharp.Core/Instructs/InsturctionPlugin.cs new file mode 100644 index 00000000..7b4596ff --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Instructs/InsturctionPlugin.cs @@ -0,0 +1,23 @@ +using BotSharp.Abstraction.Plugins.Models; +using Microsoft.Extensions.Configuration; + +namespace BotSharp.Core.Instructs; + +public class InsturctionPlugin : IBotSharpPlugin +{ + public string Id => "8189e133-819c-4505-9f82-84f793bc1be0"; + public string Name => "Instruction"; + public string Description => "Handle agent instruction request"; + + public void RegisterDI(IServiceCollection services, IConfiguration config) + { + + } + + public bool AttachMenu(List menu) + { + var section = menu.First(x => x.Label == "Apps"); + menu.Add(new PluginMenuDef("Instruction", link: "page/instruction", icon: "bx bx-book-content", weight: section.Weight + 5)); + return true; + } +} diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.Execute.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs similarity index 100% rename from src/Infrastructure/BotSharp.Core/Instructs/InstructService.Execute.cs rename to src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Execute.cs diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.Instruct.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs similarity index 100% rename from src/Infrastructure/BotSharp.Core/Instructs/InstructService.Instruct.cs rename to src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.Instruct.cs diff --git a/src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs b/src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.cs similarity index 100% rename from src/Infrastructure/BotSharp.Core/Instructs/InstructService.cs rename to src/Infrastructure/BotSharp.Core/Instructs/Services/InstructService.cs diff --git a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs index 100bbf16..587de372 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs @@ -135,18 +135,6 @@ public class BotSharpDbContext : Database, IBotSharpRepository => throw new NotImplementedException(); #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/FileRepository.Log.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Log.cs index 08898864..f82cb6fa 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Log.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.Log.cs @@ -1,40 +1,10 @@ using BotSharp.Abstraction.Loggers.Models; -using Serilog; using System.IO; namespace BotSharp.Core.Repository { public partial class FileRepository { - #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); - 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_FILE); - logs = File.ReadAllLines(file)?.ToList() ?? new List(); - return logs; - } - #endregion - #region LLM Completion Log public void SaveLlmCompletionLog(LlmCompletionLog log) { diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs index a5a2ffef..78e90e4b 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.cs @@ -50,9 +50,6 @@ public partial class FileRepository : IBotSharpRepository private const string KNOWLEDGE_DOC_FOLDER = "document"; private const string KNOWLEDGE_DOC_META_FILE = "meta.json"; - private const string EXECUTION_LOG_FILE = "execution.log"; - private const string PLUGIN_CONFIG_FILE = "config.json"; - private const string STATS_FOLDER = "stats"; private const string STATS_FILE = "stats.json"; diff --git a/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs b/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs index 68d83c87..25f08c22 100644 --- a/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs +++ b/src/Infrastructure/BotSharp.Logger/Hooks/CommonContentGeneratingHook.cs @@ -29,7 +29,8 @@ public class CommonContentGeneratingHook : IContentGeneratingHook MessageId = message.MessageId, AgentId = message.CurrentAgentId, Prompt = tokenStats.Prompt, - Response = message.Content + Response = message.Content, + CreatedTime = DateTime.UtcNow }; db.SaveLlmCompletionLog(completionLog); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs index f41c69fe..75dc1113 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs @@ -79,8 +79,9 @@ public class ConversationController : ControllerBase [HttpGet("/conversation/{conversationId}/dialogs")] public async Task> GetDialogs([FromRoute] string conversationId) { - var storage = _services.GetRequiredService(); - var history = storage.GetDialogs(conversationId); + var conv = _services.GetRequiredService(); + conv.SetConversationId(conversationId, [], isReadOnly: true); + var history = conv.GetDialogHistory(fromBreakpoint: false); var userService = _services.GetRequiredService(); var agentService = _services.GetRequiredService(); diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs index 433d691a..dbce9598 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/InstructModeController.cs @@ -44,7 +44,7 @@ public class InstructModeController : ControllerBase } [HttpPost("/instruct/text-completion")] - public async Task TextCompletion([FromBody] IncomingMessageModel input) + public async Task TextCompletion([FromBody] IncomingInstructRequest input) { var state = _services.GetRequiredService(); input.States.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); @@ -53,12 +53,12 @@ public class InstructModeController : ControllerBase .SetState("model_id", input.ModelId, source: StateSource.External); var textCompletion = CompletionProvider.GetTextCompletion(_services); - return await textCompletion.GetCompletion(input.Text, Guid.Empty.ToString(), Guid.NewGuid().ToString()); + return await textCompletion.GetCompletion(input.Text, input.AgentId ?? Guid.Empty.ToString(), Guid.NewGuid().ToString()); } #region Chat [HttpPost("/instruct/chat-completion")] - public async Task ChatCompletion([FromBody] IncomingMessageModel input) + public async Task ChatCompletion([FromBody] IncomingInstructRequest input) { var state = _services.GetRequiredService(); input.States.ForEach(x => state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); @@ -66,10 +66,11 @@ public class InstructModeController : ControllerBase .SetState("model", input.Model, source: StateSource.External) .SetState("model_id", input.ModelId, source: StateSource.External); - var textCompletion = CompletionProvider.GetChatCompletion(_services); - var message = await textCompletion.GetChatCompletions(new Agent() + var completion = CompletionProvider.GetChatCompletion(_services); + var message = await completion.GetChatCompletions(new Agent() { - Id = Guid.Empty.ToString(), + Id = input.AgentId ?? Guid.Empty.ToString(), + Instruction = input.Instruction }, new List { new RoleDialogModel(AgentRole.User, input.Text) diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/LlmProviderController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/LlmProviderController.cs index 02282b85..6b87bec2 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/LlmProviderController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/LlmProviderController.cs @@ -27,4 +27,11 @@ public class LlmProviderController : ControllerBase var list = _llmProvider.GetProviderModels(provider); return list.Where(x => x.Type == LlmModelType.Chat); } + + [HttpGet("/llm-configs")] + public List GetLlmConfigs([FromQuery] LlmConfigOptions options) + { + var configs = _llmProvider.GetLlmConfigs(options); + return configs; + } } diff --git a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Instructs/InstructMessageModel.cs b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Instructs/InstructMessageModel.cs index b736330f..3b0303fd 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Instructs/InstructMessageModel.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/ViewModels/Instructs/InstructMessageModel.cs @@ -9,3 +9,10 @@ public class InstructMessageModel : IncomingMessageModel public override string Channel { get; set; } = ConversationChannel.OpenAPI; public string? Template { get; set; } } + + +public class IncomingInstructRequest : IncomingMessageModel +{ + public string? AgentId { get; set; } + public string? Instruction { get; set; } +} \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ExecutionLogDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ExecutionLogDocument.cs deleted file mode 100644 index 6b961141..00000000 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/ExecutionLogDocument.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BotSharp.Plugin.MongoStorage.Collections; - -public class ExecutionLogDocument : MongoBase -{ - public string ConversationId { get; set; } = default!; - public List Logs { get; set; } = []; -} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogDocument.cs index 077fddc3..f26ac9fb 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/LlmCompletionLogDocument.cs @@ -3,5 +3,9 @@ namespace BotSharp.Plugin.MongoStorage.Collections; public class LlmCompletionLogDocument : MongoBase { public string ConversationId { get; set; } = default!; - public List Logs { get; set; } = []; + public string MessageId { get; set; } = default!; + public string AgentId { get; set; } = default!; + public string Prompt { get; set; } = default!; + public string? Response { get; set; } + public DateTime CreatedTime { get; set; } } diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/PromptLogMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/PromptLogMongoElement.cs deleted file mode 100644 index b8dabaa5..00000000 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/PromptLogMongoElement.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace BotSharp.Plugin.MongoStorage.Models; - -[BsonIgnoreExtraElements(Inherited = true)] -public class PromptLogMongoElement -{ - public string MessageId { get; set; } = default!; - public string AgentId { get; set; } = default!; - public string Prompt { get; set; } = default!; - public string? Response { get; set; } - public DateTime CreateDateTime { get; set; } -} diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs index 4d7f76a4..4aa82b2e 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs @@ -154,9 +154,6 @@ public class MongoDbContext public IMongoCollection ConversationStates => CreateConversationStateIndex(); - public IMongoCollection ExectionLogs - => GetCollectionOrCreate("ExecutionLogs"); - public IMongoCollection LlmCompletionLogs => GetCollectionOrCreate("LlmCompletionLogs"); diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs index 7d45e972..8b6dded6 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Conversation.cs @@ -56,13 +56,11 @@ public partial class MongoRepository var filterConv = Builders.Filter.In(x => x.Id, conversationIds); var filterDialog = Builders.Filter.In(x => x.ConversationId, conversationIds); var filterSates = Builders.Filter.In(x => x.ConversationId, conversationIds); - var filterExeLog = Builders.Filter.In(x => x.ConversationId, conversationIds); var filterPromptLog = Builders.Filter.In(x => x.ConversationId, conversationIds); var filterContentLog = Builders.Filter.In(x => x.ConversationId, conversationIds); var filterStateLog = Builders.Filter.In(x => x.ConversationId, conversationIds); var conbTabItems = Builders.Filter.In(x => x.ConversationId, conversationIds); - var exeLogDeleted = _dc.ExectionLogs.DeleteMany(filterExeLog); var promptLogDeleted = _dc.LlmCompletionLogs.DeleteMany(filterPromptLog); var contentLogDeleted = _dc.ContentLogs.DeleteMany(filterContentLog); var stateLogDeleted = _dc.StateLogs.DeleteMany(filterStateLog); @@ -71,10 +69,8 @@ public partial class MongoRepository var cronDeleted = _dc.CrontabItems.DeleteMany(conbTabItems); var convDeleted = _dc.Conversations.DeleteMany(filterConv); - return convDeleted.DeletedCount > 0 || dialogDeleted.DeletedCount > 0 || statesDeleted.DeletedCount > 0 - || exeLogDeleted.DeletedCount > 0 || promptLogDeleted.DeletedCount > 0 - || contentLogDeleted.DeletedCount > 0 || stateLogDeleted.DeletedCount > 0 - || convDeleted.DeletedCount > 0; + return convDeleted.DeletedCount > 0 || dialogDeleted.DeletedCount > 0 || statesDeleted.DeletedCount > 0 || promptLogDeleted.DeletedCount > 0 + || contentLogDeleted.DeletedCount > 0 || stateLogDeleted.DeletedCount > 0 || convDeleted.DeletedCount > 0; } [SideCar] diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Log.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Log.cs index 2316fdab..e4c64527 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Log.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Log.cs @@ -4,32 +4,6 @@ namespace BotSharp.Plugin.MongoStorage.Repository; public partial class MongoRepository { - #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) - { - List logs = []; - 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 ?? []; - return logs; - } - #endregion - #region LLM Completion Log public void SaveLlmCompletionLog(LlmCompletionLog log) { @@ -38,21 +12,17 @@ public partial class MongoRepository var conversationId = log.ConversationId.IfNullOrEmptyAs(Guid.NewGuid().ToString()); var messageId = log.MessageId.IfNullOrEmptyAs(Guid.NewGuid().ToString()); - var logElement = new PromptLogMongoElement + var data = new LlmCompletionLogDocument { + Id = Guid.NewGuid().ToString(), + ConversationId = conversationId, MessageId = messageId, AgentId = log.AgentId, Prompt = log.Prompt, Response = log.Response, - CreateDateTime = log.CreateDateTime + CreatedTime = log.CreatedTime }; - - var filter = Builders.Filter.Eq(x => x.ConversationId, conversationId); - var update = Builders.Update - .SetOnInsert(x => x.Id, Guid.NewGuid().ToString()) - .Push(x => x.Logs, logElement); - - _dc.LlmCompletionLogs.UpdateOne(filter, update, _options); + _dc.LlmCompletionLogs.InsertOne(data); } #endregion diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj b/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj index ace808b0..c5436fe6 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj +++ b/src/Plugins/BotSharp.Plugin.WebDriver/BotSharp.Plugin.WebDriver.csproj @@ -1,4 +1,4 @@ - + $(TargetFramework) @@ -16,21 +16,8 @@ - - - - - - - - - - - - - - - + + @@ -38,9 +25,6 @@ - - PreserveNewest - PreserveNewest @@ -50,6 +34,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -59,15 +46,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -110,6 +88,15 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs index efe8e7eb..4c65aa32 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightInstance.cs @@ -57,7 +57,8 @@ public class PlaywrightInstance : IDisposable } else { - string userDataDir = args.UserDataDir ?? $"{Path.GetTempPath()}\\playwright\\{ctxId}"; + string localAppDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + string userDataDir = args.UserDataDir ?? $"{localAppDataFolder}\\playwright\\{ctxId}"; _contexts[ctxId] = await _playwright.Chromium.LaunchPersistentContextAsync(userDataDir, new BrowserTypeLaunchPersistentContextOptions { Headless = args.Headless, diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs index 371a8c06..7327bb40 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.GoToPage.cs @@ -15,9 +15,12 @@ public partial class PlaywrightWebDriver if (page != null) { - await page.EvaluateAsync(@"() => { - window.open('', '_blank'); - }"); + if (page.Url != "about:blank") + { + await page.EvaluateAsync(@"() => { + window.open('', '_blank'); + }"); + } if (args.EnableResponseCallback) { @@ -36,13 +39,6 @@ public partial class PlaywrightWebDriver else { page = await _instance.NewPage(message, args); - - Serilog.Log.Information($"goto page: {args.Url}"); - - if (args.OpenNewTab && page != null && page.Url == "about:blank") - { - page = await _instance.NewPage(message, args); - } } if (page == null) @@ -95,6 +91,7 @@ public partial class PlaywrightWebDriver } result.ResponseStatusCode = response.Status; + result.UrlAfterAction = page.Url; if (response.Status == 200) { result.IsSuccess = true; diff --git a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs index 4d13e26f..67c9bf8d 100644 --- a/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs +++ b/src/Plugins/BotSharp.Plugin.WebDriver/Drivers/PlaywrightDriver/PlaywrightWebDriver.cs @@ -78,4 +78,9 @@ public partial class PlaywrightWebDriver : IWebBrowser await page.Keyboard.PressAsync(key); } } + + public async Task IsBrowserClosed(string contextId) + { + return !_instance.Contexts.ContainsKey(contextId); + } }