< Summary

Information
Class: Intentum.AI.Gemini.GeminiEmbeddingProvider
Assembly: Intentum.AI.Gemini
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.AI.Gemini/GeminiEmbeddingProvider.cs
Line coverage
96%
Covered lines: 26
Uncovered lines: 1
Coverable lines: 27
Total lines: 59
Line coverage: 96.2%
Branch coverage
50%
Covered branches: 2
Total branches: 4
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(...)100%11100%
Embed(...)100%11100%
EmbedAsync()50%44100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.AI.Gemini/GeminiEmbeddingProvider.cs

#LineLine coverage
 1using System.Net.Http.Json;
 2using System.Text.Json.Serialization;
 3using Intentum.AI.Embeddings;
 4using Intentum.AI.Http;
 5using JetBrains.Annotations;
 6
 7namespace Intentum.AI.Gemini;
 8
 9/// <summary>
 10/// Gemini embedding provider. On 429 after retries throws <see cref="GeminiRateLimitException"/>.
 11/// Built-in retry for 429 (up to 5 attempts, respects Retry-After).
 12/// </summary>
 113public sealed class GeminiEmbeddingProvider(GeminiOptions options, HttpClient httpClient) : IIntentEmbeddingProvider
 14{
 15    /// <inheritdoc />
 16    public IntentEmbedding Embed(string behaviorKey)
 117        => EmbedAsync(behaviorKey, CancellationToken.None).GetAwaiter().GetResult();
 18
 19    /// <inheritdoc />
 20    public async Task<IntentEmbedding> EmbedAsync(string behaviorKey, CancellationToken cancellationToken = default)
 121    {
 122        options.Validate();
 23
 124        var request = new GeminiEmbedRequest(
 125            new GeminiContent([new GeminiPart(behaviorKey)]));
 126        var url = $"models/{options.EmbeddingModel}:embedContent?key={options.ApiKey}";
 27
 128        var response = await EmbeddingHttpRetryHandler.SendWithRetryAsync(
 129            ct => httpClient.PostAsJsonAsync(url, request, ct),
 030            (retryAfterSec, body) => throw new GeminiRateLimitException(retryAfterSec, body),
 131            cancellationToken: cancellationToken);
 32
 133        var payload = await response.Content
 134            .ReadFromJsonAsync<GeminiEmbedResponse>(cancellationToken);
 35
 136        var values = payload?.Embedding.Values ?? [];
 137        var score = EmbeddingScore.Normalize(values);
 38
 139        return new IntentEmbedding(Source: behaviorKey, Score: score);
 140    }
 41
 42    [UsedImplicitly]
 143    private sealed record GeminiEmbedRequest(
 144        [property: JsonPropertyName("content")] GeminiContent Content);
 45
 46    [UsedImplicitly]
 147    private sealed record GeminiContent(
 148        [property: JsonPropertyName("parts")] IReadOnlyList<GeminiPart> Parts);
 49
 50    [UsedImplicitly]
 151    private sealed record GeminiPart(
 152        [property: JsonPropertyName("text")] string Text);
 53
 154    private sealed record GeminiEmbedResponse(
 255        [property: JsonPropertyName("embedding")] GeminiEmbedding Embedding);
 56
 157    private sealed record GeminiEmbedding(
 258        [property: JsonPropertyName("values")] List<double> Values);
 59}