feat: externalize AI configuration, implement resilience policies, and update extraction prompt formatting
This commit is contained in:
@@ -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>();
|
||||
|
||||
Reference in New Issue
Block a user