Code improvement based on feedback.

This commit is contained in:
103048 2024-07-11 11:02:14 -05:00
parent 6abc7aba43
commit 149de9a62d
8 changed files with 115 additions and 117 deletions

View file

@ -0,0 +1,11 @@
namespace BotSharp.Abstraction.Email.Settings;
public class EmailHandlerSettings
{
public string EmailAddress { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string SMTPServer { get; set; } = string.Empty;
public int SMTPPort { get; set; }
}

View file

@ -1,12 +0,0 @@
namespace BotSharp.Abstraction.Email.Settings
{
public class EmailPluginSettings
{
public string EmailAddress { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string SMTPServer { get; set; } = string.Empty;
public int SMTPPort { get; set; }
}
}

View file

@ -11,15 +11,15 @@
</PropertyGroup>
<ItemGroup>
<None Remove="data\agents\00000000-0000-0000-0000-000000000000\functions\handle_email_request.json" />
<None Remove="data\agents\00000000-0000-0000-0000-000000000000\templates\handle_email_request.fn.liquid" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_request.json" />
<None Remove="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_request.fn.liquid" />
</ItemGroup>
<ItemGroup>
<Content Include="data\agents\00000000-0000-0000-0000-000000000000\functions\handle_email_request.json">
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\functions\handle_email_request.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\00000000-0000-0000-0000-000000000000\templates\handle_email_request.fn.liquid">
<Content Include="data\agents\6745151e-6d46-4a02-8de4-1c4f21c7da95\templates\handle_email_request.fn.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

View file

@ -23,7 +23,7 @@ namespace BotSharp.Plugin.EmailHandler
services.AddScoped(provider =>
{
var settingService = provider.GetRequiredService<ISettingService>();
return settingService.Bind<EmailPluginSettings>("EmailPlugin");
return settingService.Bind<EmailHandlerSettings>("EmailHandler");
});
services.AddScoped<IAgentHook, EmailHandlerHook>();

View file

@ -1,5 +1,6 @@
using BotSharp.Abstraction.Email.Settings;
using BotSharp.Plugin.EmailHandler.LlmContexts;
using MailKit;
using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.AspNetCore.Http;
@ -7,72 +8,71 @@ using Microsoft.Extensions.Logging;
using MimeKit;
using System.Net.Http;
namespace BotSharp.Plugin.EmailHandler.Functions
namespace BotSharp.Plugin.EmailHandler.Functions;
public class HandleEmailRequestFn : IFunctionCallback
{
public class HandleEmailRequestFn : IFunctionCallback
public string Name => "handle_email_request";
public string Indication => "Handling email request";
private readonly IServiceProvider _services;
private readonly ILogger<HandleEmailRequestFn> _logger;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IHttpContextAccessor _context;
private readonly BotSharpOptions _options;
private readonly EmailHandlerSettings _emailSettings;
public HandleEmailRequestFn(IServiceProvider services,
ILogger<HandleEmailRequestFn> logger,
IHttpClientFactory httpClientFactory,
IHttpContextAccessor context,
BotSharpOptions options,
EmailHandlerSettings emailPluginSettings)
{
public string Name => "handle_email_request";
public string Indication => "Handling email request";
_services = services;
_logger = logger;
_httpClientFactory = httpClientFactory;
_context = context;
_options = options;
_emailSettings = emailPluginSettings;
}
public async Task<bool> Execute(RoleDialogModel message)
{
var args = JsonSerializer.Deserialize<LlmContextIn>(message.FunctionArgs, _options.JsonSerializerOptions);
var recipient = args?.ToAddress;
var body = args?.Content;
var subject = args?.Subject;
private readonly IServiceProvider _services;
private readonly ILogger<HandleEmailRequestFn> _logger;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IHttpContextAccessor _context;
private readonly BotSharpOptions _options;
private readonly EmailPluginSettings _emailSettings;
public HandleEmailRequestFn(IServiceProvider services,
ILogger<HandleEmailRequestFn> logger,
IHttpClientFactory httpClientFactory,
IHttpContextAccessor context,
BotSharpOptions options,
EmailPluginSettings emailPluginSettings)
try
{
_services = services;
_logger = logger;
_httpClientFactory = httpClientFactory;
_context = context;
_options = options;
_emailSettings = emailPluginSettings;
var mailMessage = new MimeMessage();
mailMessage.From.Add(new MailboxAddress(_emailSettings.Name, _emailSettings.EmailAddress));
mailMessage.To.Add(new MailboxAddress("", recipient));
mailMessage.Subject = subject;
mailMessage.Body = new TextPart("plain")
{
Text = body
};
var response = await HandleSendEmailBySMTP(mailMessage);
_logger.LogWarning($"Email successfully send over to {recipient}. Email Subject: {subject} [{response}]");
message.Content = response;
return true;
}
public async Task<bool> Execute(RoleDialogModel message)
catch (Exception ex)
{
var args = JsonSerializer.Deserialize<LlmContextIn>(message.FunctionArgs, _options.JsonSerializerOptions);
var recipient = args?.ToAddress;
var body = args?.Content;
var subject = args?.Subject;
try
{
var mailMessage = new MimeMessage();
mailMessage.From.Add(new MailboxAddress(_emailSettings.Name, _emailSettings.EmailAddress));
mailMessage.To.Add(new MailboxAddress("", recipient));
mailMessage.Subject = subject;
mailMessage.Body = new TextPart("plain")
{
Text = body
};
await HandleSendEmailBySMTP(mailMessage);
message.Content = $"Email successfully send over to {recipient}. Email Subject: {subject}";
return true;
}
catch (Exception ex)
{
var msg = $"Failed to send the email. {ex.Message}";
_logger.LogWarning($"{msg}\n(Error: {ex.Message})");
message.Content = msg;
return false;
}
}
public async Task HandleSendEmailBySMTP(MimeMessage mailMessage)
{
using (var smtpClient = new SmtpClient())
{
await smtpClient.ConnectAsync(_emailSettings.SMTPServer, _emailSettings.SMTPPort, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync(_emailSettings.EmailAddress, _emailSettings.Password);
await smtpClient.SendAsync(mailMessage);
smtpClient.Disconnect(true);
}
var msg = $"Failed to send the email. {ex.Message}";
_logger.LogError($"{msg}\n(Error: {ex.Message})");
message.Content = msg;
return false;
}
}
public async Task<string> HandleSendEmailBySMTP(MimeMessage mailMessage)
{
using var smtpClient = new SmtpClient();
await smtpClient.ConnectAsync(_emailSettings.SMTPServer, _emailSettings.SMTPPort, SecureSocketOptions.StartTls);
await smtpClient.AuthenticateAsync(_emailSettings.EmailAddress, _emailSettings.Password);
var response = await smtpClient.SendAsync(mailMessage);
return response;
}
}

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Agents.Settings;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories;
@ -9,56 +10,54 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BotSharp.Plugin.EmailHandler.Hooks
namespace BotSharp.Plugin.EmailHandler.Hooks;
public class EmailHandlerHook : AgentHookBase
{
public class EmailHandlerHook : AgentHookBase
private static string FUNCTION_NAME = "handle_email_request";
public override string SelfId => string.Empty;
public EmailHandlerHook(IServiceProvider services, AgentSettings settings)
: base(services, settings)
{
private static string UTILITY_ASSISTANT = Guid.Empty.ToString();
private static string FUNCTION_NAME = "handle_email_request";
}
public override void OnAgentLoaded(Agent agent)
{
var conv = _services.GetRequiredService<IConversationService>();
var isConvMode = conv.IsConversationMode();
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.EmailHandler);
public override string SelfId => string.Empty;
public EmailHandlerHook(IServiceProvider services, AgentSettings settings)
: base(services, settings)
if (isConvMode && isEnabled)
{
}
public override void OnAgentLoaded(Agent agent)
{
var conv = _services.GetRequiredService<IConversationService>();
var isConvMode = conv.IsConversationMode();
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.EmailHandler);
if (isConvMode && isEnabled)
var (prompt, fn) = GetPromptAndFunction();
if (fn != null)
{
var (prompt, fn) = GetPromptAndFunction();
if (fn != null)
if (!string.IsNullOrWhiteSpace(prompt))
{
if (!string.IsNullOrWhiteSpace(prompt))
{
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
}
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
}
if (agent.Functions == null)
{
agent.Functions = new List<FunctionDef> { fn };
}
else
{
agent.Functions.Add(fn);
}
if (agent.Functions == null)
{
agent.Functions = new List<FunctionDef> { fn };
}
else
{
agent.Functions.Add(fn);
}
}
base.OnAgentLoaded(agent);
}
private (string, FunctionDef?) GetPromptAndFunction()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var agent = db.GetAgent(UTILITY_ASSISTANT);
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{FUNCTION_NAME}.fn"))?.Content ?? string.Empty;
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(FUNCTION_NAME));
return (prompt, loadAttachmentFn);
}
base.OnAgentLoaded(agent);
}
private (string, FunctionDef?) GetPromptAndFunction()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{FUNCTION_NAME}.fn"))?.Content ?? string.Empty;
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(FUNCTION_NAME));
return (prompt, loadAttachmentFn);
}
}