Merge pull request #271 from hchen2020/master

Change planner setting to agent level.
This commit is contained in:
Haiping 2024-01-26 19:18:49 -06:00 committed by GitHub
commit 3ce4f13818
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 64 additions and 53 deletions

View file

@ -53,12 +53,6 @@ public class RoleDialogModel : ITrackableMessage
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public bool StopCompletion { get; set; }
/// <summary>
/// Router routed to a wrong agent.
/// Set this flag as True will force router to re-route current request to a new agent.
/// </summary>
public bool UnmatchedAgent { get; set; }
public FunctionCallFromLlm Instruction { get; set; }
private RoleDialogModel()

View file

@ -11,4 +11,9 @@ public class RuleType
/// Redirect to other agent if data validation failed
/// </summary>
public const string DataValidation = "data-validation";
/// <summary>
/// The planning approach name for next step
/// </summary>
public const string Planner = "planner";
}

View file

@ -27,7 +27,7 @@ public interface IRoutingService
/// <returns></returns>
RoutingRule[] GetRulesByAgentId(string id);
List<RoutingHandlerDef> GetHandlers();
List<RoutingHandlerDef> GetHandlers(Agent router);
void ResetRecursiveCounter();
Task<bool> InvokeAgent(string agentId, List<RoleDialogModel> dialogs);
Task<bool> InvokeFunction(string name, RoleDialogModel message);

View file

@ -2,5 +2,4 @@ namespace BotSharp.Abstraction.Routing.Settings;
public class RoutingSettings
{
public string Planner { get; set; } = string.Empty;
}

View file

@ -4,7 +4,6 @@ using BotSharp.Abstraction.Planning;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Settings;
using BotSharp.Abstraction.Templating;
namespace BotSharp.Core.Planning;

View file

@ -3,7 +3,6 @@ using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Planning;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Settings;
using BotSharp.Abstraction.Templating;
namespace BotSharp.Core.Planning;

View file

@ -63,7 +63,6 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
var response = _dialogs.Last();
inst.Response = response.Content;
inst.UnmatchedAgent = response.UnmatchedAgent;
return true;
}

View file

@ -28,7 +28,7 @@ public class RoutingAgentHook : AgentHookBase
var routing = _services.GetRequiredService<IRoutingService>();
var agents = routing.GetRoutableAgents(_agent.Profiles);
dict["routing_agents"] = agents;
dict["routing_handlers"] = routing.GetHandlers();
dict["routing_handlers"] = routing.GetHandlers(_agent);
return base.OnInstructionLoaded(template, dict);
}
@ -51,13 +51,18 @@ public class RoutingAgentHook : AgentHookBase
user_goal_agent = new
{
type = "string",
description = $"the fixed value is: {_agent.Name}"
description = $"{_agent.Name}"
},
next_action_agent = new
{
type = "string",
description = $"the fixed value is: {redirectAgent.Name}"
}
description = $"{redirectAgent.Name}"
},
reason = new
{
type = "string",
description = $"the reason why you need to fallback to [{redirectAgent.Name}] from [{_agent.Name}]"
},
});
functions.Add(new FunctionDef
{
@ -65,7 +70,13 @@ public class RoutingAgentHook : AgentHookBase
Description = $"If the user's request is beyond your capabilities, you can call this function to handle by other agent ({redirectAgent.Name}).",
Parameters =
{
Properties = JsonSerializer.Deserialize<JsonDocument>(json)
Properties = JsonSerializer.Deserialize<JsonDocument>(json),
Required = new List<string>
{
"user_goal_agent",
"next_action_agent",
"reason"
}
}
});
}

View file

@ -38,17 +38,5 @@ public class RoutingPlugin : IBotSharpPlugin
services.AddScoped<NaivePlanner>();
services.AddScoped<HFPlanner>();
services.AddScoped<SequentialPlanner>();
services.AddScoped<IPlaner>(provider =>
{
var settingService = provider.GetRequiredService<ISettingService>();
var routingSettings = settingService.Bind<RoutingSettings>("Router");
if (routingSettings.Planner == nameof(HFPlanner))
return provider.GetRequiredService<HFPlanner>();
else if (routingSettings.Planner == nameof(SequentialPlanner))
return provider.GetRequiredService<SequentialPlanner>();
else
return provider.GetRequiredService<NaivePlanner>();
});
}
}

View file

@ -0,0 +1,21 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Planning;
using BotSharp.Abstraction.Routing.Enums;
using BotSharp.Core.Planning;
namespace BotSharp.Core.Routing;
public partial class RoutingService
{
public IPlaner GetPlanner(Agent router)
{
var planner = router.RoutingRules.FirstOrDefault(x => x.Type == RuleType.Planner);
if (planner?.Field == nameof(HFPlanner))
return _services.GetRequiredService<HFPlanner>();
else if (planner?.Field == nameof(SequentialPlanner))
return _services.GetRequiredService<SequentialPlanner>();
else
return _services.GetRequiredService<NaivePlanner>();
}
}

View file

@ -57,18 +57,8 @@ public partial class RoutingService
// Call functions
await conversationService.CallFunctions(message);
// Router selected the wrong agent, handle this excluding the agent
if (message.UnmatchedAgent)
{
// Save to memory dialogs
var msg = RoleDialogModel.From(message,
role: AgentRole.Function,
content: message.Content);
msg.UnmatchedAgent = true;
dialogs.Add(msg);
}
// Pass execution result to LLM to get response
else if (!message.StopCompletion)
if (!message.StopCompletion)
{
var routing = _services.GetRequiredService<RoutingContext>();

View file

@ -73,9 +73,10 @@ public partial class RoutingService : IRoutingService
var dialogs = conv.GetDialogHistory();
var context = _services.GetRequiredService<RoutingContext>();
var planner = _services.GetRequiredService<IPlaner>();
var executor = _services.GetRequiredService<IExecutor>();
var planner = GetPlanner(_router);
context.Push(_router.Id);
int loopCount = 0;
@ -85,7 +86,6 @@ public partial class RoutingService : IRoutingService
var conversation = await GetConversationContent(dialogs);
_router.TemplateDict["conversation"] = conversation;
_router.TemplateDict["planner"] = _settings.Planner;
// Get instruction from Planner
var inst = await planner.GetNextInstruction(_router, message.MessageId);
@ -109,9 +109,9 @@ public partial class RoutingService : IRoutingService
return response;
}
public List<RoutingHandlerDef> GetHandlers()
public List<RoutingHandlerDef> GetHandlers(Agent router)
{
var planer = _services.GetRequiredService<IPlaner>();
var planer = GetPlanner(router);
return _services.GetServices<IRoutingHandler>()
.Where(x => x.Planers == null || x.Planers.Contains(planer.GetType().Name))

View file

@ -7,5 +7,12 @@
"updatedDateTime": "2023-08-18T14:39:32.2349686Z",
"iconUrl": "https://cdn.iconscout.com/icon/premium/png-256-thumb/route-1613278-1368497.png",
"disabled": false,
"isPublic": true
"isPublic": true,
"profiles": [ "default" ],
"routingRules": [
{
"type": "planner",
"field": "HFPlanner"
}
]
}

View file

@ -33,9 +33,15 @@ public class AgentController : ControllerBase
public async Task<PagedItems<AgentViewModel>> GetAgents([FromQuery] AgentFilter filter)
{
var pagedAgents = await _agentService.GetAgents(filter);
var items = new List<Agent>();
foreach (var agent in pagedAgents.Items)
{
var renderedAgent = await _agentService.LoadAgent(agent.Id);
items.Add(renderedAgent);
}
return new PagedItems<AgentViewModel>
{
Items = pagedAgents.Items.Select(x => AgentViewModel.FromAgent(x)).ToList(),
Items = items.Select(x => AgentViewModel.FromAgent(x)).ToList(),
Count = pagedAgents.Count
};
}

View file

@ -17,18 +17,13 @@ public class AgentViewModel
public List<FunctionDef> Functions { get; set; }
public List<AgentResponse> Responses { get; set; }
public List<string> Samples { get; set; }
[JsonPropertyName("is_public")]
public bool IsPublic { get; set; }
[JsonPropertyName("is_router")]
public bool IsRouter { get; set; }
[JsonPropertyName("is_host")]
public bool IsHost { get; set; }
[JsonPropertyName("allow_routing")]
public bool AllowRouting { get; set; }
public bool Disabled { get; set; }
[JsonPropertyName("icon_url")]

View file

@ -27,7 +27,6 @@ public class SearchKnowledgesFn : IFunctionCallback
if (string.IsNullOrEmpty(knowledge))
{
message.Content = "Can't find any relevant data in local knowledge base.";
message.UnmatchedAgent = true;
}
return true;

View file

@ -60,7 +60,6 @@
],
"Router": {
"Planner": "NaivePlanner"
},
"Evaluator": {