< Summary

Information
Class: OpenAiIntegration.ServiceCollectionExtensions
Assembly: OpenAiIntegration
File(s): /home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/ServiceCollectionExtensions.cs
Line coverage
88%
Covered lines: 39
Uncovered lines: 5
Coverable lines: 44
Total lines: 153
Line coverage: 88.6%
Branch coverage
90%
Covered branches: 9
Total branches: 10
Branch coverage: 90%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
AddOpenAiPredictor(...)100%11100%
AddOpenAiPredictor(...)100%210%
AddOpenAiPredictor(...)100%66100%
AddOpenAiPredictor(...)100%11100%
AddOpenAiPredictor(...)75%44100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/OpenAiIntegration/ServiceCollectionExtensions.cs

#LineLine coverage
 1using System.ClientModel;
 2using System.ClientModel.Primitives;
 3using EHonda.KicktippAi.Core;
 4using Microsoft.Extensions.DependencyInjection;
 5using Microsoft.Extensions.DependencyInjection.Extensions;
 6using Microsoft.Extensions.Configuration;
 7using Microsoft.Extensions.FileProviders;
 8using Microsoft.Extensions.Logging;
 9using OpenAI.Responses;
 10
 11namespace OpenAiIntegration;
 12
 13/// <summary>
 14/// Extension methods for configuring OpenAI services in dependency injection
 15/// </summary>
 16public static class ServiceCollectionExtensions
 17{
 118    private static readonly TimeSpan OpenAiNetworkTimeout = TimeSpan.FromMinutes(15);
 19
 20    /// <summary>
 21    /// Adds OpenAI predictor services to the service collection
 22    /// </summary>
 23    /// <param name="services">The service collection</param>
 24    /// <param name="apiKey">The OpenAI API key</param>
 25    /// <param name="model">The OpenAI model to use (defaults to gpt-4o-mini)</param>
 26    /// <returns>The service collection for chaining</returns>
 27    public static IServiceCollection AddOpenAiPredictor(
 28        this IServiceCollection services,
 29        string apiKey,
 30        string model = "gpt-4o-mini")
 31    {
 132        return services.AddOpenAiPredictor(apiKey, model, options: null);
 33    }
 34
 35    /// <summary>
 36    /// Adds OpenAI predictor services to the service collection
 37    /// </summary>
 38    /// <param name="services">The service collection</param>
 39    /// <param name="apiKey">The OpenAI API key</param>
 40    /// <param name="options">The prediction service options</param>
 41    /// <returns>The service collection for chaining</returns>
 42    public static IServiceCollection AddOpenAiPredictor(
 43        this IServiceCollection services,
 44        string apiKey,
 45        PredictionServiceOptions? options)
 46    {
 047        return services.AddOpenAiPredictor(apiKey, "gpt-4o-mini", options);
 48    }
 49
 50    /// <summary>
 51    /// Adds OpenAI predictor services to the service collection
 52    /// </summary>
 53    /// <param name="services">The service collection</param>
 54    /// <param name="apiKey">The OpenAI API key</param>
 55    /// <param name="model">The OpenAI model to use</param>
 56    /// <param name="options">The prediction service options</param>
 57    /// <returns>The service collection for chaining</returns>
 58    public static IServiceCollection AddOpenAiPredictor(
 59        this IServiceCollection services,
 60        string apiKey,
 61        string model,
 62        PredictionServiceOptions? options)
 63    {
 164        if (string.IsNullOrWhiteSpace(apiKey))
 65        {
 166            throw new ArgumentException("OpenAI API key cannot be null or empty", nameof(apiKey));
 67        }
 68
 69        // Register the ResponsesClient as a singleton
 170        services.TryAddSingleton<ResponsesClient>(serviceProvider =>
 171        {
 172            return new ResponsesClient(
 173                new ApiKeyCredential(apiKey),
 174                new ResponsesClientOptions
 175                {
 176                    NetworkTimeout = OpenAiNetworkTimeout,
 177                    RetryPolicy = new ClientRetryPolicy(maxRetries: 0)
 178                });
 179        });
 80
 81        // Register the predictor context
 182        services.TryAddScoped<PredictorContext>(_ => PredictorContext.CreateBasic());
 83
 84        // Register the predictor implementation
 185        services.TryAddScoped<IPredictor<PredictorContext>>(serviceProvider =>
 086            new OpenAiPredictor(
 087                serviceProvider.GetRequiredService<ResponsesClient>(),
 088                serviceProvider.GetRequiredService<ILogger<OpenAiPredictor>>(),
 089                model));
 90
 91        // Register the cost calculation service
 192        services.TryAddScoped<ICostCalculationService, CostCalculationService>();
 93
 94        // Register the file provider for prompts
 195        services.TryAddSingleton(PromptsFileProvider.Create());
 96
 97        // Register the instructions template provider
 198        services.TryAddSingleton<IInstructionsTemplateProvider, InstructionsTemplateProvider>();
 99
 1100        services.TryAddScoped<IMatchPromptReconstructionService, MatchPromptReconstructionService>();
 101
 102        // Register the token usage tracker as singleton (to accumulate across requests)
 1103        services.TryAddSingleton<ITokenUsageTracker>(serviceProvider =>
 1104            new TokenUsageTracker(
 1105                serviceProvider.GetRequiredService<ILogger<TokenUsageTracker>>(),
 1106                serviceProvider.GetRequiredService<ICostCalculationService>()));
 107
 108        // Register the prediction service with model parameter
 1109        services.TryAddScoped<IPredictionService>(serviceProvider =>
 1110            new PredictionService(
 1111                serviceProvider.GetRequiredService<ResponsesClient>(),
 1112                serviceProvider.GetRequiredService<ILogger<PredictionService>>(),
 1113                serviceProvider.GetRequiredService<ICostCalculationService>(),
 1114                serviceProvider.GetRequiredService<ITokenUsageTracker>(),
 1115                serviceProvider.GetRequiredService<IInstructionsTemplateProvider>(),
 1116                model,
 1117                options));
 118
 1119        return services;
 120    }
 121
 122    /// <summary>
 123    /// Adds OpenAI predictor services to the service collection using configuration
 124    /// </summary>
 125    /// <param name="services">The service collection</param>
 126    /// <param name="configuration">The configuration containing OpenAI settings</param>
 127    /// <returns>The service collection for chaining</returns>
 128    public static IServiceCollection AddOpenAiPredictor(
 129        this IServiceCollection services,
 130        IConfiguration configuration)
 131    {
 1132        return services.AddOpenAiPredictor(configuration, options: null);
 133    }
 134
 135    /// <summary>
 136    /// Adds OpenAI predictor services to the service collection using configuration
 137    /// </summary>
 138    /// <param name="services">The service collection</param>
 139    /// <param name="configuration">The configuration containing OpenAI settings</param>
 140    /// <param name="options">The prediction service options</param>
 141    /// <returns>The service collection for chaining</returns>
 142    public static IServiceCollection AddOpenAiPredictor(
 143        this IServiceCollection services,
 144        IConfiguration configuration,
 145        PredictionServiceOptions? options)
 146    {
 1147        var apiKey = configuration["OPENAI_API_KEY"] ??
 1148                    Environment.GetEnvironmentVariable("OPENAI_API_KEY");
 1149        var model = configuration["OPENAI_MODEL"] ?? "gpt-4o-mini";
 150
 1151        return services.AddOpenAiPredictor(apiKey!, model, options);
 152    }
 153}