< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Workflows.Middleware.AgentResiliencePlugin
Assembly: NexusLabs.Needlr.AgentFramework.Workflows
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Workflows/Middleware/AgentResiliencePlugin.cs
Line coverage
100%
Covered lines: 18
Uncovered lines: 0
Coverable lines: 18
Total lines: 49
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Configure(...)100%11100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Workflows/Middleware/AgentResiliencePlugin.cs

#LineLine coverage
 1using Microsoft.Agents.AI;
 2
 3using NexusLabs.Needlr.AgentFramework;
 4
 5using Polly;
 6
 7namespace NexusLabs.Needlr.AgentFramework.Workflows.Middleware;
 8
 9/// <summary>
 10/// MAF agent-level middleware that wraps each agent run call in a
 11/// <see cref="ResiliencePipeline{TResult}"/> from Microsoft.Extensions.Resilience / Polly.
 12/// </summary>
 13/// <remarks>
 14/// This is the right middleware level for agent resilience because it wraps the entire
 15/// <c>RunAsync()</c> call and catches LLM failures, tool failures, and orchestration errors
 16/// together. Streaming <c>RunStreamingAsync()</c> passes through without retry.
 17/// </remarks>
 18public sealed class AgentResiliencePlugin : IAIAgentBuilderPlugin
 19{
 20    private readonly ResiliencePipeline<AgentResponse> _pipeline;
 21
 22    /// <param name="pipeline">
 23    /// The resilience pipeline to wrap around each <c>RunAsync</c> call.
 24    /// </param>
 1425    public AgentResiliencePlugin(ResiliencePipeline<AgentResponse> pipeline)
 26    {
 1427        ArgumentNullException.ThrowIfNull(pipeline);
 1328        _pipeline = pipeline;
 1329    }
 30
 31    /// <inheritdoc />
 32    public void Configure(AIAgentBuilderPluginOptions options)
 33    {
 1134        ArgumentNullException.ThrowIfNull(options);
 35
 1036        options.AgentBuilder.Use(
 1037            // Non-streaming: wrap in resilience pipeline.
 1038            async (messages, session, runOptions, innerAgent, cancellationToken) =>
 439                await _pipeline.ExecuteAsync(
 640                    async ct => await innerAgent.RunAsync(messages, session, runOptions, ct).ConfigureAwait(false),
 441                    cancellationToken)
 442                .ConfigureAwait(false),
 1043
 1044            // Streaming: pass through without retry — retrying a partially-consumed stream
 1045            // is not meaningful.
 1046            (messages, session, runOptions, innerAgent, cancellationToken) =>
 1047                innerAgent.RunStreamingAsync(messages, session, runOptions, cancellationToken));
 1048    }
 49}