feat: externalize AI configuration, implement resilience policies, and update extraction prompt formatting

This commit is contained in:
2026-04-26 10:01:47 +02:00
parent d8e6931289
commit 412320980f
6 changed files with 65 additions and 38 deletions
@@ -7,6 +7,9 @@ using GeminiDotnet.Extensions.AI;
using NexusReader.Infrastructure.Persistence;
using NexusReader.Application.Abstractions.Services;
using NexusReader.Infrastructure.Services;
using NexusReader.Infrastructure.Configuration;
using Polly;
using Polly.Retry;
namespace NexusReader.Infrastructure;
@@ -18,17 +21,31 @@ public static class DependencyInjection
services.AddDbContext<AppDbContext>(options =>
options.UseSqlite(connectionString));
var apiKey = configuration["Ai:Google:ApiKey"];
if (string.IsNullOrWhiteSpace(apiKey))
{
throw new InvalidOperationException("AI Studio ApiKey is missing in configuration (Ai:Google:ApiKey).");
}
var modelId = configuration["Ai:Google:Model"] ?? "gemini-1.5-flash";
services.Configure<AiSettings>(configuration.GetSection(AiSettings.SectionName));
var aiSettings = configuration.GetSection(AiSettings.SectionName).Get<AiSettings>() ?? new AiSettings();
services.AddSingleton<IChatClient>(new GeminiChatClient(new GeminiClientOptions
if (string.IsNullOrWhiteSpace(aiSettings.ApiKey) || aiSettings.ApiKey == "PLACEHOLDER")
{
// We don't throw here to allow the app to start, but services using AI will fail gracefully
}
services.AddResiliencePipeline("ai-retry", builder =>
{
builder.AddRetry(new RetryStrategyOptions
{
ShouldHandle = new PredicateBuilder().Handle<Exception>(ex =>
ex.Message.Contains("429") || ex.Message.Contains("Too Many Requests") || ex.Message.Contains("quota")),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true,
MaxRetryAttempts = aiSettings.RetryAttempts,
Delay = TimeSpan.FromSeconds(2)
});
});
services.AddChatClient(new GeminiChatClient(new GeminiClientOptions
{
ApiKey = apiKey,
ModelId = modelId
ApiKey = aiSettings.ApiKey,
ModelId = aiSettings.Model
}));
services.AddScoped<IKnowledgeService, KnowledgeService>();