Build-in routing prompt.
This commit is contained in:
commit
a7b6c4083f
|
|
@ -2,7 +2,7 @@
|
|||
<PropertyGroup>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<OutputPath>..\..\..\packages</OutputPath>
|
||||
<PackageVersion>0.13.0</PackageVersion>
|
||||
<BotSharpVersion>0.13.0</BotSharpVersion>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -6,6 +6,10 @@ public enum AgentField
|
|||
Name,
|
||||
Description,
|
||||
IsPublic,
|
||||
Disabled,
|
||||
AllowRouting,
|
||||
Profiles,
|
||||
RoutingRules,
|
||||
Instruction,
|
||||
Function,
|
||||
Template,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ public class Agent
|
|||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
public DateTime UpdatedDateTime { get; set; }
|
||||
|
||||
|
|
@ -81,6 +81,10 @@ public class Agent
|
|||
Samples = agent.Samples,
|
||||
Knowledges = agent.Knowledges,
|
||||
IsPublic = agent.IsPublic,
|
||||
Disabled = agent.Disabled,
|
||||
AllowRouting = agent.AllowRouting,
|
||||
Profiles = agent.Profiles,
|
||||
RoutingRules = agent.RoutingRules,
|
||||
CreatedDateTime = agent.CreatedDateTime,
|
||||
UpdatedDateTime = agent.UpdatedDateTime,
|
||||
};
|
||||
|
|
@ -94,7 +98,7 @@ public class Agent
|
|||
|
||||
public Agent SetTemplates(List<AgentTemplate> templates)
|
||||
{
|
||||
Templates = templates;
|
||||
Templates = templates ?? new List<AgentTemplate>();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -133,4 +137,28 @@ public class Agent
|
|||
IsPublic = isPublic;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent SetDisabled(bool disabled)
|
||||
{
|
||||
Disabled = disabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent SetAllowRouting(bool allowRouting)
|
||||
{
|
||||
AllowRouting = allowRouting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent SetProfiles(List<string> profiles)
|
||||
{
|
||||
Profiles = profiles ?? new List<string>();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Agent SetRoutingRules(List<RoutingRule> rules)
|
||||
{
|
||||
RoutingRules = rules ?? new List<RoutingRule>();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<PackageIcon>Icon.png</PackageIcon>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ public class FunctionCallFromLlm
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Function}: {Parameters}";
|
||||
return $"{Function} {Parameters}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,23 @@ namespace BotSharp.Abstraction.MLTasks;
|
|||
|
||||
public interface IChatCompletion
|
||||
{
|
||||
/// <summary>
|
||||
/// The LLM provider like Microsoft Azure, OpenAI, ClaudAI
|
||||
/// </summary>
|
||||
string Provider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Set model name, one provider can consume different model or version(s)
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
void SetModelName(string model);
|
||||
|
||||
Task<bool> GetChatCompletionsAsync(Agent agent,
|
||||
List<RoleDialogModel> conversations,
|
||||
Func<RoleDialogModel, Task> onMessageReceived,
|
||||
Func<RoleDialogModel, Task> onFunctionExecuting);
|
||||
|
||||
Task<bool> GetChatCompletionsStreamingAsync(Agent agent, List<RoleDialogModel> conversations, Func<RoleDialogModel, Task> onMessageReceived);
|
||||
Task<bool> GetChatCompletionsStreamingAsync(Agent agent,
|
||||
List<RoleDialogModel> conversations,
|
||||
Func<RoleDialogModel, Task> onMessageReceived);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ namespace BotSharp.Abstraction.Routing;
|
|||
|
||||
public interface IRoutingService
|
||||
{
|
||||
Agent LoadRouter();
|
||||
List<RoleDialogModel> Dialogs { get; }
|
||||
Task<RoleDialogModel> Enter(Agent agent, List<RoleDialogModel> whileDialogs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ public class RetrievalArgs : RoutingArgs
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{AgentName} {Question} ({JsonSerializer.Serialize(Arguments)}) => {Answer} ({Reason})";
|
||||
return $" [{AgentName}]: {Question} ({JsonSerializer.Serialize(Arguments)}) => {Answer} ({Reason})";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,4 +18,9 @@ public class RoutingRule
|
|||
{
|
||||
return $"{AgentName} {Field}";
|
||||
}
|
||||
|
||||
public RoutingRule()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,5 @@ public class RoutingSettings
|
|||
/// </summary>
|
||||
public string RouterId { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Reasoner Agent Id
|
||||
/// </summary>
|
||||
public string ReasonerId { get; set; } = string.Empty;
|
||||
public bool EnableReasoning { get; set; } = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ public partial class AgentService
|
|||
.SetName(foundAgent.Name)
|
||||
.SetDescription(foundAgent.Description)
|
||||
.SetIsPublic(foundAgent.IsPublic)
|
||||
.SetDisabled(foundAgent.Disabled)
|
||||
.SetAllowRouting(foundAgent.AllowRouting)
|
||||
.SetProfiles(foundAgent.Profiles)
|
||||
.SetRoutingRules(foundAgent.RoutingRules)
|
||||
.SetInstruction(foundAgent.Instruction)
|
||||
.SetTemplates(foundAgent.Templates)
|
||||
.SetFunctions(foundAgent.Functions)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
|
||||
namespace BotSharp.Core.Agents.Services;
|
||||
|
|
@ -18,7 +20,9 @@ public partial class AgentService
|
|||
hook.OnAgentLoading(ref id);
|
||||
}
|
||||
|
||||
var agent = await GetAgent(id);
|
||||
var settings = _services.GetRequiredService<RoutingSettings>();
|
||||
var routingService = _services.GetRequiredService<IRoutingService>();
|
||||
var agent = settings.RouterId == id ? routingService.LoadRouter() : await GetAgent(id);
|
||||
var templateDict = new Dictionary<string, object>();
|
||||
PopulateState(templateDict);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Agents.Services;
|
||||
|
|
@ -15,6 +16,11 @@ public partial class AgentService
|
|||
|
||||
record.Name = agent.Name ?? string.Empty;
|
||||
record.Description = agent.Description ?? string.Empty;
|
||||
record.IsPublic = agent.IsPublic;
|
||||
record.Disabled = agent.Disabled;
|
||||
record.AllowRouting = agent.AllowRouting;
|
||||
record.Profiles = agent.Profiles ?? new List<string>();
|
||||
record.RoutingRules = agent.RoutingRules ?? new List<RoutingRule>();
|
||||
record.Instruction = agent.Instruction ?? string.Empty;
|
||||
record.Functions = agent.Functions ?? new List<string>();
|
||||
record.Templates = agent.Templates ?? new List<AgentTemplate>();
|
||||
|
|
@ -53,6 +59,10 @@ public partial class AgentService
|
|||
.SetName(foundAgent.Name)
|
||||
.SetDescription(foundAgent.Description)
|
||||
.SetIsPublic(foundAgent.IsPublic)
|
||||
.SetDisabled(foundAgent.Disabled)
|
||||
.SetAllowRouting(foundAgent.AllowRouting)
|
||||
.SetProfiles(foundAgent.Profiles)
|
||||
.SetRoutingRules(foundAgent.RoutingRules)
|
||||
.SetInstruction(foundAgent.Instruction)
|
||||
.SetTemplates(foundAgent.Templates)
|
||||
.SetFunctions(foundAgent.Functions)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -74,6 +74,20 @@
|
|||
<Compile Remove="CoreController.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Routing\Prompts\reasoning_functions.liquid" />
|
||||
<None Remove="Routing\router_prompt.liquid" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Routing\Prompts\reasoning_functions.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Routing\Prompts\router_prompt.liquid">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\arts\Icon.png">
|
||||
<Pack>True</Pack>
|
||||
|
|
|
|||
|
|
@ -51,16 +51,11 @@ public static class BotSharpServiceCollectionExtensions
|
|||
config.Bind("Router", routingSettings);
|
||||
services.AddSingleton((IServiceProvider x) => routingSettings);
|
||||
|
||||
services.AddScoped<Router>();
|
||||
services.AddScoped<Reasoner>();
|
||||
services.AddScoped<IAgentRouting, Router>();
|
||||
|
||||
// Register function callback
|
||||
services.AddScoped<IFunctionCallback, RouteToAgentFn>();
|
||||
|
||||
// Register Hooks
|
||||
services.AddScoped<IAgentHook, RoutingHook>();
|
||||
|
||||
services.AddScoped<Simulator>();
|
||||
services.AddScoped<IRoutingService, RoutingService>();
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public partial class ConversationService
|
|||
}
|
||||
}
|
||||
|
||||
// reasoning
|
||||
// Routing with reasoning
|
||||
var settings = _services.GetRequiredService<RoutingSettings>();
|
||||
if (settings.RouterId == agent.Id)
|
||||
{
|
||||
|
|
@ -82,6 +82,13 @@ public partial class ConversationService
|
|||
agent = await agentService.LoadAgent(reasonedContext.CurrentAgentId);
|
||||
}
|
||||
}
|
||||
else if (reasonedContext.FunctionName == "route_to_agent")
|
||||
{
|
||||
if (reasonedContext.CurrentAgentId != agent.Id)
|
||||
{
|
||||
agent = await agentService.LoadAgent(reasonedContext.CurrentAgentId);
|
||||
}
|
||||
}
|
||||
|
||||
routing.Dialogs.ForEach(x =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
|
@ -44,9 +45,10 @@ public class ConversationStorage : IConversationStorage
|
|||
}
|
||||
else
|
||||
{
|
||||
var agent = db.Agents.First(x => x.Id == agentId);
|
||||
var routingSetting = _services.GetRequiredService<RoutingSettings>();
|
||||
var agentName = routingSetting.RouterId == agentId ? "Router" : db.Agents.First(x => x.Id == agentId).Name;
|
||||
|
||||
sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{agent.Name}|");
|
||||
sb.AppendLine($"{dialog.CreatedAt}|{dialog.Role}|{agentId}|{agentName}|");
|
||||
var content = dialog.Content.Replace("\r", " ").Replace("\n", " ").Trim();
|
||||
if (string.IsNullOrEmpty(content))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,16 +4,31 @@ namespace BotSharp.Core.Infrastructures;
|
|||
|
||||
public class CompletionProvider
|
||||
{
|
||||
public static IChatCompletion GetChatCompletion(IServiceProvider services, string? provider = null)
|
||||
public static IChatCompletion GetChatCompletion(IServiceProvider services, string? provider = null, string? model = null)
|
||||
{
|
||||
var completions = services.GetServices<IChatCompletion>();
|
||||
|
||||
var state = services.GetRequiredService<IConversationStateService>();
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
provider = state.GetState("provider", "azure-gpt-3.5");
|
||||
provider = state.GetState("provider", "azure-openai");
|
||||
}
|
||||
|
||||
return completions.FirstOrDefault(x => x.Provider == provider);
|
||||
|
||||
if (model == null)
|
||||
{
|
||||
model = state.GetState("model", "gpt-3.5-turbo");
|
||||
}
|
||||
|
||||
var completer = completions.FirstOrDefault(x => x.Provider == provider);
|
||||
if (completer == null)
|
||||
{
|
||||
var logger = services.GetRequiredService<ILogger<CompletionProvider>>();
|
||||
logger.LogError($"Can't resolve completion provider by {provider}");
|
||||
}
|
||||
|
||||
completer.SetModelName(model);
|
||||
|
||||
return completer;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
|
|||
using BotSharp.Abstraction.Users.Models;
|
||||
using BotSharp.Abstraction.Agents.Models;
|
||||
using MongoDB.Driver;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Core.Repository;
|
||||
|
||||
|
|
@ -240,6 +241,18 @@ public class FileRepository : IBotSharpRepository
|
|||
case AgentField.IsPublic:
|
||||
UpdateAgentIsPublic(agent.Id, agent.IsPublic);
|
||||
break;
|
||||
case AgentField.Disabled:
|
||||
UpdateAgentDisabled(agent.Id, agent.Disabled);
|
||||
break;
|
||||
case AgentField.AllowRouting:
|
||||
UpdateAgentAllowRouting(agent.Id, agent.AllowRouting);
|
||||
break;
|
||||
case AgentField.Profiles:
|
||||
UpdateAgentProfiles(agent.Id, agent.Profiles);
|
||||
break;
|
||||
case AgentField.RoutingRules:
|
||||
UpdateAgentRoutingRules(agent.Id, agent.RoutingRules);
|
||||
break;
|
||||
case AgentField.Instruction:
|
||||
UpdateAgentInstruction(agent.Id, agent.Instruction);
|
||||
break;
|
||||
|
|
@ -298,6 +311,54 @@ public class FileRepository : IBotSharpRepository
|
|||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentDisabled(string agentId, bool disabled)
|
||||
{
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.Disabled = disabled;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentAllowRouting(string agentId, bool allowRouting)
|
||||
{
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.AllowRouting = allowRouting;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentProfiles(string agentId, List<string> profiles)
|
||||
{
|
||||
if (profiles.IsNullOrEmpty()) return;
|
||||
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.Profiles = profiles;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentRoutingRules(string agentId, List<RoutingRule> rules)
|
||||
{
|
||||
if (rules.IsNullOrEmpty()) return;
|
||||
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.RoutingRules = rules;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentInstruction(string agentId, string instruction)
|
||||
{
|
||||
if (string.IsNullOrEmpty(instruction)) return;
|
||||
|
|
@ -396,6 +457,10 @@ public class FileRepository : IBotSharpRepository
|
|||
agent.Name = inputAgent.Name;
|
||||
agent.Description = inputAgent.Description;
|
||||
agent.IsPublic = inputAgent.IsPublic;
|
||||
agent.Disabled = inputAgent.Disabled;
|
||||
agent.AllowRouting = inputAgent.AllowRouting;
|
||||
agent.Profiles = inputAgent.Profiles;
|
||||
agent.RoutingRules = inputAgent.RoutingRules;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# retrieve_data_from_agent
|
||||
Retrieve data from appropriate agent.
|
||||
Parameters:
|
||||
1. agent_name: the name of the agent;
|
||||
2. question: the question you will ask the agent to get the necessary data
|
||||
3. args: required parameters extracted from question and hand over to the next agent. The args should be in JSON format.
|
||||
|
||||
# continue_execute_task
|
||||
Continue to execute user's request without further information retrival.
|
||||
Parameters:
|
||||
1. agent_name: the name of the agent;
|
||||
2. args: required parameters extracted from question.
|
||||
|
||||
# interrupt_task_execution
|
||||
Can't continue user's request becauase the requirements are not met or you have already known the answer.
|
||||
Parameters:
|
||||
1. reason: the reason why the request is interrupted;
|
||||
|
||||
# response_to_user
|
||||
You have already known the answer according the dialogs.
|
||||
Parameters:
|
||||
1. answer: the answer of user's question;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
You're a Agent Router with reasoning, you can dispatch request to different agent to complete the task.
|
||||
|
||||
{% for agent in routing_records %}
|
||||
# Agent: {{ agent.name }}
|
||||
{{ agent.description }}
|
||||
{% if agent.required_fields != empty -%}Required information: {{ agent.required_fields }}.{%- endif %}
|
||||
{% endfor %}
|
||||
|
||||
### Function instructions
|
||||
# route_to_agent
|
||||
Route request to appropriate agent.
|
||||
Parameters:
|
||||
1. agent_name: the name of the agent;
|
||||
|
||||
# task_end
|
||||
Call this function when current task is completed.
|
||||
Parameters:
|
||||
1. abandoned_arguments: the arguments next task can't reuse;
|
||||
|
||||
# conversation_end
|
||||
Call this function when user wants to end this conversation or all tasks have been completed.
|
||||
|
||||
# transfer_to_csr
|
||||
Reach out to a real customer representative to help.
|
||||
|
||||
{{ reasoning_functions }}
|
||||
|
||||
### Your response must meet below requirements strictly
|
||||
* If you can find an appropriate Agent, you must call appropriate function with required arguments.
|
||||
|
||||
### Below are the dialogs between user and different agents:
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
using BotSharp.Abstraction.Routing.Settings;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
public class Reasoner : Router
|
||||
{
|
||||
public override string AgentId => _settings.ReasonerId;
|
||||
|
||||
public Reasoner(IServiceProvider services,
|
||||
ILogger<Reasoner> logger,
|
||||
RoutingSettings settings) : base(services, logger, settings)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
public class RoutingHook : AgentHookBase
|
||||
{
|
||||
public RoutingHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnInstructionLoaded(string template, Dictionary<string, object> dict)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray();
|
||||
|
||||
var router = _services.GetRequiredService<IAgentRouting>();
|
||||
dict["routing_records"] = agents.Select(x => new RoutingItem
|
||||
{
|
||||
AgentId = x.Id,
|
||||
Description = x.Description,
|
||||
Name = x.Name,
|
||||
RequiredFields = x.RoutingRules.Where(x => x.Required)
|
||||
.Select(x => x.Field)
|
||||
.ToArray()
|
||||
}).ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,19 +4,26 @@ using BotSharp.Abstraction.Functions.Models;
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Routing;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Routing.Settings;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using System.IO;
|
||||
|
||||
namespace BotSharp.Core.Routing;
|
||||
|
||||
public class RoutingService : IRoutingService
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly RoutingSettings _settings;
|
||||
private readonly ILogger _logger;
|
||||
private List<RoleDialogModel> _dialogs;
|
||||
public List<RoleDialogModel> Dialogs => _dialogs;
|
||||
|
||||
public RoutingService(IServiceProvider services, ILogger<RoutingService> logger)
|
||||
public RoutingService(IServiceProvider services,
|
||||
RoutingSettings settings,
|
||||
ILogger<RoutingService> logger)
|
||||
{
|
||||
_services = services;
|
||||
_settings = settings;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +97,9 @@ public class RoutingService : IRoutingService
|
|||
new RoleDialogModel(AgentRole.User, inst.Parameters.Question)
|
||||
});
|
||||
|
||||
response.Content += $"\r\nDo you want to continue current task?";
|
||||
inst.Parameters.Answer = response.Content;
|
||||
response.Content += $"\r\nDo you want to continue current task?";
|
||||
|
||||
_dialogs.Add(new RoleDialogModel(AgentRole.Function, $"{record.Name}: {response.Content}")
|
||||
{
|
||||
FunctionName = inst.Function,
|
||||
|
|
@ -111,9 +120,10 @@ public class RoutingService : IRoutingService
|
|||
|
||||
private async Task<FunctionCallFromLlm> GetNextInstructionFromReasoner(Agent reasoner)
|
||||
{
|
||||
var responseFormat = "{\"function\": \"\", \"parameters\": {\"agent_name\": \"\", \"args\":{}}";
|
||||
var wholeDialogs = new List<RoleDialogModel>
|
||||
{
|
||||
new RoleDialogModel(AgentRole.User, @"What's the next step? Response in JSON format with ""function"" and ""parameters"".")
|
||||
new RoleDialogModel(AgentRole.User, $"What's the next step? Response in JSON format {responseFormat}.")
|
||||
};
|
||||
|
||||
var chatCompletion = CompletionProvider.GetChatCompletion(_services);
|
||||
|
|
@ -132,6 +142,8 @@ public class RoutingService : IRoutingService
|
|||
|
||||
args.Function = args.Function.Split('.').Last();
|
||||
|
||||
_logger.LogInformation($"Next Instruction: {args}");
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
|
@ -180,4 +192,39 @@ public class RoutingService : IRoutingService
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Agent LoadRouter()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
|
||||
var router = new Agent()
|
||||
{
|
||||
Id = _settings.RouterId,
|
||||
};
|
||||
var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray();
|
||||
|
||||
var dict = new Dictionary<string, object>();
|
||||
dict["routing_records"] = agents.Select(x => new RoutingItem
|
||||
{
|
||||
AgentId = x.Id,
|
||||
Description = x.Description,
|
||||
Name = x.Name,
|
||||
RequiredFields = x.RoutingRules.Where(x => x.Required)
|
||||
.Select(x => x.Field)
|
||||
.ToArray()
|
||||
}).ToArray();
|
||||
|
||||
var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Routing", "Prompts");
|
||||
var template = File.ReadAllText(Path.Combine(dir, "router_prompt.liquid"));
|
||||
|
||||
if (_settings.EnableReasoning)
|
||||
{
|
||||
dict["reasoning_functions"] = File.ReadAllText(Path.Combine(dir, "reasoning_functions.liquid"));
|
||||
}
|
||||
|
||||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
router.Instruction = render.Render(template, dict);
|
||||
|
||||
return router;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,38 @@ public class AgentController : ControllerBase, IApiAdapter
|
|||
await _agentService.UpdateAgent(model, AgentField.IsPublic);
|
||||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/disabled")]
|
||||
public async Task UpdateAgentDisabled([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
var model = agent.ToAgent();
|
||||
model.Id = agentId;
|
||||
await _agentService.UpdateAgent(model, AgentField.Disabled);
|
||||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/allow-routing")]
|
||||
public async Task UpdateAgentAllowRouting([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
var model = agent.ToAgent();
|
||||
model.Id = agentId;
|
||||
await _agentService.UpdateAgent(model, AgentField.AllowRouting);
|
||||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/profiles")]
|
||||
public async Task UpdateAgentProfiles([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
var model = agent.ToAgent();
|
||||
model.Id = agentId;
|
||||
await _agentService.UpdateAgent(model, AgentField.Profiles);
|
||||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/routing-rules")]
|
||||
public async Task UpdateAgentRoutingRules([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
var model = agent.ToAgent();
|
||||
model.Id = agentId;
|
||||
await _agentService.UpdateAgent(model, AgentField.RoutingRules);
|
||||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/instruction")]
|
||||
public async Task UpdateAgentInstruction([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
|
|
@ -83,7 +115,7 @@ public class AgentController : ControllerBase, IApiAdapter
|
|||
}
|
||||
|
||||
[HttpPut("/agent/{agentId}/templates")]
|
||||
public async Task UpdateAgenttemplates([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
public async Task UpdateAgentTemplates([FromRoute] string agentId, [FromBody] AgentUpdateModel agent)
|
||||
{
|
||||
var model = agent.ToAgent();
|
||||
model.Id = agentId;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class InstructModeController : ControllerBase, IApiAdapter
|
|||
}
|
||||
|
||||
[HttpPost("/instruct/{agentId}")]
|
||||
public async Task<InstructResult> NewConversation([FromRoute] string agentId,
|
||||
public async Task<InstructResult> InstructCompletion([FromRoute] string agentId,
|
||||
[FromBody] InstructMessageModel input)
|
||||
{
|
||||
var instructor = _services.GetRequiredService<IInstructService>();
|
||||
|
|
@ -28,13 +28,17 @@ public class InstructModeController : ControllerBase, IApiAdapter
|
|||
Agent agent = await agentService.LoadAgent(agentId);
|
||||
|
||||
// switch to different instruction template
|
||||
if (!string.IsNullOrEmpty(input.TemplateName))
|
||||
if (!string.IsNullOrEmpty(input.Template))
|
||||
{
|
||||
var agentSettings = _services.GetRequiredService<AgentSettings>();
|
||||
var filePath = Path.Combine(agentService.GetAgentDataDir(agentId), $"{input.TemplateName}.{agentSettings.TemplateFormat}");
|
||||
var filePath = Path.Combine(agentService.GetAgentDataDir(agentId), $"{input.Template}.{agentSettings.TemplateFormat}");
|
||||
agent.Instruction = System.IO.File.ReadAllText(filePath);
|
||||
}
|
||||
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
conv.States.SetState("provider", input.Provider)
|
||||
.SetState("model", input.Model);
|
||||
|
||||
return await instructor.ExecuteInstruction(agent,
|
||||
new RoleDialogModel(AgentRole.User, input.Text),
|
||||
fn => Task.CompletedTask,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Agents;
|
||||
|
||||
|
|
@ -11,6 +12,10 @@ public class AgentCreationModel
|
|||
public List<string> Functions { get; set; }
|
||||
public List<AgentResponse> Responses { get; set; }
|
||||
public bool IsPublic { get; set; }
|
||||
public bool AllowRouting { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<RoutingRuleUpdateModel> RoutingRules { get; set; }
|
||||
|
||||
public Agent ToAgent()
|
||||
{
|
||||
|
|
@ -22,7 +27,13 @@ public class AgentCreationModel
|
|||
Templates = Templates,
|
||||
Functions = Functions,
|
||||
Responses = Responses,
|
||||
IsPublic = IsPublic
|
||||
IsPublic = IsPublic,
|
||||
AllowRouting = AllowRouting,
|
||||
Disabled = Disabled,
|
||||
Profiles = Profiles,
|
||||
RoutingRules = RoutingRules?
|
||||
.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?
|
||||
.ToList() ?? new List<RoutingRule>()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Agents;
|
||||
|
||||
|
|
@ -32,12 +33,32 @@ public class AgentUpdateModel
|
|||
/// </summary>
|
||||
public List<AgentResponse>? Responses { get; set; }
|
||||
|
||||
public bool IsPublic { get; set; }
|
||||
|
||||
public bool AllowRouting { get; set; }
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile by channel
|
||||
/// </summary>
|
||||
public List<string>? Profiles { get; set; }
|
||||
|
||||
public List<RoutingRuleUpdateModel>? RoutingRules { get; set; }
|
||||
|
||||
public Agent ToAgent()
|
||||
{
|
||||
var agent = new Agent()
|
||||
{
|
||||
Name = Name ?? string.Empty,
|
||||
Description = Description ?? string.Empty,
|
||||
IsPublic = IsPublic,
|
||||
Disabled = Disabled,
|
||||
AllowRouting = AllowRouting,
|
||||
Profiles = Profiles ?? new List<string>(),
|
||||
RoutingRules = RoutingRules?
|
||||
.Select(x => RoutingRuleUpdateModel.ToDomainElement(x))?
|
||||
.ToList() ?? new List<RoutingRule>(),
|
||||
Instruction = Instruction ?? string.Empty,
|
||||
Templates = Templates ?? new List<AgentTemplate>(),
|
||||
Functions = Functions ?? new List<string>(),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Agents;
|
||||
|
||||
|
|
@ -12,6 +13,11 @@ public class AgentViewModel
|
|||
public List<string> Functions { get; set; }
|
||||
public List<AgentResponse> Responses { get; set; }
|
||||
public bool IsPublic { get; set; }
|
||||
public bool AllowRouting { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<RoutingRule> RoutingRules { get; set; }
|
||||
|
||||
public DateTime CreatedDateTime { get; set; }
|
||||
public DateTime UpdatedDateTime { get; set; }
|
||||
|
||||
|
|
@ -27,6 +33,10 @@ public class AgentViewModel
|
|||
Functions = agent.Functions,
|
||||
Responses = agent.Responses,
|
||||
IsPublic= agent.IsPublic,
|
||||
Disabled = agent.Disabled,
|
||||
AllowRouting = agent.AllowRouting,
|
||||
Profiles = agent.Profiles,
|
||||
RoutingRules = agent.RoutingRules,
|
||||
CreatedDateTime = agent.CreatedDateTime,
|
||||
UpdatedDateTime = agent.UpdatedDateTime
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.OpenAPI.ViewModels.Agents;
|
||||
|
||||
public class RoutingRuleUpdateModel
|
||||
{
|
||||
public string Field { get; set; }
|
||||
public bool Required { get; set; }
|
||||
public string? RedirectTo { get; set; }
|
||||
|
||||
public RoutingRuleUpdateModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static RoutingRule ToDomainElement(RoutingRuleUpdateModel model)
|
||||
{
|
||||
return new RoutingRule
|
||||
{
|
||||
Field = model.Field,
|
||||
Required = model.Required,
|
||||
RedirectTo = model.RedirectTo
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -4,5 +4,5 @@ namespace BotSharp.OpenAPI.ViewModels.Instructs;
|
|||
public class InstructMessageModel : IncomingMessageModel
|
||||
{
|
||||
public override string Channel { get; set; } = "openapi";
|
||||
public string? TemplateName { get; set; }
|
||||
public string? Template { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,5 @@ public class AzureOpenAiPlugin : IBotSharpPlugin
|
|||
|
||||
services.AddScoped<ITextCompletion, TextCompletionProvider>();
|
||||
services.AddScoped<IChatCompletion, ChatCompletionProvider>();
|
||||
services.AddScoped<IChatCompletion, GPT4CompletionProvider>();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ namespace BotSharp.Plugin.AzureOpenAI.Providers;
|
|||
|
||||
public class ChatCompletionProvider : IChatCompletion
|
||||
{
|
||||
protected readonly AzureOpenAiSettings _settings;
|
||||
protected readonly IServiceProvider _services;
|
||||
protected readonly ILogger _logger;
|
||||
private readonly AzureOpenAiSettings _settings;
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger _logger;
|
||||
private string _model;
|
||||
|
||||
public virtual string Provider => "azure-gpt-3.5";
|
||||
public virtual string Provider => "azure-openai";
|
||||
|
||||
public ChatCompletionProvider(AzureOpenAiSettings settings,
|
||||
ILogger<ChatCompletionProvider> logger,
|
||||
|
|
@ -37,8 +38,16 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
|
||||
protected virtual (OpenAIClient, string) GetClient()
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
return (client, _settings.DeploymentModel.ChatCompletionModel);
|
||||
if (_model == "gpt-4")
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.GPT4.Endpoint), new AzureKeyCredential(_settings.GPT4.ApiKey));
|
||||
return (client, _settings.GPT4.DeploymentModel);
|
||||
}
|
||||
else
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.Endpoint), new AzureKeyCredential(_settings.ApiKey));
|
||||
return (client, _settings.DeploymentModel.ChatCompletionModel);
|
||||
}
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetChatSamples(string sampleText)
|
||||
|
|
@ -243,4 +252,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
|
||||
return chatCompletionsOptions;
|
||||
}
|
||||
|
||||
public void SetModelName(string model)
|
||||
{
|
||||
_model = model;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
using Azure;
|
||||
using Azure.AI.OpenAI;
|
||||
using BotSharp.Plugin.AzureOpenAI.Settings;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
|
||||
namespace BotSharp.Plugin.AzureOpenAI.Providers;
|
||||
|
||||
public class GPT4CompletionProvider : ChatCompletionProvider
|
||||
{
|
||||
public override string Provider => "azure-gpt-4";
|
||||
|
||||
public GPT4CompletionProvider(AzureOpenAiSettings settings,
|
||||
ILogger<GPT4CompletionProvider> logger,
|
||||
IServiceProvider services) : base(settings, logger, services)
|
||||
{
|
||||
}
|
||||
|
||||
protected override (OpenAIClient, string) GetClient()
|
||||
{
|
||||
var client = new OpenAIClient(new Uri(_settings.GPT4.Endpoint), new AzureKeyCredential(_settings.GPT4.ApiKey));
|
||||
return (client, _settings.GPT4.DeploymentModel);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
namespace BotSharp.Abstraction.Routing.Settings;
|
||||
namespace BotSharp.Plugin.AzureOpenAI.Settings;
|
||||
|
||||
public class GPT4Settings
|
||||
{
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
private readonly IServiceProvider _services;
|
||||
private readonly HuggingFaceSettings _settings;
|
||||
private readonly ILogger _logger;
|
||||
private string _model;
|
||||
|
||||
public ChatCompletionProvider(IServiceProvider services,
|
||||
HuggingFaceSettings settings,
|
||||
|
|
@ -69,4 +70,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetModelName(string model)
|
||||
{
|
||||
_model = model;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
private readonly IServiceProvider _services;
|
||||
private readonly ILogger _logger;
|
||||
private readonly LlamaSharpSettings _settings;
|
||||
private string _model;
|
||||
|
||||
public ChatCompletionProvider(IServiceProvider services,
|
||||
ILogger<ChatCompletionProvider> logger,
|
||||
|
|
@ -118,4 +119,9 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetModelName(string model)
|
||||
{
|
||||
_model = model;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
|
|
@ -11,6 +12,10 @@ public class AgentCollection : MongoBase
|
|||
public List<string> Functions { get; set; }
|
||||
public List<AgentResponse> Responses { get; set; }
|
||||
public bool IsPublic { get; set; }
|
||||
public bool AllowRouting { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<RoutingRuleMongoElement> RoutingRules { get; set; }
|
||||
|
||||
public DateTime CreatedTime { get; set; }
|
||||
public DateTime UpdatedTime { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
namespace BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
public class RoutingItemCollection : MongoBase
|
||||
{
|
||||
public Guid AgentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public List<string> RequiredFields { get; set; }
|
||||
public Guid? RedirectTo { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
namespace BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
public class RoutingProfileCollection : MongoBase
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<Guid> AgentIds { get; set; }
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using BotSharp.Abstraction.Routing.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
public class RoutingRuleMongoElement
|
||||
{
|
||||
public string Field { get; set; }
|
||||
public bool Required { get; set; }
|
||||
public Guid? RedirectTo { get; set; }
|
||||
|
||||
public RoutingRuleMongoElement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static RoutingRuleMongoElement ToMongoElement(RoutingRule routingRule)
|
||||
{
|
||||
return new RoutingRuleMongoElement
|
||||
{
|
||||
Field = routingRule.Field,
|
||||
Required = routingRule.Required,
|
||||
RedirectTo = !string.IsNullOrEmpty(routingRule.RedirectTo) ? Guid.Parse(routingRule.RedirectTo) : null
|
||||
};
|
||||
}
|
||||
|
||||
public static RoutingRule ToDomainElement(string agentId, string agentName, RoutingRuleMongoElement rule)
|
||||
{
|
||||
return new RoutingRule
|
||||
{
|
||||
AgentId = agentId,
|
||||
AgentName = agentName,
|
||||
Field = rule.Field,
|
||||
Required = rule.Required,
|
||||
RedirectTo = rule.RedirectTo?.ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -42,10 +42,4 @@ public class MongoDbContext
|
|||
|
||||
public IMongoCollection<UserAgentCollection> UserAgents
|
||||
=> Database.GetCollection<UserAgentCollection>($"{_collectionPrefix}_UserAgents");
|
||||
|
||||
public IMongoCollection<RoutingItemCollection> RoutingItems
|
||||
=> Database.GetCollection<RoutingItemCollection>($"{_collectionPrefix}_RoutingItems");
|
||||
|
||||
public IMongoCollection<RoutingProfileCollection> RoutingProfiles
|
||||
=> Database.GetCollection<RoutingProfileCollection>($"{_collectionPrefix}_RoutingProfiles");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
using BotSharp.Plugin.MongoStorage.Collections;
|
||||
using BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Repository;
|
||||
|
||||
|
|
@ -42,6 +44,12 @@ public class MongoRepository : IBotSharpRepository
|
|||
Functions = x.Functions,
|
||||
Responses = x.Responses,
|
||||
IsPublic = x.IsPublic,
|
||||
Disabled = x.Disabled,
|
||||
AllowRouting = x.AllowRouting,
|
||||
Profiles = x.Profiles,
|
||||
RoutingRules = x.RoutingRules?
|
||||
.Select(r => RoutingRuleMongoElement.ToDomainElement(x.Id.ToString(), x.Name, r))?
|
||||
.ToList() ?? new List<RoutingRule>(),
|
||||
CreatedDateTime = x.CreatedTime,
|
||||
UpdatedDateTime = x.UpdatedTime
|
||||
}).ToList();
|
||||
|
|
@ -206,6 +214,12 @@ public class MongoRepository : IBotSharpRepository
|
|||
Functions = x.Functions,
|
||||
Responses = x.Responses,
|
||||
IsPublic = x.IsPublic,
|
||||
AllowRouting = x.AllowRouting,
|
||||
Disabled = x.Disabled,
|
||||
Profiles = x.Profiles,
|
||||
RoutingRules = x.RoutingRules?
|
||||
.Select(r => RoutingRuleMongoElement.ToMongoElement(r))?
|
||||
.ToList() ?? new List<RoutingRuleMongoElement>(),
|
||||
CreatedTime = x.CreatedDateTime,
|
||||
UpdatedTime = x.UpdatedDateTime
|
||||
}).ToList();
|
||||
|
|
@ -221,6 +235,10 @@ public class MongoRepository : IBotSharpRepository
|
|||
.Set(x => x.Functions, agent.Functions)
|
||||
.Set(x => x.Responses, agent.Responses)
|
||||
.Set(x => x.IsPublic, agent.IsPublic)
|
||||
.Set(x => x.AllowRouting, agent.AllowRouting)
|
||||
.Set(x => x.Disabled, agent.Disabled)
|
||||
.Set(x => x.Profiles, agent.Profiles)
|
||||
.Set(x => x.RoutingRules, agent.RoutingRules)
|
||||
.Set(x => x.CreatedTime, agent.CreatedTime)
|
||||
.Set(x => x.UpdatedTime, agent.UpdatedTime);
|
||||
_dc.Agents.UpdateOne(filter, update, _options);
|
||||
|
|
@ -299,6 +317,18 @@ public class MongoRepository : IBotSharpRepository
|
|||
case AgentField.IsPublic:
|
||||
UpdateAgentIsPublic(agent.Id, agent.IsPublic);
|
||||
break;
|
||||
case AgentField.Disabled:
|
||||
UpdateAgentDisabled(agent.Id, agent.Disabled);
|
||||
break;
|
||||
case AgentField.AllowRouting:
|
||||
UpdateAgentAllowRouting(agent.Id, agent.AllowRouting);
|
||||
break;
|
||||
case AgentField.Profiles:
|
||||
UpdateAgentProfiles(agent.Id, agent.Profiles);
|
||||
break;
|
||||
case AgentField.RoutingRules:
|
||||
UpdateAgentRoutingRules(agent.Id, agent.RoutingRules);
|
||||
break;
|
||||
case AgentField.Instruction:
|
||||
UpdateAgentInstruction(agent.Id, agent.Instruction);
|
||||
break;
|
||||
|
|
@ -354,6 +384,51 @@ public class MongoRepository : IBotSharpRepository
|
|||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentDisabled(string agentId, bool disabled)
|
||||
{
|
||||
var filter = Builders<AgentCollection>.Filter.Eq(x => x.Id, Guid.Parse(agentId));
|
||||
var update = Builders<AgentCollection>.Update
|
||||
.Set(x => x.Disabled, disabled)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentAllowRouting(string agentId, bool allowRouting)
|
||||
{
|
||||
var filter = Builders<AgentCollection>.Filter.Eq(x => x.Id, Guid.Parse(agentId));
|
||||
var update = Builders<AgentCollection>.Update
|
||||
.Set(x => x.AllowRouting, allowRouting)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentProfiles(string agentId, List<string> profiles)
|
||||
{
|
||||
if (profiles.IsNullOrEmpty()) return;
|
||||
|
||||
var filter = Builders<AgentCollection>.Filter.Eq(x => x.Id, Guid.Parse(agentId));
|
||||
var update = Builders<AgentCollection>.Update
|
||||
.Set(x => x.Profiles, profiles)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentRoutingRules(string agentId, List<RoutingRule> rules)
|
||||
{
|
||||
if (rules.IsNullOrEmpty()) return;
|
||||
|
||||
var ruleElements = rules.Select(x => RoutingRuleMongoElement.ToMongoElement(x)).ToList();
|
||||
var filter = Builders<AgentCollection>.Filter.Eq(x => x.Id, Guid.Parse(agentId));
|
||||
var update = Builders<AgentCollection>.Update
|
||||
.Set(x => x.RoutingRules, ruleElements)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentInstruction(string agentId, string instruction)
|
||||
{
|
||||
if (string.IsNullOrEmpty(instruction)) return;
|
||||
|
|
@ -408,6 +483,10 @@ public class MongoRepository : IBotSharpRepository
|
|||
var update = Builders<AgentCollection>.Update
|
||||
.Set(x => x.Name, agent.Name)
|
||||
.Set(x => x.Description, agent.Description)
|
||||
.Set(x => x.Disabled, agent.Disabled)
|
||||
.Set(x => x.AllowRouting, agent.AllowRouting)
|
||||
.Set(x => x.Profiles, agent.Profiles)
|
||||
.Set(x => x.RoutingRules, agent.RoutingRules.Select(x => RoutingRuleMongoElement.ToMongoElement(x)).ToList())
|
||||
.Set(x => x.Instruction, agent.Instruction)
|
||||
.Set(x => x.Templates, agent.Templates)
|
||||
.Set(x => x.Functions, agent.Functions)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class RoutingConversationHook: ConversationHookBase
|
|||
public override async Task AfterCompletion(RoleDialogModel message)
|
||||
{
|
||||
var routerSettings = _services.GetRequiredService<RoutingSettings>();
|
||||
bool saveFlag = (message.CurrentAgentId != routerSettings.RouterId) && (message.CurrentAgentId != routerSettings.ReasonerId);
|
||||
bool saveFlag = message.CurrentAgentId != routerSettings.RouterId;
|
||||
|
||||
if (saveFlag)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<LangVersion>$(LangVersion)</LangVersion>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
|
||||
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
<PackageProjectUrl>https://github.com/Oceania2018/botsharp-channel-weixin</PackageProjectUrl>
|
||||
<Copyright>Apache 2.0</Copyright>
|
||||
<PackageTags>botsharp, wechat, wexin, chatbot</PackageTags>
|
||||
<VersionPrefix>$(PackageVersion)</VersionPrefix>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ public class GetPizzaTypesFn : IFunctionCallback
|
|||
public async Task<bool> Execute(RoleDialogModel message)
|
||||
{
|
||||
message.ExecutionResult = "Pepperoni Pizza, Cheese Pizza, Margherita Pizza";
|
||||
message.ExecutionData = new List<string>
|
||||
{
|
||||
"Pepperoni Pizza",
|
||||
"Cheese Pizza",
|
||||
"Margherita Pizza"
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue