112 lines
3.7 KiB
C#
112 lines
3.7 KiB
C#
using MAF1.PluginContract;
|
|
using MAF1.Web;
|
|
|
|
namespace MAF1.Plugins;
|
|
|
|
public sealed class NodeCatalogSnapshot
|
|
{
|
|
public string PluginsRoot { get; init; } = "";
|
|
public List<AgentTypeInfo> System { get; init; } = [];
|
|
public List<AgentTypeInfo> Plugins { get; init; } = [];
|
|
public List<AgentTypeInfo> Nodes { get; init; } = [];
|
|
public List<CatalogIssue> Issues { get; init; } = [];
|
|
public IReadOnlyList<LoadedPlugin> LoadedPlugins { get; init; } = [];
|
|
}
|
|
|
|
public sealed class NodeCatalogService(PluginScanner scanner)
|
|
{
|
|
public NodeCatalogSnapshot Load()
|
|
{
|
|
PluginScanResult scan = scanner.Scan();
|
|
List<CatalogIssue> issues = [.. scan.Issues];
|
|
List<AgentTypeInfo> system = AgentCatalog.SystemNodes
|
|
.Select(Clone)
|
|
.ToList();
|
|
foreach (AgentTypeInfo item in system)
|
|
{
|
|
item.Origin = "system";
|
|
}
|
|
|
|
Dictionary<string, AgentTypeInfo> systemByType = system.ToDictionary(n => n.Type, StringComparer.OrdinalIgnoreCase);
|
|
List<AgentTypeInfo> plugins = [];
|
|
foreach (LoadedPlugin plugin in scan.Plugins)
|
|
{
|
|
AgentTypeInfo info = ToTypeInfo(plugin);
|
|
if (systemByType.ContainsKey(info.Type))
|
|
{
|
|
issues.Add(new CatalogIssue
|
|
{
|
|
Level = "info",
|
|
Source = info.Type,
|
|
Message = $"插件 `{info.Type}` 覆盖了同名系统节点,画布运行将走插件进程。",
|
|
});
|
|
systemByType[info.Type].Overridden = true;
|
|
}
|
|
|
|
plugins.Add(info);
|
|
}
|
|
|
|
Dictionary<string, AgentTypeInfo> merged = systemByType
|
|
.ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase);
|
|
foreach (AgentTypeInfo plugin in plugins)
|
|
{
|
|
merged[plugin.Type] = plugin;
|
|
}
|
|
|
|
return new NodeCatalogSnapshot
|
|
{
|
|
PluginsRoot = scan.Root,
|
|
System = system,
|
|
Plugins = plugins,
|
|
Nodes = merged.Values.OrderBy(n => n.Origin).ThenBy(n => n.Name).ToList(),
|
|
Issues = issues,
|
|
LoadedPlugins = scan.Plugins,
|
|
};
|
|
}
|
|
|
|
public LoadedPlugin? FindPlugin(string type)
|
|
=> Load().LoadedPlugins.FirstOrDefault(p => p.Manifest.Id.Equals(type, StringComparison.OrdinalIgnoreCase));
|
|
|
|
private static AgentTypeInfo ToTypeInfo(LoadedPlugin plugin)
|
|
{
|
|
PluginManifest manifest = plugin.Manifest;
|
|
return new AgentTypeInfo
|
|
{
|
|
Type = manifest.Id,
|
|
Name = string.IsNullOrWhiteSpace(manifest.Name) ? manifest.Id : manifest.Name,
|
|
Description = manifest.Description,
|
|
Origin = "plugin",
|
|
Version = manifest.Version,
|
|
Folder = plugin.FolderName,
|
|
Inputs = manifest.Inputs.Select(ToPort).ToList(),
|
|
Outputs = manifest.Outputs.Select(ToPort).ToList(),
|
|
Credentials = manifest.Credentials,
|
|
};
|
|
}
|
|
|
|
private static PortInfo ToPort(PluginPort port)
|
|
=> new()
|
|
{
|
|
Name = port.Name,
|
|
Type = port.Type,
|
|
Description = port.Description,
|
|
Required = port.Required,
|
|
};
|
|
|
|
private static AgentTypeInfo Clone(AgentTypeInfo source)
|
|
=> new()
|
|
{
|
|
Type = source.Type,
|
|
Name = source.Name,
|
|
Description = source.Description,
|
|
Origin = source.Origin,
|
|
Version = source.Version,
|
|
Folder = source.Folder,
|
|
Overridden = source.Overridden,
|
|
Handler = source.Handler,
|
|
Inputs = source.Inputs,
|
|
Outputs = source.Outputs,
|
|
Credentials = source.Credentials,
|
|
};
|
|
}
|