< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Generators.AgentFrameworkFunctionRegistryGenerator
Assembly: NexusLabs.Needlr.AgentFramework.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Generators/AgentFrameworkFunctionRegistryGenerator.cs
Line coverage
100%
Covered lines: 197
Uncovered lines: 0
Coverable lines: 197
Total lines: 351
Line coverage: 100%
Branch coverage
94%
Covered branches: 17
Total branches: 18
Branch coverage: 94.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Initialize(...)100%11100%
ExecuteAll(...)87.5%88100%
BuildGraphDataByName(...)100%1010100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Generators/AgentFrameworkFunctionRegistryGenerator.cs

#LineLine coverage
 1// Copyright (c) NexusLabs. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.Immutable;
 7using System.Linq;
 8using System.Text;
 9using System.Threading;
 10
 11using Microsoft.CodeAnalysis;
 12using Microsoft.CodeAnalysis.CSharp.Syntax;
 13using Microsoft.CodeAnalysis.Text;
 14
 15namespace NexusLabs.Needlr.AgentFramework.Generators;
 16
 17/// <summary>
 18/// Source generator for Microsoft Agent Framework functions.
 19/// Discovers classes with [AgentFunction] methods and generates a compile-time type registry.
 20/// Also discovers classes with [AgentFunctionGroup] attributes and generates a group registry.
 21/// Also discovers classes with [NeedlrAiAgent] attributes and generates an agent registry.
 22/// Always emits a [ModuleInitializer] that auto-registers all discovered types with
 23/// AgentFrameworkGeneratedBootstrap on assembly load.
 24/// </summary>
 25[Generator]
 26public class AgentFrameworkFunctionRegistryGenerator : IIncrementalGenerator
 27{
 28    private const string NeedlrAiAgentAttributeName = "NexusLabs.Needlr.AgentFramework.NeedlrAiAgentAttribute";
 29    private const string AgentHandoffsToAttributeName = "NexusLabs.Needlr.AgentFramework.AgentHandoffsToAttribute";
 30    private const string AgentGroupChatMemberAttributeName = "NexusLabs.Needlr.AgentFramework.AgentGroupChatMemberAttrib
 31    private const string AgentSequenceMemberAttributeName = "NexusLabs.Needlr.AgentFramework.AgentSequenceMemberAttribut
 32    private const string WorkflowRunTerminationConditionAttributeName = "NexusLabs.Needlr.AgentFramework.WorkflowRunTerm
 33    private const string ProgressSinksAttributeName = "NexusLabs.Needlr.AgentFramework.ProgressSinksAttribute";
 34    private const string AgentGraphEdgeAttributeName = "NexusLabs.Needlr.AgentFramework.AgentGraphEdgeAttribute";
 35    private const string AgentGraphEntryAttributeName = "NexusLabs.Needlr.AgentFramework.AgentGraphEntryAttribute";
 36    private const string AgentGraphNodeAttributeName = "NexusLabs.Needlr.AgentFramework.AgentGraphNodeAttribute";
 37    private const string AgentGraphReducerAttributeName = "NexusLabs.Needlr.AgentFramework.AgentGraphReducerAttribute";
 38
 39    public void Initialize(IncrementalGeneratorInitializationContext context)
 40    {
 41        // [AgentFunction] method-bearing classes → AgentFrameworkFunctionRegistry
 10142        var functionClasses = context.SyntaxProvider
 10143            .CreateSyntaxProvider(
 11167844                predicate: static (s, _) => s is ClassDeclarationSyntax,
 196645                transform: static (ctx, ct) => AgentDiscoveryHelper.GetAgentFunctionTypeInfo(ctx, ct))
 206746            .Where(static m => m is not null);
 47
 48        // [AgentFunctionGroup] class-level annotations → AgentFrameworkFunctionGroupRegistry
 10149        var groupClasses = context.SyntaxProvider
 10150            .CreateSyntaxProvider(
 11167851                predicate: static (s, _) => s is ClassDeclarationSyntax,
 196652                transform: static (ctx, ct) => AgentDiscoveryHelper.GetAgentFunctionGroupEntries(ctx, ct))
 206753            .Where(static arr => arr.Length > 0);
 54
 55        // [NeedlrAiAgent] declared agent types → AgentRegistry + partial companions
 10156        var agentClasses = context.SyntaxProvider
 10157            .ForAttributeWithMetadataName(
 10158                NeedlrAiAgentAttributeName,
 10759                predicate: static (s, _) => s is ClassDeclarationSyntax,
 10760                transform: static (ctx, ct) => AgentDiscoveryHelper.GetNeedlrAiAgentTypeInfo(ctx, ct))
 20861            .Where(static m => m is not null);
 62
 63        // [AgentHandoffsTo] annotations → handoff topology registry
 10164        var handoffEntries = context.SyntaxProvider
 10165            .ForAttributeWithMetadataName(
 10166                AgentHandoffsToAttributeName,
 567                predicate: static (s, _) => s is ClassDeclarationSyntax,
 568                transform: static (ctx, ct) => AgentDiscoveryHelper.GetHandoffEntries(ctx, ct))
 10669            .Where(static arr => arr.Length > 0);
 70
 71        // [AgentGroupChatMember] annotations → group chat registry
 10172        var groupChatEntries = context.SyntaxProvider
 10173            .ForAttributeWithMetadataName(
 10174                AgentGroupChatMemberAttributeName,
 875                predicate: static (s, _) => s is ClassDeclarationSyntax,
 876                transform: static (ctx, ct) => AgentDiscoveryHelper.GetGroupChatEntries(ctx, ct))
 10977            .Where(static arr => arr.Length > 0);
 78
 79        // [AgentSequenceMember] annotations → sequential pipeline registry
 10180        var sequenceEntries = context.SyntaxProvider
 10181            .ForAttributeWithMetadataName(
 10182                AgentSequenceMemberAttributeName,
 2483                predicate: static (s, _) => s is ClassDeclarationSyntax,
 2484                transform: static (ctx, ct) => AgentDiscoveryHelper.GetSequenceEntries(ctx, ct))
 12585            .Where(static arr => arr.Length > 0);
 86
 87        // [WorkflowRunTerminationCondition] → termination conditions per agent
 10188        var terminationConditionEntries = context.SyntaxProvider
 10189            .ForAttributeWithMetadataName(
 10190                WorkflowRunTerminationConditionAttributeName,
 891                predicate: static (s, _) => s is ClassDeclarationSyntax,
 892                transform: static (ctx, ct) => AgentDiscoveryHelper.GetTerminationConditionEntries(ctx, ct))
 10993            .Where(static arr => arr.Length > 0);
 94
 95        // [ProgressSinks] → per-agent progress sink declarations
 10196        var progressSinksEntries = context.SyntaxProvider
 10197            .ForAttributeWithMetadataName(
 10198                ProgressSinksAttributeName,
 499                predicate: static (s, _) => s is ClassDeclarationSyntax,
 4100                transform: static (ctx, ct) => AgentDiscoveryHelper.GetProgressSinksEntries(ctx, ct))
 105101            .Where(static arr => arr.Length > 0);
 102
 103        // [AgentGraphEdge] annotations → graph edge topology
 101104        var graphEdgeEntries = context.SyntaxProvider
 101105            .ForAttributeWithMetadataName(
 101106                AgentGraphEdgeAttributeName,
 23107                predicate: static (s, _) => s is ClassDeclarationSyntax,
 19108                transform: static (ctx, ct) => GraphDiscoveryHelper.GetGraphEdgeEntries(ctx, ct))
 120109            .Where(static arr => arr.Length > 0);
 110
 111        // [AgentGraphEntry] annotations → graph entry points
 101112        var graphEntryPointEntries = context.SyntaxProvider
 101113            .ForAttributeWithMetadataName(
 101114                AgentGraphEntryAttributeName,
 21115                predicate: static (s, _) => s is ClassDeclarationSyntax,
 21116                transform: static (ctx, ct) => GraphDiscoveryHelper.GetGraphEntryPointEntries(ctx, ct))
 122117            .Where(static arr => arr.Length > 0);
 118
 119        // [AgentGraphNode] annotations → graph node join modes
 101120        var graphNodeEntries = context.SyntaxProvider
 101121            .ForAttributeWithMetadataName(
 101122                AgentGraphNodeAttributeName,
 2123                predicate: static (s, _) => s is ClassDeclarationSyntax,
 2124                transform: static (ctx, ct) => GraphDiscoveryHelper.GetGraphNodeEntries(ctx, ct))
 103125            .Where(static arr => arr.Length > 0);
 126
 127        // [AgentGraphReducer] annotations → graph reducer metadata
 101128        var graphReducerEntries = context.SyntaxProvider
 101129            .ForAttributeWithMetadataName(
 101130                AgentGraphReducerAttributeName,
 3131                predicate: static (s, _) => s is ClassDeclarationSyntax,
 3132                transform: static (ctx, ct) => GraphDiscoveryHelper.GetGraphReducerEntries(ctx, ct))
 104133            .Where(static arr => arr.Length > 0);
 134
 135        // Unified output: all pipelines combined with compilation metadata and build config.
 136        // Always emits all registries + [ModuleInitializer] bootstrap, even when empty.
 101137        var combined = functionClasses.Collect()
 101138            .Combine(groupClasses.Collect())
 101139            .Combine(agentClasses.Collect())
 101140            .Combine(handoffEntries.Collect())
 101141            .Combine(groupChatEntries.Collect())
 101142            .Combine(sequenceEntries.Collect())
 101143            .Combine(terminationConditionEntries.Collect())
 101144            .Combine(progressSinksEntries.Collect())
 101145            .Combine(graphEdgeEntries.Collect())
 101146            .Combine(graphEntryPointEntries.Collect())
 101147            .Combine(graphNodeEntries.Collect())
 101148            .Combine(graphReducerEntries.Collect())
 101149            .Combine(context.CompilationProvider)
 101150            .Combine(context.AnalyzerConfigOptionsProvider);
 151
 101152        context.RegisterSourceOutput(combined,
 101153            static (spc, data) =>
 101154            {
 101155                var (((((((((((((functionData, groupData), agentData), handoffData), groupChatData), sequenceData), term
 101156                ExecuteAll(functionData, groupData, agentData, handoffData, groupChatData, sequenceData, terminationData
 202157            });
 101158    }
 159
 160    private static void ExecuteAll(
 161        ImmutableArray<AgentFunctionTypeInfo?> functionData,
 162        ImmutableArray<ImmutableArray<AgentFunctionGroupEntry>> groupData,
 163        ImmutableArray<NeedlrAiAgentTypeInfo?> agentData,
 164        ImmutableArray<ImmutableArray<HandoffEntry>> handoffData,
 165        ImmutableArray<ImmutableArray<GroupChatEntry>> groupChatData,
 166        ImmutableArray<ImmutableArray<SequenceEntry>> sequenceData,
 167        ImmutableArray<ImmutableArray<TerminationConditionEntry>> terminationData,
 168        ImmutableArray<ImmutableArray<ProgressSinksEntry>> progressSinksData,
 169        ImmutableArray<ImmutableArray<GraphEdgeEntry>> graphEdgeData,
 170        ImmutableArray<ImmutableArray<GraphEntryPointEntry>> graphEntryData,
 171        ImmutableArray<ImmutableArray<GraphNodeEntry>> graphNodeData,
 172        ImmutableArray<ImmutableArray<GraphReducerEntry>> graphReducerData,
 173        Compilation compilation,
 174        Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptionsProvider configOptions,
 175        SourceProductionContext spc)
 176    {
 101177        var assemblyName = compilation.AssemblyName ?? "UnknownAssembly";
 101178        var safeAssemblyName = AgentDiscoveryHelper.SanitizeIdentifier(assemblyName);
 179
 101180        var validFunctionTypes = functionData
 20181            .Where(t => t.HasValue)
 20182            .Select(t => t!.Value)
 101183            .ToList();
 184
 115185        var allGroupEntries = groupData.SelectMany(a => a).ToList();
 101186        var groupedByName = allGroupEntries
 14187            .GroupBy(e => e.GroupName)
 141188            .ToDictionary(g => g.Key, g => g.Select(e => e.TypeName).Distinct().ToList());
 189
 101190        var validAgentTypes = agentData
 107191            .Where(t => t.HasValue)
 107192            .Select(t => t!.Value)
 101193            .ToList();
 194
 106195        var allHandoffEntries = handoffData.SelectMany(a => a).ToList();
 101196        var handoffByInitialAgent = allHandoffEntries
 5197            .GroupBy(e => (e.InitialAgentTypeName, e.InitialAgentClassName))
 101198            .ToDictionary(
 5199                g => g.Key,
 111200                g => g.Select(e => (e.TargetAgentTypeName, e.HandoffReason)).ToList());
 201
 109202        var allGroupChatEntries = groupChatData.SelectMany(a => a).ToList();
 101203        var groupChatByGroupName = allGroupChatEntries
 8204            .GroupBy(e => e.GroupName)
 101205            .ToDictionary(
 4206                g => g.Key,
 12207                g => g.OrderBy(e => e.Order)
 8208                    .ThenBy(e => e.AgentTypeName, StringComparer.Ordinal)
 8209                    .Select(e => e.AgentTypeName)
 105210                    .Distinct()
 105211                    .ToList());
 212
 125213        var allSequenceEntries = sequenceData.SelectMany(a => a).ToList();
 101214        var sequenceByPipelineName = allSequenceEntries
 24215            .GroupBy(e => e.PipelineName)
 101216            .ToDictionary(
 13217                g => g.Key,
 162218                g => g.OrderBy(e => e.Order).Select(e => e.AgentTypeName).ToList());
 219
 101220        var conditionsByAgentTypeName = terminationData
 8221            .SelectMany(a => a)
 8222            .GroupBy(e => e.AgentTypeName)
 117223            .ToDictionary(g => g.Key, g => g.ToList());
 224
 101225        var progressSinksByAgent = progressSinksData
 4226            .SelectMany(a => a)
 109227            .ToDictionary(e => e.AgentClassName, e => e.SinkTypeFQNs);
 228
 120229        var allGraphEdges = graphEdgeData.SelectMany(a => a).ToList();
 122230        var allGraphEntryPoints = graphEntryData.SelectMany(a => a).ToList();
 103231        var allGraphNodes = graphNodeData.SelectMany(a => a).ToList();
 104232        var allGraphReducers = graphReducerData.SelectMany(a => a).ToList();
 233
 101234        var graphDataByName = BuildGraphDataByName(allGraphEdges, allGraphEntryPoints, allGraphNodes, allGraphReducers);
 235
 236        // Always emit all registries (may be empty) and the bootstrap
 101237        spc.AddSource("AgentFrameworkFunctions.g.cs",
 101238            SourceText.From(RegistryCodeGenerator.GenerateRegistrySource(validFunctionTypes, safeAssemblyName), Encoding
 239
 101240        spc.AddSource("AgentFrameworkFunctionGroups.g.cs",
 101241            SourceText.From(RegistryCodeGenerator.GenerateGroupRegistrySource(groupedByName, safeAssemblyName), Encoding
 242
 101243        spc.AddSource("AgentRegistry.g.cs",
 101244            SourceText.From(RegistryCodeGenerator.GenerateAgentRegistrySource(validAgentTypes, safeAssemblyName), Encodi
 245
 101246        spc.AddSource("AgentHandoffTopologyRegistry.g.cs",
 101247            SourceText.From(RegistryCodeGenerator.GenerateHandoffTopologyRegistrySource(handoffByInitialAgent, safeAssem
 248
 101249        spc.AddSource("AgentGroupChatRegistry.g.cs",
 101250            SourceText.From(RegistryCodeGenerator.GenerateGroupChatRegistrySource(groupChatByGroupName, safeAssemblyName
 251
 101252        spc.AddSource("AgentSequentialTopologyRegistry.g.cs",
 101253            SourceText.From(RegistryCodeGenerator.GenerateSequentialTopologyRegistrySource(sequenceByPipelineName, safeA
 254
 101255        spc.AddSource("AgentGraphTopologyRegistry.g.cs",
 101256            SourceText.From(RegistryCodeGenerator.GenerateGraphTopologyRegistrySource(graphDataByName, safeAssemblyName)
 257
 101258        spc.AddSource("NeedlrAgentFrameworkBootstrap.g.cs",
 101259            SourceText.From(BootstrapCodeGenerator.GenerateBootstrapSource(safeAssemblyName), Encoding.UTF8));
 260
 101261        spc.AddSource("WorkflowFactoryExtensions.g.cs",
 101262            SourceText.From(ExtensionsCodeGenerator.GenerateWorkflowFactoryExtensionsSource(
 101263                handoffByInitialAgent, groupChatByGroupName, sequenceByPipelineName,
 101264                conditionsByAgentTypeName, graphDataByName, safeAssemblyName), Encoding.UTF8));
 265
 101266        spc.AddSource("AgentFactoryExtensions.g.cs",
 101267            SourceText.From(ExtensionsCodeGenerator.GenerateAgentFactoryExtensionsSource(validAgentTypes, progressSinksB
 268
 101269        spc.AddSource("AgentTopologyConstants.g.cs",
 101270            SourceText.From(ExtensionsCodeGenerator.GenerateAgentTopologyConstantsSource(validAgentTypes, allGroupEntrie
 271
 101272        spc.AddSource("AgentFrameworkSyringeExtensions.g.cs",
 101273            SourceText.From(ExtensionsCodeGenerator.GenerateSyringeExtensionsSource(allGroupEntries, safeAssemblyName), 
 274
 101275        if (progressSinksByAgent.Count > 0)
 276        {
 3277            spc.AddSource("GeneratedProgressSinkRegistrations.g.cs",
 3278                SourceText.From(ExtensionsCodeGenerator.GenerateProgressSinkRegistrationSource(progressSinksByAgent, saf
 279        }
 280
 101281        spc.AddSource("GeneratedAIFunctionProvider.g.cs",
 101282            SourceText.From(AIFunctionProviderCodeGenerator.GenerateAIFunctionProviderSource(validFunctionTypes, safeAss
 283
 101284        configOptions.GlobalOptions.TryGetValue("build_property.NeedlrDiagnostics", out var diagValue);
 101285        if (string.Equals(diagValue, "true", StringComparison.OrdinalIgnoreCase))
 286        {
 6287            var mermaid = TopologyGraphCodeGenerator.GenerateMermaidDiagram(handoffByInitialAgent, groupChatByGroupName,
 288
 6289            spc.AddSource("AgentTopologyGraph.g.cs",
 6290                SourceText.From(TopologyGraphCodeGenerator.GenerateTopologyGraphSource(mermaid, safeAssemblyName), Encod
 291        }
 292
 293        // Partial companions for [NeedlrAiAgent] classes declared as partial
 331294        foreach (var agentType in validAgentTypes.Where(a => a.IsPartial))
 295        {
 11296            var safeTypeName = agentType.TypeName
 11297                .Replace("global::", "")
 11298                .Replace(".", "_")
 11299                .Replace("<", "_")
 11300                .Replace(">", "_");
 301
 11302            spc.AddSource($"{safeTypeName}.NeedlrAiAgent.g.cs",
 11303                SourceText.From(BootstrapCodeGenerator.GeneratePartialCompanionSource(agentType, groupedByName), Encodin
 304        }
 101305    }
 306
 307    private static Dictionary<string, GraphData> BuildGraphDataByName(
 308        List<GraphEdgeEntry> allEdges,
 309        List<GraphEntryPointEntry> allEntryPoints,
 310        List<GraphNodeEntry> allNodes,
 311        List<GraphReducerEntry> allReducers)
 312    {
 101313        var graphNames = new HashSet<string>(StringComparer.Ordinal);
 271314        foreach (var e in allEdges) graphNames.Add(e.GraphName);
 265315        foreach (var e in allEntryPoints) graphNames.Add(e.GraphName);
 208316        foreach (var e in allNodes) graphNames.Add(e.GraphName);
 211317        foreach (var e in allReducers) graphNames.Add(e.GraphName);
 318
 101319        var result = new Dictionary<string, GraphData>(StringComparer.Ordinal);
 244320        foreach (var name in graphNames)
 321        {
 21322            result[name] = new GraphData(
 25323                allEdges.Where(e => string.Equals(e.GraphName, name, StringComparison.Ordinal)).ToList(),
 23324                allEntryPoints.Where(e => string.Equals(e.GraphName, name, StringComparison.Ordinal)).ToList(),
 2325                allNodes.Where(e => string.Equals(e.GraphName, name, StringComparison.Ordinal)).ToList(),
 24326                allReducers.Where(e => string.Equals(e.GraphName, name, StringComparison.Ordinal)).ToList());
 327        }
 328
 101329        return result;
 330    }
 331}
 332
 333internal sealed class GraphData
 334{
 335    public GraphData(
 336        List<GraphEdgeEntry> edges,
 337        List<GraphEntryPointEntry> entryPoints,
 338        List<GraphNodeEntry> nodes,
 339        List<GraphReducerEntry> reducers)
 340    {
 341        Edges = edges;
 342        EntryPoints = entryPoints;
 343        Nodes = nodes;
 344        Reducers = reducers;
 345    }
 346
 347    public List<GraphEdgeEntry> Edges { get; }
 348    public List<GraphEntryPointEntry> EntryPoints { get; }
 349    public List<GraphNodeEntry> Nodes { get; }
 350    public List<GraphReducerEntry> Reducers { get; }
 351}

Methods/Properties

Initialize(Microsoft.CodeAnalysis.IncrementalGeneratorInitializationContext)
ExecuteAll(System.Collections.Immutable.ImmutableArray`1<System.Nullable`1<NexusLabs.Needlr.AgentFramework.Generators.AgentFunctionTypeInfo>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.AgentFunctionGroupEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Nullable`1<NexusLabs.Needlr.AgentFramework.Generators.NeedlrAiAgentTypeInfo>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.HandoffEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.GroupChatEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.SequenceEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.TerminationConditionEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.ProgressSinksEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.GraphEdgeEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.GraphEntryPointEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.GraphNodeEntry>>,System.Collections.Immutable.ImmutableArray`1<System.Collections.Immutable.ImmutableArray`1<NexusLabs.Needlr.AgentFramework.Generators.GraphReducerEntry>>,Microsoft.CodeAnalysis.Compilation,Microsoft.CodeAnalysis.Diagnostics.AnalyzerConfigOptionsProvider,Microsoft.CodeAnalysis.SourceProductionContext)
BuildGraphDataByName(System.Collections.Generic.List`1<NexusLabs.Needlr.AgentFramework.Generators.GraphEdgeEntry>,System.Collections.Generic.List`1<NexusLabs.Needlr.AgentFramework.Generators.GraphEntryPointEntry>,System.Collections.Generic.List`1<NexusLabs.Needlr.AgentFramework.Generators.GraphNodeEntry>,System.Collections.Generic.List`1<NexusLabs.Needlr.AgentFramework.Generators.GraphReducerEntry>)