Merge branch 'master' into v0.20-json-schema

This commit is contained in:
Haiping Chen 2023-11-30 20:19:00 -06:00
commit 9cc9839796
8 changed files with 55 additions and 29 deletions

View file

@ -0,0 +1,24 @@
# Logging
## Setting
To initialize the logging feature, set up the following flags in `Conversation`. Each flag can display or record specific content during conversation.
* `ShowVerboseLog`: print conversation details or prompt in console.
* `EnableLlmCompletionLog`: log LLM completion results, e.g., real-time prompt sent to LLM and response generated from LLm.
* `EnableExecutionLog`: log details after events, e.g., receiving message, executing function, generating response, etc.
```json
"Conversation": {
"ShowVerboseLog": false,
"EnableLlmCompletionLog": false,
"EnableExecutionLog": true
}
```
### Usage
To enable the logging functionality, add the following line of code in `Program.cs`.
```csharp
builder.Services.AddBotSharpLogger(builder.Configuration);
```

View file

@ -102,6 +102,7 @@ The main documentation for the site is organized into the following sections:
architecture/plugin architecture/plugin
architecture/hooks architecture/hooks
architecture/routing architecture/routing
architecture/logging
architecture/data-persistence architecture/data-persistence
If you feel that this project is helpful to you, please Star us on the project, we will be very grateful. If you feel that this project is helpful to you, please Star us on the project, we will be very grateful.

View file

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

View file

@ -6,7 +6,7 @@ public static class BotSharpLoggerExtensions
{ {
services.AddScoped<IContentGeneratingHook, CommonContentGeneratingHook>(); services.AddScoped<IContentGeneratingHook, CommonContentGeneratingHook>();
services.AddScoped<IContentGeneratingHook, TokenStatsConversationHook>(); services.AddScoped<IContentGeneratingHook, TokenStatsConversationHook>();
services.AddScoped<IVerboseLogHook, VerboseLogHook>(); services.AddScoped<IContentGeneratingHook, VerboseLogHook>();
return services; return services;
} }
} }

View file

@ -7,10 +7,6 @@ public class CommonContentGeneratingHook : IContentGeneratingHook
_services = services; _services = services;
} }
/// <summary>
/// After content generated.
/// </summary>
/// <returns></returns>
public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats) public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats)
{ {
SaveLlmCompletionLog(message, tokenStats); SaveLlmCompletionLog(message, tokenStats);

View file

@ -1,20 +1,45 @@
using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Agents.Enums;
namespace BotSharp.Logger.Hooks; namespace BotSharp.Logger.Hooks;
public class VerboseLogHook : IVerboseLogHook public class VerboseLogHook : IContentGeneratingHook
{ {
private readonly ConversationSetting _convSettings; private readonly ConversationSetting _convSettings;
private readonly ILogger<VerboseLogHook> _logger; private readonly ILogger<VerboseLogHook> _logger;
private readonly IServiceProvider _services;
public VerboseLogHook(ConversationSetting convSettings, ILogger<VerboseLogHook> logger) public VerboseLogHook(
ConversationSetting convSettings,
IServiceProvider serivces,
ILogger<VerboseLogHook> logger)
{ {
_convSettings = convSettings; _convSettings = convSettings;
_services = serivces;
_logger = logger; _logger = logger;
} }
public void GenerateLog(string text) public async Task BeforeGenerating(Agent agent, List<RoleDialogModel> conversations)
{ {
if (!_convSettings.ShowVerboseLog) return; if (!_convSettings.ShowVerboseLog) return;
_logger.LogInformation(text); var dialog = conversations.Last();
var log = $"{dialog.Role}: {dialog.Content}";
_logger.LogInformation(log);
}
public async Task AfterGenerated(RoleDialogModel message, TokenStatsModel tokenStats)
{
if (!_convSettings.ShowVerboseLog) return;
var agentService = _services.GetRequiredService<IAgentService>();
var agent = await agentService.LoadAgent(message.CurrentAgentId);
var log = message.Role == AgentRole.Function ?
$"[{agent.Name}]: {message.FunctionName}({message.FunctionArgs})" :
$"[{agent.Name}]: {message.Content}";
_logger.LogInformation(tokenStats.Prompt);
_logger.LogInformation(log);
} }
} }

View file

@ -4,7 +4,6 @@ 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.Conversations.Settings;
using BotSharp.Abstraction.Loggers; using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks;
using BotSharp.Plugin.AzureOpenAI.Settings; using BotSharp.Plugin.AzureOpenAI.Settings;
@ -39,7 +38,6 @@ public class ChatCompletionProvider : IChatCompletion
public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> conversations) public RoleDialogModel GetChatCompletions(Agent agent, List<RoleDialogModel> conversations)
{ {
var contentHooks = _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(contentHooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
@ -75,11 +73,6 @@ public class ChatCompletionProvider : IChatCompletion
} }
} }
var log = responseMessage.Role == AgentRole.Function ?
$"[{agent.Name}]: {responseMessage.FunctionName}({responseMessage.FunctionArgs})" :
$"[{agent.Name}]: {responseMessage.Content}";
logHook?.GenerateLog(log);
// After chat completion hook // After chat completion hook
Task.WaitAll(contentHooks.Select(hook => Task.WaitAll(contentHooks.Select(hook =>
hook.AfterGenerated(responseMessage, new TokenStatsModel hook.AfterGenerated(responseMessage, new TokenStatsModel
@ -192,7 +185,6 @@ 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();
@ -248,7 +240,6 @@ public class ChatCompletionProvider : IChatCompletion
// chatCompletionsOptions.PresencePenalty = 0; // chatCompletionsOptions.PresencePenalty = 0;
var prompt = GetPrompt(chatCompletionsOptions); var prompt = GetPrompt(chatCompletionsOptions);
logHook?.GenerateLog(prompt);
return (prompt, chatCompletionsOptions); return (prompt, chatCompletionsOptions);
} }

View file

@ -3,7 +3,6 @@ using BotSharp.Abstraction.MLTasks;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using BotSharp.Plugin.AzureOpenAI.Settings; using BotSharp.Plugin.AzureOpenAI.Settings;
using Microsoft.Extensions.Logging;
using BotSharp.Abstraction.Conversations; using BotSharp.Abstraction.Conversations;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
@ -32,7 +31,6 @@ public class TextCompletionProvider : ITextCompletion
public async Task<string> GetCompletion(string text, string agentId, string messageId) public async Task<string> GetCompletion(string text, string agentId, string messageId)
{ {
var contentHooks = _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()
@ -63,7 +61,6 @@ public class TextCompletionProvider : ITextCompletion
MaxTokens = 256, MaxTokens = 256,
}; };
completionsOptions.StopSequences.Add($"{AgentRole.Assistant}:"); completionsOptions.StopSequences.Add($"{AgentRole.Assistant}:");
logHook?.GenerateLog(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"));
@ -80,8 +77,6 @@ public class TextCompletionProvider : ITextCompletion
completion += t.Text; completion += t.Text;
}; };
logHook?.GenerateLog(completion);
// After chat completion hook // After chat completion hook
var responseMessage = new RoleDialogModel(AgentRole.Assistant, completion) var responseMessage = new RoleDialogModel(AgentRole.Assistant, completion)
{ {