< Summary

Information
Class: NexusLabs.Needlr.AgentFramework.Iterative.IterationRecordEvaluationExtensions
Assembly: NexusLabs.Needlr.AgentFramework
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework/Iterative/IterationRecordEvaluationExtensions.cs
Line coverage
100%
Covered lines: 27
Uncovered lines: 0
Coverable lines: 27
Total lines: 83
Line coverage: 100%
Branch coverage
91%
Covered branches: 11
Total branches: 12
Branch coverage: 91.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ToToolCallTrajectory(...)87.5%88100%
ToToolCallTrajectory(...)100%44100%

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.AgentFramework/Iterative/IterationRecordEvaluationExtensions.cs

#LineLine coverage
 1using Microsoft.Extensions.AI;
 2
 3namespace NexusLabs.Needlr.AgentFramework.Iterative;
 4
 5/// <summary>
 6/// Extensions that convert <see cref="IterationRecord"/> and collections of iteration
 7/// records into Microsoft.Extensions.AI shapes suitable for evaluation libraries
 8/// (e.g., Microsoft.Extensions.AI.Evaluation's <c>ToolCallAccuracyEvaluator</c>).
 9/// </summary>
 10public static class IterationRecordEvaluationExtensions
 11{
 12    /// <summary>
 13    /// Materializes a tool-call trajectory as a list of <see cref="ChatMessage"/>
 14    /// instances suitable for Microsoft.Extensions.AI.Evaluation trajectory-aware
 15    /// evaluators. Each tool call becomes an assistant message containing a
 16    /// <see cref="FunctionCallContent"/>, immediately followed by a tool message
 17    /// containing the matching <see cref="FunctionResultContent"/>.
 18    /// </summary>
 19    /// <param name="record">The iteration record to convert.</param>
 20    /// <returns>
 21    /// An ordered trajectory of <see cref="ChatMessage"/> entries. Empty if the
 22    /// iteration produced no tool calls.
 23    /// </returns>
 24    public static IReadOnlyList<ChatMessage> ToToolCallTrajectory(this IterationRecord record)
 25    {
 826        ArgumentNullException.ThrowIfNull(record);
 27
 728        if (record.ToolCalls.Count == 0)
 29        {
 230            return Array.Empty<ChatMessage>();
 31        }
 32
 533        var messages = new List<ChatMessage>(record.ToolCalls.Count * 2);
 2634        for (var i = 0; i < record.ToolCalls.Count; i++)
 35        {
 836            var call = record.ToolCalls[i];
 837            var callId = $"i{record.Iteration}-c{i}";
 38
 839            var callContent = new FunctionCallContent(
 840                callId: callId,
 841                name: call.FunctionName,
 842                arguments: call.Arguments is null
 843                    ? null
 844                    : new Dictionary<string, object?>(call.Arguments));
 845            messages.Add(new ChatMessage(ChatRole.Assistant, [callContent]));
 46
 847            var resultContent = new FunctionResultContent(
 848                callId: callId,
 849                result: call.Succeeded
 850                    ? ToolResultSerializer.Serialize(call.Result)
 851                    : call.ErrorMessage);
 852            messages.Add(new ChatMessage(ChatRole.Tool, [resultContent]));
 53        }
 54
 555        return messages;
 56    }
 57
 58    /// <summary>
 59    /// Materializes a tool-call trajectory across an entire iterative run by
 60    /// concatenating the trajectories of each iteration in order.
 61    /// </summary>
 62    /// <param name="records">The iteration records to flatten.</param>
 63    /// <returns>
 64    /// An ordered trajectory of <see cref="ChatMessage"/> entries across all
 65    /// iterations. Empty if no iteration produced any tool calls.
 66    /// </returns>
 67    public static IReadOnlyList<ChatMessage> ToToolCallTrajectory(
 68        this IEnumerable<IterationRecord> records)
 69    {
 270        ArgumentNullException.ThrowIfNull(records);
 71
 172        var messages = new List<ChatMessage>();
 873        foreach (var record in records)
 74        {
 1875            foreach (var message in record.ToToolCallTrajectory())
 76            {
 677                messages.Add(message);
 78            }
 79        }
 80
 181        return messages;
 82    }
 83}