Merge branch 'SciSharp:master' into master
This commit is contained in:
commit
cbf81345c1
|
|
@ -1,10 +1,5 @@
|
|||
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;
|
||||
|
||||
|
|
@ -60,73 +55,5 @@ public abstract class AgentHookBase : IAgentHook
|
|||
|
||||
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);
|
||||
|
||||
foreach (var fn in functions)
|
||||
{
|
||||
if (!agent.Functions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
agent.Functions.Add(fn);
|
||||
}
|
||||
}
|
||||
|
||||
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 ([], []);
|
||||
}
|
||||
|
||||
var prefix = "util-";
|
||||
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
|
||||
var functionNames = utilities.SelectMany(x => x.Functions)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
var templateNames = utilities.SelectMany(x => x.Templates)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
|
||||
return (functionNames, templateNames);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ public class AgentUtility
|
|||
Functions = functions ?? [];
|
||||
Templates = templates ?? [];
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using BotSharp.Abstraction.Plugins.Models;
|
|||
using BotSharp.Abstraction.Settings;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Core.Agents.Hooks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace BotSharp.Core.Agents;
|
||||
|
|
@ -30,6 +31,7 @@ public class AgentPlugin : IBotSharpPlugin
|
|||
{
|
||||
services.AddScoped<ILlmProviderService, LlmProviderService>();
|
||||
services.AddScoped<IAgentService, AgentService>();
|
||||
services.AddScoped<IAgentHook, BasicAgentHook>();
|
||||
|
||||
services.AddScoped(provider =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
namespace BotSharp.Core.Agents.Hooks;
|
||||
|
||||
public class BasicAgentHook : AgentHookBase
|
||||
{
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
public BasicAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override 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);
|
||||
|
||||
foreach (var fn in functions)
|
||||
{
|
||||
if (!agent.Functions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
agent.Functions.Add(fn);
|
||||
}
|
||||
}
|
||||
|
||||
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 ([], []);
|
||||
}
|
||||
|
||||
var prefix = "util-";
|
||||
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
|
||||
var functionNames = utilities.SelectMany(x => x.Functions)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
var templateNames = utilities.SelectMany(x => x.Templates)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
|
||||
return (functionNames, templateNames);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ using BotSharp.Abstraction.Infrastructures.Enums;
|
|||
using BotSharp.Abstraction.Planning;
|
||||
using BotSharp.Abstraction.Routing.Enums;
|
||||
using BotSharp.Abstraction.Routing.Reasoning;
|
||||
using BotSharp.Core.Routing.Reasoning;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ public partial class RoutingService
|
|||
var states = _services.GetRequiredService<IConversationStateService>();
|
||||
var executor = _services.GetRequiredService<IExecutor>();
|
||||
|
||||
var planner = GetReasoner(_router);
|
||||
var reasoner = GetReasoner(_router);
|
||||
|
||||
_context.Push(_router.Id);
|
||||
|
||||
|
|
@ -46,7 +45,7 @@ public partial class RoutingService
|
|||
|
||||
// Get first instruction
|
||||
_router.TemplateDict["conversation"] = await GetConversationContent(dialogs);
|
||||
var inst = await planner.GetNextInstruction(_router, message.MessageId, dialogs);
|
||||
var inst = await reasoner.GetNextInstruction(_router, message.MessageId, dialogs);
|
||||
|
||||
int loopCount = 1;
|
||||
while (true)
|
||||
|
|
@ -63,30 +62,30 @@ public partial class RoutingService
|
|||
#else
|
||||
_logger.LogInformation($"*** Next Instruction *** {inst}");
|
||||
#endif
|
||||
await planner.AgentExecuting(_router, inst, message, dialogs);
|
||||
await reasoner.AgentExecuting(_router, inst, message, dialogs);
|
||||
|
||||
// Handover to Task Agent
|
||||
if (inst.HandleDialogsByPlanner)
|
||||
{
|
||||
var dialogWithoutContext = planner.BeforeHandleContext(inst, message, dialogs);
|
||||
var dialogWithoutContext = reasoner.BeforeHandleContext(inst, message, dialogs);
|
||||
response = await executor.Execute(this, inst, message, dialogWithoutContext);
|
||||
planner.AfterHandleContext(dialogs, dialogWithoutContext);
|
||||
reasoner.AfterHandleContext(dialogs, dialogWithoutContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = await executor.Execute(this, inst, message, dialogs);
|
||||
}
|
||||
|
||||
await planner.AgentExecuted(_router, inst, response, dialogs);
|
||||
await reasoner.AgentExecuted(_router, inst, response, dialogs);
|
||||
|
||||
if (loopCount >= planner.MaxLoopCount || _context.IsEmpty)
|
||||
if (loopCount >= reasoner.MaxLoopCount || _context.IsEmpty)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get next instruction from Planner
|
||||
_router.TemplateDict["conversation"] = await GetConversationContent(dialogs);
|
||||
inst = await planner.GetNextInstruction(_router, message.MessageId, dialogs);
|
||||
inst = await reasoner.GetNextInstruction(_router, message.MessageId, dialogs);
|
||||
loopCount++;
|
||||
}
|
||||
|
||||
|
|
@ -103,8 +102,7 @@ public partial class RoutingService
|
|||
return _services.GetServices<IRoutingReasoner>().First(x => x.Name == "Naive Reasoner");
|
||||
}
|
||||
|
||||
var reasoner = _services.GetServices<IRoutingReasoner>().
|
||||
FirstOrDefault(x => x.GetType().Name.EndsWith(rule.Field));
|
||||
var reasoner = _services.GetServices<IRoutingReasoner>().FirstOrDefault(x => x.GetType().Name.EndsWith(rule.Field));
|
||||
|
||||
if (reasoner == null)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue