< Summary

Information
Class: Elsa.AI.Copilot.Adapters.ElsaCopilotToolFunction
Assembly: Elsa.AI.Copilot
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.AI.Copilot/Adapters/ElsaCopilotToolFunction.cs
Line coverage
90%
Covered lines: 47
Uncovered lines: 5
Coverable lines: 52
Total lines: 89
Line coverage: 90.3%
Branch coverage
65%
Covered branches: 13
Total branches: 20
Branch coverage: 65%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.cctor()100%11100%
get_Name()100%11100%
get_Description()100%11100%
get_JsonSchema()100%11100%
get_JsonSerializerOptions()100%210%
get_UnderlyingMethod()100%210%
get_AdditionalProperties()100%11100%
InvokeCoreAsync()50%22100%
InvokeToolAsync()50%22100%
ReadToolCallId(...)75%9871.42%
ToJsonObject(...)75%44100%
CreateAdditionalProperties(...)50%4488.88%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.AI.Copilot/Adapters/ElsaCopilotToolFunction.cs

#LineLine coverage
 1using System.Reflection;
 2using System.Text.Json;
 3using Elsa.AI.Abstractions.Contracts;
 4using Elsa.AI.Abstractions.Models;
 5using GitHub.Copilot;
 6using Microsoft.Extensions.AI;
 7
 8namespace Elsa.AI.Copilot.Adapters;
 9
 210public class ElsaCopilotToolFunction(AIToolDefinition definition, IAIProviderToolInvoker toolInvoker) : AIFunction
 11{
 112    private static readonly MethodInfo InvokeMethod = typeof(ElsaCopilotToolFunction).GetMethod(nameof(InvokeToolAsync),
 113    private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
 214    private readonly JsonElement _jsonSchema = JsonSerializer.SerializeToElement(definition.Schema, SerializerOptions);
 215    private readonly IReadOnlyDictionary<string, object?> _additionalProperties = CreateAdditionalProperties(definition)
 16
 117    public override string Name => definition.Name;
 118    public override string Description => definition.Description;
 119    public override JsonElement JsonSchema => _jsonSchema;
 020    public override JsonSerializerOptions JsonSerializerOptions => SerializerOptions;
 021    public override MethodInfo UnderlyingMethod => InvokeMethod;
 122    public override IReadOnlyDictionary<string, object?> AdditionalProperties => _additionalProperties;
 23
 24    protected override async ValueTask<object?> InvokeCoreAsync(AIFunctionArguments arguments, CancellationToken cancell
 25    {
 126        var result = await InvokeToolAsync(arguments, cancellationToken);
 127        return new ToolResultAIContent(new ToolResultObject
 128        {
 129            TextResultForLlm = result.Summary,
 130            ResultType = result.Status == AIToolInvocationStatus.Failed ? "error" : "text",
 131            Error = result.Error,
 132            ToolTelemetry = new Dictionary<string, object>
 133            {
 134                ["status"] = result.Status.ToString(),
 135                ["toolName"] = definition.Name
 136            }
 137        });
 138    }
 39
 40    private async ValueTask<AIToolResult> InvokeToolAsync(AIFunctionArguments arguments, CancellationToken cancellationT
 41    {
 142        var invocation = new AIProviderToolInvocation
 143        {
 144            Id = ReadToolCallId(arguments) ?? Guid.NewGuid().ToString("N"),
 145            ToolName = definition.Name,
 146            Arguments = ToJsonObject(arguments)
 147        };
 48
 149        return await toolInvoker.InvokeAsync(invocation, cancellationToken);
 150    }
 51
 52    private static string? ReadToolCallId(AIFunctionArguments arguments)
 53    {
 154        if (arguments.Context == null)
 055            return null;
 56
 357        foreach (var value in arguments.Context.Values)
 58        {
 159            if (value is ToolInvocation invocation && !string.IsNullOrWhiteSpace(invocation.ToolCallId))
 160                return invocation.ToolCallId;
 61        }
 62
 063        return null;
 164    }
 65
 66    private static JsonObject ToJsonObject(AIFunctionArguments arguments)
 67    {
 168        var json = new JsonObject();
 469        foreach (var (key, value) in arguments)
 170            json[key] = value == null ? null : JsonSerializer.SerializeToNode(value, SerializerOptions);
 71
 172        return json;
 73    }
 74
 75    private static IReadOnlyDictionary<string, object?> CreateAdditionalProperties(AIToolDefinition definition)
 76    {
 277        var properties = new Dictionary<string, object?>
 278        {
 279            ["elsa_mutability"] = definition.Mutability.ToString(),
 280            ["elsa_danger_level"] = definition.DangerLevel.ToString(),
 281            ["skip_permission"] = definition.Mutability == AIToolMutability.ReadOnly && definition.DangerLevel == AITool
 282        };
 83
 284        if (!string.IsNullOrWhiteSpace(definition.Provider))
 085            properties["elsa_provider"] = definition.Provider;
 86
 287        return properties;
 88    }
 89}