< Summary

Information
Class: Intentum.AI.Models.LlmInferenceStep
Assembly: Intentum.AI
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.AI/Models/LlmInferenceStep.cs
Line coverage
80%
Covered lines: 29
Uncovered lines: 7
Coverable lines: 36
Total lines: 79
Line coverage: 80.5%
Branch coverage
50%
Covered branches: 3
Total branches: 6
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)50%44100%
Infer(...)100%11100%
InferAsync()100%110%
BuildResult(...)50%2294.11%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.AI/Models/LlmInferenceStep.cs

#LineLine coverage
 1using Intentum.AI.Embeddings;
 2using Intentum.AI.Similarity;
 3using Intentum.Core.Behavior;
 4using Intentum.Core.Intents;
 5using Intentum.Core.Pipeline;
 6
 7namespace Intentum.AI.Models;
 8
 9/// <summary>
 10/// LLM-based inference step: embeddings + similarity -> raw result (name, score, signals, reasoning).
 11/// Used by IntentResolutionPipeline; also used by LlmIntentModel internally.
 12/// </summary>
 13public sealed class LlmInferenceStep : IIntentInferenceStep
 14{
 15    private readonly IIntentEmbeddingProvider _embeddingProvider;
 16    private readonly IIntentSimilarityEngine _similarityEngine;
 17
 18    /// <summary>
 19    /// Creates an LLM inference step with the given embedding provider and similarity engine.
 20    /// </summary>
 7321    public LlmInferenceStep(
 7322        IIntentEmbeddingProvider embeddingProvider,
 7323        IIntentSimilarityEngine similarityEngine)
 7324    {
 7325        _embeddingProvider = embeddingProvider ?? throw new ArgumentNullException(nameof(embeddingProvider));
 7326        _similarityEngine = similarityEngine ?? throw new ArgumentNullException(nameof(similarityEngine));
 7327    }
 28
 29    /// <inheritdoc />
 30    public IntentInferenceResult Infer(BehaviorSpace behaviorSpace, BehaviorVector vector)
 9731    {
 9732        var embeddings = vector.Dimensions.Keys
 9733            .Select(_embeddingProvider.Embed)
 9734            .ToList();
 35
 9736        return BuildResult(behaviorSpace, embeddings, vector);
 9737    }
 38
 39    /// <summary>
 40    /// Async version of inference that properly awaits embedding calls.
 41    /// </summary>
 42    public async Task<IntentInferenceResult> InferAsync(
 43        BehaviorSpace behaviorSpace,
 44        BehaviorVector vector,
 45        CancellationToken cancellationToken = default)
 046    {
 047        var tasks = vector.Dimensions.Keys
 048            .Select(k => _embeddingProvider.EmbedAsync(k, cancellationToken));
 049        var embeddings = (await Task.WhenAll(tasks)).ToList();
 50
 051        return BuildResult(behaviorSpace, embeddings, vector);
 052    }
 53
 54    private IntentInferenceResult BuildResult(
 55        BehaviorSpace behaviorSpace,
 56        List<IntentEmbedding> embeddings,
 57        BehaviorVector vector)
 9758    {
 59        double score;
 9760        if (_similarityEngine is ITimeAwareSimilarityEngine timeAware)
 061            score = timeAware.CalculateIntentScoreWithTimeDecay(behaviorSpace, embeddings);
 62        else
 9763            score = _similarityEngine.CalculateIntentScore(embeddings, vector.Dimensions);
 64
 9765        var signals = embeddings.Select(e =>
 22866            new IntentSignal(
 22867                Source: "ai",
 22868                Description: e.Source,
 22869                Weight: e.Score))
 9770            .ToList();
 71
 9772        return new IntentInferenceResult(
 9773            Name: "AI-Inferred-Intent",
 9774            Score: score,
 9775            Signals: signals,
 9776            Reasoning: null
 9777        );
 9778    }
 79}