Resolve conflict.

This commit is contained in:
Haiping Chen 2023-11-29 21:01:08 -06:00
commit 52bfe435f5
31 changed files with 290 additions and 137 deletions

View file

@ -73,7 +73,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.WebDriver",
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.ChatHub", "src\Plugins\BotSharp.Plugin.ChatHub\BotSharp.Plugin.ChatHub.csproj", "{EDCD9C20-2D9D-4098-A16E-03F97B306CB8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotSharp.Plugin.ChatHub", "src\Plugins\BotSharp.Plugin.ChatHub\BotSharp.Plugin.ChatHub.csproj", "{EDCD9C20-2D9D-4098-A16E-03F97B306CB8}"
EndProject 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 EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution 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|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.ActiveCfg = Release|Any CPU
{DCA18996-4D3A-4E98-BCD0-1FB77C59253E}.Release|x64.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -320,6 +330,7 @@ Global
{F06B22CB-B143-4680-8FFF-35B9E50E6C47} = {51AFE054-AE99-497D-A593-69BAEFB5106F} {F06B22CB-B143-4680-8FFF-35B9E50E6C47} = {51AFE054-AE99-497D-A593-69BAEFB5106F}
{EDCD9C20-2D9D-4098-A16E-03F97B306CB8} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00} {EDCD9C20-2D9D-4098-A16E-03F97B306CB8} = {64264688-0F5C-4AB0-8F2B-B59B717CCE00}
{DCA18996-4D3A-4E98-BCD0-1FB77C59253E} = {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 EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19}

View file

@ -7,4 +7,6 @@ public class ConversationSetting
public bool EnableKnowledgeBase { get; set; } public bool EnableKnowledgeBase { get; set; }
public bool ShowVerboseLog { get; set; } public bool ShowVerboseLog { get; set; }
public int MaxRecursiveDepth { get; set; } = 3; public int MaxRecursiveDepth { get; set; } = 3;
public bool EnableLlmCompletionLog { get; set; }
public bool EnableExecutionLog { get; set; }
} }

View file

@ -1,4 +1,4 @@
namespace BotSharp.Abstraction.MLTasks; namespace BotSharp.Abstraction.Loggers;
/// <summary> /// <summary>
/// Model content generating hook, it can be used for logging, metrics and tracing. /// Model content generating hook, it can be used for logging, metrics and tracing.

View file

@ -0,0 +1,6 @@
namespace BotSharp.Abstraction.Loggers;
public interface IVerboseLogHook
{
void GenerateLog(string text);
}

View file

@ -38,8 +38,11 @@ public interface IBotSharpRepository
List<Conversation> GetConversations(ConversationFilter filter); List<Conversation> GetConversations(ConversationFilter filter);
void UpdateConversationTitle(string conversationId, string title); void UpdateConversationTitle(string conversationId, string title);
List<Conversation> GetLastConversations(); List<Conversation> GetLastConversations();
void AddExectionLogs(string conversationId, List<string> logs); #endregion
List<string> GetExectionLogs(string conversationId);
#region Execution Log
void AddExecutionLogs(string conversationId, List<string> logs);
List<string> GetExecutionLogs(string conversationId);
#endregion #endregion
#region LLM Completion Log #region LLM Completion Log

View file

@ -22,9 +22,9 @@ using BotSharp.Core.Planning;
namespace BotSharp.Core; 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<IUserService, UserService>(); services.AddScoped<IUserService, UserService>();

View file

@ -21,6 +21,6 @@ public class ExecutionLogger : IExecutionLogger
content = content.Replace("\r\n", " ").Replace("\n", " "); content = content.Replace("\r\n", " ").Replace("\n", " ");
content = Regex.Replace(content, @"\s+", " "); content = Regex.Replace(content, @"\s+", " ");
var db = _services.GetRequiredService<IBotSharpRepository>(); var db = _services.GetRequiredService<IBotSharpRepository>();
db.AddExectionLogs(conversationId, new List<string> { content }); db.AddExecutionLogs(conversationId, new List<string> { content });
} }
} }

View file

@ -168,16 +168,6 @@ public class BotSharpDbContext : Database, IBotSharpRepository
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void AddExectionLogs(string conversationId, List<string> logs)
{
throw new NotImplementedException();
}
public List<string> GetExectionLogs(string conversationId)
{
throw new NotImplementedException();
}
#endregion #endregion
@ -198,6 +188,19 @@ public class BotSharpDbContext : Database, IBotSharpRepository
} }
#endregion #endregion
#region Execution Log
public void AddExecutionLogs(string conversationId, List<string> logs)
{
throw new NotImplementedException();
}
public List<string> GetExecutionLogs(string conversationId)
{
throw new NotImplementedException();
}
#endregion
#region LLM Completion Log #region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log) public void SaveLlmCompletionLog(LlmCompletionLog log)
{ {

View file

@ -6,8 +6,6 @@ using BotSharp.Abstraction.Agents.Models;
using MongoDB.Driver; using MongoDB.Driver;
using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Utilities;
using BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Core.Repository; namespace BotSharp.Core.Repository;
@ -789,33 +787,6 @@ public class FileRepository : IBotSharpRepository
.Select(g => g.OrderByDescending(x => x.CreatedTime).First()) .Select(g => g.OrderByDescending(x => x.CreatedTime).First())
.ToList(); .ToList();
} }
public void AddExectionLogs(string conversationId, List<string> 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<string> GetExectionLogs(string conversationId)
{
var logs = new List<string>();
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<string>();
return logs;
}
#endregion #endregion
#region User #region User
@ -843,6 +814,35 @@ public class FileRepository : IBotSharpRepository
} }
#endregion #endregion
#region Execution Log
public void AddExecutionLogs(string conversationId, List<string> 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<string> GetExecutionLogs(string conversationId)
{
var logs = new List<string>();
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<string>();
return logs;
}
#endregion
#region LLM Completion Log #region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log) public void SaveLlmCompletionLog(LlmCompletionLog log)
{ {
@ -855,6 +855,7 @@ public class FileRepository : IBotSharpRepository
Directory.CreateDirectory(logDir); Directory.CreateDirectory(logDir);
} }
log.Id = Guid.NewGuid().ToString();
var index = GetLlmCompletionLogIndex(logDir, log.MessageId); var index = GetLlmCompletionLogIndex(logDir, log.MessageId);
var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log"); var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log");
File.WriteAllText(file, JsonSerializer.Serialize(log, _options)); File.WriteAllText(file, JsonSerializer.Serialize(log, _options));

View file

@ -0,0 +1,58 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>$(LangVersion)</LangVersion>
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup>
<Authors>Haiping Chen</Authors>
<Company>SciSharp STACK</Company>
<Product>LL Application Framework</Product>
<Description>
Open source LLM application framework to build scalable, flexible and robust AI system.
</Description>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/SciSharp/BotSharp</RepositoryUrl>
<PackageTags>Chatbot, Bot, LLM, AI, ChatGPT, OpenAI</PackageTags>
<PackageReleaseNotes>Support dialogue status tracking.</PackageReleaseNotes>
<Copyright>Since 2018 Haiping Chen</Copyright>
<PackageProjectUrl>https://github.com/SciSharp/BotSharp</PackageProjectUrl>
<PackageIconUrl>https://raw.githubusercontent.com/SciSharp/BotSharp/master/docs/static/logos/BotSharp.png</PackageIconUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/SciSharp/BotSharp/master/LICENSE</PackageLicenseUrl>
<PackageIcon>Icon.png</PackageIcon>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG</DefineConstants>
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE;</DefineConstants>
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\..\arts\Icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,12 @@
namespace BotSharp.Logger;
public static class BotSharpLoggerExtensions
{
public static IServiceCollection AddBotSharpLogger(this IServiceCollection services, IConfiguration config)
{
services.AddScoped<IContentGeneratingHook, CommonContentGeneratingHook>();
services.AddScoped<IContentGeneratingHook, TokenStatsConversationHook>();
services.AddScoped<IVerboseLogHook, VerboseLogHook>();
return services;
}
}

View file

@ -0,0 +1,39 @@
public class CommonContentGeneratingHook : IContentGeneratingHook
{
private readonly IServiceProvider _services;
public CommonContentGeneratingHook(IServiceProvider services)
{
_services = services;
}
/// <summary>
/// After content generated.
/// </summary>
/// <returns></returns>
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<ConversationSetting>();
if (!convSettings.EnableLlmCompletionLog) return;
var db = _services.GetRequiredService<IBotSharpRepository>();
var state = _services.GetRequiredService<IConversationStateService>();
var completionLog = new LlmCompletionLog
{
ConversationId = state.GetConversationId(),
MessageId = message.MessageId,
AgentId = message.CurrentAgentId,
Prompt = tokenStats.Prompt,
Response = message.Content
};
db.SaveLlmCompletionLog(completionLog);
}
}

View file

@ -1,15 +1,5 @@
using BotSharp.Abstraction.Agents.Models; namespace BotSharp.Logger.Hooks;
using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.MLTasks;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace BotSharp.Plugin.AzureOpenAI.Hooks;
/// <summary>
/// Token statistics for Azure OpenAI
/// </summary>
public class TokenStatsConversationHook : IContentGeneratingHook public class TokenStatsConversationHook : IContentGeneratingHook
{ {
private readonly ITokenStatistics _tokenStatistics; private readonly ITokenStatistics _tokenStatistics;
@ -22,14 +12,15 @@ public class TokenStatsConversationHook : IContentGeneratingHook
public async Task BeforeGenerating(Agent agent, List<RoleDialogModel> conversations) public async Task BeforeGenerating(Agent agent, List<RoleDialogModel> conversations)
{ {
_tokenStatistics.StartTimer(); _tokenStatistics.StartTimer();
await Task.CompletedTask;
} }
public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats) public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats)
{ {
_tokenStatistics.StopTimer(); _tokenStatistics.StopTimer();
tokenStats.PromptCost = 0.0015f; tokenStats.PromptCost = 0.0015f;
tokenStats.CompletionCost = 0.002f; tokenStats.CompletionCost = 0.002f;
_tokenStatistics.AddToken(tokenStats); _tokenStatistics.AddToken(tokenStats);
await Task.CompletedTask;
} }
} }

View file

@ -0,0 +1,20 @@
namespace BotSharp.Logger.Hooks;
public class VerboseLogHook : IVerboseLogHook
{
private readonly ConversationSetting _convSettings;
private readonly ILogger<VerboseLogHook> _logger;
public VerboseLogHook(ConversationSetting convSettings, ILogger<VerboseLogHook> logger)
{
_convSettings = convSettings;
_logger = logger;
}
public void GenerateLog(string text)
{
if (!_convSettings.ShowVerboseLog) return;
_logger.LogInformation(text);
}
}

View file

@ -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;

View file

@ -1,7 +1,6 @@
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Plugins; using BotSharp.Abstraction.Plugins;
using BotSharp.Abstraction.Utilities; using BotSharp.Abstraction.Utilities;
using BotSharp.Plugin.AzureOpenAI.Hooks;
using BotSharp.Plugin.AzureOpenAI.Providers; using BotSharp.Plugin.AzureOpenAI.Providers;
using BotSharp.Plugin.AzureOpenAI.Settings; using BotSharp.Plugin.AzureOpenAI.Settings;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -30,6 +29,5 @@ public class AzureOpenAiPlugin : IBotSharpPlugin
services.AddScoped<ITextCompletion, TextCompletionProvider>(); services.AddScoped<ITextCompletion, TextCompletionProvider>();
services.AddScoped<IChatCompletion, ChatCompletionProvider>(); services.AddScoped<IChatCompletion, ChatCompletionProvider>();
services.AddScoped<IContentGeneratingHook, TokenStatsConversationHook>();
} }
} }

View file

@ -1,4 +1,3 @@
using Azure;
using Azure.AI.OpenAI; using Azure.AI.OpenAI;
using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Enums;
@ -6,9 +5,9 @@ using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Conversations.Settings; using BotSharp.Abstraction.Conversations.Settings;
using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.AzureOpenAI.Settings; using BotSharp.Plugin.AzureOpenAI.Settings;
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System; using System;
@ -39,10 +38,11 @@ public class ChatCompletionProvider : IChatCompletion
public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> conversations) public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
{ {
var hooks = _services.GetServices<IContentGeneratingHook>().ToList(); var contentHooks = _services.GetServices<IContentGeneratingHook>().ToList();
var logHook = _services.GetService<IVerboseLogHook>();
// Before chat completion hook // Before chat completion hook
Task.WaitAll(hooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
hook.BeforeGenerating(agent, conversations)).ToArray()); hook.BeforeGenerating(agent, conversations)).ToArray());
var client = ProviderHelper.GetClient(_model, _settings); var client = ProviderHelper.GetClient(_model, _settings);
@ -75,16 +75,13 @@ public class ChatCompletionProvider : IChatCompletion
} }
} }
var setting = _services.GetRequiredService<ConversationSetting>(); var log = responseMessage.Role == AgentRole.Function ?
if (setting.ShowVerboseLog)
{
_logger.LogInformation(responseMessage.Role == AgentRole.Function ?
$"[{agent.Name}]: {responseMessage.FunctionName}({responseMessage.FunctionArgs})" : $"[{agent.Name}]: {responseMessage.FunctionName}({responseMessage.FunctionArgs})" :
$"[{agent.Name}]: {responseMessage.Content}"); $"[{agent.Name}]: {responseMessage.Content}";
} logHook?.GenerateLog(log);
// After chat completion hook // After chat completion hook
Task.WaitAll(hooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
hook.AfterGenerated(responseMessage, new TokenStatsModel hook.AfterGenerated(responseMessage, new TokenStatsModel
{ {
Prompt = prompt, Prompt = prompt,
@ -195,6 +192,7 @@ public class ChatCompletionProvider : IChatCompletion
protected (string, ChatCompletionsOptions) PrepareOptions(Agent agent, List<RoleDialogModel> conversations) protected (string, ChatCompletionsOptions) PrepareOptions(Agent agent, List<RoleDialogModel> conversations)
{ {
var agentService = _services.GetRequiredService<IAgentService>(); var agentService = _services.GetRequiredService<IAgentService>();
var logHook = _services.GetService<IVerboseLogHook>();
var chatCompletionsOptions = new ChatCompletionsOptions(); var chatCompletionsOptions = new ChatCompletionsOptions();
@ -250,11 +248,7 @@ public class ChatCompletionProvider : IChatCompletion
// chatCompletionsOptions.PresencePenalty = 0; // chatCompletionsOptions.PresencePenalty = 0;
var prompt = GetPrompt(chatCompletionsOptions); var prompt = GetPrompt(chatCompletionsOptions);
var convSetting = _services.GetRequiredService<ConversationSetting>(); logHook?.GenerateLog(prompt);
if (convSetting.ShowVerboseLog)
{
_logger.LogInformation(prompt);
}
return (prompt, chatCompletionsOptions); return (prompt, chatCompletionsOptions);
} }

View file

@ -11,7 +11,7 @@ using BotSharp.Abstraction.Agents.Enums;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Settings; using BotSharp.Abstraction.Loggers;
namespace BotSharp.Plugin.AzureOpenAI.Providers; namespace BotSharp.Plugin.AzureOpenAI.Providers;
@ -19,22 +19,20 @@ public class TextCompletionProvider : ITextCompletion
{ {
private readonly IServiceProvider _services; private readonly IServiceProvider _services;
private readonly AzureOpenAiSettings _settings; private readonly AzureOpenAiSettings _settings;
private readonly ILogger _logger;
private string _model; private string _model;
public string Provider => "azure-openai"; public string Provider => "azure-openai";
public TextCompletionProvider(IServiceProvider services, public TextCompletionProvider(IServiceProvider services,
AzureOpenAiSettings settings, AzureOpenAiSettings settings)
ILogger<TextCompletionProvider> logger)
{ {
_services = services; _services = services;
_settings = settings; _settings = settings;
_logger = logger;
} }
public async Task<string> GetCompletion(string text, string agentId, string messageId) public async Task<string> GetCompletion(string text, string agentId, string messageId)
{ {
var hooks = _services.GetServices<IContentGeneratingHook>().ToList(); var contentHooks = _services.GetServices<IContentGeneratingHook>().ToList();
var logHook = _services.GetService<IVerboseLogHook>();
// Before chat completion hook // Before chat completion hook
var agent = new Agent() var agent = new Agent()
@ -47,7 +45,7 @@ public class TextCompletionProvider : ITextCompletion
MessageId = messageId MessageId = messageId
}; };
Task.WaitAll(hooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
hook.BeforeGenerating(agent, hook.BeforeGenerating(agent,
new List<RoleDialogModel> new List<RoleDialogModel>
{ {
@ -65,12 +63,7 @@ public class TextCompletionProvider : ITextCompletion
MaxTokens = 256, MaxTokens = 256,
}; };
completionsOptions.StopSequences.Add($"{AgentRole.Assistant}:"); completionsOptions.StopSequences.Add($"{AgentRole.Assistant}:");
logHook?.GenerateLog(text);
var setting = _services.GetRequiredService<ConversationSetting>();
if (setting.ShowVerboseLog)
{
_logger.LogInformation(text);
}
var state = _services.GetRequiredService<IConversationStateService>(); var state = _services.GetRequiredService<IConversationStateService>();
var temperature = float.Parse(state.GetState("temperature", "0.5")); var temperature = float.Parse(state.GetState("temperature", "0.5"));
@ -87,10 +80,7 @@ public class TextCompletionProvider : ITextCompletion
completion += t.Text; completion += t.Text;
}; };
if (setting.ShowVerboseLog) logHook?.GenerateLog(completion);
{
_logger.LogInformation(completion);
}
// After chat completion hook // After chat completion hook
var responseMessage = new RoleDialogModel(AgentRole.Assistant, completion) var responseMessage = new RoleDialogModel(AgentRole.Assistant, completion)
@ -98,7 +88,7 @@ public class TextCompletionProvider : ITextCompletion
CurrentAgentId = agentId, CurrentAgentId = agentId,
MessageId = messageId MessageId = messageId
}; };
Task.WaitAll(hooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
hook.AfterGenerated(responseMessage, new TokenStatsModel hook.AfterGenerated(responseMessage, new TokenStatsModel
{ {
Prompt = text, Prompt = text,

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Routing; using BotSharp.Abstraction.Routing;
using BotSharp.Plugin.GoogleAI.Settings; using BotSharp.Plugin.GoogleAI.Settings;

View file

@ -1,5 +1,6 @@
using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Loggers;
using BotSharp.Plugin.GoogleAI.Settings; using BotSharp.Plugin.GoogleAI.Settings;
using LLMSharp.Google.Palm; using LLMSharp.Google.Palm;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations.Settings; using BotSharp.Abstraction.Conversations.Settings;
using BotSharp.Abstraction.Loggers;
using BotSharp.Plugin.HuggingFace.Services; using BotSharp.Plugin.HuggingFace.Services;
using BotSharp.Plugin.HuggingFace.Settings; using BotSharp.Plugin.HuggingFace.Settings;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Loggers;
namespace BotSharp.Plugin.LLamaSharp.Providers; namespace BotSharp.Plugin.LLamaSharp.Providers;

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Loggers;
namespace BotSharp.Plugin.LLamaSharp.Providers; namespace BotSharp.Plugin.LLamaSharp.Providers;
public class TextCompletionProvider : ITextCompletion public class TextCompletionProvider : ITextCompletion

View file

@ -4,7 +4,6 @@ using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Users.Models;
using BotSharp.Abstraction.Utilities;
using BotSharp.Plugin.MongoStorage.Collections; using BotSharp.Plugin.MongoStorage.Collections;
using BotSharp.Plugin.MongoStorage.Models; using BotSharp.Plugin.MongoStorage.Models;
@ -782,30 +781,6 @@ public class MongoRepository : IBotSharpRepository
UpdatedTime = c.UpdatedTime UpdatedTime = c.UpdatedTime
}).ToList(); }).ToList();
} }
public void AddExectionLogs(string conversationId, List<string> logs)
{
if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return;
var filter = Builders<ExectionLogCollection>.Filter.Eq(x => x.ConversationId, conversationId);
var update = Builders<ExectionLogCollection>.Update
.SetOnInsert(x => x.Id, Guid.NewGuid().ToString())
.PushEach(x => x.Logs, logs);
_dc.ExectionLogs.UpdateOne(filter, update, _options);
}
public List<string> GetExectionLogs(string conversationId)
{
var logs = new List<string>();
if (string.IsNullOrEmpty(conversationId)) return logs;
var filter = Builders<ExectionLogCollection>.Filter.Eq(x => x.ConversationId, conversationId);
var logCollection = _dc.ExectionLogs.Find(filter).FirstOrDefault();
logs = logCollection?.Logs ?? new List<string>();
return logs;
}
#endregion #endregion
#region User #region User
@ -863,6 +838,32 @@ public class MongoRepository : IBotSharpRepository
} }
#endregion #endregion
#region Execution Log
public void AddExecutionLogs(string conversationId, List<string> logs)
{
if (string.IsNullOrEmpty(conversationId) || logs.IsNullOrEmpty()) return;
var filter = Builders<ExectionLogCollection>.Filter.Eq(x => x.ConversationId, conversationId);
var update = Builders<ExectionLogCollection>.Update
.SetOnInsert(x => x.Id, Guid.NewGuid().ToString())
.PushEach(x => x.Logs, logs);
_dc.ExectionLogs.UpdateOne(filter, update, _options);
}
public List<string> GetExecutionLogs(string conversationId)
{
var logs = new List<string>();
if (string.IsNullOrEmpty(conversationId)) return logs;
var filter = Builders<ExectionLogCollection>.Filter.Eq(x => x.ConversationId, conversationId);
var logCollection = _dc.ExectionLogs.Find(filter).FirstOrDefault();
logs = logCollection?.Logs ?? new List<string>();
return logs;
}
#endregion
#region LLM Completion Log #region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log) public void SaveLlmCompletionLog(LlmCompletionLog log)
{ {

View file

@ -3,6 +3,7 @@ using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel; using Microsoft.SemanticKernel;

View file

@ -2,7 +2,7 @@ using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.Loggers;
using Microsoft; using Microsoft;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel; using Microsoft.SemanticKernel;

View file

@ -2,6 +2,7 @@ using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Users; using BotSharp.Abstraction.Users;
using BotSharp.Core; using BotSharp.Core;
using BotSharp.Core.Users.Services; using BotSharp.Core.Users.Services;
using BotSharp.Logger;
using BotSharp.Plugin.ChatHub; using BotSharp.Plugin.ChatHub;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -46,7 +47,8 @@ builder.Services.AddAuthentication(options =>
builder.Services.AddScoped<IUserIdentity, UserIdentity>(); builder.Services.AddScoped<IUserIdentity, UserIdentity>();
// Add BotSharp // Add BotSharp
builder.Services.AddBotSharp(builder.Configuration); builder.Services.AddBotSharpCore(builder.Configuration);
builder.Services.AddBotSharpLogger(builder.Configuration);
builder.Services.AddCors(options => builder.Services.AddCors(options =>
{ {

View file

@ -21,6 +21,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup Condition="$(SolutionName)==PizzaBot"> <ItemGroup Condition="$(SolutionName)==PizzaBot">
<PackageReference Include="BotSharp.Logger" Version="$(BotSharpVersion)" />
<PackageReference Include="BotSharp.OpenAPI" Version="$(BotSharpVersion)" /> <PackageReference Include="BotSharp.OpenAPI" Version="$(BotSharpVersion)" />
<PackageReference Include="BotSharp.Plugin.AzureOpenAI" Version="$(BotSharpVersion)" /> <PackageReference Include="BotSharp.Plugin.AzureOpenAI" Version="$(BotSharpVersion)" />
<PackageReference Include="BotSharp.Plugin.GoogleAI" Version="$(BotSharpVersion)" /> <PackageReference Include="BotSharp.Plugin.GoogleAI" Version="$(BotSharpVersion)" />
@ -45,6 +46,7 @@
<ItemGroup Condition="$(SolutionName)==BotSharp"> <ItemGroup Condition="$(SolutionName)==BotSharp">
<ProjectReference Include="..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" /> <ProjectReference Include="..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" />
<ProjectReference Include="..\Infrastructure\BotSharp.Logger\BotSharp.Logger.csproj" />
<ProjectReference Include="..\Infrastructure\BotSharp.OpenAPI\BotSharp.OpenAPI.csproj" /> <ProjectReference Include="..\Infrastructure\BotSharp.OpenAPI\BotSharp.OpenAPI.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj" /> <ProjectReference Include="..\Plugins\BotSharp.Plugin.GoogleAI\BotSharp.Plugin.GoogleAI.csproj" />
<ProjectReference Include="..\Plugins\BotSharp.Plugin.MongoStorage\BotSharp.Plugin.MongoStorage.csproj" /> <ProjectReference Include="..\Plugins\BotSharp.Plugin.MongoStorage\BotSharp.Plugin.MongoStorage.csproj" />

View file

@ -34,7 +34,9 @@
"Conversation": { "Conversation": {
"DataDir": "conversations", "DataDir": "conversations",
"ShowVerboseLog": false "ShowVerboseLog": false,
"EnableLlmCompletionLog": false,
"EnableExecutionLog": true
}, },
"LlamaSharp": { "LlamaSharp": {
@ -134,8 +136,9 @@
"PluginLoader": { "PluginLoader": {
"Assemblies": [ "Assemblies": [
"BotSharp.Core",
"BotSharp.Plugin.MongoStorage", "BotSharp.Plugin.MongoStorage",
"BotSharp.Core",
"BotSharp.Logger",
"BotSharp.Plugin.AzureOpenAI", "BotSharp.Plugin.AzureOpenAI",
"BotSharp.Plugin.GoogleAI", "BotSharp.Plugin.GoogleAI",
"BotSharp.Plugin.MetaAI", "BotSharp.Plugin.MetaAI",

View file

@ -1,37 +1,26 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using BotSharp.Abstraction.Agents; using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.SemanticKernel;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Moq; using Moq;
using Xunit;
using BotSharp.Abstraction.Agents.Enums; using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using System.Linq;
using System.Runtime;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using BotSharp.Abstraction.Models;
using Microsoft.SemanticKernel.AI.ChatCompletion; using Microsoft.SemanticKernel.AI.ChatCompletion;
using Microsoft.SemanticKernel.AI; using Microsoft.SemanticKernel.AI;
using Microsoft.SemanticKernel.Connectors.AI.OpenAI.AzureSdk;
using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers; using BotSharp.Plugin.SemanticKernel.UnitTests.Helpers;
using BotSharp.Abstraction.Loggers;
namespace BotSharp.Plugin.SemanticKernel.Tests namespace BotSharp.Plugin.SemanticKernel.Tests
{ {
public class SemanticKernelChatCompletionProviderTests public class SemanticKernelChatCompletionProviderTests
{ {
private readonly Mock<Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion> _chatCompletionMock; private readonly Mock<IChatCompletion> _chatCompletionMock;
private readonly Mock<IServiceProvider> _servicesMock; private readonly Mock<IServiceProvider> _servicesMock;
private readonly Mock<ITokenStatistics> _tokenStatisticsMock; private readonly Mock<ITokenStatistics> _tokenStatisticsMock;
private readonly SemanticKernelChatCompletionProvider _provider; private readonly SemanticKernelChatCompletionProvider _provider;
public SemanticKernelChatCompletionProviderTests() public SemanticKernelChatCompletionProviderTests()
{ {
_chatCompletionMock = new Mock<Microsoft.SemanticKernel.AI.ChatCompletion.IChatCompletion>(); _chatCompletionMock = new Mock<IChatCompletion>();
_servicesMock = new Mock<IServiceProvider>(); _servicesMock = new Mock<IServiceProvider>();
_tokenStatisticsMock = new Mock<ITokenStatistics>(); _tokenStatisticsMock = new Mock<ITokenStatistics>();
_provider = new SemanticKernelChatCompletionProvider(_chatCompletionMock.Object, _servicesMock.Object, _tokenStatisticsMock.Object); _provider = new SemanticKernelChatCompletionProvider(_chatCompletionMock.Object, _servicesMock.Object, _tokenStatisticsMock.Object);

View file

@ -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; global using Xunit;