| | | 1 | | using Microsoft.CodeAnalysis; |
| | | 2 | | |
| | | 3 | | namespace NexusLabs.Needlr.AgentFramework.Analyzers; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Contains diagnostic descriptors for all Needlr Agent Framework analyzers. |
| | | 7 | | /// </summary> |
| | | 8 | | public static class MafDiagnosticDescriptors |
| | | 9 | | { |
| | | 10 | | private const string Category = "NexusLabs.Needlr.AgentFramework"; |
| | | 11 | | private const string HelpLinkBase = "https://github.com/nexus-labs/needlr/blob/main/docs/analyzers/"; |
| | | 12 | | |
| | | 13 | | /// <summary> |
| | | 14 | | /// NDLRMAF001: <c>[AgentHandoffsTo(typeof(X))]</c> target type X is not decorated with <c>[NeedlrAiAgent]</c>. |
| | | 15 | | /// </summary> |
| | 1 | 16 | | public static readonly DiagnosticDescriptor HandoffsToTargetNotNeedlrAgent = new( |
| | 1 | 17 | | id: MafDiagnosticIds.HandoffsToTargetNotNeedlrAgent, |
| | 1 | 18 | | title: "[AgentHandoffsTo] target type is not a declared agent", |
| | 1 | 19 | | messageFormat: "'{0}' is referenced as a handoff target but is not decorated with [NeedlrAiAgent]. Handoff targe |
| | 1 | 20 | | category: Category, |
| | 1 | 21 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 22 | | isEnabledByDefault: true, |
| | 1 | 23 | | description: "Types used as handoff targets in [AgentHandoffsTo] must also be decorated with [NeedlrAiAgent] so |
| | 1 | 24 | | helpLinkUri: HelpLinkBase + "NDLRMAF001.md"); |
| | | 25 | | |
| | | 26 | | /// <summary> |
| | | 27 | | /// NDLRMAF002: <c>[AgentGroupChatMember("g")]</c> group "g" has fewer than two members. |
| | | 28 | | /// </summary> |
| | 1 | 29 | | public static readonly DiagnosticDescriptor GroupChatTooFewMembers = new( |
| | 1 | 30 | | id: MafDiagnosticIds.GroupChatTooFewMembers, |
| | 1 | 31 | | title: "Group chat has fewer than two members", |
| | 1 | 32 | | messageFormat: "Group chat '{0}' has only {1} member(s) in this compilation. A group chat requires at least two |
| | 1 | 33 | | category: Category, |
| | 1 | 34 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 35 | | isEnabledByDefault: true, |
| | 1 | 36 | | description: "IWorkflowFactory.CreateGroupChatWorkflow() throws at runtime when fewer than two agents are regist |
| | 1 | 37 | | helpLinkUri: HelpLinkBase + "NDLRMAF002.md", |
| | 1 | 38 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 39 | | |
| | | 40 | | /// <summary> |
| | | 41 | | /// NDLRMAF003: A class has <c>[AgentHandoffsTo]</c> but is not decorated with <c>[NeedlrAiAgent]</c>. |
| | | 42 | | /// </summary> |
| | 1 | 43 | | public static readonly DiagnosticDescriptor HandoffsToSourceNotNeedlrAgent = new( |
| | 1 | 44 | | id: MafDiagnosticIds.HandoffsToSourceNotNeedlrAgent, |
| | 1 | 45 | | title: "[AgentHandoffsTo] source class is not a declared agent", |
| | 1 | 46 | | messageFormat: "'{0}' has [AgentHandoffsTo] but is not decorated with [NeedlrAiAgent]. The source agent of a han |
| | 1 | 47 | | category: Category, |
| | 1 | 48 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 49 | | isEnabledByDefault: true, |
| | 1 | 50 | | description: "The class that carries [AgentHandoffsTo] is the initial agent of a handoff workflow and must also |
| | 1 | 51 | | helpLinkUri: HelpLinkBase + "NDLRMAF003.md"); |
| | | 52 | | |
| | | 53 | | /// <summary> |
| | | 54 | | /// NDLRMAF004: A cyclic handoff chain was detected. |
| | | 55 | | /// </summary> |
| | 1 | 56 | | public static readonly DiagnosticDescriptor CyclicHandoffChain = new( |
| | 1 | 57 | | id: MafDiagnosticIds.CyclicHandoffChain, |
| | 1 | 58 | | title: "Cyclic handoff chain detected", |
| | 1 | 59 | | messageFormat: "'{0}' participates in a cyclic handoff chain: {1}. This may cause infinite routing loops at runt |
| | 1 | 60 | | category: Category, |
| | 1 | 61 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 62 | | isEnabledByDefault: true, |
| | 1 | 63 | | description: "A handoff cycle exists where an agent can eventually hand off back to itself. While MAF may handle |
| | 1 | 64 | | helpLinkUri: HelpLinkBase + "NDLRMAF004.md", |
| | 1 | 65 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 66 | | |
| | | 67 | | /// <summary> |
| | | 68 | | /// NDLRMAF005: An agent declares a FunctionGroups entry with no matching [AgentFunctionGroup] class. |
| | | 69 | | /// </summary> |
| | 1 | 70 | | public static readonly DiagnosticDescriptor UnresolvedFunctionGroupReference = new( |
| | 1 | 71 | | id: MafDiagnosticIds.UnresolvedFunctionGroupReference, |
| | 1 | 72 | | title: "FunctionGroups references an unregistered group name", |
| | 1 | 73 | | messageFormat: "'{0}' declares FunctionGroups entry '{1}' but no class decorated with [AgentFunctionGroup(\"{1}\ |
| | 1 | 74 | | category: Category, |
| | 1 | 75 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 76 | | isEnabledByDefault: true, |
| | 1 | 77 | | description: "When an agent declares FunctionGroups = new[] { \"name\" }, a class with [AgentFunctionGroup(\"nam |
| | 1 | 78 | | helpLinkUri: HelpLinkBase + "NDLRMAF005.md", |
| | 1 | 79 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 80 | | |
| | | 81 | | /// <summary> |
| | | 82 | | /// NDLRMAF006: Duplicate Order value within the same [AgentSequenceMember] pipeline. |
| | | 83 | | /// </summary> |
| | 1 | 84 | | public static readonly DiagnosticDescriptor DuplicateSequenceOrder = new( |
| | 1 | 85 | | id: MafDiagnosticIds.DuplicateSequenceOrder, |
| | 1 | 86 | | title: "Duplicate Order value in sequential pipeline", |
| | 1 | 87 | | messageFormat: "Pipeline '{0}' has a duplicate Order value ({1}) on '{2}'. Each agent in a sequential pipeline m |
| | 1 | 88 | | category: Category, |
| | 1 | 89 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 90 | | isEnabledByDefault: true, |
| | 1 | 91 | | description: "Two or more agents in the same [AgentSequenceMember] pipeline declare the same Order value. This i |
| | 1 | 92 | | helpLinkUri: HelpLinkBase + "NDLRMAF006.md", |
| | 1 | 93 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 94 | | |
| | | 95 | | /// <summary> |
| | | 96 | | /// NDLRMAF007: Gap in Order sequence within the same [AgentSequenceMember] pipeline. |
| | | 97 | | /// </summary> |
| | 1 | 98 | | public static readonly DiagnosticDescriptor GapInSequenceOrder = new( |
| | 1 | 99 | | id: MafDiagnosticIds.GapInSequenceOrder, |
| | 1 | 100 | | title: "Gap in sequential pipeline Order values", |
| | 1 | 101 | | messageFormat: "Pipeline '{0}' has a gap in its Order sequence — Order {1} is missing. Use contiguous Order valu |
| | 1 | 102 | | category: Category, |
| | 1 | 103 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 104 | | isEnabledByDefault: true, |
| | 1 | 105 | | description: "The Order values declared via [AgentSequenceMember] for this pipeline are not contiguous. This is |
| | 1 | 106 | | helpLinkUri: HelpLinkBase + "NDLRMAF007.md", |
| | 1 | 107 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 108 | | |
| | | 109 | | /// <summary> |
| | | 110 | | /// NDLRMAF008: Agent participates in no topology declaration. |
| | | 111 | | /// </summary> |
| | 1 | 112 | | public static readonly DiagnosticDescriptor OrphanAgent = new( |
| | 1 | 113 | | id: MafDiagnosticIds.OrphanAgent, |
| | 1 | 114 | | title: "Agent participates in no topology declaration", |
| | 1 | 115 | | messageFormat: "'{0}' is decorated with [NeedlrAiAgent] but does not appear in any topology declaration ([AgentH |
| | 1 | 116 | | category: Category, |
| | 1 | 117 | | defaultSeverity: DiagnosticSeverity.Info, |
| | 1 | 118 | | isEnabledByDefault: true, |
| | 1 | 119 | | description: "An agent registered with [NeedlrAiAgent] is not referenced in any topology. It will not appear in |
| | 1 | 120 | | helpLinkUri: HelpLinkBase + "NDLRMAF008.md", |
| | 1 | 121 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 122 | | |
| | | 123 | | /// <summary> |
| | | 124 | | /// NDLRMAF009: <c>[WorkflowRunTerminationCondition]</c> declared on a non-agent class. |
| | | 125 | | /// </summary> |
| | 1 | 126 | | public static readonly DiagnosticDescriptor WorkflowRunTerminationConditionOnNonAgent = new( |
| | 1 | 127 | | id: MafDiagnosticIds.WorkflowRunTerminationConditionOnNonAgent, |
| | 1 | 128 | | title: "[WorkflowRunTerminationCondition] declared on a non-agent class", |
| | 1 | 129 | | messageFormat: "'{0}' has [WorkflowRunTerminationCondition] but is not decorated with [NeedlrAiAgent]. Terminati |
| | 1 | 130 | | category: Category, |
| | 1 | 131 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 132 | | isEnabledByDefault: true, |
| | 1 | 133 | | description: "A class carries [WorkflowRunTerminationCondition] but is not decorated with [NeedlrAiAgent], so it |
| | 1 | 134 | | helpLinkUri: HelpLinkBase + "NDLRMAF009.md"); |
| | | 135 | | |
| | | 136 | | /// <summary> |
| | | 137 | | /// NDLRMAF010: Condition type does not implement <c>IWorkflowTerminationCondition</c>. |
| | | 138 | | /// </summary> |
| | 1 | 139 | | public static readonly DiagnosticDescriptor TerminationConditionTypeInvalid = new( |
| | 1 | 140 | | id: MafDiagnosticIds.TerminationConditionTypeInvalid, |
| | 1 | 141 | | title: "Termination condition type does not implement IWorkflowTerminationCondition", |
| | 1 | 142 | | messageFormat: "'{0}' does not implement IWorkflowTerminationCondition and cannot be used as a termination condi |
| | 1 | 143 | | category: Category, |
| | 1 | 144 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 145 | | isEnabledByDefault: true, |
| | 1 | 146 | | description: "The conditionType argument passed to [WorkflowRunTerminationCondition] or [AgentTerminationConditi |
| | 1 | 147 | | helpLinkUri: HelpLinkBase + "NDLRMAF010.md"); |
| | | 148 | | |
| | | 149 | | /// <summary> |
| | | 150 | | /// NDLRMAF011: Prefer <c>[AgentTerminationCondition]</c> over |
| | | 151 | | /// <c>[WorkflowRunTerminationCondition]</c> for group chat members. |
| | | 152 | | /// </summary> |
| | 1 | 153 | | public static readonly DiagnosticDescriptor PreferAgentTerminationConditionForGroupChat = new( |
| | 1 | 154 | | id: MafDiagnosticIds.PreferAgentTerminationConditionForGroupChat, |
| | 1 | 155 | | title: "Prefer [AgentTerminationCondition] over [WorkflowRunTerminationCondition] for group chat members", |
| | 1 | 156 | | messageFormat: "'{0}' is an [AgentGroupChatMember] with [WorkflowRunTerminationCondition]. Consider using [Agent |
| | 1 | 157 | | category: Category, |
| | 1 | 158 | | defaultSeverity: DiagnosticSeverity.Info, |
| | 1 | 159 | | isEnabledByDefault: true, |
| | 1 | 160 | | description: "For group chat agents, [AgentTerminationCondition] is evaluated inside MAF's group chat loop befor |
| | 1 | 161 | | helpLinkUri: HelpLinkBase + "NDLRMAF011.md"); |
| | | 162 | | |
| | | 163 | | /// <summary> |
| | | 164 | | /// NDLRMAF012: <c>[AgentFunction]</c> method has no <c>[Description]</c> attribute. |
| | | 165 | | /// </summary> |
| | 1 | 166 | | public static readonly DiagnosticDescriptor AgentFunctionMissingDescription = new( |
| | 1 | 167 | | id: MafDiagnosticIds.AgentFunctionMissingDescription, |
| | 1 | 168 | | title: "[AgentFunction] method is missing a [Description] attribute", |
| | 1 | 169 | | messageFormat: "'{0}' is decorated with [AgentFunction] but has no [Description] attribute. Without a descriptio |
| | 1 | 170 | | category: Category, |
| | 1 | 171 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 172 | | isEnabledByDefault: true, |
| | 1 | 173 | | description: "The LLM uses the [Description] text to decide when to invoke an agent function tool. A method with |
| | 1 | 174 | | helpLinkUri: HelpLinkBase + "NDLRMAF012.md"); |
| | | 175 | | |
| | | 176 | | /// <summary> |
| | | 177 | | /// NDLRMAF013: Parameter of an <c>[AgentFunction]</c> method is missing a <c>[Description]</c> attribute. |
| | | 178 | | /// </summary> |
| | 1 | 179 | | public static readonly DiagnosticDescriptor AgentFunctionParameterMissingDescription = new( |
| | 1 | 180 | | id: MafDiagnosticIds.AgentFunctionParameterMissingDescription, |
| | 1 | 181 | | title: "[AgentFunction] method parameter is missing a [Description] attribute", |
| | 1 | 182 | | messageFormat: "Parameter '{0}' on [AgentFunction] method '{1}' has no [Description] attribute. Without a descri |
| | 1 | 183 | | category: Category, |
| | 1 | 184 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 185 | | isEnabledByDefault: true, |
| | 1 | 186 | | description: "Each parameter of an [AgentFunction] method should carry a [Description] attribute so the LLM know |
| | 1 | 187 | | helpLinkUri: HelpLinkBase + "NDLRMAF013.md"); |
| | | 188 | | |
| | | 189 | | /// <summary> |
| | | 190 | | /// NDLRMAF014: A type in <c>FunctionTypes</c> on <c>[NeedlrAiAgent]</c> has no |
| | | 191 | | /// <c>[AgentFunction]</c> methods. |
| | | 192 | | /// </summary> |
| | 1 | 193 | | public static readonly DiagnosticDescriptor AgentFunctionTypesMiswired = new( |
| | 1 | 194 | | id: MafDiagnosticIds.AgentFunctionTypesMiswired, |
| | 1 | 195 | | title: "FunctionTypes entry has no [AgentFunction] methods", |
| | 1 | 196 | | messageFormat: "'{0}' is listed in FunctionTypes on '{1}' but has no methods decorated with [AgentFunction]. The |
| | 1 | 197 | | category: Category, |
| | 1 | 198 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 199 | | isEnabledByDefault: true, |
| | 1 | 200 | | description: "A type referenced in FunctionTypes must contain at least one method decorated with [AgentFunction] |
| | 1 | 201 | | helpLinkUri: HelpLinkBase + "NDLRMAF014.md"); |
| | | 202 | | |
| | | 203 | | /// <summary> |
| | | 204 | | /// NDLRMAF015: <c>.ToString()</c> is called on a tool result property that may |
| | | 205 | | /// contain a <c>JsonElement</c>. Use <c>ToolResultSerializer.Serialize()</c> instead. |
| | | 206 | | /// </summary> |
| | 1 | 207 | | public static readonly DiagnosticDescriptor ToolResultToStringCall = new( |
| | 1 | 208 | | id: MafDiagnosticIds.ToolResultToStringCall, |
| | 1 | 209 | | title: "Do not call ToString() on tool result objects", |
| | 1 | 210 | | messageFormat: "'{0}.Result.ToString()' may produce a C# type name instead of JSON. Use ToolResultSerializer.Ser |
| | 1 | 211 | | category: Category, |
| | 1 | 212 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 213 | | isEnabledByDefault: true, |
| | 1 | 214 | | description: "Tool result objects (ToolCallResult.Result, FunctionResultContent.Result) are typed as object? and |
| | 1 | 215 | | helpLinkUri: HelpLinkBase + "NDLRMAF015.md"); |
| | | 216 | | |
| | | 217 | | /// <summary> |
| | | 218 | | /// NDLRMAF016: A cycle was detected in an agent graph. |
| | | 219 | | /// </summary> |
| | 1 | 220 | | public static readonly DiagnosticDescriptor GraphCycleDetected = new( |
| | 1 | 221 | | id: MafDiagnosticIds.GraphCycleDetected, |
| | 1 | 222 | | title: "Cycle detected in agent graph", |
| | 1 | 223 | | messageFormat: "Graph '{0}' contains a cycle: {1}. Agent graphs must be directed acyclic graphs (DAGs).", |
| | 1 | 224 | | category: Category, |
| | 1 | 225 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 226 | | isEnabledByDefault: true, |
| | 1 | 227 | | description: "Agent graph workflows use superstep-based BSP execution which requires a directed acyclic graph (D |
| | 1 | 228 | | helpLinkUri: HelpLinkBase + "NDLRMAF016.md", |
| | 1 | 229 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 230 | | |
| | | 231 | | /// <summary> |
| | | 232 | | /// NDLRMAF017: A named agent graph has no entry point. |
| | | 233 | | /// </summary> |
| | 1 | 234 | | public static readonly DiagnosticDescriptor GraphNoEntryPoint = new( |
| | 1 | 235 | | id: MafDiagnosticIds.GraphNoEntryPoint, |
| | 1 | 236 | | title: "Graph has no entry point", |
| | 1 | 237 | | messageFormat: "Graph '{0}' has [AgentGraphEdge] declarations but no [AgentGraphEntry]. Every graph must have ex |
| | 1 | 238 | | category: Category, |
| | 1 | 239 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 240 | | isEnabledByDefault: true, |
| | 1 | 241 | | description: "A named agent graph requires exactly one [AgentGraphEntry] declaration to identify the starting ag |
| | 1 | 242 | | helpLinkUri: HelpLinkBase + "NDLRMAF017.md", |
| | 1 | 243 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 244 | | |
| | | 245 | | /// <summary> |
| | | 246 | | /// NDLRMAF018: A named agent graph has multiple entry points. |
| | | 247 | | /// </summary> |
| | 1 | 248 | | public static readonly DiagnosticDescriptor GraphMultipleEntryPoints = new( |
| | 1 | 249 | | id: MafDiagnosticIds.GraphMultipleEntryPoints, |
| | 1 | 250 | | title: "Graph has multiple entry points", |
| | 1 | 251 | | messageFormat: "Graph '{0}' has multiple [AgentGraphEntry] declarations: {1}. A graph must have exactly one entr |
| | 1 | 252 | | category: Category, |
| | 1 | 253 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 254 | | isEnabledByDefault: true, |
| | 1 | 255 | | description: "Each named agent graph must have exactly one [AgentGraphEntry]. Multiple entry points create ambig |
| | 1 | 256 | | helpLinkUri: HelpLinkBase + "NDLRMAF018.md", |
| | 1 | 257 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 258 | | |
| | | 259 | | /// <summary> |
| | | 260 | | /// NDLRMAF019: An <c>[AgentGraphEdge]</c> references a target that is not a declared agent. |
| | | 261 | | /// </summary> |
| | 1 | 262 | | public static readonly DiagnosticDescriptor GraphEdgeTargetNotAgent = new( |
| | 1 | 263 | | id: MafDiagnosticIds.GraphEdgeTargetNotAgent, |
| | 1 | 264 | | title: "Graph edge target is not a declared agent", |
| | 1 | 265 | | messageFormat: "'{0}' is referenced as a graph edge target but is not decorated with [NeedlrAiAgent]. Graph edge |
| | 1 | 266 | | category: Category, |
| | 1 | 267 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 268 | | isEnabledByDefault: true, |
| | 1 | 269 | | description: "Types used as targets in [AgentGraphEdge] must be decorated with [NeedlrAiAgent] so Needlr can reg |
| | 1 | 270 | | helpLinkUri: HelpLinkBase + "NDLRMAF019.md"); |
| | | 271 | | |
| | | 272 | | /// <summary> |
| | | 273 | | /// NDLRMAF020: A class has <c>[AgentGraphEdge]</c> but is not a declared agent. |
| | | 274 | | /// </summary> |
| | 1 | 275 | | public static readonly DiagnosticDescriptor GraphEdgeSourceNotAgent = new( |
| | 1 | 276 | | id: MafDiagnosticIds.GraphEdgeSourceNotAgent, |
| | 1 | 277 | | title: "Graph edge source is not a declared agent", |
| | 1 | 278 | | messageFormat: "'{0}' has [AgentGraphEdge] but is not decorated with [NeedlrAiAgent]. The source of a graph edge |
| | 1 | 279 | | category: Category, |
| | 1 | 280 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 281 | | isEnabledByDefault: true, |
| | 1 | 282 | | description: "The class that carries [AgentGraphEdge] is a node in the agent graph and must be registered with N |
| | 1 | 283 | | helpLinkUri: HelpLinkBase + "NDLRMAF020.md"); |
| | | 284 | | |
| | | 285 | | /// <summary> |
| | | 286 | | /// NDLRMAF021: A class has <c>[AgentGraphEntry]</c> but is not a declared agent. |
| | | 287 | | /// </summary> |
| | 1 | 288 | | public static readonly DiagnosticDescriptor GraphEntryPointNotAgent = new( |
| | 1 | 289 | | id: MafDiagnosticIds.GraphEntryPointNotAgent, |
| | 1 | 290 | | title: "Graph entry point is not a declared agent", |
| | 1 | 291 | | messageFormat: "'{0}' has [AgentGraphEntry] but is not decorated with [NeedlrAiAgent]. The graph entry point mus |
| | 1 | 292 | | category: Category, |
| | 1 | 293 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 294 | | isEnabledByDefault: true, |
| | 1 | 295 | | description: "The class that carries [AgentGraphEntry] is the starting node of the graph workflow and must be re |
| | 1 | 296 | | helpLinkUri: HelpLinkBase + "NDLRMAF021.md"); |
| | | 297 | | |
| | | 298 | | /// <summary> |
| | | 299 | | /// NDLRMAF022: An agent graph contains unreachable agents. |
| | | 300 | | /// </summary> |
| | 1 | 301 | | public static readonly DiagnosticDescriptor GraphUnreachableAgent = new( |
| | 1 | 302 | | id: MafDiagnosticIds.GraphUnreachableAgent, |
| | 1 | 303 | | title: "Graph contains unreachable agents", |
| | 1 | 304 | | messageFormat: "'{0}' declares edges in graph '{1}' but is not reachable from the entry point. It will never be |
| | 1 | 305 | | category: Category, |
| | 1 | 306 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 307 | | isEnabledByDefault: true, |
| | 1 | 308 | | description: "An agent that declares [AgentGraphEdge] for a named graph is not reachable from that graph's [Agen |
| | 1 | 309 | | helpLinkUri: HelpLinkBase + "NDLRMAF022.md", |
| | 1 | 310 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 311 | | |
| | | 312 | | // NDLRMAF023 (GraphInvalidMaxSupersteps) removed — MaxSupersteps property |
| | | 313 | | // was removed from AgentGraphEntryAttribute. |
| | | 314 | | |
| | | 315 | | /// <summary> |
| | | 316 | | /// NDLRMAF024: All edges from a fan-out node are optional. |
| | | 317 | | /// </summary> |
| | 1 | 318 | | public static readonly DiagnosticDescriptor GraphAllEdgesOptional = new( |
| | 1 | 319 | | id: MafDiagnosticIds.GraphAllEdgesOptional, |
| | 1 | 320 | | title: "All edges from fan-out node are optional", |
| | 1 | 321 | | messageFormat: "All {0} outgoing edges from '{1}' in graph '{2}' have IsRequired = false. If all optional branch |
| | 1 | 322 | | category: Category, |
| | 1 | 323 | | defaultSeverity: DiagnosticSeverity.Warning, |
| | 1 | 324 | | isEnabledByDefault: true, |
| | 1 | 325 | | description: "A fan-out node (a node with multiple outgoing edges) has all edges marked as optional (IsRequired |
| | 1 | 326 | | helpLinkUri: HelpLinkBase + "NDLRMAF024.md", |
| | 1 | 327 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 328 | | |
| | | 329 | | /// <summary> |
| | | 330 | | /// NDLRMAF027: A terminal node has outgoing edges. |
| | | 331 | | /// </summary> |
| | 1 | 332 | | public static readonly DiagnosticDescriptor GraphTerminalNodeHasOutgoingEdges = new( |
| | 1 | 333 | | id: MafDiagnosticIds.GraphTerminalNodeHasOutgoingEdges, |
| | 1 | 334 | | title: "Terminal node has outgoing edges", |
| | 1 | 335 | | messageFormat: "'{0}' is marked as a terminal node via [AgentGraphNode(IsTerminal = true)] in graph '{1}' but al |
| | 1 | 336 | | category: Category, |
| | 1 | 337 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 338 | | isEnabledByDefault: true, |
| | 1 | 339 | | description: "A node marked with IsTerminal = true on [AgentGraphNode] is expected to be a leaf node with no out |
| | 1 | 340 | | helpLinkUri: HelpLinkBase + "NDLRMAF027.md", |
| | 1 | 341 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 342 | | |
| | | 343 | | /// <summary> |
| | | 344 | | /// NDLRMAF025: CreateGraphWorkflow called on a graph that has WaitAny nodes. |
| | | 345 | | /// </summary> |
| | 1 | 346 | | public static readonly DiagnosticDescriptor WaitAnyIncompatibleWithCreateGraphWorkflow = new( |
| | 1 | 347 | | id: MafDiagnosticIds.WaitAnyIncompatibleWithCreateGraphWorkflow, |
| | 1 | 348 | | title: "CreateGraphWorkflow is incompatible with GraphJoinMode.WaitAny", |
| | 1 | 349 | | messageFormat: "Graph '{0}' contains a WaitAny node but CreateGraphWorkflow returns a MAF Workflow that uses BSP |
| | 1 | 350 | | category: Category, |
| | 1 | 351 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 352 | | isEnabledByDefault: true, |
| | 1 | 353 | | description: "CreateGraphWorkflow returns a MAF Workflow object that uses Bulk Synchronous Parallel (BSP) execut |
| | 1 | 354 | | helpLinkUri: HelpLinkBase + "NDLRMAF025.md", |
| | 1 | 355 | | customTags: WellKnownDiagnosticTags.CompilationEnd); |
| | | 356 | | |
| | | 357 | | /// <summary> |
| | | 358 | | /// NDLRMAF028: Condition method not found or invalid signature. |
| | | 359 | | /// </summary> |
| | 1 | 360 | | public static readonly DiagnosticDescriptor GraphConditionMethodInvalid = new( |
| | 1 | 361 | | id: MafDiagnosticIds.GraphConditionMethodInvalid, |
| | 1 | 362 | | title: "Condition method not found or has wrong signature", |
| | 1 | 363 | | messageFormat: "Condition '{0}' on [AgentGraphEdge] for '{1}' must be a public static method with signature 'sta |
| | 1 | 364 | | category: Category, |
| | 1 | 365 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 366 | | isEnabledByDefault: true, |
| | 1 | 367 | | description: "The Condition property on [AgentGraphEdge] references a static method on the decorated class that |
| | 1 | 368 | | helpLinkUri: HelpLinkBase + "NDLRMAF028.md"); |
| | | 369 | | |
| | | 370 | | /// <summary> |
| | | 371 | | /// NDLRMAF029: Reducer method not found or invalid signature. |
| | | 372 | | /// </summary> |
| | 1 | 373 | | public static readonly DiagnosticDescriptor GraphReducerMethodInvalid = new( |
| | 1 | 374 | | id: MafDiagnosticIds.GraphReducerMethodInvalid, |
| | 1 | 375 | | title: "Reducer method not found or has wrong signature", |
| | 1 | 376 | | messageFormat: "ReducerMethod '{0}' on [AgentGraphReducer] for '{1}' must be a public static method with signatu |
| | 1 | 377 | | category: Category, |
| | 1 | 378 | | defaultSeverity: DiagnosticSeverity.Error, |
| | 1 | 379 | | isEnabledByDefault: true, |
| | 1 | 380 | | description: "The ReducerMethod property on [AgentGraphReducer] references a static method that aggregates multi |
| | 1 | 381 | | helpLinkUri: HelpLinkBase + "NDLRMAF029.md"); |
| | | 382 | | } |