< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Workflows.Diagnostics.DiagnosticsExtensions
Assembly: NexusLabs.Needlr.AgentFramework.Workflows
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Workflows/Diagnostics/DiagnosticsExtensions.cs
Line coverage
100%
Covered lines: 35
Uncovered lines: 0
Coverable lines: 35
Total lines: 64
Line coverage: 100%
Branch coverage
62%
Covered branches: 5
Total branches: 8
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
UsingDiagnostics(...)62.5%88100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework.Workflows/Diagnostics/DiagnosticsExtensions.cs

#LineLine coverage
 1using Microsoft.Extensions.AI;
 2using Microsoft.Extensions.DependencyInjection;
 3
 4using NexusLabs.Needlr.AgentFramework;
 5using NexusLabs.Needlr.AgentFramework.Diagnostics;
 6using NexusLabs.Needlr.AgentFramework.Progress;
 7using NexusLabs.Needlr.AgentFramework.Workflows.Budget;
 8
 9namespace NexusLabs.Needlr.AgentFramework.Workflows.Diagnostics;
 10
 11/// <summary>
 12/// Extension methods for wiring agent diagnostics into the <see cref="AgentFrameworkSyringe"/>.
 13/// </summary>
 14public static class DiagnosticsExtensions
 15{
 16    /// <summary>
 17    /// Enables agent-run diagnostics for every agent created by the factory.
 18    /// Wires the agent-run, chat-completion, and function-calling middleware layers,
 19    /// and emits <see cref="IAgentMetrics"/> counters/histograms for OpenTelemetry.
 20    /// Automatically includes token tracking via <c>UsingTokenTracking()</c>.
 21    /// </summary>
 22    public static AgentFrameworkSyringe UsingDiagnostics(
 23        this AgentFrameworkSyringe syringe)
 24    {
 3625        ArgumentNullException.ThrowIfNull(syringe);
 26
 3627        syringe = syringe.UsingTokenTracking();
 28
 3629        var result = syringe.Configure(opts =>
 3630        {
 3531            var metrics = opts.ServiceProvider.GetRequiredService<IAgentMetrics>();
 3532            var progressAccessor = opts.ServiceProvider.GetRequiredService<IProgressReporterAccessor>();
 3533            var metricsOptions = opts.ServiceProvider.GetService<AgentFrameworkMetricsOptions>();
 3534            var chatMiddleware = new DiagnosticsChatClientMiddleware(
 3535                metrics, progressAccessor,
 3536                metricsOptions?.ChatCompletionActivityMode ?? ChatCompletionActivityMode.Always);
 3637
 3638            // Register the real collector via the DI-managed holder — NOT a static field.
 3539            var holder = opts.ServiceProvider.GetRequiredService<ChatCompletionCollectorHolder>();
 3540            holder.SetCollector(chatMiddleware);
 3641
 3642            // Register the tool call collector via the DI-managed holder.
 3543            var toolCallCollector = new ToolCallCollector();
 3544            var toolCallHolder = opts.ServiceProvider.GetRequiredService<ToolCallCollectorHolder>();
 3545            toolCallHolder.SetCollector(toolCallCollector);
 3646
 3547            var existingFactory = opts.ChatClientFactory;
 3548            opts.ChatClientFactory = sp =>
 3549            {
 4450                var innerClient = existingFactory?.Invoke(sp)
 4451                    ?? sp.GetRequiredService<IChatClient>();
 3552
 4453                return new DiagnosticsRecordingChatClient(innerClient, chatMiddleware);
 3554            };
 7155        });
 56
 3657        return result with
 3658        {
 3659            Plugins = (result.Plugins ?? [])
 3660                .Append(new AgentDiagnosticsPlugin(syringe.ServiceProvider))
 3661                .ToList()
 3662        };
 63    }
 64}