Support rendering submenu.

This commit is contained in:
Haiping Chen 2024-01-15 15:35:01 -06:00
parent 6286393242
commit 9d698fc79d
9 changed files with 70 additions and 27 deletions

View file

@ -25,5 +25,5 @@ public interface IBotSharpPlugin
void RegisterDI(IServiceCollection services, IConfiguration config); void RegisterDI(IServiceCollection services, IConfiguration config);
PluginMenuDef[] GetMenus() => new PluginMenuDef[0]; bool AttachMenu(List<PluginMenuDef> menu) => true;
} }

View file

@ -6,6 +6,9 @@ public class PluginDef
public string Name { get; set; } public string Name { get; set; }
public string Description { get; set; } public string Description { get; set; }
public string Assembly { get; set; } public string Assembly { get; set; }
[JsonPropertyName("is_core")]
public bool IsCore => Assembly == "BotSharp.Core";
[JsonPropertyName("icon_url")] [JsonPropertyName("icon_url")]
public string? IconUrl { get; set; } public string? IconUrl { get; set; }
@ -17,6 +20,4 @@ public class PluginDef
public IBotSharpPlugin Module { get; set; } public IBotSharpPlugin Module { get; set; }
public bool Enabled { get; set; } public bool Enabled { get; set; }
public PluginMenuDef[] Menus { get; set; }
} }

View file

@ -2,18 +2,36 @@ namespace BotSharp.Abstraction.Plugins.Models;
public class PluginMenuDef public class PluginMenuDef
{ {
[JsonIgnore]
public string Id { get; set; }
public string Label { get; set; } public string Label { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Icon { get; set; } public string? Icon { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Link { get; set; } public string? Link { get; set; }
public bool IsHeader { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? IsHeader { get; set; }
[JsonIgnore]
public int Weight { get; set; } public int Weight { get; set; }
public PluginMenuDef(string lable, string? link = null, string? icon = null, int weight = 0, bool isHeader = false) [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<PluginMenuDef>? SubMenu { get; set; }
public PluginMenuDef(string lable, string? link = null, string? icon = null, int weight = 0)
{ {
Label = lable; Label = lable;
Link = link; Link = link;
Icon = icon; Icon = icon;
Weight = weight; Weight = weight;
IsHeader = isHeader; }
public override string ToString()
{
return $"{Label} {Link} {Weight}";
} }
} }

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.MLTasks; using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Settings; using BotSharp.Abstraction.Settings;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -26,4 +27,20 @@ public class AgentPlugin : IBotSharpPlugin
return settingService.Bind<AgentSettings>("Agent"); return settingService.Bind<AgentSettings>("Agent");
}); });
} }
public bool AttachMenu(List<PluginMenuDef> menu)
{
var section = menu.First(x => x.Label == "Apps");
menu.Add(new PluginMenuDef("Agent", icon: "bx bx-bot", weight: section.Weight + 1)
{
SubMenu = new List<PluginMenuDef>
{
new PluginMenuDef("Router", link: "/page/agent/router"), // icon: "bx bx-map-pin"
new PluginMenuDef("Evaluator", link: "/page/agent/evaluator"), // icon: "bx bx-task"
new PluginMenuDef("Agents", link: "/page/agent"), // icon: "bx bx-bot"
}
});
return true;
}
} }

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Instructs; using BotSharp.Abstraction.Instructs;
using BotSharp.Abstraction.Messaging; using BotSharp.Abstraction.Messaging;
using BotSharp.Abstraction.Planning; using BotSharp.Abstraction.Planning;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Settings; using BotSharp.Abstraction.Settings;
using BotSharp.Abstraction.Templating; using BotSharp.Abstraction.Templating;
using BotSharp.Core.Instructs; using BotSharp.Core.Instructs;
@ -45,4 +46,11 @@ public class ConversationPlugin : IBotSharpPlugin
services.AddScoped<IInstructService, InstructService>(); services.AddScoped<IInstructService, InstructService>();
services.AddScoped<ITokenStatistics, TokenStatistics>(); services.AddScoped<ITokenStatistics, TokenStatistics>();
} }
public bool AttachMenu(List<PluginMenuDef> menu)
{
var section = menu.First(x => x.Label == "Apps");
menu.Add(new PluginMenuDef("Conversation", link: "/page/conversation", icon: "bx bx-conversation", weight: section.Weight + 5));
return true;
}
} }

View file

@ -57,8 +57,7 @@ public class PluginLoader
Description = module.Description, Description = module.Description,
Assembly = assemblyName, Assembly = assemblyName,
IconUrl = module.IconUrl, IconUrl = module.IconUrl,
AgentIds = module.AgentIds, AgentIds = module.AgentIds
Menus = module.GetMenus(),
}); });
Console.Write($"Loaded plugin "); Console.Write($"Loaded plugin ");
Console.Write(name, Color.Green); Console.Write(name, Color.Green);
@ -85,7 +84,7 @@ public class PluginLoader
var config = db.GetPluginConfig(); var config = db.GetPluginConfig();
foreach (var plugin in _plugins) foreach (var plugin in _plugins)
{ {
plugin.Enabled = config.EnabledPlugins.Contains(plugin.Id); plugin.Enabled = plugin.IsCore || config.EnabledPlugins.Contains(plugin.Id);
} }
return _plugins; return _plugins;
} }

View file

@ -4,6 +4,6 @@
"058094a7-4ad3-4284-b94d-ac1373cf63d8", "058094a7-4ad3-4284-b94d-ac1373cf63d8",
"65185362-392c-44fd-a023-95a198824436", "65185362-392c-44fd-a023-95a198824436",
"5b18ca9b-82ed-494b-b121-e3499661edb0", "5b18ca9b-82ed-494b-b121-e3499661edb0",
"6e52d42d-1e23-406b-8599-36af36c83209" "6e52d42d-1e23-406b-8599-36af36c83209"
] ]
} }

View file

@ -26,19 +26,21 @@ public class PluginController : ControllerBase
[HttpGet("/plugin/menu")] [HttpGet("/plugin/menu")]
public List<PluginMenuDef> GetPluginMenu() public List<PluginMenuDef> GetPluginMenu()
{ {
var menus = new List<PluginMenuDef> var menu = new List<PluginMenuDef>
{ {
new PluginMenuDef("Dashboard", link: "/page/dashboard", icon: "bx bx-home-circle", weight: 1), new PluginMenuDef("Dashboard", link: "/page/dashboard", icon: "bx bx-home-circle", weight: 1),
new PluginMenuDef("Agent", isHeader: true, weight: 5), new PluginMenuDef("Apps", weight: 5)
new PluginMenuDef("Router", link: "/page/agent/router", icon: "bx bx-map-pin", weight: 6), {
// new PluginMenuDef("Evaluator", link: "/page/agent/evaluator", icon: "bx bx-task", weight: 7), IsHeader = true,
new PluginMenuDef("Agents", link: "/page/agent", icon: "bx bx-bot", weight: 8), },
new PluginMenuDef("Conversation", isHeader: true, weight: 15), new PluginMenuDef("System", weight: 30)
new PluginMenuDef("Conversations", link: "/page/conversation", icon: "bx bx-conversation", weight: 16), {
new PluginMenuDef("System", isHeader: true, weight: 30), IsHeader = true
},
new PluginMenuDef("Plugins", link: "/page/plugin", icon: "bx bx-plug", weight: 31), new PluginMenuDef("Plugins", link: "/page/plugin", icon: "bx bx-plug", weight: 31),
new PluginMenuDef("Settings", link: "/page/setting", icon: "bx bx-cog", weight: 32), new PluginMenuDef("Settings", link: "/page/setting", icon: "bx bx-cog", weight: 32),
}; };
var loader = _services.GetRequiredService<PluginLoader>(); var loader = _services.GetRequiredService<PluginLoader>();
foreach (var plugin in loader.GetPlugins(_services)) foreach (var plugin in loader.GetPlugins(_services))
{ {
@ -46,10 +48,10 @@ public class PluginController : ControllerBase
{ {
continue; continue;
} }
menus.AddRange(plugin.Menus); plugin.Module.AttachMenu(menu);
} }
menus = menus.OrderBy(x => x.Weight).ToList(); menu = menu.OrderBy(x => x.Weight).ToList();
return menus; return menu;
} }
[HttpPost("/plugin/{id}/enable")] [HttpPost("/plugin/{id}/enable")]

View file

@ -27,12 +27,10 @@ public class KnowledgeBasePlugin : IBotSharpPlugin
services.AddSingleton<IPdf2TextConverter, PigPdf2TextConverter>(); services.AddSingleton<IPdf2TextConverter, PigPdf2TextConverter>();
} }
public PluginMenuDef[] GetMenus() public bool AttachMenu(List<PluginMenuDef> menu)
{ {
return new PluginMenuDef[] var section = menu.First(x => x.Label == "Apps");
{ menu.Add(new PluginMenuDef("Knowledge Base", link: "/page/knowledge-base", icon: "bx bx-book-open", weight: section.Weight + 1));
new PluginMenuDef("RAG", isHeader: true, weight: 20), return true;
new PluginMenuDef("Knowledge Base", link: "/page/knowledge-base", icon: "bx bx-book-open", weight: 21),
};
} }
} }