Merge pull request #761 from iceljc/features/merge-origin-agent
Features/merge origin agent
This commit is contained in:
commit
ad27596959
|
|
@ -1,5 +1,10 @@
|
|||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Conversations;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Data;
|
||||
|
||||
namespace BotSharp.Abstraction.Agents;
|
||||
|
||||
|
|
@ -49,7 +54,71 @@ public abstract class AgentHookBase : IAgentHook
|
|||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnAgentLoaded(Agent agent)
|
||||
public virtual void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnAgentUtilityLoaded(Agent agent)
|
||||
{
|
||||
if (agent.Type == AgentType.Routing) return;
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
if (!isConvMode) return;
|
||||
|
||||
agent.Functions ??= [];
|
||||
agent.Utilities ??= [];
|
||||
|
||||
var (functions, templates) = GetUtilityContent(agent);
|
||||
|
||||
agent.Functions.AddRange(functions);
|
||||
foreach (var prompt in templates)
|
||||
{
|
||||
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
private (IEnumerable<FunctionDef>, IEnumerable<string>) GetUtilityContent(Agent agent)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var (functionNames, templateNames) = GetUniqueContent(agent.Utilities);
|
||||
|
||||
if (agent.MergeUtility)
|
||||
{
|
||||
var routing = _services.GetRequiredService<IRoutingContext>();
|
||||
var entryAgentId = routing.EntryAgentId;
|
||||
if (!string.IsNullOrEmpty(entryAgentId))
|
||||
{
|
||||
var entryAgent = db.GetAgent(entryAgentId);
|
||||
var (fns, tps) = GetUniqueContent(entryAgent?.Utilities);
|
||||
functionNames = functionNames.Concat(fns).Distinct().ToList();
|
||||
templateNames = templateNames.Concat(tps).Distinct().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
var ua = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var functions = ua?.Functions?.Where(x => functionNames.Contains(x.Name, StringComparer.OrdinalIgnoreCase))?.ToList() ?? [];
|
||||
var templates = ua?.Templates?.Where(x => templateNames.Contains(x.Name, StringComparer.OrdinalIgnoreCase))?.Select(x => x.Content)?.ToList() ?? [];
|
||||
return (functions, templates);
|
||||
}
|
||||
|
||||
private (IEnumerable<string>, IEnumerable<string>) GetUniqueContent(IEnumerable<AgentUtility>? utilities)
|
||||
{
|
||||
if (utilities.IsNullOrEmpty())
|
||||
{
|
||||
return ([], []);
|
||||
}
|
||||
|
||||
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
|
||||
var functionNames = utilities.SelectMany(x => x.Functions)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
var templateNames = utilities.SelectMany(x => x.Templates)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
|
||||
return (functionNames, templateNames);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ public interface IAgentHook
|
|||
|
||||
bool OnSamplesLoaded(List<string> samples);
|
||||
|
||||
void OnAgentUtilityLoaded(Agent agent);
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when agent is loaded completely.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -59,5 +59,5 @@ public interface IAgentService
|
|||
|
||||
PluginDef GetPlugin(string agentId);
|
||||
|
||||
IEnumerable<string> GetAgentUtilities();
|
||||
IEnumerable<AgentUtility> GetAgentUtilityOptions();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ namespace BotSharp.Abstraction.Agents;
|
|||
|
||||
public interface IAgentUtilityHook
|
||||
{
|
||||
void AddUtilities(List<string> utilities);
|
||||
void AddUtilities(List<AgentUtility> utilities);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,13 +87,17 @@ public class Agent
|
|||
/// <summary>
|
||||
/// Profile by channel
|
||||
/// </summary>
|
||||
public List<string> Profiles { get; set; }
|
||||
= new List<string>();
|
||||
public List<string> Profiles { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Merge utilities from entry agent
|
||||
/// </summary>
|
||||
public bool MergeUtility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Agent utilities
|
||||
/// </summary>
|
||||
public List<string> Utilities { get; set; } = new();
|
||||
public List<AgentUtility> Utilities { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Inherit from agent
|
||||
|
|
@ -173,9 +177,9 @@ public class Agent
|
|||
return this;
|
||||
}
|
||||
|
||||
public Agent SetUtilities(List<string> utilities)
|
||||
public Agent SetUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
Utilities = utilities ?? new List<string>();
|
||||
Utilities = utilities ?? new List<AgentUtility>();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -215,6 +219,12 @@ public class Agent
|
|||
return this;
|
||||
}
|
||||
|
||||
public Agent SetMergeUtility(bool merge)
|
||||
{
|
||||
MergeUtility = merge;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent SetAgentType(string type)
|
||||
{
|
||||
Type = type;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
namespace BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
public class AgentUtility
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public IEnumerable<UtilityFunction> Functions { get; set; } = [];
|
||||
public IEnumerable<UtilityTemplate> Templates { get; set; } = [];
|
||||
|
||||
public AgentUtility()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AgentUtility(
|
||||
string name,
|
||||
IEnumerable<UtilityFunction>? functions = null,
|
||||
IEnumerable<UtilityTemplate>? templates = null)
|
||||
{
|
||||
Name = name;
|
||||
Functions = functions ?? [];
|
||||
Templates = templates ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class UtilityFunction : UtilityBase
|
||||
{
|
||||
public UtilityFunction()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UtilityFunction(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public class UtilityTemplate : UtilityBase
|
||||
{
|
||||
public UtilityTemplate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UtilityTemplate(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public class UtilityBase
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ public interface IRoutingContext
|
|||
string FirstGoalAgentId();
|
||||
bool ContainsAgentId(string agentId);
|
||||
string OriginAgentId { get; }
|
||||
string EntryAgentId { get; }
|
||||
string ConversationId { get; }
|
||||
string MessageId { get; }
|
||||
void SetMessageId(string conversationId, string messageId);
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ namespace BotSharp.Abstraction.Templating;
|
|||
public interface ITemplateRender
|
||||
{
|
||||
string Render(string template, Dictionary<string, object> dict);
|
||||
void Register(Type type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
namespace BotSharp.Abstraction.Users.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// User actions on agent level
|
||||
/// </summary>
|
||||
public static class UserAction
|
||||
{
|
||||
public const string Edit = "edit";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
namespace BotSharp.Abstraction.Users.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// User permission
|
||||
/// </summary>
|
||||
public static class UserPermission
|
||||
{
|
||||
public const string CreateAgent = "create-agent";
|
||||
|
|
|
|||
|
|
@ -22,4 +22,26 @@ public static class UserAuthorizationExtension
|
|||
var actions = found.Actions ?? [];
|
||||
return actions.Any(x => x == targetAction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get allowed user actions on the agent. If user is admin, returns null;
|
||||
/// </summary>
|
||||
/// <param name="auth"></param>
|
||||
/// <param name="agentId"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string>? GetAllowedAgentActions(this UserAuthorization auth, string agentId)
|
||||
{
|
||||
if (auth == null || string.IsNullOrEmpty(agentId))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
if (auth.IsAdmin)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var found = auth.AgentActions.FirstOrDefault(x => x.AgentId == agentId);
|
||||
return found?.Actions ?? [];
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
|
||||
<ProjectReference Include="..\BotSharp.Core\BotSharp.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using BotSharp.Core.Infrastructures;
|
||||
|
||||
namespace BotSharp.Core.SideCar.Services;
|
||||
|
||||
public class BotSharpConversationSideCar : IConversationSideCar
|
||||
|
|
@ -116,7 +118,7 @@ public class BotSharpConversationSideCar : IConversationSideCar
|
|||
state.ResetCurrentState();
|
||||
routing.Context.ResetRecursiveCounter();
|
||||
routing.Context.ResetAgentStack();
|
||||
|
||||
Utilities.ClearCache();
|
||||
}
|
||||
|
||||
private void AfterExecute()
|
||||
|
|
@ -130,6 +132,7 @@ public class BotSharpConversationSideCar : IConversationSideCar
|
|||
state.SetCurrentState(node.State);
|
||||
routing.Context.SetRecursiveCounter(node.RecursiveCounter);
|
||||
routing.Context.SetAgentStack(node.RoutingStack);
|
||||
Utilities.ClearCache();
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using BotSharp.Abstraction.MLTasks;
|
||||
using BotSharp.Abstraction.Plugins.Models;
|
||||
using BotSharp.Abstraction.Settings;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using BotSharp.Abstraction.Users.Enums;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
|
|
@ -33,6 +34,8 @@ public class AgentPlugin : IBotSharpPlugin
|
|||
services.AddScoped(provider =>
|
||||
{
|
||||
var settingService = provider.GetRequiredService<ISettingService>();
|
||||
var render = provider.GetRequiredService<ITemplateRender>();
|
||||
render.Register(typeof(AgentSettings));
|
||||
return settingService.Bind<AgentSettings>("Agent");
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public partial class AgentService
|
|||
hook.OnSamplesLoaded(agent.Samples);
|
||||
}
|
||||
|
||||
hook.OnAgentUtilityLoaded(agent);
|
||||
hook.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,16 @@ public partial class AgentService
|
|||
public string RenderedInstruction(Agent agent)
|
||||
{
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
// update states
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
|
||||
// update states
|
||||
foreach (var t in conv.States.GetStates())
|
||||
{
|
||||
agent.TemplateDict[t.Key] = t.Value;
|
||||
}
|
||||
return render.Render(agent.Instruction, agent.TemplateDict);
|
||||
|
||||
var res = render.Render(agent.Instruction, agent.TemplateDict);
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool RenderFunction(Agent agent, FunctionDef def)
|
||||
|
|
@ -108,16 +111,18 @@ public partial class AgentService
|
|||
|
||||
public string RenderedTemplate(Agent agent, string templateName)
|
||||
{
|
||||
// render liquid template
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
var template = agent.Templates.First(x => x.Name == templateName).Content;
|
||||
// update states
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
|
||||
var template = agent.Templates.First(x => x.Name == templateName).Content;
|
||||
|
||||
// update states
|
||||
foreach (var t in conv.States.GetStates())
|
||||
{
|
||||
agent.TemplateDict[t.Key] = t.Value;
|
||||
}
|
||||
|
||||
// render liquid template
|
||||
var content = render.Render(template, agent.TemplateDict);
|
||||
|
||||
HookEmitter.Emit<IContentGeneratingHook>(_services, async hook =>
|
||||
|
|
@ -126,4 +131,4 @@ public partial class AgentService
|
|||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using BotSharp.Abstraction.Repositories.Enums;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using System.IO;
|
||||
|
|
@ -28,16 +27,17 @@ public partial class AgentService
|
|||
record.Description = agent.Description ?? string.Empty;
|
||||
record.IsPublic = agent.IsPublic;
|
||||
record.Disabled = agent.Disabled;
|
||||
record.MergeUtility = agent.MergeUtility;
|
||||
record.Type = agent.Type;
|
||||
record.Profiles = agent.Profiles ?? new List<string>();
|
||||
record.RoutingRules = agent.RoutingRules ?? new List<RoutingRule>();
|
||||
record.Profiles = agent.Profiles ?? [];
|
||||
record.RoutingRules = agent.RoutingRules ?? [];
|
||||
record.Instruction = agent.Instruction ?? string.Empty;
|
||||
record.ChannelInstructions = agent.ChannelInstructions ?? new List<ChannelInstruction>();
|
||||
record.Functions = agent.Functions ?? new List<FunctionDef>();
|
||||
record.Templates = agent.Templates ?? new List<AgentTemplate>();
|
||||
record.Responses = agent.Responses ?? new List<AgentResponse>();
|
||||
record.Samples = agent.Samples ?? new List<string>();
|
||||
record.Utilities = agent.Utilities ?? new List<string>();
|
||||
record.ChannelInstructions = agent.ChannelInstructions ?? [];
|
||||
record.Functions = agent.Functions ?? [];
|
||||
record.Templates = agent.Templates ?? [];
|
||||
record.Responses = agent.Responses ?? [];
|
||||
record.Samples = agent.Samples ?? [];
|
||||
record.Utilities = agent.Utilities ?? [];
|
||||
if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit)
|
||||
{
|
||||
record.LlmConfig = agent.LlmConfig;
|
||||
|
|
@ -90,6 +90,7 @@ public partial class AgentService
|
|||
.SetDescription(foundAgent.Description)
|
||||
.SetIsPublic(foundAgent.IsPublic)
|
||||
.SetDisabled(foundAgent.Disabled)
|
||||
.SetMergeUtility(foundAgent.MergeUtility)
|
||||
.SetAgentType(foundAgent.Type)
|
||||
.SetProfiles(foundAgent.Profiles)
|
||||
.SetRoutingRules(foundAgent.RoutingRules)
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ public partial class AgentService : IAgentService
|
|||
return userAgents;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAgentUtilities()
|
||||
public IEnumerable<AgentUtility> GetAgentUtilityOptions()
|
||||
{
|
||||
var utilities = new List<string>();
|
||||
var utilities = new List<AgentUtility>();
|
||||
var hooks = _services.GetServices<IAgentUtilityHook>();
|
||||
foreach (var hook in hooks)
|
||||
{
|
||||
hook.AddUtilities(utilities);
|
||||
}
|
||||
return utilities.Where(x => !string.IsNullOrWhiteSpace(x)).Distinct().OrderBy(x => x).ToList();
|
||||
return utilities.Where(x => !string.IsNullOrWhiteSpace(x.Name)).OrderBy(x => x.Name).ToList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ using BotSharp.Core.Processors;
|
|||
using StackExchange.Redis;
|
||||
using BotSharp.Core.Infrastructures.Events;
|
||||
using BotSharp.Core.Roles.Services;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using BotSharp.Core.Templating;
|
||||
|
||||
namespace BotSharp.Core;
|
||||
|
||||
|
|
@ -24,6 +26,8 @@ public static class BotSharpCoreExtensions
|
|||
services.AddSingleton(x => interpreterSettings);
|
||||
|
||||
services.AddSingleton<DistributedLocker>();
|
||||
// Register template render
|
||||
services.AddSingleton<ITemplateRender, TemplateRender>();
|
||||
|
||||
services.AddScoped<ISettingService, SettingService>();
|
||||
services.AddScoped<IRoleService, RoleService>();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ public class ConversationPlugin : IBotSharpPlugin
|
|||
services.AddScoped(provider =>
|
||||
{
|
||||
var settingService = provider.GetRequiredService<ISettingService>();
|
||||
var render = provider.GetRequiredService<ITemplateRender>();
|
||||
render.Register(typeof(ConversationSetting));
|
||||
return settingService.Bind<ConversationSetting>("Conversation");
|
||||
});
|
||||
|
||||
|
|
@ -48,8 +50,6 @@ public class ConversationPlugin : IBotSharpPlugin
|
|||
// Rich content messaging
|
||||
services.AddScoped<IRichContentService, RichContentService>();
|
||||
|
||||
// Register template render
|
||||
services.AddSingleton<ITemplateRender, TemplateRender>();
|
||||
services.AddScoped<IResponseTemplateService, ResponseTemplateService>();
|
||||
|
||||
services.AddScoped<IExecutor, InstructExecutor>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using BotSharp.Abstraction.Conversations.Enums;
|
||||
using BotSharp.Abstraction.Users.Enums;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
|
|
@ -21,13 +20,14 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
/// </summary>
|
||||
private ConversationState _historyStates;
|
||||
|
||||
public ConversationStateService(ILogger<ConversationStateService> logger,
|
||||
public ConversationStateService(
|
||||
IServiceProvider services,
|
||||
IBotSharpRepository db)
|
||||
IBotSharpRepository db,
|
||||
ILogger<ConversationStateService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_services = services;
|
||||
_db = db;
|
||||
_logger = logger;
|
||||
_curStates = new ConversationState();
|
||||
_historyStates = new ConversationState();
|
||||
}
|
||||
|
|
@ -125,8 +125,13 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
var curMsgId = routingCtx.MessageId;
|
||||
|
||||
_historyStates = _db.GetConversationStates(conversationId);
|
||||
|
||||
var endNodes = new Dictionary<string, string>();
|
||||
|
||||
if (_historyStates.IsNullOrEmpty()) return endNodes;
|
||||
|
||||
var dialogs = _db.GetConversationDialogs(conversationId);
|
||||
var userDialogs = dialogs.Where(x => x.MetaData?.Role == AgentRole.User || x.MetaData?.Role == UserRole.User)
|
||||
var userDialogs = dialogs.Where(x => x.MetaData?.Role == AgentRole.User)
|
||||
.GroupBy(x => x.MetaData?.MessageId)
|
||||
.Select(g => g.First())
|
||||
.OrderBy(x => x.MetaData?.CreateTime)
|
||||
|
|
@ -134,9 +139,6 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
var curMsgIndex = userDialogs.FindIndex(x => !string.IsNullOrEmpty(curMsgId) && x.MetaData?.MessageId == curMsgId);
|
||||
curMsgIndex = curMsgIndex < 0 ? userDialogs.Count() : curMsgIndex;
|
||||
|
||||
var endNodes = new Dictionary<string, string>();
|
||||
if (_historyStates.IsNullOrEmpty()) return endNodes;
|
||||
|
||||
foreach (var state in _historyStates)
|
||||
{
|
||||
var key = state.Key;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace BotSharp.Core.Repository
|
|||
UpdateAgentLlmConfig(agent.Id, agent.LlmConfig);
|
||||
break;
|
||||
case AgentField.Utility:
|
||||
UpdateAgentUtilities(agent.Id, agent.Utilities);
|
||||
UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities);
|
||||
break;
|
||||
case AgentField.All:
|
||||
UpdateAgentAllFields(agent);
|
||||
|
|
@ -151,13 +151,14 @@ namespace BotSharp.Core.Repository
|
|||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentUtilities(string agentId, List<string> utilities)
|
||||
private void UpdateAgentUtilities(string agentId, bool mergeUtility, List<AgentUtility> utilities)
|
||||
{
|
||||
if (utilities == null) return;
|
||||
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.MergeUtility = mergeUtility;
|
||||
agent.Utilities = utilities;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
|
|
@ -291,6 +292,7 @@ namespace BotSharp.Core.Repository
|
|||
agent.Description = inputAgent.Description;
|
||||
agent.IsPublic = inputAgent.IsPublic;
|
||||
agent.Disabled = inputAgent.Disabled;
|
||||
agent.MergeUtility = inputAgent.MergeUtility;
|
||||
agent.Type = inputAgent.Type;
|
||||
agent.Profiles = inputAgent.Profiles;
|
||||
agent.Utilities = inputAgent.Utilities;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ public class RoutingContext : IRoutingContext
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
_routerAgentIds = agentService.GetAgents(new AgentFilter
|
||||
{
|
||||
Type = AgentType.Routing
|
||||
Type = AgentType.Routing,
|
||||
Pager = new Pagination { Size = 100 }
|
||||
}).Result.Items.Select(x => x.Id).ToArray();
|
||||
}
|
||||
|
||||
|
|
@ -49,6 +50,17 @@ public class RoutingContext : IRoutingContext
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry agent
|
||||
/// </summary>
|
||||
public string EntryAgentId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _stack.LastOrDefault() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty => !_stack.Any();
|
||||
|
||||
public string GetCurrentAgentId()
|
||||
|
|
@ -231,12 +243,16 @@ public class RoutingContext : IRoutingContext
|
|||
|
||||
public Stack<string> GetAgentStack()
|
||||
{
|
||||
return new Stack<string>(_stack);
|
||||
var copy = _stack.ToList();
|
||||
copy.Reverse();
|
||||
return new Stack<string>(copy);
|
||||
}
|
||||
|
||||
public void SetAgentStack(Stack<string> stack)
|
||||
{
|
||||
_stack = new Stack<string>(stack);
|
||||
var copy = stack.ToList();
|
||||
copy.Reverse();
|
||||
_stack = new Stack<string>(copy);
|
||||
}
|
||||
|
||||
public void ResetAgentStack()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using BotSharp.Abstraction.Conversations.Enums;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.Drawing;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,11 @@ namespace BotSharp.Core.Routing;
|
|||
|
||||
public partial class RoutingService
|
||||
{
|
||||
//private int _currentRecursionDepth = 0;
|
||||
public async Task<bool> InvokeAgent(string agentId, List<RoleDialogModel> dialogs)
|
||||
{
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var agent = await agentService.LoadAgent(agentId);
|
||||
|
||||
//_currentRecursionDepth++;
|
||||
Context.IncreaseRecursiveCounter();
|
||||
if (Context.CurrentRecursionDepth > agent.LlmConfig.MaxRecursionDepth)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,21 +14,6 @@ public partial class RoutingService : IRoutingService
|
|||
public IRoutingContext Context => _context;
|
||||
public Agent Router => _router;
|
||||
|
||||
//public int GetRecursiveCounter()
|
||||
//{
|
||||
// return _currentRecursionDepth;
|
||||
//}
|
||||
|
||||
//public void SetRecursiveCounter(int counter)
|
||||
//{
|
||||
// _currentRecursionDepth = counter;
|
||||
//}
|
||||
|
||||
//public void ResetRecursiveCounter()
|
||||
//{
|
||||
// _currentRecursionDepth = 0;
|
||||
//}
|
||||
|
||||
public RoutingService(
|
||||
IServiceProvider services,
|
||||
RoutingSettings settings,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using BotSharp.Abstraction.Translation.Models;
|
||||
using Fluid;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
|
||||
namespace BotSharp.Core.Templating;
|
||||
|
||||
|
|
@ -48,4 +48,47 @@ public class TemplateRender : ITemplateRender
|
|||
return template;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Register(Type type)
|
||||
{
|
||||
if (type == null || IsStringType(type)) return;
|
||||
|
||||
if (IsListType(type))
|
||||
{
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
var genericType = type.GetGenericArguments()[0];
|
||||
Register(genericType);
|
||||
}
|
||||
}
|
||||
else if (IsTrackToNextLevel(type))
|
||||
{
|
||||
_options.MemberAccessStrategy.Register(type);
|
||||
var props = type.GetProperties();
|
||||
foreach (var prop in props)
|
||||
{
|
||||
Register(prop.PropertyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Private methods
|
||||
private static bool IsStringType(Type type)
|
||||
{
|
||||
return type == typeof(string);
|
||||
}
|
||||
|
||||
private static bool IsListType(Type type)
|
||||
{
|
||||
var interfaces = type.GetTypeInfo().ImplementedInterfaces;
|
||||
return type.IsArray || interfaces.Any(x => x.Name == typeof(IEnumerable).Name);
|
||||
}
|
||||
|
||||
private static bool IsTrackToNextLevel(Type type)
|
||||
{
|
||||
return type.IsClass || type.IsInterface || type.IsAbstract;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.Controllers;
|
||||
|
||||
|
|
@ -59,11 +59,7 @@ public class AgentController : ControllerBase
|
|||
|
||||
var userService = _services.GetRequiredService<IUserService>();
|
||||
var auth = await userService.GetUserAuthorizations(new List<string> { targetAgent.Id });
|
||||
|
||||
targetAgent.Editable = auth.IsAgentActionAllowed(targetAgent.Id, UserAction.Edit);
|
||||
targetAgent.Chatable = auth.IsAgentActionAllowed(targetAgent.Id, UserAction.Chat);
|
||||
targetAgent.Trainable = auth.IsAgentActionAllowed(targetAgent.Id, UserAction.Train);
|
||||
targetAgent.Evaluable = auth.IsAgentActionAllowed(targetAgent.Id, UserAction.Evaluate);
|
||||
targetAgent.Actions = auth.GetAllowedAgentActions(targetAgent.Id);
|
||||
return targetAgent;
|
||||
}
|
||||
|
||||
|
|
@ -90,10 +86,7 @@ public class AgentController : ControllerBase
|
|||
agents = pagedAgents?.Items?.Select(x =>
|
||||
{
|
||||
var model = AgentViewModel.FromAgent(x);
|
||||
model.Editable = auth.IsAgentActionAllowed(x.Id, UserAction.Edit);
|
||||
model.Chatable = auth.IsAgentActionAllowed(x.Id, UserAction.Chat);
|
||||
model.Trainable = auth.IsAgentActionAllowed(x.Id, UserAction.Train);
|
||||
model.Evaluable = auth.IsAgentActionAllowed(x.Id, UserAction.Evaluate);
|
||||
model.Actions = auth.GetAllowedAgentActions(x.Id);
|
||||
return model;
|
||||
})?.ToList() ?? [];
|
||||
|
||||
|
|
@ -153,9 +146,9 @@ public class AgentController : ControllerBase
|
|||
return await _agentService.DeleteAgent(agentId);
|
||||
}
|
||||
|
||||
[HttpGet("/agent/utilities")]
|
||||
public IEnumerable<string> GetAgentUtilities()
|
||||
[HttpGet("/agent/utility/options")]
|
||||
public IEnumerable<AgentUtility> GetAgentUtilityOptions()
|
||||
{
|
||||
return _agentService.GetAgentUtilities();
|
||||
return _agentService.GetAgentUtilityOptions();
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +48,10 @@ public class AgentCreationModel
|
|||
/// Combine different Agents together to form a Profile.
|
||||
/// </summary>
|
||||
public List<string> Profiles { get; set; } = new();
|
||||
public List<string> Utilities { get; set; } = new();
|
||||
|
||||
public bool MergeUtility { get; set; }
|
||||
|
||||
public List<AgentUtility> Utilities { get; set; } = new();
|
||||
public List<RoutingRuleUpdateModel> RoutingRules { get; set; } = new();
|
||||
public AgentLlmConfig? LlmConfig { get; set; }
|
||||
|
||||
|
|
@ -68,6 +71,7 @@ public class AgentCreationModel
|
|||
IsPublic = IsPublic,
|
||||
Type = Type,
|
||||
Disabled = Disabled,
|
||||
MergeUtility = MergeUtility,
|
||||
Profiles = Profiles,
|
||||
RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? new List<RoutingRule>(),
|
||||
LlmConfig = LlmConfig
|
||||
|
|
|
|||
|
|
@ -31,10 +31,13 @@ public class AgentUpdateModel
|
|||
/// </summary>
|
||||
public List<string>? Samples { get; set; }
|
||||
|
||||
[JsonPropertyName("merge_utility")]
|
||||
public bool MergeUtility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Utilities
|
||||
/// </summary>
|
||||
public List<string>? Utilities { get; set; }
|
||||
public List<AgentUtility>? Utilities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Functions
|
||||
|
|
@ -73,6 +76,7 @@ public class AgentUpdateModel
|
|||
Description = Description ?? string.Empty,
|
||||
IsPublic = IsPublic,
|
||||
Disabled = Disabled,
|
||||
MergeUtility = MergeUtility,
|
||||
Type = Type,
|
||||
Profiles = Profiles ?? new List<string>(),
|
||||
RoutingRules = RoutingRules?.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?.ToList() ?? new List<RoutingRule>(),
|
||||
|
|
@ -81,7 +85,7 @@ public class AgentUpdateModel
|
|||
Templates = Templates ?? new List<AgentTemplate>(),
|
||||
Functions = Functions ?? new List<FunctionDef>(),
|
||||
Responses = Responses ?? new List<AgentResponse>(),
|
||||
Utilities = Utilities ?? new List<string>(),
|
||||
Utilities = Utilities ?? new List<AgentUtility>(),
|
||||
LlmConfig = LlmConfig
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,10 @@ public class AgentViewModel
|
|||
public List<FunctionDef> Functions { get; set; }
|
||||
public List<AgentResponse> Responses { get; set; }
|
||||
public List<string> Samples { get; set; }
|
||||
public List<string> Utilities { get; set; }
|
||||
|
||||
[JsonPropertyName("merge_utility")]
|
||||
public bool MergeUtility { get; set; }
|
||||
public List<AgentUtility> Utilities { get; set; }
|
||||
|
||||
[JsonPropertyName("is_public")]
|
||||
public bool IsPublic { get; set; }
|
||||
|
|
@ -33,8 +36,7 @@ public class AgentViewModel
|
|||
[JsonPropertyName("icon_url")]
|
||||
public string IconUrl { get; set; }
|
||||
|
||||
public List<string> Profiles { get; set; }
|
||||
= new List<string>();
|
||||
public List<string> Profiles { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("routing_rules")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
|
|
@ -46,10 +48,7 @@ public class AgentViewModel
|
|||
|
||||
public PluginDef Plugin { get; set; }
|
||||
|
||||
public bool Editable { get; set; }
|
||||
public bool Chatable { get; set; }
|
||||
public bool Trainable { get; set; }
|
||||
public bool Evaluable { get; set; }
|
||||
public IEnumerable<string>? Actions { get; set; }
|
||||
|
||||
[JsonPropertyName("created_datetime")]
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
|
|
@ -74,6 +73,7 @@ public class AgentViewModel
|
|||
Utilities = agent.Utilities,
|
||||
IsPublic= agent.IsPublic,
|
||||
Disabled = agent.Disabled,
|
||||
MergeUtility = agent.MergeUtility,
|
||||
IconUrl = agent.IconUrl,
|
||||
Profiles = agent.Profiles ?? new List<string>(),
|
||||
RoutingRules = agent.RoutingRules,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ public class AudioHandlerPlugin : IBotSharpPlugin
|
|||
});
|
||||
|
||||
services.AddScoped<IAudioCompletion, NativeWhisperProvider>();
|
||||
services.AddScoped<IAgentHook, AudioHandlerHook>();
|
||||
services.AddScoped<IAgentUtilityHook, AudioHandlerUtilityHook>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
|
||||
namespace BotSharp.Plugin.AudioHandler.Hooks;
|
||||
|
||||
public class AudioHandlerHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string HANDLER_AUDIO = "handle_audio_request";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public AudioHandlerHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.AudioHandler);
|
||||
|
||||
if (isEnabled && isConvMode)
|
||||
{
|
||||
AddUtility(agent, HANDLER_AUDIO);
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private void AddUtility(Agent agent, string functionName)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction(functionName);
|
||||
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, loadAttachmentFn);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,17 @@ namespace BotSharp.Plugin.AudioHandler.Hooks;
|
|||
|
||||
public class AudioHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string HANDLER_AUDIO = "handle_audio_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.AudioHandler);
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.AudioHandler,
|
||||
Functions = [new(HANDLER_AUDIO)],
|
||||
Templates = [new($"{HANDLER_AUDIO}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,8 +20,6 @@ namespace BotSharp.Plugin.EmailHandler
|
|||
return settingService.Bind<EmailSenderSettings>("EmailSender");
|
||||
});
|
||||
|
||||
services.AddScoped<IAgentHook, EmailSenderHook>();
|
||||
services.AddScoped<IAgentHook, EmailReaderHook>();
|
||||
services.AddScoped<IAgentUtilityHook, EmailHandlerUtilityHook>();
|
||||
|
||||
var emailReaderSettings = new EmailReaderSettings();
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Plugin.EmailHandler.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BotSharp.Plugin.EmailHandler.Hooks
|
||||
namespace BotSharp.Plugin.EmailHandler.Hooks;
|
||||
|
||||
public class EmailHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public class EmailHandlerUtilityHook : IAgentUtilityHook
|
||||
private static string EMAIL_READER_FN = "handle_email_reader";
|
||||
private static string EMAIL_SENDER_FN = "handle_email_sender";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
utilities.Add(UtilityName.EmailHandler);
|
||||
}
|
||||
Name = UtilityName.EmailHandler,
|
||||
Functions = [new(EMAIL_READER_FN), new(EMAIL_SENDER_FN)],
|
||||
Templates = [new($"{EMAIL_READER_FN}.fn"), new($"{EMAIL_SENDER_FN}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Plugin.EmailHandler.Enums;
|
||||
|
||||
namespace BotSharp.Plugin.EmailHandler.Hooks;
|
||||
|
||||
public class EmailReaderHook : AgentHookBase
|
||||
{
|
||||
private static string FUNCTION_NAME = "handle_email_reader";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public EmailReaderHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.EmailHandler);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction();
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Plugin.EmailHandler.Enums;
|
||||
|
||||
namespace BotSharp.Plugin.EmailHandler.Hooks;
|
||||
|
||||
public class EmailSenderHook : AgentHookBase
|
||||
{
|
||||
private static string FUNCTION_NAME = "handle_email_sender";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public EmailSenderHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.EmailHandler);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction();
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BotSharp.Abstraction.Plugins;
|
||||
using BotSharp.Abstraction.Settings;
|
||||
using BotSharp.Plugin.ExcelHandler.Helpers.MySql;
|
||||
|
|
@ -30,7 +25,6 @@ public class ExcelHandlerPlugin : IBotSharpPlugin
|
|||
});
|
||||
|
||||
services.AddScoped<IAgentUtilityHook, ExcelHandlerUtilityHook>();
|
||||
services.AddScoped<IAgentHook, ExcelHandlerHook>();
|
||||
services.AddScoped<ISqliteDbHelpers, SqliteDbHelpers>();
|
||||
services.AddScoped<IMySqlDbHelper, MySqlDbHelpers>();
|
||||
services.AddScoped<ISqliteService, SqliteService>();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using BotSharp.Plugin.SqlHero.Settings;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using BotSharp.Plugin.SqlDriver.Settings;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace BotSharp.Plugin.ExcelHandler.Helpers.MySql
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BotSharp.Plugin.SqlDriver.Settings;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using BotSharp.Plugin.SqlDriver.Models;
|
||||
using BotSharp.Plugin.SqlHero.Settings;
|
||||
|
||||
namespace BotSharp.Plugin.ExcelHandler.Helpers.Sqlite;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
namespace BotSharp.Plugin.ExcelHandler.Hooks;
|
||||
|
||||
public class ExcelHandlerHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string HANDLER_EXCEL = "handle_excel_request";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public ExcelHandlerHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.ExcelHandler);
|
||||
|
||||
if (isEnabled && isConvMode)
|
||||
{
|
||||
AddUtility(agent, HANDLER_EXCEL);
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private void AddUtility(Agent agent, string functionName)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction(functionName);
|
||||
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, loadAttachmentFn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2,8 +2,17 @@ namespace BotSharp.Plugin.ExcelHandler.Hooks;
|
|||
|
||||
public class ExcelHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string HANDLER_EXCEL = "handle_excel_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.ExcelHandler);
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.ExcelHandler,
|
||||
Functions = [new(HANDLER_EXCEL)],
|
||||
Templates = [new($"{HANDLER_EXCEL}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@ public class FileHandlerPlugin : IBotSharpPlugin
|
|||
return settingService.Bind<FileHandlerSettings>("FileHandler");
|
||||
});
|
||||
|
||||
services.AddScoped<IAgentHook, FileHandlerHook>();
|
||||
services.AddScoped<IAgentUtilityHook, FileHandlerUtilityHook>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
namespace BotSharp.Plugin.FileHandler.Hooks;
|
||||
|
||||
public class FileHandlerHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string READ_IMAGE_FN = "read_image";
|
||||
private const string READ_PDF_FN = "read_pdf";
|
||||
private const string GENERATE_IMAGE_FN = "generate_image";
|
||||
private const string EDIT_IMAGE_FN = "edit_image";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public FileHandlerHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
|
||||
if (isConvMode)
|
||||
{
|
||||
AddUtility(agent, UtilityName.ImageGenerator, GENERATE_IMAGE_FN);
|
||||
AddUtility(agent, UtilityName.ImageReader, READ_IMAGE_FN);
|
||||
AddUtility(agent, UtilityName.ImageEditor, EDIT_IMAGE_FN);
|
||||
AddUtility(agent, UtilityName.PdfReader, READ_PDF_FN);
|
||||
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private void AddUtility(Agent agent, string utility, string functionName)
|
||||
{
|
||||
if (!IsEnableUtility(agent, utility)) return;
|
||||
|
||||
var (prompt, fn) = GetPromptAndFunction(functionName);
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsEnableUtility(Agent agent, string utility)
|
||||
{
|
||||
return !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(utility);
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, loadAttachmentFn);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,11 +2,41 @@ namespace BotSharp.Plugin.FileHandler.Hooks;
|
|||
|
||||
public class FileHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string READ_IMAGE_FN = "read_image";
|
||||
private const string READ_PDF_FN = "read_pdf";
|
||||
private const string GENERATE_IMAGE_FN = "generate_image";
|
||||
private const string EDIT_IMAGE_FN = "edit_image";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.ImageGenerator);
|
||||
utilities.Add(UtilityName.ImageReader);
|
||||
utilities.Add(UtilityName.ImageEditor);
|
||||
utilities.Add(UtilityName.PdfReader);
|
||||
var items = new List<AgentUtility>
|
||||
{
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.ImageGenerator,
|
||||
Functions = [new(GENERATE_IMAGE_FN)],
|
||||
Templates = [new($"{GENERATE_IMAGE_FN}.fn")]
|
||||
},
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.ImageReader,
|
||||
Functions = [new(READ_IMAGE_FN)],
|
||||
Templates = [new($"{READ_IMAGE_FN}.fn")]
|
||||
},
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.ImageEditor,
|
||||
Functions = [new(EDIT_IMAGE_FN)],
|
||||
Templates = [new($"{EDIT_IMAGE_FN}.fn")]
|
||||
},
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.PdfReader,
|
||||
Functions = [new(READ_PDF_FN)],
|
||||
Templates = [new($"{READ_PDF_FN}.fn")]
|
||||
}
|
||||
};
|
||||
|
||||
utilities.AddRange(items);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents;
|
||||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Plugin.HttpHandler.Hooks;
|
||||
|
||||
public class HttpHandlerHook : AgentHookBase
|
||||
{
|
||||
private static string FUNCTION_NAME = "handle_http_request";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public HttpHandlerHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.HttpHandler);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction(FUNCTION_NAME);
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, loadAttachmentFn);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,17 @@ namespace BotSharp.Plugin.HttpHandler.Hooks;
|
|||
|
||||
public class HttpHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private static string HTTP_HANDLER_FN = "handle_http_request";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.HttpHandler);
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.HttpHandler,
|
||||
Functions = [new(HTTP_HANDLER_FN)],
|
||||
Templates = [new($"{HTTP_HANDLER_FN}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ public class HttpHandlerPlugin : IBotSharpPlugin
|
|||
return settingService.Bind<HttpHandlerSettings>("HttpHandler");
|
||||
});
|
||||
|
||||
services.AddScoped<IAgentHook, HttpHandlerHook>();
|
||||
services.AddScoped<IAgentUtilityHook, HttpHandlerUtilityHook>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
namespace BotSharp.Plugin.KnowledgeBase.Hooks;
|
||||
|
||||
public class KnowledgeBaseAgentHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
public override string SelfId => string.Empty;
|
||||
public KnowledgeBaseAgentHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
|
||||
if (isConvMode)
|
||||
{
|
||||
AddUtility(agent, UtilityName.KnowledgeRetrieval, "knowledge_retrieval");
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private void AddUtility(Agent agent, string utility, string functionName)
|
||||
{
|
||||
if (!IsEnableUtility(agent, utility)) return;
|
||||
|
||||
var (prompt, fn) = GetPromptAndFunction(functionName);
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsEnableUtility(Agent agent, string utility)
|
||||
{
|
||||
return !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(utility);
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var fn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, fn);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,17 @@ namespace BotSharp.Plugin.KnowledgeBase.Hooks;
|
|||
|
||||
public class KnowledgeBaseUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string KNOWLEDGE_RETRIEVAL_FN = "knowledge_retrieval";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.KnowledgeRetrieval);
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.KnowledgeRetrieval,
|
||||
Functions = [new(KNOWLEDGE_RETRIEVAL_FN)],
|
||||
Templates = [new($"{KNOWLEDGE_RETRIEVAL_FN}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ public class KnowledgeBasePlugin : IBotSharpPlugin
|
|||
|
||||
services.AddSingleton<IPdf2TextConverter, PigPdf2TextConverter>();
|
||||
services.AddScoped<IAgentUtilityHook, KnowledgeBaseUtilityHook>();
|
||||
services.AddScoped<IAgentHook, KnowledgeBaseAgentHook>();
|
||||
services.AddScoped<IKnowledgeService, KnowledgeService>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,15 @@ public class AgentDocument : MongoBase
|
|||
public string? InheritAgentId { get; set; }
|
||||
public string? IconUrl { get; set; }
|
||||
public string Instruction { get; set; }
|
||||
public bool IsPublic { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public bool MergeUtility { get; set; }
|
||||
public List<ChannelInstructionMongoElement> ChannelInstructions { get; set; }
|
||||
public List<AgentTemplateMongoElement> Templates { get; set; }
|
||||
public List<FunctionDefMongoElement> Functions { get; set; }
|
||||
public List<AgentResponseMongoElement> Responses { get; set; }
|
||||
public List<string> Samples { get; set; }
|
||||
public List<string> Utilities { get; set; }
|
||||
public bool IsPublic { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public List<AgentUtilityMongoElement> Utilities { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<RoutingRuleMongoElement> RoutingRules { get; set; }
|
||||
public AgentLlmConfigMongoElement? LlmConfig { get; set; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
public class AgentUtilityMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public List<UtilityFunctionMongoElement> Functions { get; set; } = [];
|
||||
public List<UtilityTemplateMongoElement> Templates { get; set; } = [];
|
||||
|
||||
public static AgentUtilityMongoElement ToMongoElement(AgentUtility utility)
|
||||
{
|
||||
return new AgentUtilityMongoElement
|
||||
{
|
||||
Name = utility.Name,
|
||||
Disabled = utility.Disabled,
|
||||
Functions = utility.Functions?.Select(x => new UtilityFunctionMongoElement(x.Name))?.ToList() ?? [],
|
||||
Templates = utility.Templates?.Select(x => new UtilityTemplateMongoElement(x.Name))?.ToList() ?? []
|
||||
};
|
||||
}
|
||||
|
||||
public static AgentUtility ToDomainElement(AgentUtilityMongoElement utility)
|
||||
{
|
||||
return new AgentUtility
|
||||
{
|
||||
Name = utility.Name,
|
||||
Disabled = utility.Disabled,
|
||||
Functions = utility.Functions?.Select(x => new UtilityFunction(x.Name))?.ToList() ?? [],
|
||||
Templates = utility.Templates?.Select(x => new UtilityTemplate(x.Name))?.ToList() ?? []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class UtilityFunctionMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public UtilityFunctionMongoElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UtilityFunctionMongoElement(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public class UtilityTemplateMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public UtilityTemplateMongoElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UtilityTemplateMongoElement(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ using BotSharp.Abstraction.Agents.Models;
|
|||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories.Filters;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Repository;
|
||||
|
||||
|
|
@ -57,7 +56,7 @@ public partial class MongoRepository
|
|||
UpdateAgentLlmConfig(agent.Id, agent.LlmConfig);
|
||||
break;
|
||||
case AgentField.Utility:
|
||||
UpdateAgentUtilities(agent.Id, agent.Utilities);
|
||||
UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities);
|
||||
break;
|
||||
case AgentField.All:
|
||||
UpdateAgentAllFields(agent);
|
||||
|
|
@ -224,13 +223,16 @@ public partial class MongoRepository
|
|||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentUtilities(string agentId, List<string> utilities)
|
||||
private void UpdateAgentUtilities(string agentId, bool mergeUtility, List<AgentUtility> utilities)
|
||||
{
|
||||
if (utilities == null) return;
|
||||
|
||||
var elements = utilities?.Select(x => AgentUtilityMongoElement.ToMongoElement(x))?.ToList() ?? [];
|
||||
|
||||
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
|
||||
var update = Builders<AgentDocument>.Update
|
||||
.Set(x => x.Utilities, utilities)
|
||||
.Set(x => x.MergeUtility, mergeUtility)
|
||||
.Set(x => x.Utilities, elements)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
|
|
@ -254,6 +256,7 @@ public partial class MongoRepository
|
|||
.Set(x => x.Name, agent.Name)
|
||||
.Set(x => x.Description, agent.Description)
|
||||
.Set(x => x.Disabled, agent.Disabled)
|
||||
.Set(x => x.MergeUtility, agent.MergeUtility)
|
||||
.Set(x => x.Type, agent.Type)
|
||||
.Set(x => x.Profiles, agent.Profiles)
|
||||
.Set(x => x.RoutingRules, agent.RoutingRules.Select(r => RoutingRuleMongoElement.ToMongoElement(r)).ToList())
|
||||
|
|
@ -263,7 +266,7 @@ public partial class MongoRepository
|
|||
.Set(x => x.Functions, agent.Functions.Select(f => FunctionDefMongoElement.ToMongoElement(f)).ToList())
|
||||
.Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList())
|
||||
.Set(x => x.Samples, agent.Samples)
|
||||
.Set(x => x.Utilities, agent.Utilities)
|
||||
.Set(x => x.Utilities, agent.Utilities.Select(u => AgentUtilityMongoElement.ToMongoElement(u)).ToList())
|
||||
.Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig))
|
||||
.Set(x => x.IsPublic, agent.IsPublic)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
|
@ -406,28 +409,19 @@ public partial class MongoRepository
|
|||
IconUrl = x.IconUrl,
|
||||
Description = x.Description,
|
||||
Instruction = x.Instruction,
|
||||
ChannelInstructions = x.ChannelInstructions?
|
||||
.Select(i => ChannelInstructionMongoElement.ToMongoElement(i))?
|
||||
.ToList() ?? new List<ChannelInstructionMongoElement>(),
|
||||
Templates = x.Templates?
|
||||
.Select(t => AgentTemplateMongoElement.ToMongoElement(t))?
|
||||
.ToList() ?? new List<AgentTemplateMongoElement>(),
|
||||
Functions = x.Functions?
|
||||
.Select(f => FunctionDefMongoElement.ToMongoElement(f))?
|
||||
.ToList() ?? new List<FunctionDefMongoElement>(),
|
||||
Responses = x.Responses?
|
||||
.Select(r => AgentResponseMongoElement.ToMongoElement(r))?
|
||||
.ToList() ?? new List<AgentResponseMongoElement>(),
|
||||
ChannelInstructions = x.ChannelInstructions?.Select(i => ChannelInstructionMongoElement.ToMongoElement(i))?.ToList() ?? [],
|
||||
Templates = x.Templates?.Select(t => AgentTemplateMongoElement.ToMongoElement(t))?.ToList() ?? [],
|
||||
Functions = x.Functions?.Select(f => FunctionDefMongoElement.ToMongoElement(f))?.ToList() ?? [],
|
||||
Responses = x.Responses?.Select(r => AgentResponseMongoElement.ToMongoElement(r))?.ToList() ?? [],
|
||||
Samples = x.Samples ?? new List<string>(),
|
||||
Utilities = x.Utilities ?? new List<string>(),
|
||||
Utilities = x.Utilities?.Select(u => AgentUtilityMongoElement.ToMongoElement(u))?.ToList() ?? [],
|
||||
IsPublic = x.IsPublic,
|
||||
Type = x.Type,
|
||||
InheritAgentId = x.InheritAgentId,
|
||||
Disabled = x.Disabled,
|
||||
MergeUtility = x.MergeUtility,
|
||||
Profiles = x.Profiles,
|
||||
RoutingRules = x.RoutingRules?
|
||||
.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?
|
||||
.ToList() ?? new List<RoutingRuleMongoElement>(),
|
||||
RoutingRules = x.RoutingRules?.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?.ToList() ?? [],
|
||||
LlmConfig = AgentLlmConfigMongoElement.ToMongoElement(x.LlmConfig),
|
||||
CreatedTime = x.CreatedDateTime,
|
||||
UpdatedTime = x.UpdatedDateTime
|
||||
|
|
@ -505,26 +499,17 @@ public partial class MongoRepository
|
|||
IconUrl = agentDoc.IconUrl,
|
||||
Description = agentDoc.Description,
|
||||
Instruction = agentDoc.Instruction,
|
||||
ChannelInstructions = !agentDoc.ChannelInstructions.IsNullOrEmpty() ? agentDoc.ChannelInstructions
|
||||
.Select(i => ChannelInstructionMongoElement.ToDomainElement(i))
|
||||
.ToList() : new List<ChannelInstruction>(),
|
||||
Templates = !agentDoc.Templates.IsNullOrEmpty() ? agentDoc.Templates
|
||||
.Select(t => AgentTemplateMongoElement.ToDomainElement(t))
|
||||
.ToList() : new List<AgentTemplate>(),
|
||||
Functions = !agentDoc.Functions.IsNullOrEmpty() ? agentDoc.Functions
|
||||
.Select(f => FunctionDefMongoElement.ToDomainElement(f))
|
||||
.ToList() : new List<FunctionDef>(),
|
||||
Responses = !agentDoc.Responses.IsNullOrEmpty() ? agentDoc.Responses
|
||||
.Select(r => AgentResponseMongoElement.ToDomainElement(r))
|
||||
.ToList() : new List<AgentResponse>(),
|
||||
RoutingRules = !agentDoc.RoutingRules.IsNullOrEmpty() ? agentDoc.RoutingRules
|
||||
.Select(r => RoutingRuleMongoElement.ToDomainElement(agentDoc.Id, agentDoc.Name, r))
|
||||
.ToList() : new List<RoutingRule>(),
|
||||
ChannelInstructions = agentDoc.ChannelInstructions?.Select(i => ChannelInstructionMongoElement.ToDomainElement(i))?.ToList() ?? [],
|
||||
Templates = agentDoc.Templates?.Select(t => AgentTemplateMongoElement.ToDomainElement(t))?.ToList() ?? [],
|
||||
Functions = agentDoc.Functions?.Select(f => FunctionDefMongoElement.ToDomainElement(f)).ToList() ?? [],
|
||||
Responses = agentDoc.Responses?.Select(r => AgentResponseMongoElement.ToDomainElement(r))?.ToList() ?? [],
|
||||
RoutingRules = agentDoc.RoutingRules?.Select(r => RoutingRuleMongoElement.ToDomainElement(agentDoc.Id, agentDoc.Name, r))?.ToList() ?? [],
|
||||
LlmConfig = AgentLlmConfigMongoElement.ToDomainElement(agentDoc.LlmConfig),
|
||||
Samples = agentDoc.Samples ?? new List<string>(),
|
||||
Utilities = agentDoc.Utilities ?? new List<string>(),
|
||||
Samples = agentDoc.Samples ?? [],
|
||||
Utilities = agentDoc.Utilities?.Select(u => AgentUtilityMongoElement.ToDomainElement(u))?.ToList() ?? [],
|
||||
IsPublic = agentDoc.IsPublic,
|
||||
Disabled = agentDoc.Disabled,
|
||||
MergeUtility = agentDoc.MergeUtility,
|
||||
Type = agentDoc.Type,
|
||||
InheritAgentId = agentDoc.InheritAgentId,
|
||||
Profiles = agentDoc.Profiles,
|
||||
|
|
|
|||
|
|
@ -27,79 +27,4 @@ public class PlannerAgentHook : AgentHookBase
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.TwoStagePlanner);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction("plan_primary_stage");
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
(prompt, fn) = GetPromptAndFunction("plan_secondary_stage");
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
(prompt, fn) = GetPromptAndFunction("plan_summary");
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private (string, FunctionDef?) GetPromptAndFunction(string functionName)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo($"{functionName}.fn"))?.Content ?? string.Empty;
|
||||
var loadAttachmentFn = agent?.Functions?.FirstOrDefault(x => x.Name.IsEqualTo(functionName));
|
||||
return (prompt, loadAttachmentFn);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,27 @@ namespace BotSharp.Plugin.Planner.Hooks;
|
|||
|
||||
public class PlannerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string PRIMARY_STAGE_FN = "plan_primary_stage";
|
||||
private const string SECONDARY_STAGE_FN = "plan_secondary_stage";
|
||||
private const string SUMMARY_FN = "plan_summary";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.TwoStagePlanner);
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
Name = UtilityName.TwoStagePlanner,
|
||||
Functions = [
|
||||
new(PRIMARY_STAGE_FN),
|
||||
new(SECONDARY_STAGE_FN),
|
||||
new(SUMMARY_FN)
|
||||
],
|
||||
Templates = [
|
||||
new($"{PRIMARY_STAGE_FN}.fn"),
|
||||
new($"{SECONDARY_STAGE_FN}.fn"),
|
||||
new($"{SUMMARY_FN}.fn")
|
||||
]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
"disabled": false,
|
||||
"isPublic": true,
|
||||
"profiles": [ "planning" ],
|
||||
"utilities": [ "two-stage-planner", "sql-dictionary-lookup", "excel-handler" ],
|
||||
"mergeUtility": true,
|
||||
"utilities": [],
|
||||
"llmConfig": {
|
||||
"provider": "openai",
|
||||
"model": "gpt-4o",
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
namespace BotSharp.Plugin.PythonInterpreter.Hooks;
|
||||
|
||||
public class InterpreterAgentHook : AgentHookBase
|
||||
{
|
||||
private static string FUNCTION_NAME = "python_interpreter";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public InterpreterAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.PythonInterpreter);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction();
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,17 @@ namespace BotSharp.Plugin.PythonInterpreter.Hooks;
|
|||
|
||||
public class InterpreterUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private static string FUNCTION_NAME = "python_interpreter";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(UtilityName.PythonInterpreter);
|
||||
var utility = new AgentUtility()
|
||||
{
|
||||
Name = UtilityName.PythonInterpreter,
|
||||
Functions = [new(FUNCTION_NAME)],
|
||||
Templates = [new($"{FUNCTION_NAME}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ public class InterpreterPlugin : IBotSharpAppPlugin
|
|||
|
||||
public void RegisterDI(IServiceCollection services, IConfiguration config)
|
||||
{
|
||||
services.AddScoped<IAgentHook, InterpreterAgentHook>();
|
||||
services.AddScoped<IAgentUtilityHook, InterpreterUtilityHook>();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(TargetFramework)</TargetFramework>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace BotSharp.Plugin.SqlDriver.Enum;
|
||||
|
||||
public class Utility
|
||||
public class UtilityName
|
||||
{
|
||||
public const string SqlExecutor = "sql-executor";
|
||||
public const string SqlDictionaryLookup = "sql-dictionary-lookup";
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
namespace BotSharp.Plugin.SqlDriver.Helpers;
|
||||
|
||||
internal static class SqlDriverHelper
|
||||
{
|
||||
internal static string GetDatabaseType(IServiceProvider services)
|
||||
{
|
||||
var settings = services.GetRequiredService<SqlDriverSetting>();
|
||||
var dbType = "MySQL";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings?.SqlServerConnectionString))
|
||||
{
|
||||
dbType = "SQL Server";
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(settings?.SqlLiteConnectionString))
|
||||
{
|
||||
dbType = "SQL Lite";
|
||||
}
|
||||
return dbType;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.Hooks;
|
||||
|
||||
public class GetTableDefinitionHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string SQL_EXECUTOR_TEMPLATE = "sql_table_definition.fn";
|
||||
private IEnumerable<string> _targetSqlExecutorFunctions = new List<string>
|
||||
{
|
||||
"sql_table_definition",
|
||||
};
|
||||
|
||||
public override string SelfId => BuiltInAgentId.Planner;
|
||||
|
||||
public GetTableDefinitionHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.SqlTableDefinition);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fns) = GetPromptAndFunctions();
|
||||
if (!fns.IsNullOrEmpty())
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
|
||||
}
|
||||
|
||||
if (agent.Functions == null)
|
||||
{
|
||||
agent.Functions = fns;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.Functions.AddRange(fns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private (string, List<FunctionDef>?) GetPromptAndFunctions()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var fns = agent?.Functions?.Where(x => _targetSqlExecutorFunctions.Contains(x.Name))?.ToList();
|
||||
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(SQL_EXECUTOR_TEMPLATE))?.Content ?? string.Empty;
|
||||
var dbType = GetDatabaseType();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
prompt = render.Render(prompt, new Dictionary<string, object>
|
||||
{
|
||||
{ "db_type", dbType }
|
||||
});
|
||||
|
||||
return (prompt, fns);
|
||||
}
|
||||
|
||||
private string GetDatabaseType()
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var dbType = "MySQL";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings?.SqlServerConnectionString))
|
||||
{
|
||||
dbType = "SQL Server";
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(settings?.SqlLiteConnectionString))
|
||||
{
|
||||
dbType = "SQL Lite";
|
||||
}
|
||||
return dbType;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.Hooks;
|
||||
|
||||
public class SqlDictionaryLookupHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string SQL_EXECUTOR_TEMPLATE = "verify_dictionary_term.fn";
|
||||
private IEnumerable<string> _targetSqlExecutorFunctions = new List<string>
|
||||
{
|
||||
"verify_dictionary_term",
|
||||
};
|
||||
|
||||
public override string SelfId => BuiltInAgentId.Planner;
|
||||
|
||||
public SqlDictionaryLookupHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.SqlDictionaryLookup);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fns) = GetPromptAndFunctions();
|
||||
if (!fns.IsNullOrEmpty())
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
|
||||
}
|
||||
|
||||
if (agent.Functions == null)
|
||||
{
|
||||
agent.Functions = fns;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.Functions.AddRange(fns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private (string, List<FunctionDef>?) GetPromptAndFunctions()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var fns = agent?.Functions?.Where(x => _targetSqlExecutorFunctions.Contains(x.Name))?.ToList();
|
||||
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(SQL_EXECUTOR_TEMPLATE))?.Content ?? string.Empty;
|
||||
var dbType = GetDatabaseType();
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
prompt = render.Render(prompt, new Dictionary<string, object>
|
||||
{
|
||||
{ "db_type", dbType }
|
||||
});
|
||||
|
||||
return (prompt, fns);
|
||||
}
|
||||
|
||||
private string GetDatabaseType()
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var dbType = "MySQL";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings?.SqlServerConnectionString))
|
||||
{
|
||||
dbType = "SQL Server";
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(settings?.SqlLiteConnectionString))
|
||||
{
|
||||
dbType = "SQL Lite";
|
||||
}
|
||||
return dbType;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using BotSharp.Abstraction.Agents.Settings;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.Hooks;
|
||||
|
||||
public class SqlDriverAgentHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
public override string SelfId => BuiltInAgentId.Planner;
|
||||
|
||||
public SqlDriverAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var dbType = SqlDriverHelper.GetDatabaseType(_services);
|
||||
agent.TemplateDict["db_type"] = dbType;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver.Hooks;
|
||||
|
||||
public class SqlExecutorHook : AgentHookBase, IAgentHook
|
||||
{
|
||||
private const string SQL_EXECUTOR_TEMPLATE = "sql_executor.fn";
|
||||
private IEnumerable<string> _targetSqlExecutorFunctions = new List<string>
|
||||
{
|
||||
"sql_select",
|
||||
"sql_table_definition",
|
||||
};
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public SqlExecutorHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(Utility.SqlExecutor);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fns) = GetPromptAndFunctions();
|
||||
if (!fns.IsNullOrEmpty())
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
|
||||
}
|
||||
|
||||
if (agent.Functions == null)
|
||||
{
|
||||
agent.Functions = fns;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.Functions.AddRange(fns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
private (string, List<FunctionDef>?) GetPromptAndFunctions()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agent = db.GetAgent(BuiltInAgentId.UtilityAssistant);
|
||||
var fns = agent?.Functions?.Where(x => _targetSqlExecutorFunctions.Contains(x.Name))?.ToList();
|
||||
|
||||
var prompt = agent?.Templates?.FirstOrDefault(x => x.Name.IsEqualTo(SQL_EXECUTOR_TEMPLATE))?.Content ?? string.Empty;
|
||||
var dbType = GetDatabaseType(); //need change-> using hook?
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
prompt = render.Render(prompt, new Dictionary<string, object>
|
||||
{
|
||||
{ "db_type", dbType }
|
||||
});
|
||||
|
||||
return (prompt, fns);
|
||||
}
|
||||
|
||||
private string GetDatabaseType()
|
||||
{
|
||||
var settings = _services.GetRequiredService<SqlDriverSetting>();
|
||||
var dbType = "MySQL";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(settings?.SqlServerConnectionString))
|
||||
{
|
||||
dbType = "SQL Server";
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(settings?.SqlLiteConnectionString))
|
||||
{
|
||||
dbType = "SQL Lite";
|
||||
}
|
||||
return dbType;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,34 @@ namespace BotSharp.Plugin.SqlDriver.Hooks;
|
|||
|
||||
public class SqlUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
private const string SQL_TABLE_DEFINITION_FN = "sql_table_definition";
|
||||
private const string VERIFY_DICTIONARY_TERM_FN = "verify_dictionary_term";
|
||||
private const string SQL_SELECT_FN = "sql_select";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
utilities.Add(Utility.SqlExecutor);
|
||||
utilities.Add(Utility.SqlDictionaryLookup);
|
||||
utilities.Add(Utility.SqlTableDefinition);
|
||||
var items = new List<AgentUtility>
|
||||
{
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.SqlTableDefinition,
|
||||
Functions = [new(SQL_TABLE_DEFINITION_FN)],
|
||||
Templates = [new($"{SQL_TABLE_DEFINITION_FN}.fn")]
|
||||
},
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.SqlDictionaryLookup,
|
||||
Functions = [new(VERIFY_DICTIONARY_TERM_FN)],
|
||||
Templates = [new($"{VERIFY_DICTIONARY_TERM_FN}.fn")]
|
||||
},
|
||||
new AgentUtility
|
||||
{
|
||||
Name = UtilityName.SqlExecutor,
|
||||
Functions = [new(SQL_SELECT_FN), new(SQL_TABLE_DEFINITION_FN)],
|
||||
Templates = [new($"sql_executor.fn")]
|
||||
}
|
||||
};
|
||||
|
||||
utilities.AddRange(items);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
namespace BotSharp.Plugin.SqlHero.Settings;
|
||||
namespace BotSharp.Plugin.SqlDriver.Settings;
|
||||
|
||||
public class SqlDriverSetting
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Planning;
|
||||
|
||||
namespace BotSharp.Plugin.SqlDriver;
|
||||
|
|
@ -25,12 +24,10 @@ public class SqlDriverPlugin : IBotSharpPlugin
|
|||
|
||||
services.AddScoped<SqlDriverService>();
|
||||
services.AddScoped<DbKnowledgeService>();
|
||||
services.AddScoped<IKnowledgeHook, SqlDriverKnowledgeHook>();
|
||||
services.AddScoped<IAgentHook, SqlExecutorHook>();
|
||||
services.AddScoped<IAgentUtilityHook, SqlUtilityHook>();
|
||||
services.AddScoped<IPlanningHook, SqlDriverPlanningHook>();
|
||||
services.AddScoped<IAgentHook, SqlDictionaryLookupHook>();
|
||||
services.AddScoped<IAgentHook, GetTableDefinitionHook>();
|
||||
services.AddScoped<IKnowledgeHook, SqlDriverKnowledgeHook>();
|
||||
services.AddScoped<IAgentHook, SqlDriverAgentHook>();
|
||||
services.AddScoped<IConversationHook, SqlDriverConversationHook>();
|
||||
services.AddScoped<IAgentUtilityHook, SqlUtilityHook>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@ global using System.Text.RegularExpressions;
|
|||
global using System.Threading.Tasks;
|
||||
global using System.Linq;
|
||||
global using System.Text.Json;
|
||||
|
||||
global using Microsoft.Extensions.Configuration;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
|
||||
global using BotSharp.Abstraction.Conversations;
|
||||
global using BotSharp.Abstraction.Plugins;
|
||||
global using BotSharp.Abstraction.Conversations.Models;
|
||||
|
|
@ -26,9 +24,10 @@ global using BotSharp.Abstraction.Settings;
|
|||
global using BotSharp.Plugin.SqlDriver.Hooks;
|
||||
global using BotSharp.Plugin.SqlDriver.Services;
|
||||
global using BotSharp.Plugin.SqlDriver.Enum;
|
||||
global using BotSharp.Plugin.SqlHero.Settings;
|
||||
global using BotSharp.Abstraction.Agents.Enums;
|
||||
global using BotSharp.Abstraction.Instructs;
|
||||
global using BotSharp.Abstraction.Instructs.Models;
|
||||
global using BotSharp.Abstraction.Routing;
|
||||
global using BotSharp.Plugin.SqlDriver.Interfaces;
|
||||
global using BotSharp.Plugin.SqlDriver.Helpers;
|
||||
global using BotSharp.Plugin.SqlDriver.Settings;
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Utilities;
|
||||
using BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Enums;
|
||||
|
||||
namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Hooks
|
||||
{
|
||||
internal class OutboundPhoneCallHandlerHook : AgentHookBase
|
||||
{
|
||||
private static string FUNCTION_NAME = "twilio_outbound_phone_call";
|
||||
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public OutboundPhoneCallHandlerHook(IServiceProvider services, AgentSettings settings) : base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnAgentLoaded(Agent agent)
|
||||
{
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
var isConvMode = conv.IsConversationMode();
|
||||
var isEnabled = !agent.Utilities.IsNullOrEmpty() && agent.Utilities.Contains(UtilityName.OutboundPhoneCall);
|
||||
|
||||
if (isConvMode && isEnabled)
|
||||
{
|
||||
var (prompt, fn) = GetPromptAndFunction();
|
||||
if (fn != null)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(prompt))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,21 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Enums;
|
||||
|
||||
namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Hooks
|
||||
namespace BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.Hooks;
|
||||
|
||||
public class OutboundPhoneCallHandlerUtilityHook : IAgentUtilityHook
|
||||
{
|
||||
public class OutboundPhoneCallHandlerUtilityHook : IAgentUtilityHook
|
||||
private static string OUTBOUND_PHONE_CALL_FN = "twilio_outbound_phone_call";
|
||||
|
||||
public void AddUtilities(List<AgentUtility> utilities)
|
||||
{
|
||||
public void AddUtilities(List<string> utilities)
|
||||
var utility = new AgentUtility
|
||||
{
|
||||
utilities.Add(UtilityName.OutboundPhoneCall);
|
||||
}
|
||||
Name = UtilityName.OutboundPhoneCall,
|
||||
Functions = [new(OUTBOUND_PHONE_CALL_FN)],
|
||||
Templates = [new($"{OUTBOUND_PHONE_CALL_FN}.fn")]
|
||||
};
|
||||
|
||||
utilities.Add(utility);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ public class TwilioPlugin : IBotSharpPlugin
|
|||
services.AddSingleton<TwilioMessageQueue>();
|
||||
services.AddHostedService<TwilioMessageQueueService>();
|
||||
services.AddTwilioRequestValidation();
|
||||
services.AddScoped<IAgentHook, OutboundPhoneCallHandlerHook>();
|
||||
services.AddScoped<IAgentUtilityHook, OutboundPhoneCallHandlerUtilityHook>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue